OSDN Git Service

Merge tag '5.6-rc-smb3-plugfest-patches' of git://git.samba.org/sfrench/cifs-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 9 Feb 2020 21:27:17 +0000 (13:27 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 9 Feb 2020 21:27:17 +0000 (13:27 -0800)
Pull cifs fixes from Steve French:
 "13 cifs/smb3 patches, most from testing at the SMB3 plugfest this week:

   - Important fix for multichannel and for modefromsid mounts.

   - Two reconnect fixes

   - Addition of SMB3 change notify support

   - Backup tools fix

   - A few additional minor debug improvements (tracepoints and
     additional logging found useful during testing this week)"

* tag '5.6-rc-smb3-plugfest-patches' of git://git.samba.org/sfrench/cifs-2.6:
  smb3: Add defines for new information level, FileIdInformation
  smb3: print warning once if posix context returned on open
  smb3: add one more dynamic tracepoint missing from strict fsync path
  cifs: fix mode bits from dir listing when mounted with modefromsid
  cifs: fix channel signing
  cifs: add SMB3 change notification support
  cifs: make multichannel warning more visible
  cifs: fix soft mounts hanging in the reconnect code
  cifs: Add tracepoints for errors on flush or fsync
  cifs: log warning message (once) if out of disk space
  cifs: fail i/o on soft mounts if sessionsetup errors out
  smb3: fix problem with null cifs super block with previous patch
  SMB3: Backup intent flag missing from some more ops

2455 files changed:
.mailmap
Documentation/ABI/testing/rtc-cdev
Documentation/ABI/testing/sysfs-driver-pciback
Documentation/ABI/testing/sysfs-driver-xen-blkback
Documentation/admin-guide/bootconfig.rst [new file with mode: 0644]
Documentation/admin-guide/index.rst
Documentation/admin-guide/kernel-parameters.txt
Documentation/admin-guide/pm/cpuidle.rst
Documentation/admin-guide/pm/intel_idle.rst
Documentation/admin-guide/pm/sleep-states.rst
Documentation/arm/microchip.rst
Documentation/devicetree/bindings/arm/amlogic.yaml
Documentation/devicetree/bindings/arm/atmel-at91.yaml
Documentation/devicetree/bindings/arm/atmel-sysregs.txt
Documentation/devicetree/bindings/arm/cpus.yaml
Documentation/devicetree/bindings/arm/fsl.yaml
Documentation/devicetree/bindings/arm/msm/qcom,llcc.yaml
Documentation/devicetree/bindings/arm/psci.yaml
Documentation/devicetree/bindings/arm/qcom.yaml
Documentation/devicetree/bindings/arm/rockchip.yaml
Documentation/devicetree/bindings/arm/sprd/sprd.yaml [moved from Documentation/devicetree/bindings/arm/sprd.yaml with 92% similarity]
Documentation/devicetree/bindings/arm/sunxi.yaml
Documentation/devicetree/bindings/arm/ux500.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-de-clks.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clocks.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/amlogic,meson8-ddr-clkc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/amlogic,meson8b-clkc.txt
Documentation/devicetree/bindings/clock/bitmain,bm1880-clk.yaml
Documentation/devicetree/bindings/clock/fsl,plldig.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/imx8mn-clock.yaml
Documentation/devicetree/bindings/clock/imx8mp-clock.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/milbeaut-clock.yaml
Documentation/devicetree/bindings/clock/qcom,dispcc.txt [deleted file]
Documentation/devicetree/bindings/clock/qcom,gcc-apq8064.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-ipq8074.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-msm8996.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-msm8998.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-qcs404.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-sc7180.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc-sm8150.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,gcc.yaml
Documentation/devicetree/bindings/clock/qcom,gpucc.txt [deleted file]
Documentation/devicetree/bindings/clock/qcom,mmcc.txt [deleted file]
Documentation/devicetree/bindings/clock/qcom,mmcc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,msm8998-gpucc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,rpmhcc.yaml
Documentation/devicetree/bindings/clock/qcom,sc7180-dispcc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,sc7180-videocc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,sdm845-dispcc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,sdm845-gpucc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,sdm845-videocc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/clock/qcom,videocc.txt [deleted file]
Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
Documentation/devicetree/bindings/clock/st,stm32mp1-rcc.yaml
Documentation/devicetree/bindings/clock/sun8i-de2.txt [deleted file]
Documentation/devicetree/bindings/clock/sun9i-de.txt [deleted file]
Documentation/devicetree/bindings/clock/sun9i-usb.txt [deleted file]
Documentation/devicetree/bindings/clock/ti-clkctrl.txt
Documentation/devicetree/bindings/clock/ti/dra7-atl.txt
Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/display/mxsfb.txt
Documentation/devicetree/bindings/dma/atmel-xdma.txt
Documentation/devicetree/bindings/eeprom/at24.yaml
Documentation/devicetree/bindings/eeprom/at25.txt
Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
Documentation/devicetree/bindings/hwmon/adi,ltc2947.yaml
Documentation/devicetree/bindings/i2c/i2c-at91.txt
Documentation/devicetree/bindings/i2c/i2c-jz4780.txt
Documentation/devicetree/bindings/i2c/i2c-mux-pca954x.txt
Documentation/devicetree/bindings/i2c/renesas,i2c.txt
Documentation/devicetree/bindings/i2c/renesas,iic.txt
Documentation/devicetree/bindings/iio/adc/adi,ad7124.yaml
Documentation/devicetree/bindings/iio/adc/adi,ad7192.yaml
Documentation/devicetree/bindings/iio/adc/at91-sama5d2_adc.txt
Documentation/devicetree/bindings/iio/adc/microchip,mcp3911.yaml
Documentation/devicetree/bindings/iio/adc/st,stm32-dfsdm-adc.yaml
Documentation/devicetree/bindings/iio/dac/lltc,ltc1660.yaml
Documentation/devicetree/bindings/input/gpio-vibrator.yaml
Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
Documentation/devicetree/bindings/input/touchscreen/goodix.txt [deleted file]
Documentation/devicetree/bindings/input/touchscreen/goodix.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/input/touchscreen/touchscreen.txt
Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/iommu/iommu.txt
Documentation/devicetree/bindings/leds/leds-lm3692x.txt
Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.txt
Documentation/devicetree/bindings/media/atmel-isi.txt
Documentation/devicetree/bindings/media/fsl-pxp.txt
Documentation/devicetree/bindings/media/rc.yaml
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.txt [deleted file]
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/ab8500.txt
Documentation/devicetree/bindings/mfd/atmel-gpbr.txt
Documentation/devicetree/bindings/mfd/atmel-matrix.txt
Documentation/devicetree/bindings/mfd/atmel-smc.txt
Documentation/devicetree/bindings/mfd/atmel-usart.txt
Documentation/devicetree/bindings/mfd/da9062.txt
Documentation/devicetree/bindings/mfd/max14577.txt
Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/mfd/tps6105x.txt
Documentation/devicetree/bindings/misc/aspeed-p2a-ctrl.txt
Documentation/devicetree/bindings/mtd/atmel-nand.txt
Documentation/devicetree/bindings/net/can/atmel-can.txt
Documentation/devicetree/bindings/net/can/rcar_can.txt
Documentation/devicetree/bindings/net/can/rcar_canfd.txt
Documentation/devicetree/bindings/nvmem/nvmem.yaml
Documentation/devicetree/bindings/pci/intel-gw-pcie.yaml
Documentation/devicetree/bindings/phy/intel,lgm-emmc-phy.yaml
Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/pinctrl/aspeed,ast2400-pinctrl.yaml
Documentation/devicetree/bindings/pinctrl/aspeed,ast2500-pinctrl.yaml
Documentation/devicetree/bindings/power/qcom,rpmpd.txt [deleted file]
Documentation/devicetree/bindings/power/qcom,rpmpd.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/power/reset/xlnx,zynqmp-power.txt
Documentation/devicetree/bindings/pwm/allwinner,sun4i-a10-pwm.yaml
Documentation/devicetree/bindings/pwm/mxs-pwm.txt
Documentation/devicetree/bindings/remoteproc/mtk,scp.txt [new file with mode: 0644]
Documentation/devicetree/bindings/remoteproc/qcom,adsp.txt
Documentation/devicetree/bindings/remoteproc/qcom,q6v5.txt
Documentation/devicetree/bindings/reset/brcm,bcm7216-pcie-sata-rescal.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/reset/intel,rcu-gw.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/reset/nuvoton,npcm-reset.txt [new file with mode: 0644]
Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt [deleted file]
Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml [new file with mode: 0644]
Documentation/devicetree/bindings/soc/mediatek/scpsys.txt
Documentation/devicetree/bindings/spi/fsl-spi.txt
Documentation/devicetree/bindings/timer/renesas,tmu.txt
Documentation/devicetree/bindings/vendor-prefixes.yaml
Documentation/devicetree/bindings/watchdog/da9062-wdt.txt
Documentation/devicetree/bindings/watchdog/mtk-wdt.txt
Documentation/doc-guide/contributing.rst
Documentation/doc-guide/maintainer-profile.rst
Documentation/driver-api/dmaengine/client.rst
Documentation/features/debug/kprobes-on-ftrace/arch-support.txt
Documentation/filesystems/fuse.rst [moved from Documentation/filesystems/fuse.txt with 80% similarity]
Documentation/filesystems/index.rst
Documentation/filesystems/mount_api.txt
Documentation/i2c/busses/i2c-parport-light.rst [deleted file]
Documentation/i2c/busses/index.rst
Documentation/i2c/dev-interface.rst
Documentation/i2c/dma-considerations.rst
Documentation/i2c/i2c-protocol.rst
Documentation/i2c/i2c-topology.rst
Documentation/i2c/i2c.svg [new file with mode: 0644]
Documentation/i2c/index.rst
Documentation/i2c/instantiating-devices.rst
Documentation/i2c/old-module-parameters.rst
Documentation/i2c/slave-interface.rst
Documentation/i2c/smbus-protocol.rst
Documentation/i2c/summary.rst
Documentation/i2c/writing-clients.rst
Documentation/locking/spinlocks.rst
Documentation/memory-barriers.txt
Documentation/networking/nf_flowtable.txt
Documentation/power/interface.rst [deleted file]
Documentation/powerpc/imc.rst [new file with mode: 0644]
Documentation/powerpc/index.rst
Documentation/powerpc/papr_hcalls.rst [new file with mode: 0644]
Documentation/process/changes.rst
Documentation/trace/boottime-trace.rst [new file with mode: 0644]
Documentation/trace/events.rst
Documentation/trace/index.rst
Documentation/trace/kprobetrace.rst
Documentation/translations/it_IT/process/changes.rst
Documentation/translations/ko_KR/howto.rst
Documentation/virt/kvm/api.txt
MAINTAINERS
arch/Kconfig
arch/alpha/kernel/srm_env.c
arch/arc/include/asm/pgtable.h
arch/arm/Kconfig
arch/arm/Kconfig.debug
arch/arm/boot/compressed/Makefile
arch/arm/boot/compressed/head.S
arch/arm/boot/dts/Makefile
arch/arm/boot/dts/am335x-evm.dts
arch/arm/boot/dts/am335x-evmsk.dts
arch/arm/boot/dts/am335x-icev2.dts
arch/arm/boot/dts/am33xx-l4.dtsi
arch/arm/boot/dts/am33xx.dtsi
arch/arm/boot/dts/am3517.dtsi
arch/arm/boot/dts/am3703.dtsi [new file with mode: 0644]
arch/arm/boot/dts/am3715.dtsi [new file with mode: 0644]
arch/arm/boot/dts/am4372.dtsi
arch/arm/boot/dts/am437x-l4.dtsi
arch/arm/boot/dts/am437x-sk-evm.dts
arch/arm/boot/dts/am43x-epos-evm.dts
arch/arm/boot/dts/am43xx-clocks.dtsi
arch/arm/boot/dts/am57xx-idk-common.dtsi
arch/arm/boot/dts/armada-385-clearfog-gtr-l8.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-385-clearfog-gtr-s4.dts [new file with mode: 0644]
arch/arm/boot/dts/armada-385-clearfog-gtr.dtsi [new file with mode: 0644]
arch/arm/boot/dts/armada-388-clearfog.dtsi
arch/arm/boot/dts/armada-388-helios4.dts
arch/arm/boot/dts/armada-38x-solidrun-microsom.dtsi
arch/arm/boot/dts/aspeed-bmc-facebook-wedge100.dts
arch/arm/boot/dts/aspeed-bmc-facebook-wedge40.dts
arch/arm/boot/dts/aspeed-bmc-facebook-yamp.dts
arch/arm/boot/dts/aspeed-bmc-ibm-rainier.dts
arch/arm/boot/dts/aspeed-bmc-inspur-fp5280g2.dts
arch/arm/boot/dts/aspeed-bmc-opp-swift.dts
arch/arm/boot/dts/aspeed-bmc-opp-vesnin.dts
arch/arm/boot/dts/aspeed-bmc-opp-witherspoon.dts
arch/arm/boot/dts/aspeed-g4.dtsi
arch/arm/boot/dts/aspeed-g5.dtsi
arch/arm/boot/dts/aspeed-g6.dtsi
arch/arm/boot/dts/ast2500-facebook-netbmc-common.dtsi
arch/arm/boot/dts/at91-kizbox.dts
arch/arm/boot/dts/at91-kizboxmini-base.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-kizboxmini-common.dtsi [moved from arch/arm/boot/dts/at91-kizboxmini.dts with 51% similarity]
arch/arm/boot/dts/at91-kizboxmini-mb.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-kizboxmini-rd.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-nattis-2-natte-2.dts
arch/arm/boot/dts/at91-sam9x60ek.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-sama5d27_som1.dtsi
arch/arm/boot/dts/at91-sama5d27_som1_ek.dts
arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi [new file with mode: 0644]
arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts [new file with mode: 0644]
arch/arm/boot/dts/at91-smartkiz.dts [new file with mode: 0644]
arch/arm/boot/dts/at91sam9260.dtsi
arch/arm/boot/dts/at91sam9261.dtsi
arch/arm/boot/dts/at91sam9263.dtsi
arch/arm/boot/dts/at91sam9g45.dtsi
arch/arm/boot/dts/at91sam9rl.dtsi
arch/arm/boot/dts/bcm2711.dtsi
arch/arm/boot/dts/bcm2835-common.dtsi
arch/arm/boot/dts/bcm283x.dtsi
arch/arm/boot/dts/bcm958625hr.dts
arch/arm/boot/dts/dm3725.dtsi [new file with mode: 0644]
arch/arm/boot/dts/dra7-evm-common.dtsi
arch/arm/boot/dts/dra7-l4.dtsi
arch/arm/boot/dts/dra7.dtsi
arch/arm/boot/dts/dra72-evm-common.dtsi
arch/arm/boot/dts/dra72x.dtsi
arch/arm/boot/dts/dra74x.dtsi
arch/arm/boot/dts/dra76-evm.dts
arch/arm/boot/dts/dra76x.dtsi
arch/arm/boot/dts/dra7xx-clocks.dtsi
arch/arm/boot/dts/e60k02.dtsi
arch/arm/boot/dts/exynos3250.dtsi
arch/arm/boot/dts/exynos4210-universal_c210.dts
arch/arm/boot/dts/exynos4210.dtsi
arch/arm/boot/dts/exynos4412-galaxy-s3.dtsi
arch/arm/boot/dts/exynos4412-midas.dtsi
arch/arm/boot/dts/exynos4412-n710x.dts
arch/arm/boot/dts/exynos4412-odroid-common.dtsi
arch/arm/boot/dts/exynos4412-tiny4412.dts
arch/arm/boot/dts/exynos4412.dtsi
arch/arm/boot/dts/exynos5.dtsi
arch/arm/boot/dts/exynos5250-arndale.dts
arch/arm/boot/dts/exynos5250-smdk5250.dts
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/boot/dts/exynos5260-xyref5260.dts
arch/arm/boot/dts/exynos5260.dtsi
arch/arm/boot/dts/exynos5410-odroidxu.dts
arch/arm/boot/dts/exynos5410-smdk5410.dts
arch/arm/boot/dts/exynos5410.dtsi
arch/arm/boot/dts/exynos5420-arndale-octa.dts
arch/arm/boot/dts/exynos5420-cpus.dtsi
arch/arm/boot/dts/exynos5420-smdk5420.dts
arch/arm/boot/dts/exynos5420.dtsi
arch/arm/boot/dts/exynos5422-cpus.dtsi
arch/arm/boot/dts/exynos5422-odroid-core.dtsi
arch/arm/boot/dts/exynos5422-odroidhc1.dts
arch/arm/boot/dts/exynos5422-odroidxu3-common.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/ibm-power9-dual.dtsi
arch/arm/boot/dts/imx25-eukrea-mbimxsd25-baseboard.dts
arch/arm/boot/dts/imx25-pdk.dts
arch/arm/boot/dts/imx25.dtsi
arch/arm/boot/dts/imx51-babbage.dts
arch/arm/boot/dts/imx6dl-gw5907.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw5910.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw5912.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6dl-gw5913.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw5907.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw5910.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw5912.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-gw5913.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6q-logicpd.dts
arch/arm/boot/dts/imx6qdl-apalis.dtsi
arch/arm/boot/dts/imx6qdl-gw5907.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw5910.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw5912.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-gw5913.dtsi [new file with mode: 0644]
arch/arm/boot/dts/imx6qdl-icore-1.5.dtsi
arch/arm/boot/dts/imx6qdl-icore.dtsi
arch/arm/boot/dts/imx6qdl-phytec-phycore-som.dtsi
arch/arm/boot/dts/imx6qdl-zii-rdu2.dtsi
arch/arm/boot/dts/imx6sl-tolino-shine3.dts [new file with mode: 0644]
arch/arm/boot/dts/imx6sll.dtsi
arch/arm/boot/dts/imx6sx-sdb-reva.dts
arch/arm/boot/dts/imx6ul-14x14-evk.dtsi
arch/arm/boot/dts/imx6ull-colibri.dtsi
arch/arm/boot/dts/imx7d-pico.dtsi
arch/arm/boot/dts/imx7d-sdb-reva.dts
arch/arm/boot/dts/imx7d.dtsi
arch/arm/boot/dts/imx7s.dtsi
arch/arm/boot/dts/imx7ulp-com.dts [new file with mode: 0644]
arch/arm/boot/dts/iwg20d-q7-common.dtsi
arch/arm/boot/dts/iwg20d-q7-dbcm-ca.dtsi
arch/arm/boot/dts/ls1021a-tsn.dts
arch/arm/boot/dts/ls1021a.dtsi
arch/arm/boot/dts/meson.dtsi
arch/arm/boot/dts/meson6.dtsi
arch/arm/boot/dts/meson8.dtsi
arch/arm/boot/dts/meson8b-ec100.dts
arch/arm/boot/dts/meson8b-mxq.dts
arch/arm/boot/dts/meson8b-odroidc1.dts
arch/arm/boot/dts/meson8b.dtsi
arch/arm/boot/dts/mmp3-dell-ariel.dts
arch/arm/boot/dts/mmp3.dtsi
arch/arm/boot/dts/motorola-cpcap-mapphone.dtsi
arch/arm/boot/dts/motorola-mapphone-common.dtsi
arch/arm/boot/dts/omap2.dtsi
arch/arm/boot/dts/omap2430.dtsi
arch/arm/boot/dts/omap3-echo.dts [new file with mode: 0644]
arch/arm/boot/dts/omap3-n900.dts
arch/arm/boot/dts/omap3.dtsi
arch/arm/boot/dts/omap36xx.dtsi
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/omap44xx-clocks.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/omap54xx-clocks.dtsi
arch/arm/boot/dts/qcom-apq8084.dtsi
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/r7s72100.dtsi
arch/arm/boot/dts/r8a73a4.dtsi
arch/arm/boot/dts/r8a7740-armadillo800eva.dts
arch/arm/boot/dts/r8a7740.dtsi
arch/arm/boot/dts/r8a7743.dtsi
arch/arm/boot/dts/r8a7744.dtsi
arch/arm/boot/dts/r8a7745-iwg22d-sodimm.dts
arch/arm/boot/dts/r8a7745.dtsi
arch/arm/boot/dts/r8a77470-iwg23s-sbc.dts
arch/arm/boot/dts/r8a77470.dtsi
arch/arm/boot/dts/r8a7778.dtsi
arch/arm/boot/dts/r8a7779-marzen.dts
arch/arm/boot/dts/r8a7779.dtsi
arch/arm/boot/dts/r8a7790-lager.dts
arch/arm/boot/dts/r8a7790.dtsi
arch/arm/boot/dts/r8a7791-koelsch.dts
arch/arm/boot/dts/r8a7791-porter.dts
arch/arm/boot/dts/r8a7791.dtsi
arch/arm/boot/dts/r8a7792.dtsi
arch/arm/boot/dts/r8a7793-gose.dts
arch/arm/boot/dts/r8a7793.dtsi
arch/arm/boot/dts/r8a7794-alt.dts
arch/arm/boot/dts/r8a7794-silk.dts
arch/arm/boot/dts/r8a7794.dtsi
arch/arm/boot/dts/rk3036.dtsi
arch/arm/boot/dts/rk3188-bqedison2qc.dts
arch/arm/boot/dts/rk322x.dtsi
arch/arm/boot/dts/rk3288-evb.dtsi
arch/arm/boot/dts/rk3288-tinker.dtsi
arch/arm/boot/dts/rk3288-veyron-brain.dts
arch/arm/boot/dts/rk3288-veyron-broadcom-bluetooth.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rk3288-veyron-chromebook.dtsi
arch/arm/boot/dts/rk3288-veyron-edp.dtsi
arch/arm/boot/dts/rk3288-veyron-fievel.dts
arch/arm/boot/dts/rk3288-veyron-jaq.dts
arch/arm/boot/dts/rk3288-veyron-jerry.dts
arch/arm/boot/dts/rk3288-veyron-mickey.dts
arch/arm/boot/dts/rk3288-veyron-minnie.dts
arch/arm/boot/dts/rk3288-veyron-pinky.dts
arch/arm/boot/dts/rk3288-veyron-speedy.dts
arch/arm/boot/dts/rk3288-veyron-tiger.dts
arch/arm/boot/dts/rk3288-veyron.dtsi
arch/arm/boot/dts/rk3288.dtsi
arch/arm/boot/dts/rk3xxx.dtsi
arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi [new file with mode: 0644]
arch/arm/boot/dts/rv1108.dtsi
arch/arm/boot/dts/s3c2416-smdk2416.dts
arch/arm/boot/dts/s3c6410-smdk6410.dts
arch/arm/boot/dts/sam9x60.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sama5d2.dtsi
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sama5d3_can.dtsi
arch/arm/boot/dts/sama5d3_tcb1.dtsi
arch/arm/boot/dts/sama5d3_uart.dtsi
arch/arm/boot/dts/sh73a0.dtsi
arch/arm/boot/dts/ste-ab8500.dtsi
arch/arm/boot/dts/ste-ab8505.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-db8500.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-db8520.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-dbx5x0-pinctrl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-dbx5x0.dtsi
arch/arm/boot/dts/ste-href-ab8505.dtsi [deleted file]
arch/arm/boot/dts/ste-href-family-pinctrl.dtsi
arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi [new file with mode: 0644]
arch/arm/boot/dts/ste-href-tvk1281618.dtsi
arch/arm/boot/dts/ste-href.dtsi
arch/arm/boot/dts/ste-href520-tvk.dts [new file with mode: 0644]
arch/arm/boot/dts/ste-hrefprev60-stuib.dts
arch/arm/boot/dts/ste-hrefprev60-tvk.dts
arch/arm/boot/dts/ste-hrefprev60.dtsi
arch/arm/boot/dts/ste-hrefv60plus-stuib.dts
arch/arm/boot/dts/ste-hrefv60plus-tvk.dts
arch/arm/boot/dts/ste-hrefv60plus.dtsi
arch/arm/boot/dts/ste-nomadik-pinctrl.dtsi
arch/arm/boot/dts/ste-snowball.dts
arch/arm/boot/dts/ste-ux500-samsung-golden.dts [new file with mode: 0644]
arch/arm/boot/dts/stm32429i-eval.dts
arch/arm/boot/dts/stm32f4-pinctrl.dtsi
arch/arm/boot/dts/stm32f429.dtsi
arch/arm/boot/dts/stm32f469-disco.dts
arch/arm/boot/dts/stm32f7-pinctrl.dtsi
arch/arm/boot/dts/stm32f746.dtsi
arch/arm/boot/dts/stm32h743.dtsi
arch/arm/boot/dts/stm32mp15-pinctrl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/stm32mp151.dtsi [moved from arch/arm/boot/dts/stm32mp157c.dtsi with 87% similarity]
arch/arm/boot/dts/stm32mp153.dtsi [new file with mode: 0644]
arch/arm/boot/dts/stm32mp157-pinctrl.dtsi [deleted file]
arch/arm/boot/dts/stm32mp157.dtsi [new file with mode: 0644]
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/stm32mp157xaa-pinctrl.dtsi [deleted file]
arch/arm/boot/dts/stm32mp157xab-pinctrl.dtsi [deleted file]
arch/arm/boot/dts/stm32mp157xac-pinctrl.dtsi [deleted file]
arch/arm/boot/dts/stm32mp157xad-pinctrl.dtsi [deleted file]
arch/arm/boot/dts/stm32mp15xc.dtsi [new file with mode: 0644]
arch/arm/boot/dts/stm32mp15xx-dkx.dtsi [new file with mode: 0644]
arch/arm/boot/dts/stm32mp15xxaa-pinctrl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/stm32mp15xxab-pinctrl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/stm32mp15xxac-pinctrl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/stm32mp15xxad-pinctrl.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun4i-a10.dtsi
arch/arm/boot/dts/sun5i.dtsi
arch/arm/boot/dts/sun6i-a31.dtsi
arch/arm/boot/dts/sun7i-a20.dtsi
arch/arm/boot/dts/sun8i-a23-a33.dtsi
arch/arm/boot/dts/sun8i-a83t.dtsi
arch/arm/boot/dts/sun8i-h3-beelink-x2.dts
arch/arm/boot/dts/sun8i-h3-emlid-neutis-n5h3-devboard.dts [new file with mode: 0644]
arch/arm/boot/dts/sun8i-h3-emlid-neutis-n5h3.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sun8i-h3-nanopi-duo2.dts
arch/arm/boot/dts/sun8i-h3.dtsi
arch/arm/boot/dts/sun8i-r40.dtsi
arch/arm/boot/dts/sun8i-v3s.dtsi
arch/arm/boot/dts/sun9i-a80.dtsi
arch/arm/boot/dts/sunxi-h3-h5-emlid-neutis.dtsi [new file with mode: 0644]
arch/arm/boot/dts/sunxi-h3-h5.dtsi
arch/arm/boot/dts/sunxi-libretech-all-h3-it.dtsi [new file with mode: 0644]
arch/arm/boot/dts/tegra124-apalis-emc.dtsi
arch/arm/boot/dts/tegra124-jetson-tk1-emc.dtsi
arch/arm/boot/dts/tegra124-nyan-big-emc.dtsi
arch/arm/boot/dts/tegra124-nyan-blaze-emc.dtsi
arch/arm/boot/dts/tegra124.dtsi
arch/arm/boot/dts/tegra20-paz00.dts
arch/arm/boot/dts/uniphier-ld4.dtsi
arch/arm/boot/dts/uniphier-pinctrl.dtsi
arch/arm/boot/dts/uniphier-pro4.dtsi
arch/arm/boot/dts/uniphier-pro5.dtsi
arch/arm/boot/dts/uniphier-pxs2.dtsi
arch/arm/boot/dts/uniphier-sld8.dtsi
arch/arm/boot/dts/vf610-zii-dev-rev-b.dts
arch/arm/boot/dts/vf610-zii-scu4-aib.dts
arch/arm/boot/dts/zynq-7000.dtsi
arch/arm/configs/at91_dt_defconfig
arch/arm/configs/exynos_defconfig
arch/arm/configs/gemini_defconfig
arch/arm/configs/imx_v6_v7_defconfig
arch/arm/configs/multi_v7_defconfig
arch/arm/configs/qcom_defconfig
arch/arm/configs/shmobile_defconfig
arch/arm/configs/u8500_defconfig
arch/arm/include/asm/arch_gicv3.h
arch/arm/include/asm/pgtable-2level.h
arch/arm/include/asm/pgtable-3level.h
arch/arm/include/asm/pgtable-nommu.h
arch/arm/include/asm/tlb.h
arch/arm/include/debug/brcmstb.S
arch/arm/kernel/atags_proc.c
arch/arm/kernel/stacktrace.c
arch/arm/kernel/traps.c
arch/arm/mach-at91/Kconfig
arch/arm/mach-at91/Makefile
arch/arm/mach-at91/at91sam9.c
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/sam9x60.c [new file with mode: 0644]
arch/arm/mach-bcm/Kconfig
arch/arm/mach-davinci/Makefile
arch/arm/mach-davinci/board-dm365-evm.c
arch/arm/mach-davinci/board-dm644x-evm.c
arch/arm/mach-davinci/devices-da8xx.c
arch/arm/mach-davinci/devices.c
arch/arm/mach-davinci/dm365.c
arch/arm/mach-davinci/include/mach/common.h
arch/arm/mach-davinci/include/mach/time.h [deleted file]
arch/arm/mach-davinci/time.c [deleted file]
arch/arm/mach-exynos/Kconfig
arch/arm/mach-exynos/common.h
arch/arm/mach-exynos/exynos.c
arch/arm/mach-exynos/include/mach/map.h
arch/arm/mach-exynos/pm.c
arch/arm/mach-exynos/smc.h
arch/arm/mach-exynos/suspend.c
arch/arm/mach-imx/Kconfig
arch/arm/mach-imx/cpu.c
arch/arm/mach-omap2/Makefile
arch/arm/mach-omap2/clockdomains43xx_data.c
arch/arm/mach-omap2/clockdomains7xx_data.c
arch/arm/mach-omap2/common.h
arch/arm/mach-omap2/dma.c
arch/arm/mach-omap2/io.c
arch/arm/mach-omap2/omap-iommu.c
arch/arm/mach-omap2/omap-secure.c
arch/arm/mach-omap2/omap-secure.h
arch/arm/mach-omap2/omap-smc.S
arch/arm/mach-omap2/omap_device.c
arch/arm/mach-omap2/omap_device.h
arch/arm/mach-omap2/omap_hwmod.c
arch/arm/mach-omap2/omap_hwmod.h
arch/arm/mach-omap2/omap_hwmod_2420_data.c
arch/arm/mach-omap2/omap_hwmod_2430_data.c
arch/arm/mach-omap2/omap_hwmod_2xxx_ipblock_data.c
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_3xxx_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_hwmod_common_data.h
arch/arm/mach-omap2/omap_hwmod_reset.c
arch/arm/mach-omap2/pdata-quirks.c
arch/arm/mach-omap2/pm24xx.c
arch/arm/mach-omap2/pm33xx-core.c
arch/arm/mach-omap2/pm34xx.c
arch/arm/mach-omap2/prcm43xx.h
arch/arm/mach-s3c24xx/Kconfig
arch/arm/mach-s3c24xx/mach-rx1950.c
arch/arm/mach-s3c64xx/Kconfig
arch/arm/mach-tegra/sleep-tegra30.S
arch/arm/mach-zynq/platsmp.c
arch/arm/mm/alignment.c
arch/arm/mm/dma-mapping.c
arch/arm/mm/init.c
arch/arm/plat-omap/dma.c
arch/arm/plat-samsung/adc.c
arch/arm/plat-samsung/devs.c
arch/arm/plat-samsung/gpio-samsung.c
arch/arm/plat-samsung/include/plat/samsung-time.h
arch/arm64/Kconfig
arch/arm64/Kconfig.debug
arch/arm64/boot/dts/allwinner/Makefile
arch/arm64/boot/dts/allwinner/axp803.dtsi
arch/arm64/boot/dts/allwinner/sun50i-a64-amarula-relic.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-bananapi-m64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-a64-nanopi-a64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-oceanic-5205-5inmfd.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino-emmc.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-olinuxino.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-orangepi-win.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-plus.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pine64.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-pinebook.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine-baseboard.dts
arch/arm64/boot/dts/allwinner/sun50i-a64-sopine.dtsi
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-devboard.dts
arch/arm64/boot/dts/allwinner/sun50i-h5-emlid-neutis-n5.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h3-cc.dts
arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h3-it.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h5-cc.dts [new file with mode: 0644]
arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo-plus2.dts
arch/arm64/boot/dts/allwinner/sun50i-h5-nanopi-neo2.dts
arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-prime.dts
arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus.dts
arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-zero-plus2.dts
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-lite2.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi-one-plus.dts
arch/arm64/boot/dts/allwinner/sun50i-h6-orangepi.dtsi
arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts [new file with mode: 0644]
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/Makefile
arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/Makefile
arch/arm64/boot/dts/amlogic/meson-a1.dtsi
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
arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-gxl-s905d-libretech-pc.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts [new file with mode: 0644]
arch/arm64/boot/dts/amlogic/meson-sm1.dtsi
arch/arm64/boot/dts/bitmain/bm1880-sophon-edge.dts
arch/arm64/boot/dts/bitmain/bm1880.dtsi
arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
arch/arm64/boot/dts/exynos/exynos5433-tm2.dts
arch/arm64/boot/dts/exynos/exynos5433-tm2e.dts
arch/arm64/boot/dts/exynos/exynos7-espresso.dts
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-frwy.dts
arch/arm64/boot/dts/freescale/fsl-ls1046a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1088a-qds.dts
arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa-rdb.dtsi
arch/arm64/boot/dts/freescale/fsl-ls208xa.dtsi
arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-lx2160a-honeycomb.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/fsl-lx2160a-rdb.dts
arch/arm64/boot/dts/freescale/fsl-lx2160a.dtsi
arch/arm64/boot/dts/freescale/imx8mm-evk.dts
arch/arm64/boot/dts/freescale/imx8mm-pinfunc.h
arch/arm64/boot/dts/freescale/imx8mm.dtsi
arch/arm64/boot/dts/freescale/imx8mn-ddr4-evk.dts
arch/arm64/boot/dts/freescale/imx8mn-evk.dtsi
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-phanbell.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq-sr-som.dtsi
arch/arm64/boot/dts/freescale/imx8mq-thor96.dts [new file with mode: 0644]
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-rmb3.dts
arch/arm64/boot/dts/freescale/imx8mq-zii-ultra-zest.dts
arch/arm64/boot/dts/freescale/imx8mq.dtsi
arch/arm64/boot/dts/freescale/imx8qxp.dtsi
arch/arm64/boot/dts/hisilicon/hi3798cv200-poplar.dts
arch/arm64/boot/dts/hisilicon/hi3798cv200.dtsi
arch/arm64/boot/dts/intel/Makefile
arch/arm64/boot/dts/intel/socfpga_agilex.dtsi
arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts [new file with mode: 0644]
arch/arm64/boot/dts/marvell/armada-3720-uDPU.dts
arch/arm64/boot/dts/marvell/armada-8040-clearfog-gt-8k.dts
arch/arm64/boot/dts/mediatek/mt8173.dtsi
arch/arm64/boot/dts/mediatek/mt8183.dtsi
arch/arm64/boot/dts/nvidia/tegra132.dtsi
arch/arm64/boot/dts/nvidia/tegra186-p3310.dtsi
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-p3450-0000.dts
arch/arm64/boot/dts/qcom/Makefile
arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi
arch/arm64/boot/dts/qcom/apq8016-sbc.dtsi
arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi [deleted file]
arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi [deleted file]
arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts [new file with mode: 0644]
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/pm6150.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/pm6150l.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/pm8004.dtsi
arch/arm64/boot/dts/qcom/pm8916.dtsi
arch/arm64/boot/dts/qcom/pm8994.dtsi
arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
arch/arm64/boot/dts/qcom/qcs404.dtsi
arch/arm64/boot/dts/qcom/sc7180-idp.dts [new file with mode: 0644]
arch/arm64/boot/dts/qcom/sc7180.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/qcom/sdm845-cheza.dtsi
arch/arm64/boot/dts/qcom/sdm845-db845c.dts
arch/arm64/boot/dts/qcom/sdm845-mtp.dts
arch/arm64/boot/dts/qcom/sdm845.dtsi
arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts
arch/arm64/boot/dts/qcom/sm8150-mtp.dts
arch/arm64/boot/dts/qcom/sm8150.dtsi
arch/arm64/boot/dts/renesas/Makefile
arch/arm64/boot/dts/renesas/hihope-common.dtsi
arch/arm64/boot/dts/renesas/r8a774a1.dtsi
arch/arm64/boot/dts/renesas/r8a774b1.dtsi
arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dts [new file with mode: 0644]
arch/arm64/boot/dts/renesas/r8a774c0.dtsi
arch/arm64/boot/dts/renesas/r8a77950-salvator-x.dts [moved from arch/arm64/boot/dts/renesas/r8a7795-es1-salvator-x.dts with 96% similarity]
arch/arm64/boot/dts/renesas/r8a77950-ulcb-kf.dts [moved from arch/arm64/boot/dts/renesas/r8a7795-h3ulcb-kf.dts with 75% similarity]
arch/arm64/boot/dts/renesas/r8a77950-ulcb.dts [moved from arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb.dts with 89% similarity]
arch/arm64/boot/dts/renesas/r8a77950.dtsi [moved from arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi with 98% similarity]
arch/arm64/boot/dts/renesas/r8a77951-salvator-x.dts [moved from arch/arm64/boot/dts/renesas/r8a7795-salvator-x.dts with 96% similarity]
arch/arm64/boot/dts/renesas/r8a77951-salvator-xs.dts [moved from arch/arm64/boot/dts/renesas/r8a7795-salvator-xs.dts with 96% similarity]
arch/arm64/boot/dts/renesas/r8a77951-ulcb-kf.dts [moved from arch/arm64/boot/dts/renesas/r8a7795-es1-h3ulcb-kf.dts with 75% similarity]
arch/arm64/boot/dts/renesas/r8a77951-ulcb.dts [moved from arch/arm64/boot/dts/renesas/r8a7795-h3ulcb.dts with 92% similarity]
arch/arm64/boot/dts/renesas/r8a77951.dtsi [moved from arch/arm64/boot/dts/renesas/r8a7795.dtsi with 94% similarity]
arch/arm64/boot/dts/renesas/r8a77960-salvator-x.dts [moved from arch/arm64/boot/dts/renesas/r8a7796-salvator-x.dts with 94% similarity]
arch/arm64/boot/dts/renesas/r8a77960-salvator-xs.dts [moved from arch/arm64/boot/dts/renesas/r8a7796-salvator-xs.dts with 94% similarity]
arch/arm64/boot/dts/renesas/r8a77960-ulcb-kf.dts [moved from arch/arm64/boot/dts/renesas/r8a7796-m3ulcb-kf.dts with 77% similarity]
arch/arm64/boot/dts/renesas/r8a77960-ulcb.dts [moved from arch/arm64/boot/dts/renesas/r8a7796-m3ulcb.dts with 90% similarity]
arch/arm64/boot/dts/renesas/r8a77960.dtsi [moved from arch/arm64/boot/dts/renesas/r8a7796.dtsi with 94% similarity]
arch/arm64/boot/dts/renesas/r8a77961.dtsi
arch/arm64/boot/dts/renesas/r8a77965-ulcb-kf.dts [moved from arch/arm64/boot/dts/renesas/r8a77965-m3nulcb-kf.dts with 92% similarity]
arch/arm64/boot/dts/renesas/r8a77965-ulcb.dts [moved from arch/arm64/boot/dts/renesas/r8a77965-m3nulcb.dts with 100% similarity]
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-ebisu.dts
arch/arm64/boot/dts/renesas/r8a77990.dtsi
arch/arm64/boot/dts/renesas/r8a77995.dtsi
arch/arm64/boot/dts/renesas/salvator-common.dtsi
arch/arm64/boot/dts/renesas/ulcb.dtsi
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.dtsi
arch/arm64/boot/dts/rockchip/rk3328.dtsi
arch/arm64/boot/dts/rockchip/rk3368-lion-haikou.dts
arch/arm64/boot/dts/rockchip/rk3368.dtsi
arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
arch/arm64/boot/dts/rockchip/rk3399-gru-bob.dts
arch/arm64/boot/dts/rockchip/rk3399-gru-kevin.dts
arch/arm64/boot/dts/rockchip/rk3399-hugsun-x99.dts
arch/arm64/boot/dts/rockchip/rk3399-khadas-edge.dtsi
arch/arm64/boot/dts/rockchip/rk3399-nanopc-t4.dts
arch/arm64/boot/dts/rockchip/rk3399-nanopi4.dtsi
arch/arm64/boot/dts/rockchip/rk3399-orangepi.dts
arch/arm64/boot/dts/rockchip/rk3399-roc-pc-mezzanine.dts
arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dtsi
arch/arm64/boot/dts/rockchip/rk3399-rock-pi-4.dts
arch/arm64/boot/dts/rockchip/rk3399-rock960.dtsi
arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts
arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399-sapphire-excavator.dts
arch/arm64/boot/dts/rockchip/rk3399.dtsi
arch/arm64/boot/dts/rockchip/rk3399pro-rock-pi-n10.dts [new file with mode: 0644]
arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/socionext/uniphier-ld11.dtsi
arch/arm64/boot/dts/socionext/uniphier-ld20.dtsi
arch/arm64/boot/dts/socionext/uniphier-pxs3.dtsi
arch/arm64/boot/dts/sprd/Makefile
arch/arm64/boot/dts/sprd/sc9863a.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/sprd/sharkl3.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/sprd/sp9863a-1h10.dts [new file with mode: 0644]
arch/arm64/boot/dts/ti/k3-am65-main.dtsi
arch/arm64/boot/dts/ti/k3-am65-mcu.dtsi
arch/arm64/boot/dts/ti/k3-am65.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-mcu-wakeup.dtsi
arch/arm64/boot/dts/ti/k3-j721e-som-p0.dtsi
arch/arm64/boot/dts/ti/k3-j721e.dtsi
arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi [new file with mode: 0644]
arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi [deleted file]
arch/arm64/boot/dts/xilinx/zynqmp-zc1232-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp-zc1254-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp-zc1275-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm015-dc1.dts
arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm016-dc2.dts
arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm017-dc3.dts
arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm018-dc4.dts
arch/arm64/boot/dts/xilinx/zynqmp-zc1751-xm019-dc5.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu100-revC.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu102-revB.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu104-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu106-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp-zcu111-revA.dts
arch/arm64/boot/dts/xilinx/zynqmp.dtsi
arch/arm64/configs/defconfig
arch/arm64/include/asm/Kbuild
arch/arm64/include/asm/arch_gicv3.h
arch/arm64/include/asm/pgtable.h
arch/arm64/include/asm/ptdump.h
arch/arm64/mm/Makefile
arch/arm64/mm/dump.c
arch/arm64/mm/mmu.c
arch/arm64/mm/ptdump_debugfs.c
arch/csky/include/asm/Kbuild
arch/ia64/kernel/salinfo.c
arch/m68k/configs/amcore_defconfig
arch/m68k/configs/m5208evb_defconfig
arch/m68k/configs/m5249evb_defconfig
arch/m68k/configs/m5272c3_defconfig
arch/m68k/configs/m5275evb_defconfig
arch/m68k/configs/m5307c3_defconfig
arch/m68k/configs/m5407c3_defconfig
arch/m68k/configs/m5475evb_defconfig
arch/m68k/include/asm/uaccess_no.h
arch/m68k/kernel/bootinfo_proc.c
arch/microblaze/Kconfig
arch/microblaze/configs/mmu_defconfig
arch/microblaze/configs/nommu_defconfig
arch/microblaze/kernel/cpu/cache.c
arch/microblaze/kernel/cpu/cpuinfo.c
arch/microblaze/kernel/head.S
arch/microblaze/mm/init.c
arch/mips/include/asm/Kbuild
arch/mips/include/asm/pgtable.h
arch/mips/kernel/traps.c
arch/mips/kvm/mips.c
arch/mips/lasat/picvue_proc.c
arch/parisc/configs/712_defconfig [deleted file]
arch/parisc/configs/a500_defconfig [deleted file]
arch/parisc/configs/b180_defconfig [deleted file]
arch/parisc/configs/c3000_defconfig [deleted file]
arch/parisc/configs/c8000_defconfig [deleted file]
arch/parisc/configs/defconfig [deleted file]
arch/parisc/configs/generic-32bit_defconfig
arch/parisc/configs/generic-64bit_defconfig
arch/parisc/mm/init.c
arch/powerpc/Kconfig
arch/powerpc/Kconfig.debug
arch/powerpc/Makefile.postlink
arch/powerpc/boot/4xx.c
arch/powerpc/boot/dts/mgcoge.dts
arch/powerpc/boot/dts/mpc832x_rdb.dts
arch/powerpc/boot/dts/mpc8610_hpcd.dts
arch/powerpc/configs/44x/akebono_defconfig
arch/powerpc/configs/44x/sam440ep_defconfig
arch/powerpc/configs/52xx/pcm030_defconfig
arch/powerpc/configs/83xx/kmeter1_defconfig
arch/powerpc/configs/adder875_defconfig
arch/powerpc/configs/ep8248e_defconfig
arch/powerpc/configs/ep88xc_defconfig
arch/powerpc/configs/guest.config
arch/powerpc/configs/mgcoge_defconfig
arch/powerpc/configs/mpc512x_defconfig
arch/powerpc/configs/mpc885_ads_defconfig
arch/powerpc/configs/powernv_defconfig
arch/powerpc/configs/ppc64_defconfig
arch/powerpc/configs/ppc6xx_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/configs/skiroot_defconfig
arch/powerpc/configs/storcenter_defconfig
arch/powerpc/configs/tqm8xx_defconfig
arch/powerpc/include/asm/book3s/32/kup.h
arch/powerpc/include/asm/book3s/32/pgalloc.h
arch/powerpc/include/asm/book3s/32/pgtable.h
arch/powerpc/include/asm/book3s/64/kup-radix.h
arch/powerpc/include/asm/book3s/64/pgalloc.h
arch/powerpc/include/asm/book3s/64/pgtable.h
arch/powerpc/include/asm/cpm.h
arch/powerpc/include/asm/cputable.h
arch/powerpc/include/asm/firmware.h
arch/powerpc/include/asm/futex.h
arch/powerpc/include/asm/hw_breakpoint.h
arch/powerpc/include/asm/kasan.h
arch/powerpc/include/asm/kup.h
arch/powerpc/include/asm/nohash/32/kup-8xx.h
arch/powerpc/include/asm/nohash/32/pgtable.h
arch/powerpc/include/asm/nohash/pgalloc.h
arch/powerpc/include/asm/page.h
arch/powerpc/include/asm/pci-bridge.h
arch/powerpc/include/asm/pci.h
arch/powerpc/include/asm/pgtable.h
arch/powerpc/include/asm/pnv-pci.h
arch/powerpc/include/asm/processor.h
arch/powerpc/include/asm/reg_8xx.h
arch/powerpc/include/asm/thread_info.h
arch/powerpc/include/asm/tlb.h
arch/powerpc/include/asm/uaccess.h
arch/powerpc/include/asm/vdso_datapage.h
arch/powerpc/include/asm/xive.h
arch/powerpc/kernel/Makefile
arch/powerpc/kernel/asm-offsets.c
arch/powerpc/kernel/dt_cpu_ftrs.c
arch/powerpc/kernel/eeh.c
arch/powerpc/kernel/eeh_cache.c
arch/powerpc/kernel/eeh_driver.c
arch/powerpc/kernel/eeh_sysfs.c
arch/powerpc/kernel/entry_32.S
arch/powerpc/kernel/entry_64.S
arch/powerpc/kernel/exceptions-64s.S
arch/powerpc/kernel/fpu.S
arch/powerpc/kernel/head_32.S
arch/powerpc/kernel/head_32.h
arch/powerpc/kernel/head_40x.S
arch/powerpc/kernel/head_8xx.S
arch/powerpc/kernel/head_booke.h
arch/powerpc/kernel/head_fsl_booke.S
arch/powerpc/kernel/hw_breakpoint.c
arch/powerpc/kernel/idle.c
arch/powerpc/kernel/idle_book3s.S
arch/powerpc/kernel/idle_power4.S [deleted file]
arch/powerpc/kernel/irq.c
arch/powerpc/kernel/pci-common.c
arch/powerpc/kernel/pci-hotplug.c
arch/powerpc/kernel/pci_dn.c
arch/powerpc/kernel/pci_of_scan.c
arch/powerpc/kernel/proc_powerpc.c
arch/powerpc/kernel/process.c
arch/powerpc/kernel/rtas-proc.c
arch/powerpc/kernel/rtas_flash.c
arch/powerpc/kernel/rtasd.c
arch/powerpc/kernel/setup.h
arch/powerpc/kernel/setup_32.c
arch/powerpc/kernel/setup_64.c
arch/powerpc/kernel/traps.c
arch/powerpc/kernel/vdso.c
arch/powerpc/kernel/vdso32/Makefile
arch/powerpc/kernel/vdso32/cacheflush.S
arch/powerpc/kernel/vdso32/datapage.S
arch/powerpc/kernel/vdso32/getcpu.S
arch/powerpc/kernel/vdso32/gettimeofday.S
arch/powerpc/kernel/vdso32/vdso32.lds.S
arch/powerpc/kernel/vector.S
arch/powerpc/kernel/vmlinux.lds.S
arch/powerpc/kvm/book3s_64_mmu_radix.c
arch/powerpc/kvm/book3s_hv_rmhandlers.S
arch/powerpc/kvm/book3s_xive.c
arch/powerpc/mm/book3s32/hash_low.S
arch/powerpc/mm/book3s32/mmu.c
arch/powerpc/mm/book3s64/hash_utils.c
arch/powerpc/mm/book3s64/pgtable.c
arch/powerpc/mm/book3s64/radix_pgtable.c
arch/powerpc/mm/book3s64/radix_tlb.c
arch/powerpc/mm/fault.c
arch/powerpc/mm/kasan/kasan_init_32.c
arch/powerpc/mm/mem.c
arch/powerpc/mm/mmu_decl.h
arch/powerpc/mm/nohash/8xx.c
arch/powerpc/mm/numa.c
arch/powerpc/mm/pgtable_32.c
arch/powerpc/mm/ptdump/ptdump.c
arch/powerpc/oprofile/backtrace.c
arch/powerpc/perf/8xx-pmu.c
arch/powerpc/perf/callchain.c
arch/powerpc/perf/core-book3s.c
arch/powerpc/platforms/512x/mpc512x_lpbfifo.c
arch/powerpc/platforms/83xx/km83xx.c
arch/powerpc/platforms/83xx/misc.c
arch/powerpc/platforms/83xx/mpc832x_mds.c
arch/powerpc/platforms/83xx/mpc832x_rdb.c
arch/powerpc/platforms/83xx/mpc836x_mds.c
arch/powerpc/platforms/83xx/mpc836x_rdk.c
arch/powerpc/platforms/83xx/mpc83xx.h
arch/powerpc/platforms/85xx/corenet_generic.c
arch/powerpc/platforms/85xx/mpc85xx_mds.c
arch/powerpc/platforms/85xx/mpc85xx_rdb.c
arch/powerpc/platforms/85xx/smp.c
arch/powerpc/platforms/85xx/twr_p102x.c
arch/powerpc/platforms/Kconfig
arch/powerpc/platforms/Kconfig.cputype
arch/powerpc/platforms/cell/spufs/inode.c
arch/powerpc/platforms/maple/setup.c
arch/powerpc/platforms/powernv/opal.c
arch/powerpc/platforms/powernv/pci-ioda.c
arch/powerpc/platforms/powernv/pci.c
arch/powerpc/platforms/powernv/pci.h
arch/powerpc/platforms/powernv/setup.c
arch/powerpc/platforms/pseries/Kconfig
arch/powerpc/platforms/pseries/firmware.c
arch/powerpc/platforms/pseries/hotplug-memory.c
arch/powerpc/platforms/pseries/iommu.c
arch/powerpc/platforms/pseries/lpar.c
arch/powerpc/platforms/pseries/lparcfg.c
arch/powerpc/platforms/pseries/papr_scm.c
arch/powerpc/platforms/pseries/pci.c
arch/powerpc/platforms/pseries/reconfig.c
arch/powerpc/platforms/pseries/scanlog.c
arch/powerpc/platforms/pseries/vio.c
arch/powerpc/sysdev/fsl_pci.c
arch/powerpc/sysdev/mpic.c
arch/powerpc/tools/relocs_check.sh
arch/powerpc/xmon/dis-asm.h
arch/powerpc/xmon/xmon.c
arch/riscv/include/asm/Kbuild
arch/riscv/include/asm/pgtable-64.h
arch/riscv/include/asm/pgtable.h
arch/s390/Kconfig
arch/s390/crypto/paes_s390.c
arch/s390/hypfs/inode.c
arch/s390/include/asm/Kbuild
arch/s390/include/asm/kprobes.h
arch/s390/include/asm/kvm_host.h
arch/s390/include/asm/page.h
arch/s390/include/asm/pgtable.h
arch/s390/include/uapi/asm/pkey.h
arch/s390/include/uapi/asm/zcrypt.h
arch/s390/kernel/ftrace.c
arch/s390/kernel/kprobes.c
arch/s390/kernel/mcount.S
arch/s390/kvm/interrupt.c
arch/s390/kvm/kvm-s390.c
arch/s390/mm/hugetlbpage.c
arch/sh/mm/alignment.c
arch/sparc/Kconfig
arch/sparc/include/asm/pgtable_64.h
arch/sparc/include/asm/tlb_64.h
arch/sparc/kernel/led.c
arch/sparc/kernel/sys_sparc_64.c
arch/um/drivers/mconsole_kern.c
arch/um/kernel/exitcode.c
arch/um/kernel/process.c
arch/x86/Kconfig
arch/x86/Kconfig.debug
arch/x86/boot/compressed/acpi.c
arch/x86/hyperv/hv_init.c
arch/x86/include/asm/Kbuild
arch/x86/include/asm/apic.h
arch/x86/include/asm/kvm_host.h
arch/x86/include/asm/pci.h
arch/x86/include/asm/pgtable.h
arch/x86/include/asm/tlb.h
arch/x86/include/asm/vmx.h
arch/x86/include/asm/vmxfeatures.h
arch/x86/include/asm/x86_init.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/msi.c
arch/x86/kernel/cpu/mtrr/if.c
arch/x86/kernel/cpu/resctrl/rdtgroup.c
arch/x86/kernel/kvm.c
arch/x86/kernel/time.c
arch/x86/kernel/x86_init.c
arch/x86/kvm/hyperv.c
arch/x86/kvm/i8254.c
arch/x86/kvm/ioapic.c
arch/x86/kvm/lapic.c
arch/x86/kvm/lapic.h
arch/x86/kvm/mmu/mmu.c
arch/x86/kvm/svm.c
arch/x86/kvm/trace.h
arch/x86/kvm/vmx/evmcs.c
arch/x86/kvm/vmx/evmcs.h
arch/x86/kvm/vmx/nested.c
arch/x86/kvm/vmx/pmu_intel.c
arch/x86/kvm/vmx/vmx.c
arch/x86/kvm/x86.c
arch/x86/kvm/x86.h
arch/x86/mm/Makefile
arch/x86/mm/debug_pagetables.c
arch/x86/mm/dump_pagetables.c
arch/x86/platform/efi/efi.c
arch/x86/platform/efi/efi_32.c
arch/x86/platform/efi/efi_64.c
arch/x86/platform/uv/tlb_uv.c
arch/x86/xen/enlighten_pv.c
arch/xtensa/Kconfig
arch/xtensa/configs/audio_kc705_defconfig
arch/xtensa/configs/cadence_csp_defconfig
arch/xtensa/configs/generic_kc705_defconfig
arch/xtensa/configs/iss_defconfig
arch/xtensa/configs/nommu_kc705_defconfig
arch/xtensa/configs/smp_lx200_defconfig
arch/xtensa/configs/virt_defconfig
arch/xtensa/include/asm/Kbuild
arch/xtensa/include/asm/asmmacro.h
arch/xtensa/include/asm/core.h
arch/xtensa/include/asm/platform.h
arch/xtensa/include/asm/processor.h
arch/xtensa/include/asm/vectors.h
arch/xtensa/include/uapi/asm/setup.h
arch/xtensa/kernel/coprocessor.S
arch/xtensa/kernel/entry.S
arch/xtensa/kernel/platform.c
arch/xtensa/kernel/setup.c
arch/xtensa/kernel/vectors.S
arch/xtensa/kernel/vmlinux.lds.S
arch/xtensa/platforms/iss/include/platform/simcall.h
arch/xtensa/platforms/iss/setup.c
arch/xtensa/platforms/iss/simdisk.c
arch/xtensa/platforms/xtfpga/setup.c
block/bfq-cgroup.c
block/bfq-iosched.c
block/bfq-iosched.h
block/bfq-wf2q.c
crypto/af_alg.c
drivers/acpi/acpi_apd.c
drivers/acpi/arm64/iort.c
drivers/acpi/battery.c
drivers/acpi/proc.c
drivers/acpi/scan.c
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/pata_arasan_cf.c
drivers/ata/pata_pcmcia.c
drivers/base/devtmpfs.c
drivers/base/memory.c
drivers/base/power/domain.c
drivers/block/Kconfig
drivers/block/brd.c
drivers/block/drbd/drbd_int.h
drivers/block/drbd/drbd_nl.c
drivers/block/drbd/drbd_receiver.c
drivers/block/drbd/drbd_worker.c
drivers/block/nbd.c
drivers/block/null_blk_main.c
drivers/block/rbd.c
drivers/block/virtio_blk.c
drivers/block/xen-blkback/blkback.c
drivers/block/xen-blkback/common.h
drivers/block/xen-blkback/xenbus.c
drivers/block/xen-blkfront.c
drivers/bus/Kconfig
drivers/bus/moxtet.c
drivers/bus/ti-sysc.c
drivers/char/hpet.c
drivers/char/hw_random/bcm2835-rng.c
drivers/char/hw_random/omap-rng.c
drivers/clk/Kconfig
drivers/clk/Makefile
drivers/clk/at91/clk-sam9x60-pll.c
drivers/clk/at91/sam9x60.c
drivers/clk/clk-asm9260.c
drivers/clk/clk-bd718x7.c
drivers/clk/clk-bm1880.c
drivers/clk/clk-composite.c
drivers/clk/clk-divider.c
drivers/clk/clk-fixed-rate.c
drivers/clk/clk-fsl-sai.c [new file with mode: 0644]
drivers/clk/clk-gate.c
drivers/clk/clk-gpio.c
drivers/clk/clk-mux.c
drivers/clk/clk-plldig.c [new file with mode: 0644]
drivers/clk/clk-qoriq.c
drivers/clk/clk-scmi.c
drivers/clk/clk.c
drivers/clk/imx/Kconfig
drivers/clk/imx/Makefile
drivers/clk/imx/clk-composite-7ulp.c
drivers/clk/imx/clk-composite-8m.c
drivers/clk/imx/clk-divider-gate.c
drivers/clk/imx/clk-frac-pll.c
drivers/clk/imx/clk-imx6q.c
drivers/clk/imx/clk-imx7ulp.c
drivers/clk/imx/clk-imx8mm.c
drivers/clk/imx/clk-imx8mn.c
drivers/clk/imx/clk-imx8mp.c [new file with mode: 0644]
drivers/clk/imx/clk-imx8mq.c
drivers/clk/imx/clk-imx8qxp-lpcg.c
drivers/clk/imx/clk-pfdv2.c
drivers/clk/imx/clk-pll14xx.c
drivers/clk/imx/clk-pllv1.c
drivers/clk/imx/clk-pllv2.c
drivers/clk/imx/clk-pllv4.c
drivers/clk/imx/clk-sscg-pll.c [moved from drivers/clk/imx/clk-sccg-pll.c with 70% similarity]
drivers/clk/imx/clk.c
drivers/clk/imx/clk.h
drivers/clk/mediatek/Kconfig
drivers/clk/meson/Makefile
drivers/clk/meson/clk-mpll.c
drivers/clk/meson/clk-phase.c
drivers/clk/meson/clk-pll.c
drivers/clk/meson/g12a.c
drivers/clk/meson/meson8-ddr.c [new file with mode: 0644]
drivers/clk/meson/meson8b.c
drivers/clk/meson/sclk-div.c
drivers/clk/microchip/clk-core.c
drivers/clk/mmp/clk-frac.c
drivers/clk/mmp/clk-mix.c
drivers/clk/mmp/clk-of-mmp2.c
drivers/clk/mvebu/Kconfig
drivers/clk/qcom/Kconfig
drivers/clk/qcom/Makefile
drivers/clk/qcom/apcs-msm8916.c
drivers/clk/qcom/clk-alpha-pll.c
drivers/clk/qcom/clk-alpha-pll.h
drivers/clk/qcom/clk-hfpll.c
drivers/clk/qcom/clk-rcg.h
drivers/clk/qcom/clk-rcg2.c
drivers/clk/qcom/clk-rpmh.c
drivers/clk/qcom/clk-smd-rpm.c
drivers/clk/qcom/dispcc-sc7180.c [new file with mode: 0644]
drivers/clk/qcom/dispcc-sdm845.c
drivers/clk/qcom/gcc-ipq6018.c [new file with mode: 0644]
drivers/clk/qcom/gcc-msm8996.c
drivers/clk/qcom/gcc-msm8998.c
drivers/clk/qcom/gcc-qcs404.c
drivers/clk/qcom/gpucc-sc7180.c [new file with mode: 0644]
drivers/clk/qcom/hfpll.c
drivers/clk/qcom/mmcc-msm8974.c
drivers/clk/qcom/mmcc-msm8998.c [new file with mode: 0644]
drivers/clk/qcom/videocc-sc7180.c [new file with mode: 0644]
drivers/clk/renesas/Kconfig
drivers/clk/renesas/r7s9210-cpg-mssr.c
drivers/clk/renesas/rcar-gen2-cpg.h
drivers/clk/renesas/rcar-gen3-cpg.c
drivers/clk/rockchip/clk-pll.c
drivers/clk/sunxi-ng/ccu-sun50i-a64.c
drivers/clk/sunxi-ng/ccu-sun50i-a64.h
drivers/clk/sunxi-ng/ccu-sun6i-a31.h
drivers/clk/sunxi-ng/ccu-sun8i-a23-a33.h
drivers/clk/sunxi-ng/ccu-sun8i-r40.h
drivers/clk/sunxi/clk-sun6i-apb0-gates.c
drivers/clk/tegra/clk-dfll.c
drivers/clk/tegra/clk-divider.c
drivers/clk/tegra/clk-tegra-periph.c
drivers/clk/tegra/clk-tegra20.c
drivers/clk/tegra/clk-tegra30.c
drivers/clk/ti/clk-44xx.c
drivers/clk/ti/clk-54xx.c
drivers/clk/ti/clk-7xx.c
drivers/clk/ti/clk.c
drivers/clk/ti/clkctrl.c
drivers/clk/ti/clock.h
drivers/clk/ti/clockdomain.c
drivers/clk/uniphier/clk-uniphier-peri.c
drivers/clk/ux500/u8500_of_clk.c
drivers/clk/versatile/Kconfig
drivers/clk/zynqmp/clkc.c
drivers/clk/zynqmp/divider.c
drivers/clk/zynqmp/pll.c
drivers/clocksource/timer-davinci.c
drivers/cpufreq/scmi-cpufreq.c
drivers/cpuidle/Makefile
drivers/cpuidle/cpuidle-psci-domain.c [new file with mode: 0644]
drivers/cpuidle/cpuidle-psci.c
drivers/cpuidle/cpuidle-psci.h [new file with mode: 0644]
drivers/cpuidle/dt_idle_states.c
drivers/dma/dmaengine.c
drivers/dma/idxd/sysfs.c
drivers/dma/mv_xor_v2.c
drivers/dma/ti/omap-dma.c
drivers/firmware/Kconfig
drivers/firmware/Makefile
drivers/firmware/arm_scmi/bus.c
drivers/firmware/arm_scmi/clock.c
drivers/firmware/arm_scmi/common.h
drivers/firmware/arm_scmi/driver.c
drivers/firmware/arm_scmi/perf.c
drivers/firmware/arm_scmi/power.c
drivers/firmware/arm_scmi/reset.c
drivers/firmware/arm_scmi/scmi_pm_domain.c
drivers/firmware/arm_scmi/sensors.c
drivers/firmware/efi/arm-runtime.c
drivers/firmware/imx/Kconfig
drivers/firmware/iscsi_ibft.c
drivers/firmware/psci/psci.c
drivers/firmware/qcom_scm-32.c [deleted file]
drivers/firmware/qcom_scm-64.c [deleted file]
drivers/firmware/qcom_scm-legacy.c [new file with mode: 0644]
drivers/firmware/qcom_scm-smc.c [new file with mode: 0644]
drivers/firmware/qcom_scm.c
drivers/firmware/qcom_scm.h
drivers/firmware/turris-mox-rwtm.c
drivers/firmware/xilinx/zynqmp.c
drivers/gpio/Kconfig
drivers/gpio/Makefile
drivers/gpio/gpio-bd71828.c [new file with mode: 0644]
drivers/gpio/gpiolib-devres.c
drivers/gpio/gpiolib-of.c
drivers/gpio/gpiolib.c
drivers/gpu/drm/amd/amdgpu/Makefile
drivers/gpu/drm/amd/amdgpu/amdgpu.h
drivers/gpu/drm/amd/amdgpu/amdgpu_acp.c
drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_gpuvm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.h
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_df.h
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_gfx.h
drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.h
drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h
drivers/gpu/drm/amd/amdgpu/amdgpu_ras.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c
drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.h
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.c
drivers/gpu/drm/amd/amdgpu/amdgpu_virt.h
drivers/gpu/drm/amd/amdgpu/athub_v1_0.c
drivers/gpu/drm/amd/amdgpu/athub_v2_0.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_v8_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c [new file with mode: 0644]
drivers/gpu/drm/amd/amdgpu/gfx_v9_4.h [new file with mode: 0644]
drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
drivers/gpu/drm/amd/amdgpu/jpeg_v2_0.c
drivers/gpu/drm/amd/amdgpu/jpeg_v2_5.c
drivers/gpu/drm/amd/amdgpu/mmhub_v1_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v2_0.c
drivers/gpu/drm/amd/amdgpu/mmhub_v9_4.c
drivers/gpu/drm/amd/amdgpu/navi10_ih.c
drivers/gpu/drm/amd/amdgpu/nv.c
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c
drivers/gpu/drm/amd/amdgpu/si_dma.c
drivers/gpu/drm/amd/amdgpu/soc15.c
drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
drivers/gpu/drm/amd/amdgpu/vce_v4_0.c
drivers/gpu/drm/amd/amdgpu/vcn_v1_0.c
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.c
drivers/gpu/drm/amd/amdgpu/vcn_v2_0.h
drivers/gpu/drm/amd/amdgpu/vcn_v2_5.c
drivers/gpu/drm/amd/amdgpu/vega10_ih.c
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_hdcp.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_mst_types.c
drivers/gpu/drm/amd/display/dc/bios/command_table2.c
drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c
drivers/gpu/drm/amd/display/dc/core/dc.c
drivers/gpu/drm/amd/display/dc/core/dc_link.c
drivers/gpu/drm/amd/display/dc/core/dc_link_dp.c
drivers/gpu/drm/amd/display/dc/dc.h
drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.c
drivers/gpu/drm/amd/display/dc/dce/dce_i2c_hw.h
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_hubp.c
drivers/gpu/drm/amd/display/dc/dcn21/dcn21_resource.c
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20.c
drivers/gpu/drm/amd/display/dc/dml/dcn20/display_mode_vba_20v2.c
drivers/gpu/drm/amd/display/dc/dml/dcn21/display_mode_vba_21.c
drivers/gpu/drm/amd/display/dc/dml/display_mode_vba.h
drivers/gpu/drm/amd/display/dc/dsc/dc_dsc.c
drivers/gpu/drm/amd/display/dmub/inc/dmub_srv.h
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.c
drivers/gpu/drm/amd/display/dmub/src/dmub_dcn20.h
drivers/gpu/drm/amd/display/dmub/src/dmub_srv.c
drivers/gpu/drm/amd/display/modules/color/color_gamma.c
drivers/gpu/drm/amd/display/modules/color/color_gamma.h
drivers/gpu/drm/amd/display/modules/freesync/freesync.c
drivers/gpu/drm/amd/display/modules/hdcp/hdcp.h
drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_execution.c
drivers/gpu/drm/amd/display/modules/hdcp/hdcp1_transition.c
drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_offset.h
drivers/gpu/drm/amd/include/asic_reg/df/df_3_6_sh_mask.h
drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_0_sh_mask.h
drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_4_1_offset.h [new file with mode: 0644]
drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_4_1_sh_mask.h [new file with mode: 0644]
drivers/gpu/drm/amd/include/asic_reg/mmhub/mmhub_9_4_1_sh_mask.h
drivers/gpu/drm/amd/powerplay/amdgpu_smu.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu10_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/inc/amdgpu_smu.h
drivers/gpu/drm/amd/powerplay/inc/smu_types.h
drivers/gpu/drm/amd/powerplay/inc/smu_v11_0_ppsmc.h
drivers/gpu/drm/amd/powerplay/navi10_ppt.c
drivers/gpu/drm/amd/powerplay/smu_internal.h
drivers/gpu/drm/amd/powerplay/smu_v11_0.c
drivers/gpu/drm/amd/powerplay/smumgr/vega12_smumgr.c
drivers/gpu/drm/amd/powerplay/smumgr/vega20_smumgr.c
drivers/gpu/drm/amd/powerplay/vega20_ppt.c
drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c
drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c
drivers/gpu/drm/nouveau/dispnv50/core.h
drivers/gpu/drm/nouveau/dispnv50/corec37d.c
drivers/gpu/drm/nouveau/dispnv50/corec57d.c
drivers/gpu/drm/nouveau/dispnv50/disp.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/gv100.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_mode.h
drivers/gpu/drm/scheduler/sched_entity.c
drivers/gpu/drm/tegra/drm.c
drivers/gpu/drm/tegra/gem.c
drivers/gpu/drm/tegra/plane.c
drivers/gpu/drm/tegra/sor.c
drivers/gpu/drm/ttm/ttm_bo_vm.c
drivers/gpu/host1x/job.c
drivers/hv/channel_mgmt.c
drivers/hv/hv_balloon.c
drivers/hv/hv_fcopy.c
drivers/hv/hv_kvp.c
drivers/hv/hv_snapshot.c
drivers/hv/hv_util.c
drivers/hv/hyperv_vmbus.h
drivers/hv/vmbus_drv.c
drivers/hwmon/dell-smm-hwmon.c
drivers/hwmon/scmi-hwmon.c
drivers/hwspinlock/omap_hwspinlock.c
drivers/hwspinlock/qcom_hwspinlock.c
drivers/hwspinlock/sirf_hwspinlock.c
drivers/hwspinlock/stm32_hwspinlock.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/Makefile
drivers/i2c/busses/i2c-at91-core.c
drivers/i2c/busses/i2c-cadence.c
drivers/i2c/busses/i2c-cht-wc.c
drivers/i2c/busses/i2c-cros-ec-tunnel.c
drivers/i2c/busses/i2c-designware-platdrv.c
drivers/i2c/busses/i2c-highlander.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/busses/i2c-jz4780.c
drivers/i2c/busses/i2c-meson.c
drivers/i2c/busses/i2c-mv64xxx.c
drivers/i2c/busses/i2c-nvidia-gpu.c
drivers/i2c/busses/i2c-ocores.c
drivers/i2c/busses/i2c-parport-light.c [deleted file]
drivers/i2c/busses/i2c-parport.c
drivers/i2c/busses/i2c-parport.h [deleted file]
drivers/i2c/busses/i2c-pmcmsp.c
drivers/i2c/busses/i2c-pnx.c
drivers/i2c/busses/i2c-powermac.c
drivers/i2c/busses/i2c-stm32f7.c
drivers/i2c/busses/i2c-stu300.c
drivers/i2c/busses/i2c-synquacer.c
drivers/i2c/busses/i2c-taos-evm.c
drivers/i2c/busses/i2c-tegra.c
drivers/i2c/busses/i2c-tiny-usb.c
drivers/i2c/busses/i2c-xiic.c
drivers/i2c/i2c-core-acpi.c
drivers/i2c/i2c-core-base.c
drivers/i2c/i2c-core-of.c
drivers/i2c/muxes/i2c-mux-pca9541.c
drivers/i2c/muxes/i2c-mux-pca954x.c
drivers/ide/ide-proc.c
drivers/idle/intel_idle.c
drivers/iio/accel/cros_ec_accel_legacy.c
drivers/iio/common/cros_ec_sensors/cros_ec_sensors.c
drivers/iio/common/cros_ec_sensors/cros_ec_sensors_core.c
drivers/iio/light/cros_ec_light_prox.c
drivers/iio/pressure/cros_ec_baro.c
drivers/input/input.c
drivers/input/misc/axp20x-pek.c
drivers/input/rmi4/rmi_f11.c
drivers/input/serio/Kconfig
drivers/input/serio/Makefile
drivers/input/serio/apbps2.c
drivers/input/serio/hyperv-keyboard.c
drivers/input/serio/ioc3kbd.c [new file with mode: 0644]
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/edt-ft5x06.c
drivers/input/touchscreen/elants_i2c.c
drivers/iommu/Kconfig
drivers/iommu/Makefile
drivers/iommu/amd_iommu.c
drivers/iommu/amd_iommu_init.c
drivers/iommu/amd_iommu_types.h
drivers/iommu/arm-smmu-impl.c
drivers/iommu/arm-smmu-v3.c
drivers/iommu/arm-smmu.c
drivers/iommu/arm-smmu.h
drivers/iommu/dmar.c
drivers/iommu/intel-iommu-debugfs.c
drivers/iommu/intel-iommu.c
drivers/iommu/intel-pasid.c
drivers/iommu/intel-pasid.h
drivers/iommu/intel-svm.c
drivers/iommu/io-pgtable-arm-v7s.c
drivers/iommu/io-pgtable-arm.c
drivers/iommu/io-pgtable.c
drivers/iommu/iommu-sysfs.c
drivers/iommu/iommu.c
drivers/iommu/iova.c
drivers/iommu/ipmmu-vmsa.c
drivers/iommu/msm_iommu.c
drivers/iommu/mtk_iommu.c
drivers/iommu/of_iommu.c
drivers/iommu/qcom_iommu.c
drivers/iommu/virtio-iommu.c
drivers/irqchip/Kconfig
drivers/irqchip/irq-gic-v3-its.c
drivers/irqchip/irq-gic-v3.c
drivers/isdn/capi/kcapi_proc.c
drivers/leds/Kconfig
drivers/leds/Makefile
drivers/leds/led-class.c
drivers/leds/leds-bd2802.c
drivers/leds/leds-lm3532.c
drivers/leds/leds-lm3642.c
drivers/leds/leds-lm3692x.c
drivers/leds/leds-pca963x.c
drivers/leds/leds-tps6105x.c [new file with mode: 0644]
drivers/macintosh/Kconfig
drivers/macintosh/via-pmu.c
drivers/mailbox/armada-37xx-rwtm-mailbox.c
drivers/md/bcache/bcache.h
drivers/md/bcache/bset.h
drivers/md/bcache/journal.c
drivers/md/bcache/request.c
drivers/md/bcache/stats.c
drivers/md/bcache/super.c
drivers/md/bcache/sysfs.c
drivers/md/md-bitmap.c
drivers/md/md.c
drivers/media/platform/cros-ec-cec/cros-ec-cec.c
drivers/memory/mvebu-devbus.c
drivers/memory/samsung/Kconfig
drivers/memory/samsung/exynos-srom.c
drivers/memory/samsung/exynos5422-dmc.c
drivers/memory/tegra/Makefile
drivers/memory/tegra/tegra124-emc.c
drivers/memory/tegra/tegra186-emc.c [new file with mode: 0644]
drivers/memory/tegra/tegra186.c
drivers/memory/tegra/tegra20-emc.c
drivers/memory/tegra/tegra210.c
drivers/memory/tegra/tegra30-emc.c
drivers/mfd/Kconfig
drivers/mfd/Makefile
drivers/mfd/ab8500-core.c
drivers/mfd/atmel-hlcdc.c
drivers/mfd/axp20x.c
drivers/mfd/cros_ec_dev.c
drivers/mfd/cs47l15-tables.c
drivers/mfd/da9062-core.c
drivers/mfd/db8500-prcmu.c
drivers/mfd/dln2.c
drivers/mfd/intel-lpss-pci.c
drivers/mfd/madera-core.c
drivers/mfd/rn5t618.c
drivers/mfd/rohm-bd70528.c
drivers/mfd/rohm-bd71828.c [new file with mode: 0644]
drivers/mfd/rohm-bd718x7.c
drivers/mfd/sm501.c
drivers/mfd/syscon.c
drivers/mfd/tqmx86.c
drivers/mfd/wcd934x.c [new file with mode: 0644]
drivers/misc/eeprom/at24.c
drivers/misc/ocxl/Kconfig
drivers/misc/sgi-gru/gruprocfs.c
drivers/mtd/ubi/build.c
drivers/net/bonding/bond_alb.c
drivers/net/dsa/b53/b53_common.c
drivers/net/dsa/bcm_sf2.c
drivers/net/dsa/microchip/ksz9477_spi.c
drivers/net/ethernet/broadcom/bcmsysport.c
drivers/net/ethernet/broadcom/bnxt/bnxt.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/cavium/thunder/thunder_bgx.c
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
drivers/net/ethernet/dec/tulip/de2104x.c
drivers/net/ethernet/freescale/Kconfig
drivers/net/ethernet/freescale/dpaa/dpaa_eth.c
drivers/net/ethernet/intel/i40e/i40e_xsk.c
drivers/net/ethernet/marvell/mvneta.c
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.c
drivers/net/ethernet/mellanox/mlx5/core/accel/tls.h
drivers/net/ethernet/mellanox/mlx5/core/en_accel/tls_rxtx.c
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
drivers/net/ethernet/mellanox/mlx5/core/en_tx.c
drivers/net/ethernet/mellanox/mlx5/core/fpga/ipsec.c
drivers/net/ethernet/mellanox/mlx5/core/fs_core.c
drivers/net/ethernet/mellanox/mlx5/core/fw.c
drivers/net/ethernet/mellanox/mlxsw/core_hwmon.c
drivers/net/ethernet/mellanox/mlxsw/core_thermal.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_dpipe.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_qdisc.c
drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
drivers/net/ethernet/pensando/ionic/ionic_if.h
drivers/net/ethernet/qlogic/qed/qed_cxt.c
drivers/net/ethernet/qlogic/qed/qed_dev.c
drivers/net/ethernet/qlogic/qed/qed_ptp.c
drivers/net/ethernet/realtek/r8169_main.c
drivers/net/ethernet/sgi/ioc3-eth.c
drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c
drivers/net/gtp.c
drivers/net/hyperv/netvsc_bpf.c
drivers/net/hyperv/netvsc_drv.c
drivers/net/netdevsim/bpf.c
drivers/net/netdevsim/bus.c
drivers/net/netdevsim/dev.c
drivers/net/netdevsim/health.c
drivers/net/netdevsim/netdevsim.h
drivers/net/netdevsim/sdev.c [deleted file]
drivers/net/phy/at803x.c
drivers/net/phy/mdio-mux-meson-g12a.c
drivers/net/phy/mii_timestamper.c
drivers/net/usb/r8152.c
drivers/net/wan/fsl_ucc_hdlc.c
drivers/net/wan/fsl_ucc_hdlc.h
drivers/net/wireguard/allowedips.c
drivers/net/wireguard/netlink.c
drivers/net/wireguard/noise.c
drivers/net/wireless/cisco/airo.c
drivers/net/wireless/intel/ipw2x00/libipw_module.c
drivers/net/wireless/intel/iwlwifi/mvm/d3.c
drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c
drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
drivers/net/wireless/intel/iwlwifi/mvm/sta.c
drivers/net/wireless/intel/iwlwifi/mvm/tdls.c
drivers/net/wireless/intel/iwlwifi/mvm/time-event.c
drivers/net/wireless/intel/iwlwifi/mvm/time-event.h
drivers/net/wireless/intel/iwlwifi/mvm/tt.c
drivers/net/wireless/intersil/hostap/hostap_hw.c
drivers/net/wireless/intersil/hostap/hostap_proc.c
drivers/net/wireless/intersil/hostap/hostap_wlan.h
drivers/net/wireless/marvell/libertas/cfg.c
drivers/net/wireless/marvell/mwifiex/scan.c
drivers/net/wireless/marvell/mwifiex/sta_ioctl.c
drivers/net/wireless/marvell/mwifiex/wmm.c
drivers/net/wireless/mediatek/mt76/mt7615/eeprom.c
drivers/net/wireless/ray_cs.c
drivers/net/wireless/realtek/rtw88/wow.c
drivers/nvme/host/pci.c
drivers/nvme/target/core.c
drivers/nvme/target/fabrics-cmd.c
drivers/nvme/target/io-cmd-bdev.c
drivers/nvme/target/io-cmd-file.c
drivers/nvme/target/nvmet.h
drivers/nvmem/core.c
drivers/nvmem/nvmem.h
drivers/of/base.c
drivers/of/device.c
drivers/of/of_mdio.c
drivers/oprofile/cpu_buffer.c
drivers/parisc/led.c
drivers/pci/ats.c
drivers/pci/controller/pci-tegra.c
drivers/pci/hotplug/pnv_php.c
drivers/pci/pci.c
drivers/pci/proc.c
drivers/pcmcia/i82092.c
drivers/pcmcia/i82092aa.h
drivers/phy/phy-core.c
drivers/pinctrl/pxa/pinctrl-pxa2xx.c
drivers/platform/chrome/chromeos_laptop.c
drivers/platform/chrome/cros_ec.c
drivers/platform/chrome/cros_ec.h [new file with mode: 0644]
drivers/platform/chrome/cros_ec_chardev.c
drivers/platform/chrome/cros_ec_debugfs.c
drivers/platform/chrome/cros_ec_i2c.c
drivers/platform/chrome/cros_ec_ishtp.c
drivers/platform/chrome/cros_ec_lightbar.c
drivers/platform/chrome/cros_ec_lpc.c
drivers/platform/chrome/cros_ec_proto.c
drivers/platform/chrome/cros_ec_rpmsg.c
drivers/platform/chrome/cros_ec_sensorhub.c
drivers/platform/chrome/cros_ec_spi.c
drivers/platform/chrome/cros_ec_sysfs.c
drivers/platform/chrome/cros_ec_trace.c
drivers/platform/chrome/cros_ec_trace.h
drivers/platform/chrome/cros_ec_vbc.c
drivers/platform/chrome/cros_usbpd_logger.c
drivers/platform/chrome/wilco_ec/Kconfig
drivers/platform/chrome/wilco_ec/core.c
drivers/platform/chrome/wilco_ec/keyboard_leds.c
drivers/platform/chrome/wilco_ec/mailbox.c
drivers/platform/chrome/wilco_ec/telemetry.c
drivers/platform/x86/thinkpad_acpi.c
drivers/platform/x86/toshiba_acpi.c
drivers/pnp/isapnp/proc.c
drivers/pnp/pnpbios/proc.c
drivers/power/avs/Kconfig
drivers/power/avs/qcom-cpr.c
drivers/power/avs/rockchip-io-domain.c
drivers/power/reset/Kconfig
drivers/power/supply/cros_usbpd-charger.c
drivers/pwm/Kconfig
drivers/pwm/core.c
drivers/pwm/pwm-atmel.c
drivers/pwm/pwm-cros-ec.c
drivers/pwm/pwm-imx27.c
drivers/pwm/pwm-mxs.c
drivers/pwm/pwm-omap-dmtimer.c
drivers/pwm/pwm-pca9685.c
drivers/pwm/pwm-rcar.c
drivers/pwm/pwm-stm32.c
drivers/pwm/pwm-sun4i.c
drivers/regulator/Kconfig
drivers/regulator/Makefile
drivers/regulator/bd718x7-regulator.c
drivers/regulator/rohm-regulator.c [new file with mode: 0644]
drivers/remoteproc/Kconfig
drivers/remoteproc/Makefile
drivers/remoteproc/mtk_common.h [new file with mode: 0644]
drivers/remoteproc/mtk_scp.c [new file with mode: 0644]
drivers/remoteproc/mtk_scp_ipi.c [new file with mode: 0644]
drivers/remoteproc/qcom_q6v5_mss.c
drivers/remoteproc/qcom_q6v5_pas.c
drivers/remoteproc/qcom_sysmon.c
drivers/remoteproc/remoteproc_core.c
drivers/reset/Kconfig
drivers/reset/Makefile
drivers/reset/core.c
drivers/reset/reset-brcmstb-rescal.c [new file with mode: 0644]
drivers/reset/reset-intel-gw.c [new file with mode: 0644]
drivers/reset/reset-npcm.c [new file with mode: 0644]
drivers/reset/reset-qcom-aoss.c
drivers/reset/reset-scmi.c
drivers/reset/reset-uniphier.c
drivers/rpmsg/Kconfig
drivers/rpmsg/Makefile
drivers/rpmsg/mtk_rpmsg.c [new file with mode: 0644]
drivers/rtc/Kconfig
drivers/rtc/rtc-abx80x.c
drivers/rtc/rtc-asm9260.c
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-at91rm9200.h [deleted file]
drivers/rtc/rtc-bd70528.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-cros-ec.c
drivers/rtc/rtc-ds1343.c
drivers/rtc/rtc-hym8563.c
drivers/rtc/rtc-moxart.c
drivers/rtc/rtc-mt6397.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-pcf2127.c
drivers/rtc/rtc-pcf85063.c
drivers/rtc/rtc-pcf8523.c
drivers/rtc/rtc-pcf8563.c
drivers/rtc/rtc-rv3028.c
drivers/rtc/rtc-rv3029c2.c
drivers/rtc/rtc-rv8803.c
drivers/rtc/rtc-rx8010.c
drivers/rtc/rtc-rx8025.c
drivers/rtc/rtc-stm32.c
drivers/rtc/rtc-tps6586x.c
drivers/rtc/rtc-zynqmp.c
drivers/s390/block/dasd_proc.c
drivers/s390/cio/blacklist.c
drivers/s390/cio/css.c
drivers/s390/crypto/Makefile
drivers/s390/crypto/pkey_api.c
drivers/s390/crypto/zcrypt_api.c
drivers/s390/crypto/zcrypt_api.h
drivers/s390/crypto/zcrypt_ccamisc.h
drivers/s390/crypto/zcrypt_cex4.c
drivers/s390/crypto/zcrypt_ep11misc.c [new file with mode: 0644]
drivers/s390/crypto/zcrypt_ep11misc.h [new file with mode: 0644]
drivers/scsi/esas2r/esas2r_main.c
drivers/scsi/megaraid/megaraid_sas_base.c
drivers/scsi/pm8001/pm80xx_hwi.c
drivers/scsi/qla2xxx/qla_dbg.c
drivers/scsi/qla2xxx/qla_dbg.h
drivers/scsi/qla2xxx/qla_isr.c
drivers/scsi/scsi_devinfo.c
drivers/scsi/scsi_proc.c
drivers/scsi/sg.c
drivers/scsi/ufs/ufs.h
drivers/soc/atmel/soc.c
drivers/soc/bcm/brcmstb/biuctrl.c
drivers/soc/fsl/qe/Kconfig
drivers/soc/fsl/qe/gpio.c
drivers/soc/fsl/qe/qe.c
drivers/soc/fsl/qe/qe_common.c
drivers/soc/fsl/qe/qe_ic.c
drivers/soc/fsl/qe/qe_ic.h [deleted file]
drivers/soc/fsl/qe/qe_io.c
drivers/soc/fsl/qe/qe_tdm.c
drivers/soc/fsl/qe/ucc.c
drivers/soc/fsl/qe/ucc_fast.c
drivers/soc/fsl/qe/ucc_slow.c
drivers/soc/fsl/qe/usb.c
drivers/soc/imx/Kconfig
drivers/soc/imx/soc-imx8.c
drivers/soc/mediatek/mtk-cmdq-helper.c
drivers/soc/qcom/Kconfig
drivers/soc/qcom/qmi_interface.c
drivers/soc/qcom/rpmhpd.c
drivers/soc/renesas/Kconfig
drivers/soc/renesas/rcar-rst.c
drivers/soc/samsung/Kconfig
drivers/soc/samsung/exynos-chipid.c
drivers/soc/samsung/exynos-pmu.c
drivers/soc/samsung/exynos-pmu.h
drivers/soc/samsung/exynos3250-pmu.c
drivers/soc/samsung/exynos4-pmu.c
drivers/soc/samsung/exynos5250-pmu.c
drivers/soc/samsung/exynos5420-pmu.c
drivers/soc/tegra/Kconfig
drivers/soc/tegra/fuse/fuse-tegra.c
drivers/soc/tegra/fuse/fuse-tegra30.c
drivers/soc/tegra/fuse/fuse.h
drivers/soc/tegra/fuse/tegra-apbmisc.c
drivers/soc/tegra/regulators-tegra20.c
drivers/soc/tegra/regulators-tegra30.c
drivers/soc/ti/knav_qmss_queue.c
drivers/soc/xilinx/Kconfig
drivers/soc/xilinx/zynqmp_power.c
drivers/spi/spi-orion.c
drivers/staging/rtl8192u/ieee80211/ieee80211_module.c
drivers/tee/optee/core.c
drivers/tty/serial/8250/8250_ioc3.c
drivers/tty/serial/ucc_uart.c
drivers/tty/sysrq.c
drivers/usb/gadget/function/f_fs.c
drivers/usb/gadget/function/rndis.c
drivers/vfio/mdev/mdev_sysfs.c
drivers/vfio/pci/vfio_pci_nvlink2.c
drivers/vfio/platform/reset/vfio_platform_amdxgbe.c
drivers/vfio/vfio_iommu_spapr_tce.c
drivers/video/backlight/ams369fg06.c
drivers/video/backlight/bd6107.c
drivers/video/backlight/qcom-wled.c
drivers/video/fbdev/Kconfig
drivers/video/fbdev/hyperv_fb.c
drivers/video/fbdev/imxfb.c
drivers/video/fbdev/via/viafbdev.c
drivers/virtio/virtio_balloon.c
drivers/virtio/virtio_mmio.c
drivers/virtio/virtio_pci_common.c
drivers/watchdog/at91sam9_wdt.h
drivers/watchdog/cadence_wdt.c
drivers/watchdog/da9062_wdt.c
drivers/watchdog/dw_wdt.c
drivers/watchdog/it87_wdt.c
drivers/watchdog/mtk_wdt.c
drivers/watchdog/qcom-wdt.c
drivers/watchdog/sama5d4_wdt.c
drivers/watchdog/stm32_iwdg.c
drivers/watchdog/watchdog_core.c
drivers/watchdog/watchdog_dev.c
drivers/xen/gntdev.c
drivers/xen/xen-balloon.c
drivers/xen/xen-pciback/conf_space.c
drivers/xen/xen-pciback/conf_space.h
drivers/xen/xen-pciback/conf_space_capability.c
drivers/xen/xen-pciback/conf_space_header.c
drivers/xen/xen-pciback/pci_stub.c
drivers/xen/xen-pciback/pciback.h
drivers/xen/xenbus/xenbus_probe.c
drivers/xen/xenbus/xenbus_probe_backend.c
drivers/zorro/proc.c
fs/Kconfig
fs/Makefile
fs/afs/super.c
fs/aio.c
fs/attr.c
fs/btrfs/block-group.c
fs/btrfs/ctree.c
fs/btrfs/ctree.h
fs/btrfs/delayed-ref.c
fs/btrfs/disk-io.c
fs/btrfs/extent_io.c
fs/btrfs/inode.c
fs/btrfs/send.c
fs/btrfs/space-info.c
fs/btrfs/space-info.h
fs/btrfs/super.c
fs/btrfs/tests/btrfs-tests.c
fs/btrfs/tests/extent-io-tests.c
fs/cachefiles/rdwr.c
fs/ceph/Makefile
fs/ceph/acl.c
fs/ceph/cache.c
fs/ceph/caps.c
fs/ceph/debugfs.c
fs/ceph/dir.c
fs/ceph/file.c
fs/ceph/inode.c
fs/ceph/mds_client.c
fs/ceph/mds_client.h
fs/ceph/mdsmap.c
fs/ceph/super.c
fs/ceph/super.h
fs/ceph/util.c [moved from net/ceph/ceph_fs.c with 94% similarity]
fs/ceph/xattr.c
fs/cifs/cifs_debug.c
fs/cifs/dfs_cache.c
fs/cifs/dfs_cache.h
fs/cifs/inode.c
fs/configfs/inode.c
fs/coredump.c
fs/cramfs/inode.c
fs/debugfs/inode.c
fs/ecryptfs/mmap.c
fs/eventfd.c
fs/ext4/super.c
fs/f2fs/data.c
fs/f2fs/file.c
fs/f2fs/node.c
fs/fat/misc.c
fs/filesystems.c
fs/fs_context.c
fs/fs_parser.c
fs/fscache/internal.h
fs/fscache/object-list.c
fs/fscache/proc.c
fs/fsopen.c
fs/fuse/cuse.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/inode.c
fs/fuse/readdir.c
fs/gfs2/file.c
fs/gfs2/lops.c
fs/gfs2/ops_fstype.c
fs/hugetlbfs/inode.c
fs/inode.c
fs/io_uring.c
fs/ioctl.c
fs/jbd2/journal.c
fs/jffs2/super.c
fs/jfs/jfs_debug.c
fs/jfs/jfs_dmap.c
fs/kernfs/inode.c
fs/libfs.c
fs/lockd/procfs.c
fs/namespace.c
fs/nfs/Kconfig
fs/nfs/Makefile
fs/nfs/callback_xdr.c
fs/nfs/client.c
fs/nfs/delegation.c
fs/nfs/delegation.h
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/dns_resolve.c
fs/nfs/file.c
fs/nfs/flexfilelayout/flexfilelayout.c
fs/nfs/fs_context.c [new file with mode: 0644]
fs/nfs/fscache.c
fs/nfs/getroot.c
fs/nfs/inode.c
fs/nfs/internal.h
fs/nfs/mount_clnt.c
fs/nfs/namespace.c
fs/nfs/nfs2xdr.c
fs/nfs/nfs3_fs.h
fs/nfs/nfs3client.c
fs/nfs/nfs3proc.c
fs/nfs/nfs3xdr.c
fs/nfs/nfs42proc.c
fs/nfs/nfs4_fs.h
fs/nfs/nfs4client.c
fs/nfs/nfs4file.c
fs/nfs/nfs4namespace.c
fs/nfs/nfs4proc.c
fs/nfs/nfs4renewd.c
fs/nfs/nfs4state.c
fs/nfs/nfs4super.c
fs/nfs/nfs4trace.c
fs/nfs/nfs4trace.h
fs/nfs/nfs4xdr.c
fs/nfs/nfstrace.h
fs/nfs/pnfs.c
fs/nfs/pnfs.h
fs/nfs/pnfs_nfs.c
fs/nfs/proc.c
fs/nfs/read.c
fs/nfs/super.c
fs/nfs/write.c
fs/nfsd/Kconfig
fs/nfsd/filecache.c
fs/nfsd/filecache.h
fs/nfsd/netns.h
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4callback.c
fs/nfsd/nfs4layouts.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfs4recover.c
fs/nfsd/nfs4state.c
fs/nfsd/nfs4xdr.c
fs/nfsd/nfsctl.c
fs/nfsd/nfsd.h
fs/nfsd/nfsfh.h
fs/nfsd/nfsproc.c
fs/nfsd/nfssvc.c
fs/nfsd/state.h
fs/nfsd/stats.c
fs/nfsd/trace.h
fs/nfsd/vfs.c
fs/nfsd/vfs.h
fs/nfsd/xdr3.h
fs/nfsd/xdr4.h
fs/ntfs/inode.c
fs/ocfs2/file.c
fs/ocfs2/suballoc.c
fs/orangefs/orangefs-debugfs.c
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/export.c
fs/overlayfs/file.c
fs/overlayfs/inode.c
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/ovl_entry.h
fs/overlayfs/readdir.c
fs/overlayfs/super.c
fs/overlayfs/util.c
fs/pipe.c
fs/proc/Makefile
fs/proc/bootconfig.c [new file with mode: 0644]
fs/proc/cpuinfo.c
fs/proc/generic.c
fs/proc/inode.c
fs/proc/internal.h
fs/proc/kcore.c
fs/proc/kmsg.c
fs/proc/page.c
fs/proc/proc_net.c
fs/proc/proc_sysctl.c
fs/proc/root.c
fs/proc/stat.c
fs/proc/task_mmu.c
fs/proc/vmcore.c
fs/ramfs/inode.c
fs/read_write.c
fs/splice.c
fs/sysfs/group.c
fs/tracefs/inode.c
fs/ubifs/file.c
fs/ubifs/sb.c
fs/utimes.c
fs/vboxsf/Kconfig [new file with mode: 0644]
fs/vboxsf/Makefile [new file with mode: 0644]
fs/vboxsf/dir.c [new file with mode: 0644]
fs/vboxsf/file.c [new file with mode: 0644]
fs/vboxsf/shfl_hostintf.h [new file with mode: 0644]
fs/vboxsf/super.c [new file with mode: 0644]
fs/vboxsf/utils.c [new file with mode: 0644]
fs/vboxsf/vboxsf_wrappers.c [new file with mode: 0644]
fs/vboxsf/vfsmod.h [new file with mode: 0644]
fs/xfs/libxfs/xfs_ag.c
fs/xfs/libxfs/xfs_alloc.c
fs/xfs/libxfs/xfs_attr_remote.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_btree.c
fs/xfs/libxfs/xfs_btree.h
fs/xfs/libxfs/xfs_da_btree.c
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_refcount.c
fs/xfs/libxfs/xfs_sb.c
fs/xfs/scrub/agheader_repair.c
fs/xfs/scrub/fscounters.c
fs/xfs/scrub/repair.c
fs/xfs/xfs_attr_inactive.c
fs/xfs/xfs_buf.c
fs/xfs/xfs_buf.h
fs/xfs/xfs_buf_item.c
fs/xfs/xfs_discard.c
fs/xfs/xfs_dquot.c
fs/xfs/xfs_filestream.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_reflink.c
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_super.c
fs/xfs/xfs_symlink.c
fs/xfs/xfs_trans.h
fs/xfs/xfs_trans_buf.c
include/asm-generic/Kbuild
include/asm-generic/percpu.h
include/asm-generic/pgtable.h
include/asm-generic/tlb.h
include/drm/gpu_scheduler.h
include/dt-bindings/clock/dra7.h
include/dt-bindings/clock/imx8mp-clock.h [new file with mode: 0644]
include/dt-bindings/clock/marvell,mmp2.h
include/dt-bindings/clock/meson8-ddr-clkc.h [new file with mode: 0644]
include/dt-bindings/clock/omap4.h
include/dt-bindings/clock/omap5.h
include/dt-bindings/clock/qcom,dispcc-sc7180.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,dispcc-sdm845.h
include/dt-bindings/clock/qcom,gcc-ipq6018.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,gcc-msm8998.h
include/dt-bindings/clock/qcom,gpucc-sc7180.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,mmcc-msm8998.h [new file with mode: 0644]
include/dt-bindings/clock/qcom,videocc-sc7180.h [new file with mode: 0644]
include/dt-bindings/clock/sun50i-a64-ccu.h
include/dt-bindings/clock/sun6i-a31-ccu.h
include/dt-bindings/clock/sun8i-a23-a33-ccu.h
include/dt-bindings/clock/sun8i-r40-ccu.h
include/dt-bindings/clock/ti-dra7-atl.h [moved from include/dt-bindings/clk/ti-dra7-atl.h with 100% similarity]
include/dt-bindings/clock/xlnx-versal-clk.h [new file with mode: 0644]
include/dt-bindings/memory/tegra186-mc.h
include/dt-bindings/memory/tegra194-mc.h [new file with mode: 0644]
include/dt-bindings/power/mt6765-power.h [new file with mode: 0644]
include/dt-bindings/power/qcom-rpmpd.h
include/dt-bindings/reset-controller/mt2712-resets.h [new file with mode: 0644]
include/dt-bindings/reset-controller/mt8183-resets.h
include/dt-bindings/reset/nuvoton,npcm7xx-reset.h [new file with mode: 0644]
include/dt-bindings/reset/qcom,gcc-ipq6018.h [new file with mode: 0644]
include/linux/bitmap.h
include/linux/bitops.h
include/linux/bootconfig.h [new file with mode: 0644]
include/linux/bpf.h
include/linux/ceph/libceph.h
include/linux/ceph/mdsmap.h
include/linux/ceph/osd_client.h
include/linux/ceph/rados.h
include/linux/clk-provider.h
include/linux/clk.h
include/linux/cpuhotplug.h
include/linux/cpumask.h
include/linux/debugfs.h
include/linux/eventfd.h
include/linux/firmware/xlnx-zynqmp.h
include/linux/fs.h
include/linux/fs_context.h
include/linux/fs_parser.h
include/linux/hyperv.h
include/linux/i2c.h
include/linux/intel-iommu.h
include/linux/io-pgtable.h
include/linux/iommu.h
include/linux/irq.h
include/linux/irqchip/arm-gic-v3.h
include/linux/irqdomain.h
include/linux/kdb.h
include/linux/leds-bd2802.h
include/linux/leds.h
include/linux/libata.h
include/linux/memory_hotplug.h
include/linux/mfd/cros_ec.h [deleted file]
include/linux/mfd/db8500-prcmu.h
include/linux/mfd/dbx500-prcmu.h
include/linux/mfd/rohm-bd70528.h
include/linux/mfd/rohm-bd71828.h [new file with mode: 0644]
include/linux/mfd/rohm-bd718x7.h
include/linux/mfd/rohm-generic.h
include/linux/mfd/rohm-shared.h [new file with mode: 0644]
include/linux/mfd/syscon.h
include/linux/mfd/wcd934x/registers.h [new file with mode: 0644]
include/linux/mfd/wcd934x/wcd934x.h [new file with mode: 0644]
include/linux/mlx5/mlx5_ifc.h
include/linux/mm.h
include/linux/mm_types.h
include/linux/mmzone.h
include/linux/nfs_fs.h
include/linux/nfs_fs_sb.h
include/linux/nfs_xdr.h
include/linux/nvmem-provider.h
include/linux/of.h
include/linux/of_clk.h
include/linux/omap-dma.h
include/linux/pagewalk.h
include/linux/pci-ats.h
include/linux/percpu-defs.h
include/linux/perf_event.h
include/linux/pipe_fs_i.h
include/linux/platform_data/b53.h
include/linux/platform_data/bd6107.h
include/linux/platform_data/cros_ec_proto.h
include/linux/platform_data/microchip-ksz.h
include/linux/platform_data/ti-sysc.h
include/linux/pm_domain.h
include/linux/proc_fs.h
include/linux/psci.h
include/linux/ptdump.h [new file with mode: 0644]
include/linux/qcom_scm.h
include/linux/ramfs.h
include/linux/remoteproc/mtk_scp.h [new file with mode: 0644]
include/linux/ring_buffer.h
include/linux/rpmsg/mtk_rpmsg.h [new file with mode: 0644]
include/linux/rtc.h
include/linux/scmi_protocol.h
include/linux/seq_file.h
include/linux/shmem_fs.h
include/linux/skbuff.h
include/linux/slab.h
include/linux/soc/samsung/exynos-pmu.h
include/linux/soc/samsung/exynos-regs-pmu.h
include/linux/string.h
include/linux/sunrpc/auth.h
include/linux/sunrpc/gss_api.h
include/linux/sunrpc/stats.h
include/linux/trace_events.h
include/linux/tracefs.h
include/net/ipx.h
include/soc/fsl/cpm.h [new file with mode: 0644]
include/soc/fsl/qe/qe.h
include/soc/fsl/qe/qe_ic.h [deleted file]
include/soc/fsl/qe/ucc_fast.h
include/soc/fsl/qe/ucc_slow.h
include/sound/aess.h [deleted file]
include/sound/pcm.h
include/trace/events/intel_iommu.h
include/trace/events/pwm.h [new file with mode: 0644]
include/trace/events/rpcrdma.h
include/trace/events/scmi.h [new file with mode: 0644]
include/trace/events/sunrpc.h
include/trace/trace_events.h
include/uapi/linux/kvm.h
include/uapi/linux/rtc.h
include/uapi/sound/asound.h
include/xen/xenbus.h
init/Kconfig
init/main.c
ipc/mqueue.c
ipc/msg.c
ipc/sem.c
ipc/util.c
kernel/bpf/bpf_struct_ops.c
kernel/bpf/btf.c
kernel/bpf/inode.c
kernel/cgroup/cgroup-internal.h
kernel/cgroup/cgroup-v1.c
kernel/cgroup/cgroup.c
kernel/configs.c
kernel/debug/kdb/kdb_bp.c
kernel/debug/kdb/kdb_bt.c
kernel/debug/kdb/kdb_io.c
kernel/debug/kdb/kdb_main.c
kernel/debug/kdb/kdb_private.h
kernel/events/core.c
kernel/events/internal.h
kernel/events/ring_buffer.c
kernel/irq/debugfs.c
kernel/irq/manage.c
kernel/irq/msi.c
kernel/irq/proc.c
kernel/kallsyms.c
kernel/latencytop.c
kernel/locking/lockdep_proc.c
kernel/module.c
kernel/profile.c
kernel/sched/psi.c
kernel/smp.c
kernel/time/clocksource.c
kernel/trace/Kconfig
kernel/trace/Makefile
kernel/trace/blktrace.c
kernel/trace/ftrace.c
kernel/trace/kprobe_event_gen_test.c [new file with mode: 0644]
kernel/trace/ring_buffer.c
kernel/trace/ring_buffer_benchmark.c
kernel/trace/synth_event_gen_test.c [new file with mode: 0644]
kernel/trace/trace.c
kernel/trace/trace.h
kernel/trace/trace_boot.c [new file with mode: 0644]
kernel/trace/trace_branch.c
kernel/trace/trace_dynevent.c
kernel/trace/trace_dynevent.h
kernel/trace/trace_entries.h
kernel/trace/trace_events.c
kernel/trace/trace_events_hist.c
kernel/trace/trace_events_trigger.c
kernel/trace/trace_functions.c
kernel/trace/trace_functions_graph.c
kernel/trace/trace_hwlat.c
kernel/trace/trace_irqsoff.c
kernel/trace/trace_kdb.c
kernel/trace/trace_kprobe.c
kernel/trace/trace_mmiotrace.c
kernel/trace/trace_output.c
kernel/trace/trace_sched_switch.c
kernel/trace/trace_sched_wakeup.c
kernel/trace/trace_selftest.c
kernel/trace/trace_seq.c
kernel/trace/trace_stat.c
kernel/trace/trace_syscalls.c
kernel/trace/trace_uprobe.c
kernel/up.c
lib/Kconfig
lib/Makefile
lib/bitmap.c
lib/bootconfig.c [new file with mode: 0644]
lib/string.c
lib/test_bitmap.c
mm/Kconfig.debug
mm/Makefile
mm/gup.c
mm/hmm.c
mm/memory.c
mm/memory_hotplug.c
mm/memremap.c
mm/migrate.c
mm/mincore.c
mm/mmu_gather.c
mm/page_alloc.c
mm/page_io.c
mm/pagewalk.c
mm/ptdump.c [new file with mode: 0644]
mm/shmem.c
mm/slab_common.c
mm/sparse.c
mm/swapfile.c
net/atm/mpoa_proc.c
net/atm/proc.c
net/ceph/Makefile
net/ceph/ceph_common.c
net/ceph/osd_client.c
net/core/bpf_sk_storage.c
net/core/dev.c
net/core/devlink.c
net/core/drop_monitor.c
net/core/filter.c
net/core/pktgen.c
net/core/sock_map.c
net/hsr/hsr_slave.c
net/ipv4/ipconfig.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/route.c
net/ipv4/tcp.c
net/ipv4/tcp_input.c
net/ipv6/addrconf.c
net/l2tp/l2tp_core.c
net/mptcp/protocol.c
net/netfilter/ipset/ip_set_core.c
net/netfilter/nf_conntrack_core.c
net/netfilter/nf_flow_table_core.c
net/netfilter/nf_flow_table_offload.c
net/netfilter/x_tables.c
net/netfilter/xt_recent.c
net/rxrpc/af_rxrpc.c
net/rxrpc/ar-internal.h
net/rxrpc/call_object.c
net/rxrpc/conn_client.c
net/rxrpc/conn_event.c
net/rxrpc/conn_object.c
net/rxrpc/input.c
net/rxrpc/local_object.c
net/rxrpc/output.c
net/rxrpc/peer_event.c
net/sched/cls_rsvp.h
net/sched/cls_tcindex.c
net/sched/sch_fq_pie.c
net/sched/sch_taprio.c
net/sunrpc/addr.c
net/sunrpc/auth.c
net/sunrpc/auth_gss/auth_gss.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/sched.c
net/sunrpc/stats.c
net/sunrpc/xdr.c
net/sunrpc/xprtrdma/backchannel.c
net/sunrpc/xprtrdma/frwr_ops.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/sunrpc/xprtrdma/transport.c
net/sunrpc/xprtrdma/verbs.c
net/sunrpc/xprtrdma/xprt_rdma.h
net/unix/af_unix.c
net/xfrm/xfrm_policy.c
samples/bpf/xdpsock_user.c
samples/kfifo/bytestream-example.c
samples/kfifo/inttype-example.c
samples/kfifo/record-example.c
scripts/coccinelle/free/devm_free.cocci
scripts/sphinx-pre-install
security/selinux/hooks.c
security/smack/smack_lsm.c
sound/core/info.c
sound/core/pcm_compat.c
sound/core/pcm_native.c
sound/drivers/dummy.c
sound/hda/hdac_stream.c
sound/pci/emu10k1/emufx.c
sound/pci/hda/hda_controller.c
sound/pci/hda/hda_intel.c
sound/pci/hda/patch_hdmi.c
sound/pci/hda/patch_realtek.c
sound/pci/rme9652/hdsp.c
sound/soc/amd/raven/acp3x-i2s.c
sound/soc/amd/raven/acp3x-pcm-dma.c
sound/soc/codecs/Kconfig
sound/soc/codecs/ak4104.c
sound/soc/codecs/cs4270.c
sound/soc/codecs/max98090.c
sound/soc/codecs/rt1015.c
sound/soc/codecs/rt1308-sdw.c
sound/soc/codecs/rt700-sdw.c
sound/soc/codecs/rt711-sdw.c
sound/soc/codecs/rt715-sdw.c
sound/soc/codecs/tlv320aic32x4.c
sound/soc/intel/boards/bxt_da7219_max98357a.c
sound/soc/intel/boards/bxt_rt298.c
sound/soc/intel/boards/cml_rt1011_rt5682.c
sound/soc/intel/boards/glk_rt5682_max98357a.c
sound/soc/intel/boards/sof_rt5682.c
sound/soc/intel/common/soc-acpi-intel-icl-match.c
sound/soc/sof/core.c
sound/soc/sof/intel/hda-codec.c
sound/soc/sof/intel/hda.c
sound/soc/sof/intel/hda.h
sound/soc/sof/pcm.c
sound/soc/sof/pm.c
sound/soc/sof/sof-pci-dev.c
sound/soc/sof/trace.c
sound/soc/sunxi/sun4i-spdif.c
sound/soc/tegra/tegra30_i2s.c
sound/usb/mixer_scarlett_gen2.c
sound/usb/validate.c
tools/Makefile
tools/bootconfig/.gitignore [new file with mode: 0644]
tools/bootconfig/Makefile [new file with mode: 0644]
tools/bootconfig/include/linux/bootconfig.h [new file with mode: 0644]
tools/bootconfig/include/linux/bug.h [new file with mode: 0644]
tools/bootconfig/include/linux/ctype.h [new file with mode: 0644]
tools/bootconfig/include/linux/errno.h [new file with mode: 0644]
tools/bootconfig/include/linux/kernel.h [new file with mode: 0644]
tools/bootconfig/include/linux/printk.h [new file with mode: 0644]
tools/bootconfig/include/linux/string.h [new file with mode: 0644]
tools/bootconfig/main.c [new file with mode: 0644]
tools/bootconfig/samples/bad-array-space-comment.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-array.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-dotword.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-empty.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-keyerror.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-longkey.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-manywords.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-no-keyword.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-nonprintable.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-spaceword.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-tree.bconf [new file with mode: 0644]
tools/bootconfig/samples/bad-value.bconf [new file with mode: 0644]
tools/bootconfig/samples/escaped.bconf [new file with mode: 0644]
tools/bootconfig/samples/good-array-space-comment.bconf [new file with mode: 0644]
tools/bootconfig/samples/good-comment-after-value.bconf [new file with mode: 0644]
tools/bootconfig/samples/good-printables.bconf [new file with mode: 0644]
tools/bootconfig/samples/good-simple.bconf [new file with mode: 0644]
tools/bootconfig/samples/good-single.bconf [new file with mode: 0644]
tools/bootconfig/samples/good-space-after-value.bconf [new file with mode: 0644]
tools/bootconfig/samples/good-tree.bconf [new file with mode: 0644]
tools/bootconfig/test-bootconfig.sh [new file with mode: 0755]
tools/bpf/bpftool/feature.c
tools/bpf/bpftool/prog.c
tools/bpf/runqslower/Makefile
tools/hv/hv_fcopy_daemon.c
tools/hv/hv_kvp_daemon.c
tools/hv/hv_vss_daemon.c
tools/include/linux/bitops.h
tools/perf/arch/arm/util/cs-etm.c
tools/perf/tests/cpumap.c
tools/perf/util/evsel.c
tools/perf/util/evsel_config.h
tools/perf/util/map.c
tools/perf/util/parse-events.c
tools/perf/util/probe-finder.c
tools/perf/util/srcline.c
tools/testing/selftests/bpf/prog_tests/sockmap_basic.c [new file with mode: 0644]
tools/testing/selftests/bpf/prog_tests/trampoline_count.c
tools/testing/selftests/drivers/net/mlxsw/fib.sh
tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-syntax-errors.tc [new file with mode: 0644]
tools/testing/selftests/kvm/Makefile
tools/testing/selftests/kvm/include/kvm_util.h
tools/testing/selftests/kvm/lib/kvm_util.c
tools/testing/selftests/kvm/s390x/resets.c [new file with mode: 0644]
tools/testing/selftests/net/.gitignore
tools/testing/selftests/net/Makefile
tools/testing/selftests/net/fin_ack_lat.c [new file with mode: 0644]
tools/testing/selftests/net/fin_ack_lat.sh [new file with mode: 0755]
tools/testing/selftests/net/mptcp/mptcp_connect.c
tools/testing/selftests/powerpc/eeh/eeh-functions.sh
tools/testing/selftests/powerpc/mm/.gitignore
tools/testing/selftests/powerpc/mm/Makefile
tools/testing/selftests/powerpc/mm/bad_accesses.c [new file with mode: 0644]
tools/testing/selftests/powerpc/ptrace/ptrace-hwbreak.c
tools/testing/selftests/tc-testing/plugin-lib/buildebpfPlugin.py
tools/testing/selftests/tc-testing/tc-tests/filters/basic.json
tools/testing/selftests/wireguard/netns.sh
tools/testing/selftests/wireguard/qemu/debug.config
usr/Kconfig
usr/Makefile
virt/kvm/kvm_main.c

index de36dce..ffb8f28 100644 (file)
--- a/.mailmap
+++ b/.mailmap
@@ -18,6 +18,7 @@ Aleksey Gorelov <aleksey_gorelov@phoenix.com>
 Aleksandar Markovic <aleksandar.markovic@mips.com> <aleksandar.markovic@imgtec.com>
 Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@intel.com>
 Alex Shi <alex.shi@linux.alibaba.com> <alex.shi@linaro.org>
+Alexandre Belloni <alexandre.belloni@bootlin.com> <alexandre.belloni@free-electrons.com>
 Alexei Starovoitov <ast@kernel.org> <ast@plumgrid.com>
 Alexei Starovoitov <ast@kernel.org> <alexei.starovoitov@gmail.com>
 Alexei Starovoitov <ast@kernel.org> <ast@fb.com>
@@ -261,6 +262,7 @@ Sumit Semwal <sumit.semwal@ti.com>
 Tejun Heo <htejun@gmail.com>
 Thomas Graf <tgraf@suug.ch>
 Thomas Pedersen <twp@codeaurora.org>
+Tiezhu Yang <yangtiezhu@loongson.cn> <kernelpatch@126.com>
 Todor Tomov <todor.too@gmail.com> <todor.tomov@linaro.org>
 Tony Luck <tony.luck@intel.com>
 TripleX Chung <xxx.phy@gmail.com> <zhongyu@18mail.cn>
index 9744728..25910c3 100644 (file)
@@ -33,6 +33,14 @@ Description:
                  Requires a separate RTC_PIE_ON call to enable the periodic
                  interrupts.
 
+               * RTC_VL_READ: Read the voltage inputs status of the RTC when
+                 supported. The value is a bit field of RTC_VL_*, giving the
+                 status of the main and backup voltages.
+
+               * RTC_VL_CLEAR: Clear the voltage status of the RTC. Some RTCs
+                 need user interaction when the backup power provider is
+                 replaced or charged to be able to clear the status.
+
                The ioctl() calls supported by the older /dev/rtc interface are
                also supported by the newer RTC class framework. However,
                because the chips and systems are not standardized, some PC/AT
index 6a733bf..73308c2 100644 (file)
@@ -11,3 +11,16 @@ Description:
                 #echo 00:19.0-E0:2:FF > /sys/bus/pci/drivers/pciback/quirks
                 will allow the guest to read and write to the configuration
                 register 0x0E.
+
+What:           /sys/bus/pci/drivers/pciback/allow_interrupt_control
+Date:           Jan 2020
+KernelVersion:  5.6
+Contact:        xen-devel@lists.xenproject.org
+Description:
+                List of devices which can have interrupt control flag (INTx,
+                MSI, MSI-X) set by a connected guest. It is meant to be set
+                only when the guest is a stubdomain hosting device model (qemu)
+                and the actual device is assigned to a HVM. It is not safe
+                (similar to permissive attribute) to set for a devices assigned
+                to a PV guest. The device is automatically removed from this
+                list when the connected pcifront terminates.
index 4e7babb..ecb7942 100644 (file)
@@ -25,3 +25,13 @@ Description:
                 allocated without being in use. The time is in
                 seconds, 0 means indefinitely long.
                 The default is 60 seconds.
+
+What:           /sys/module/xen_blkback/parameters/buffer_squeeze_duration_ms
+Date:           December 2019
+KernelVersion:  5.6
+Contact:        SeongJae Park <sjpark@amazon.de>
+Description:
+                When memory pressure is reported to blkback this option
+                controls the duration in milliseconds that blkback will not
+                cache any page not backed by a grant mapping.
+                The default is 10ms.
diff --git a/Documentation/admin-guide/bootconfig.rst b/Documentation/admin-guide/bootconfig.rst
new file mode 100644 (file)
index 0000000..b342a67
--- /dev/null
@@ -0,0 +1,190 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+.. _bootconfig:
+
+==================
+Boot Configuration
+==================
+
+:Author: Masami Hiramatsu <mhiramat@kernel.org>
+
+Overview
+========
+
+The boot configuration expands the current kernel command line to support
+additional key-value data when booting the kernel in an efficient way.
+This allows administrators to pass a structured-Key config file.
+
+Config File Syntax
+==================
+
+The boot config syntax is a simple structured key-value. Each key consists
+of dot-connected-words, and key and value are connected by ``=``. The value
+has to be terminated by semi-colon (``;``) or newline (``\n``).
+For array value, array entries are separated by comma (``,``). ::
+
+KEY[.WORD[...]] = VALUE[, VALUE2[...]][;]
+
+Unlike the kernel command line syntax, spaces are OK around the comma and ``=``.
+
+Each key word must contain only alphabets, numbers, dash (``-``) or underscore
+(``_``). And each value only contains printable characters or spaces except
+for delimiters such as semi-colon (``;``), new-line (``\n``), comma (``,``),
+hash (``#``) and closing brace (``}``).
+
+If you want to use those delimiters in a value, you can use either double-
+quotes (``"VALUE"``) or single-quotes (``'VALUE'``) to quote it. Note that
+you can not escape these quotes.
+
+There can be a key which doesn't have value or has an empty value. Those keys
+are used for checking if the key exists or not (like a boolean).
+
+Key-Value Syntax
+----------------
+
+The boot config file syntax allows user to merge partially same word keys
+by brace. For example::
+
+ foo.bar.baz = value1
+ foo.bar.qux.quux = value2
+
+These can be written also in::
+
+ foo.bar {
+    baz = value1
+    qux.quux = value2
+ }
+
+Or more shorter, written as following::
+
+ foo.bar { baz = value1; qux.quux = value2 }
+
+In both styles, same key words are automatically merged when parsing it
+at boot time. So you can append similar trees or key-values.
+
+Comments
+--------
+
+The config syntax accepts shell-script style comments. The comments starting
+with hash ("#") until newline ("\n") will be ignored.
+
+::
+
+ # comment line
+ foo = value # value is set to foo.
+ bar = 1, # 1st element
+       2, # 2nd element
+       3  # 3rd element
+
+This is parsed as below::
+
+ foo = value
+ bar = 1, 2, 3
+
+Note that you can not put a comment between value and delimiter(``,`` or
+``;``). This means following config has a syntax error ::
+
+ key = 1 # comment
+       ,2
+
+
+/proc/bootconfig
+================
+
+/proc/bootconfig is a user-space interface of the boot config.
+Unlike /proc/cmdline, this file shows the key-value style list.
+Each key-value pair is shown in each line with following style::
+
+ KEY[.WORDS...] = "[VALUE]"[,"VALUE2"...]
+
+
+Boot Kernel With a Boot Config
+==============================
+
+Since the boot configuration file is loaded with initrd, it will be added
+to the end of the initrd (initramfs) image file. The Linux kernel decodes
+the last part of the initrd image in memory to get the boot configuration
+data.
+Because of this "piggyback" method, there is no need to change or
+update the boot loader and the kernel image itself.
+
+To do this operation, Linux kernel provides "bootconfig" command under
+tools/bootconfig, which allows admin to apply or delete the config file
+to/from initrd image. You can build it by the following command::
+
+ # make -C tools/bootconfig
+
+To add your boot config file to initrd image, run bootconfig as below
+(Old data is removed automatically if exists)::
+
+ # tools/bootconfig/bootconfig -a your-config /boot/initrd.img-X.Y.Z
+
+To remove the config from the image, you can use -d option as below::
+
+ # tools/bootconfig/bootconfig -d /boot/initrd.img-X.Y.Z
+
+Then add "bootconfig" on the normal kernel command line to tell the
+kernel to look for the bootconfig at the end of the initrd file.
+
+Config File Limitation
+======================
+
+Currently the maximum config size size is 32KB and the total key-words (not
+key-value entries) must be under 1024 nodes.
+Note: this is not the number of entries but nodes, an entry must consume
+more than 2 nodes (a key-word and a value). So theoretically, it will be
+up to 512 key-value pairs. If keys contains 3 words in average, it can
+contain 256 key-value pairs. In most cases, the number of config items
+will be under 100 entries and smaller than 8KB, so it would be enough.
+If the node number exceeds 1024, parser returns an error even if the file
+size is smaller than 32KB.
+Anyway, since bootconfig command verifies it when appending a boot config
+to initrd image, user can notice it before boot.
+
+
+Bootconfig APIs
+===============
+
+User can query or loop on key-value pairs, also it is possible to find
+a root (prefix) key node and find key-values under that node.
+
+If you have a key string, you can query the value directly with the key
+using xbc_find_value(). If you want to know what keys exist in the boot
+config, you can use xbc_for_each_key_value() to iterate key-value pairs.
+Note that you need to use xbc_array_for_each_value() for accessing
+each array's value, e.g.::
+
+ vnode = NULL;
+ xbc_find_value("key.word", &vnode);
+ if (vnode && xbc_node_is_array(vnode))
+    xbc_array_for_each_value(vnode, value) {
+      printk("%s ", value);
+    }
+
+If you want to focus on keys which have a prefix string, you can use
+xbc_find_node() to find a node by the prefix string, and iterate
+keys under the prefix node with xbc_node_for_each_key_value().
+
+But the most typical usage is to get the named value under prefix
+or get the named array under prefix as below::
+
+ root = xbc_find_node("key.prefix");
+ value = xbc_node_find_value(root, "option", &vnode);
+ ...
+ xbc_node_for_each_array_value(root, "array-option", value, anode) {
+    ...
+ }
+
+This accesses a value of "key.prefix.option" and an array of
+"key.prefix.array-option".
+
+Locking is not needed, since after initialization, the config becomes
+read-only. All data and keys must be copied if you need to modify it.
+
+
+Functions and structures
+========================
+
+.. kernel-doc:: include/linux/bootconfig.h
+.. kernel-doc:: lib/bootconfig.c
+
index 4433f39..f1d0ccf 100644 (file)
@@ -64,6 +64,7 @@ configure specific aspects of kernel behavior to your liking.
    binderfs
    binfmt-misc
    blockdev/index
+   bootconfig
    braille-console
    btmrvl
    cgroup-v1/index
index ddc5ccd..dbc22d6 100644 (file)
                        no delay (0).
                        Format: integer
 
+       bootconfig      [KNL]
+                       Extended command line options can be added to an initrd
+                       and this will cause the kernel to look for it.
+
+                       See Documentation/admin-guide/bootconfig.rst
+
        bert_disable    [ACPI]
                        Disable BERT OS support on buggy BIOSes.
 
index 311cd7c..6a06dc4 100644 (file)
@@ -632,16 +632,16 @@ class priority list and destroyed.  If that happens, the priority list mechanism
 will be used, again, to determine the new effective value for the whole list
 and that value will become the new real constraint.
 
-In turn, for each CPU there is only one resume latency PM QoS request
-associated with the :file:`power/pm_qos_resume_latency_us` file under
+In turn, for each CPU there is one resume latency PM QoS request associated with
+the :file:`power/pm_qos_resume_latency_us` file under
 :file:`/sys/devices/system/cpu/cpu<N>/` in ``sysfs`` and writing to it causes
 this single PM QoS request to be updated regardless of which user space
 process does that.  In other words, this PM QoS request is shared by the entire
 user space, so access to the file associated with it needs to be arbitrated
 to avoid confusion.  [Arguably, the only legitimate use of this mechanism in
 practice is to pin a process to the CPU in question and let it use the
-``sysfs`` interface to control the resume latency constraint for it.]  It
-still only is a request, however.  It is a member of a priority list used to
+``sysfs`` interface to control the resume latency constraint for it.]  It is
+still only a request, however.  It is an entry in a priority list used to
 determine the effective value to be set as the resume latency constraint for the
 CPU in question every time the list of requests is updated this way or another
 (there may be other requests coming from kernel code in that list).
index afbf778..89309e1 100644 (file)
@@ -60,6 +60,9 @@ of the system.  The former are always used if the processor model at hand is
 recognized by ``intel_idle`` and the latter are used if that is required for
 the given processor model (which is the case for all server processor models
 recognized by ``intel_idle``) or if the processor model is not recognized.
+[There is a module parameter that can be used to make the driver use the ACPI
+tables with any processor model recognized by it; see
+`below <intel-idle-parameters_>`_.]
 
 If the ACPI tables are going to be used for building the list of available idle
 states, ``intel_idle`` first looks for a ``_CST`` object under one of the ACPI
@@ -165,7 +168,7 @@ and ``idle=nomwait``.  If any of them is present in the kernel command line, the
 ``MWAIT`` instruction is not allowed to be used, so the initialization of
 ``intel_idle`` will fail.
 
-Apart from that there are two module parameters recognized by ``intel_idle``
+Apart from that there are four module parameters recognized by ``intel_idle``
 itself that can be set via the kernel command line (they cannot be updated via
 sysfs, so that is the only way to change their values).
 
@@ -186,9 +189,28 @@ QoS) feature can be used to prevent ``CPUIdle`` from touching those idle states
 even if they have been enumerated (see :ref:`cpu-pm-qos` in :doc:`cpuidle`).
 Setting ``max_cstate`` to 0 causes the ``intel_idle`` initialization to fail.
 
-The ``noacpi`` module parameter (which is recognized by ``intel_idle`` if the
-kernel has been configured with ACPI support), can be set to make the driver
-ignore the system's ACPI tables entirely (it is unset by default).
+The ``no_acpi`` and ``use_acpi`` module parameters (recognized by ``intel_idle``
+if the kernel has been configured with ACPI support) can be set to make the
+driver ignore the system's ACPI tables entirely or use them for all of the
+recognized processor models, respectively (they both are unset by default and
+``use_acpi`` has no effect if ``no_acpi`` is set).
+
+The value of the ``states_off`` module parameter (0 by default) represents a
+list of idle states to be disabled by default in the form of a bitmask.
+
+Namely, the positions of the bits that are set in the ``states_off`` value are
+the indices of idle states to be disabled by default (as reflected by the names
+of the corresponding idle state directories in ``sysfs``, :file:`state0`,
+:file:`state1` ... :file:`state<i>` ..., where ``<i>`` is the index of the given
+idle state; see :ref:`idle-states-representation` in :doc:`cpuidle`).
+
+For example, if ``states_off`` is equal to 3, the driver will disable idle
+states 0 and 1 by default, and if it is equal to 8, idle state 3 will be
+disabled by default and so on (bit positions beyond the maximum idle state index
+are ignored).
+
+The idle states disabled this way can be enabled (on a per-CPU basis) from user
+space via ``sysfs``.
 
 
 .. _intel-idle-core-and-package-idle-states:
index cd3a28c..ee55a46 100644 (file)
@@ -153,8 +153,11 @@ for the given CPU architecture includes the low-level code for system resume.
 Basic ``sysfs`` Interfaces for System Suspend and Hibernation
 =============================================================
 
-The following files located in the :file:`/sys/power/` directory can be used by
-user space for sleep states control.
+The power management subsystem provides userspace with a unified ``sysfs``
+interface for system sleep regardless of the underlying system architecture or
+platform.  That interface is located in the :file:`/sys/power/` directory
+(assuming that ``sysfs`` is mounted at :file:`/sys`) and it consists of the
+following attributes (files):
 
 ``state``
        This file contains a list of strings representing sleep states supported
@@ -162,9 +165,9 @@ user space for sleep states control.
        to start a transition of the system into the sleep state represented by
        that string.
 
-       In particular, the strings "disk", "freeze" and "standby" represent the
+       In particular, the "disk", "freeze" and "standby" strings represent the
        :ref:`hibernation <hibernation>`, :ref:`suspend-to-idle <s2idle>` and
-       :ref:`standby <standby>` sleep states, respectively.  The string "mem"
+       :ref:`standby <standby>` sleep states, respectively.  The "mem" string
        is interpreted in accordance with the contents of the ``mem_sleep`` file
        described below.
 
@@ -177,7 +180,7 @@ user space for sleep states control.
        associated with the "mem" string in the ``state`` file described above.
 
        The strings that may be present in this file are "s2idle", "shallow"
-       and "deep".  The string "s2idle" always represents :ref:`suspend-to-idle
+       and "deep".  The "s2idle" string always represents :ref:`suspend-to-idle
        <s2idle>` and, by convention, "shallow" and "deep" represent
        :ref:`standby <standby>` and :ref:`suspend-to-RAM <s2ram>`,
        respectively.
@@ -185,15 +188,17 @@ user space for sleep states control.
        Writing one of the listed strings into this file causes the system
        suspend variant represented by it to be associated with the "mem" string
        in the ``state`` file.  The string representing the suspend variant
-       currently associated with the "mem" string in the ``state`` file
-       is listed in square brackets.
+       currently associated with the "mem" string in the ``state`` file is
+       shown in square brackets.
 
        If the kernel does not support system suspend, this file is not present.
 
 ``disk``
-       This file contains a list of strings representing different operations
-       that can be carried out after the hibernation image has been saved.  The
-       possible options are as follows:
+       This file controls the operating mode of hibernation (Suspend-to-Disk).
+       Specifically, it tells the kernel what to do after creating a
+       hibernation image.
+
+       Reading from it returns a list of supported options encoded as:
 
        ``platform``
                Put the system into a special low-power state (e.g. ACPI S4) to
@@ -201,6 +206,11 @@ user space for sleep states control.
                platform firmware to take a simplified initialization path after
                wakeup.
 
+               It is only available if the platform provides a special
+               mechanism to put the system to sleep after creating a
+               hibernation image (platforms with ACPI do that as a rule, for
+               example).
+
        ``shutdown``
                Power off the system.
 
@@ -214,22 +224,53 @@ user space for sleep states control.
                the hibernation image and continue.  Otherwise, use the image
                to restore the previous state of the system.
 
+               It is available if system suspend is supported.
+
        ``test_resume``
                Diagnostic operation.  Load the image as though the system had
                just woken up from hibernation and the currently running kernel
                instance was a restore kernel and follow up with full system
                resume.
 
-       Writing one of the listed strings into this file causes the option
+       Writing one of the strings listed above into this file causes the option
        represented by it to be selected.
 
-       The currently selected option is shown in square brackets which means
+       The currently selected option is shown in square brackets, which means
        that the operation represented by it will be carried out after creating
-       and saving the image next time hibernation is triggered by writing
-       ``disk`` to :file:`/sys/power/state`.
+       and saving the image when hibernation is triggered by writing ``disk``
+       to :file:`/sys/power/state`.
 
        If the kernel does not support hibernation, this file is not present.
 
+``image_size``
+       This file controls the size of hibernation images.
+
+       It can be written a string representing a non-negative integer that will
+       be used as a best-effort upper limit of the image size, in bytes.  The
+       hibernation core will do its best to ensure that the image size will not
+       exceed that number, but if that turns out to be impossible to achieve, a
+       hibernation image will still be created and its size will be as small as
+       possible.  In particular, writing '0' to this file causes the size of
+       hibernation images to be minimum.
+
+       Reading from it returns the current image size limit, which is set to
+       around 2/5 of the available RAM size by default.
+
+``pm_trace``
+       This file controls the "PM trace" mechanism saving the last suspend
+       or resume event point in the RTC memory across reboots.  It helps to
+       debug hard lockups or reboots due to device driver failures that occur
+       during system suspend or resume (which is more common) more effectively.
+
+       If it contains "1", the fingerprint of each suspend/resume event point
+       in turn will be stored in the RTC memory (overwriting the actual RTC
+       information), so it will survive a system crash if one occurs right
+       after storing it and it can be used later to identify the driver that
+       caused the crash to happen.
+
+       It contains "0" by default, which may be changed to "1" by writing a
+       string representing a nonzero integer into it.
+
 According to the above, there are two ways to make the system go into the
 :ref:`suspend-to-idle <s2idle>` state.  The first one is to write "freeze"
 directly to :file:`/sys/power/state`.  The second one is to write "s2idle" to
@@ -244,6 +285,7 @@ system go into the :ref:`suspend-to-RAM <s2ram>` state (write "deep" into
 The default suspend variant (ie. the one to be used without writing anything
 into :file:`/sys/power/mem_sleep`) is either "deep" (on the majority of systems
 supporting :ref:`suspend-to-RAM <s2ram>`) or "s2idle", but it can be overridden
-by the value of the "mem_sleep_default" parameter in the kernel command line.
-On some ACPI-based systems, depending on the information in the ACPI tables, the
-default may be "s2idle" even if :ref:`suspend-to-RAM <s2ram>` is supported.
+by the value of the ``mem_sleep_default`` parameter in the kernel command line.
+On some systems with ACPI, depending on the information in the ACPI tables, the
+default may be "s2idle" even if :ref:`suspend-to-RAM <s2ram>` is supported in
+principle.
index 1adf53d..05e5f2d 100644 (file)
@@ -92,6 +92,12 @@ the Microchip website: http://www.microchip.com.
 
           http://ww1.microchip.com/downloads/en/DeviceDoc/DS60001517A.pdf
 
+      - sam9x60
+
+          * Datasheet
+
+          http://ww1.microchip.com/downloads/en/DeviceDoc/SAM9X60-Data-Sheet-DS60001579A.pdf
+
     * ARM Cortex-A5 based SoCs
       - sama5d3 family
 
index c6a4433..f74aba4 100644 (file)
@@ -59,6 +59,7 @@ properties:
               - friendlyarm,nanopi-k2
               - hardkernel,odroid-c2
               - nexbox,a95x
+              - videostrong,kii-pro
               - wetek,hub
               - wetek,play2
           - const: amlogic,meson-gxbb
@@ -104,6 +105,7 @@ properties:
           - enum:
               - amlogic,p230
               - amlogic,p231
+              - libretech,aml-s905d-pc
               - phicomm,n1
           - const: amlogic,s905d
           - const: amlogic,meson-gxl
@@ -115,6 +117,7 @@ properties:
               - amlogic,q201
               - khadas,vim2
               - kingnovel,r-box-pro
+              - libretech,aml-s912-pc
               - nexbox,a1
               - tronsmart,vega-s96
           - const: amlogic,s912
index 6dd8be4..0357314 100644 (file)
@@ -37,6 +37,16 @@ properties:
 
       - items:
           - enum:
+              - overkiz,kizboxmini-base # Overkiz kizbox Mini Base Board
+              - overkiz,kizboxmini-mb   # Overkiz kizbox Mini Mother Board
+              - overkiz,kizboxmini-rd   # Overkiz kizbox Mini RailDIN
+              - overkiz,smartkiz        # Overkiz SmartKiz Board
+          - const: atmel,at91sam9g25
+          - const: atmel,at91sam9x5
+          - const: atmel,at91sam9
+
+      - items:
+          - enum:
               - atmel,at91sam9g15
               - atmel,at91sam9g25
               - atmel,at91sam9g35
@@ -52,11 +62,32 @@ properties:
           - const: atmel,sama5d2
           - const: atmel,sama5
 
+      - description: Microchip SAMA5D27 WLSOM1
+        items:
+          - const: microchip,sama5d27-wlsom1
+          - const: atmel,sama5d27
+          - const: atmel,sama5d2
+          - const: atmel,sama5
+
+      - description: Microchip SAMA5D27 WLSOM1 Evaluation Kit
+        items:
+          - const: microchip,sama5d27-wlsom1-ek
+          - const: microchip,sama5d27-wlsom1
+          - const: atmel,sama5d27
+          - const: atmel,sama5d2
+          - const: atmel,sama5
+
       - items:
           - const: atmel,sama5d27
           - const: atmel,sama5d2
           - const: atmel,sama5
 
+      - description: SAM9X60-EK board
+        items:
+          - const: microchip,sam9x60ek
+          - const: microchip,sam9x60
+          - const: atmel,at91sam9
+
       - description: Nattis v2 board with Natte v2 power board
         items:
           - const: axentia,nattis-2
index e003a55..62cd4e8 100644 (file)
@@ -45,6 +45,7 @@ RAMC SDRAM/DDR Controller required properties:
                        "atmel,at91sam9260-sdramc",
                        "atmel,at91sam9g45-ddramc",
                        "atmel,sama5d3-ddramc",
+                       "microchip,sam9x60-ddramc"
 - reg: Should contain registers location and length
 
 Examples:
index c23c24f..7a9c3ce 100644 (file)
@@ -242,6 +242,21 @@ properties:
 
       where voltage is in V, frequency is in MHz.
 
+  power-domains:
+    $ref: '/schemas/types.yaml#/definitions/phandle-array'
+    description:
+      List of phandles and PM domain specifiers, as defined by bindings of the
+      PM domain provider (see also ../power_domain.txt).
+
+  power-domain-names:
+    $ref: '/schemas/types.yaml#/definitions/string-array'
+    description:
+      A list of power domain name strings sorted in the same order as the
+      power-domains property.
+
+      For PSCI based platforms, the name corresponding to the index of the PSCI
+      PM domain provider, must be "psci".
+
   qcom,saw:
     $ref: '/schemas/types.yaml#/definitions/phandle'
     description: |
index f79683a..a8e0b4a 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/arm/fsl.yaml#
+$id: http://devicetree.org/schemas/arm/fsl.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Freescale i.MX Platforms Device Tree Bindings
@@ -128,6 +128,27 @@ properties:
               - variscite,dt6customboard
           - const: fsl,imx6q
 
+      - description: i.MX6Q Gateworks Ventana Boards
+        items:
+          - enum:
+              - gw,imx6q-gw51xx
+              - gw,imx6q-gw52xx
+              - gw,imx6q-gw53xx
+              - gw,imx6q-gw5400-a
+              - gw,imx6q-gw54xx
+              - gw,imx6q-gw551x
+              - gw,imx6q-gw552x
+              - gw,imx6q-gw553x
+              - gw,imx6q-gw560x
+              - gw,imx6q-gw5903
+              - gw,imx6q-gw5904
+              - gw,imx6q-gw5907
+              - gw,imx6q-gw5910
+              - gw,imx6q-gw5912
+              - gw,imx6q-gw5913
+          - const: gw,ventana
+          - const: fsl,imx6q
+
       - description: i.MX6QP based Boards
         items:
           - enum:
@@ -154,10 +175,31 @@ properties:
               - ysoft,imx6dl-yapp4-ursa   # i.MX6 Solo Y Soft IOTA Ursa board
           - const: fsl,imx6dl
 
+      - description: i.MX6DL Gateworks Ventana Boards
+        items:
+          - enum:
+              - gw,imx6dl-gw51xx
+              - gw,imx6dl-gw52xx
+              - gw,imx6dl-gw53xx
+              - gw,imx6dl-gw54xx
+              - gw,imx6dl-gw551x
+              - gw,imx6dl-gw552x
+              - gw,imx6dl-gw553x
+              - gw,imx6dl-gw560x
+              - gw,imx6dl-gw5903
+              - gw,imx6dl-gw5904
+              - gw,imx6dl-gw5907
+              - gw,imx6dl-gw5910
+              - gw,imx6dl-gw5912
+              - gw,imx6dl-gw5913
+          - const: gw,ventana
+          - const: fsl,imx6dl
+
       - description: i.MX6SL based Boards
         items:
           - enum:
               - fsl,imx6sl-evk            # i.MX6 SoloLite EVK Board
+              - kobo,tolino-shine3
           - const: fsl,imx6sl
 
       - description: i.MX6SLL based Boards
@@ -172,6 +214,7 @@ properties:
           - enum:
               - fsl,imx6sx-sabreauto      # i.MX6 SoloX Sabre Auto Board
               - fsl,imx6sx-sdb            # i.MX6 SoloX SDB Board
+              - fsl,imx6sx-sdb-reva       # i.MX6 SoloX SDB Rev-A Board
           - const: fsl,imx6sx
 
       - description: i.MX6UL based Boards
@@ -239,6 +282,7 @@ properties:
         items:
           - enum:
               - fsl,imx7d-sdb             # i.MX7 SabreSD Board
+              - fsl,imx7d-sdb-reva        # i.MX7 SabreSD Rev-A 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
@@ -263,6 +307,7 @@ properties:
       - description: i.MX7ULP based Boards
         items:
           - enum:
+              - ea,imx7ulp-com           # i.MX7ULP Embedded Artists COM Board
               - fsl,imx7ulp-evk           # i.MX7ULP Evaluation Kit
           - const: fsl,imx7ulp
 
@@ -283,7 +328,9 @@ properties:
         items:
           - enum:
               - boundary,imx8mq-nitrogen8m # i.MX8MQ NITROGEN Board
+              - einfochips,imx8mq-thor96  # i.MX8MQ Thor96 Board
               - fsl,imx8mq-evk            # i.MX8MQ EVK Board
+              - google,imx8mq-phanbell    # Google Coral Edge TPU
               - purism,librem5-devkit     # Purism Librem5 devkit
               - solidrun,hummingboard-pulse # SolidRun Hummingboard Pulse
               - technexion,pico-pi-imx8m  # TechNexion PICO-PI-8M evk
@@ -385,6 +432,13 @@ properties:
               - fsl,ls2088a-rdb
           - const: fsl,ls2088a
 
+      - description: LX2160A based Boards
+        items:
+          - enum:
+              - fsl,lx2160a-qds
+              - fsl,lx2160a-rdb
+          - const: fsl,lx2160a
+
       - description: S32V234 based Boards
         items:
           - enum:
index 5587490..79902f4 100644 (file)
@@ -47,7 +47,7 @@ examples:
   - |
     #include <dt-bindings/interrupt-controller/arm-gic.h>
 
-    cache-controller@1100000 {
+    system-cache-controller@1100000 {
       compatible = "qcom,sdm845-llcc";
       reg = <0x1100000 0x200000>, <0x1300000 0x50000> ;
       reg-names = "llcc_base", "llcc_broadcast_base";
index 7abdf58..8ef8542 100644 (file)
@@ -102,6 +102,34 @@ properties:
       [1] Kernel documentation - ARM idle states bindings
         Documentation/devicetree/bindings/arm/idle-states.txt
 
+  "#power-domain-cells":
+    description:
+      The number of cells in a PM domain specifier as per binding in [3].
+      Must be 0 as to represent a single PM domain.
+
+      ARM systems can have multiple cores, sometimes in an hierarchical
+      arrangement. This often, but not always, maps directly to the processor
+      power topology of the system. Individual nodes in a topology have their
+      own specific power states and can be better represented hierarchically.
+
+      For these cases, the definitions of the idle states for the CPUs and the
+      CPU topology, must conform to the binding in [3]. The idle states
+      themselves must conform to the binding in [4] and must specify the
+      arm,psci-suspend-param property.
+
+      It should also be noted that, in PSCI firmware v1.0 the OS-Initiated
+      (OSI) CPU suspend mode is introduced. Using a hierarchical representation
+      helps to implement support for OSI mode and OS implementations may choose
+      to mandate it.
+
+      [3] Documentation/devicetree/bindings/power/power_domain.txt
+      [4] Documentation/devicetree/bindings/power/domain-idle-state.txt
+
+  power-domains:
+    $ref: '/schemas/types.yaml#/definitions/phandle-array'
+    description:
+      List of phandles and PM domain specifiers, as defined by bindings of the
+      PM domain provider.
 
 required:
   - compatible
@@ -160,4 +188,80 @@ examples:
       cpu_on = <0x95c10002>;
       cpu_off = <0x95c10001>;
     };
+
+  - |+
+
+    // Case 4: CPUs and CPU idle states described using the hierarchical model.
+
+    cpus {
+      #size-cells = <0>;
+      #address-cells = <1>;
+
+      CPU0: cpu@0 {
+        device_type = "cpu";
+        compatible = "arm,cortex-a53", "arm,armv8";
+        reg = <0x0>;
+        enable-method = "psci";
+        power-domains = <&CPU_PD0>;
+        power-domain-names = "psci";
+      };
+
+      CPU1: cpu@1 {
+        device_type = "cpu";
+        compatible = "arm,cortex-a57", "arm,armv8";
+        reg = <0x100>;
+        enable-method = "psci";
+        power-domains = <&CPU_PD1>;
+        power-domain-names = "psci";
+      };
+
+      idle-states {
+
+        CPU_PWRDN: cpu-power-down {
+          compatible = "arm,idle-state";
+          arm,psci-suspend-param = <0x0000001>;
+          entry-latency-us = <10>;
+          exit-latency-us = <10>;
+          min-residency-us = <100>;
+        };
+
+        CLUSTER_RET: cluster-retention {
+          compatible = "domain-idle-state";
+          arm,psci-suspend-param = <0x1000011>;
+          entry-latency-us = <500>;
+          exit-latency-us = <500>;
+          min-residency-us = <2000>;
+        };
+
+        CLUSTER_PWRDN: cluster-power-down {
+          compatible = "domain-idle-state";
+          arm,psci-suspend-param = <0x1000031>;
+          entry-latency-us = <2000>;
+          exit-latency-us = <2000>;
+          min-residency-us = <6000>;
+        };
+      };
+    };
+
+    psci {
+      compatible = "arm,psci-1.0";
+      method = "smc";
+
+      CPU_PD0: cpu-pd0 {
+        #power-domain-cells = <0>;
+        domain-idle-states = <&CPU_PWRDN>;
+        power-domains = <&CLUSTER_PD>;
+      };
+
+      CPU_PD1: cpu-pd1 {
+        #power-domain-cells = <0>;
+        domain-idle-states =  <&CPU_PWRDN>;
+        power-domains = <&CLUSTER_PD>;
+      };
+
+      CLUSTER_PD: cluster-pd {
+        #power-domain-cells = <0>;
+        domain-idle-states = <&CLUSTER_RET>, <&CLUSTER_PWRDN>;
+      };
+    };
 ...
index e39d8f0..5976c0b 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/arm/qcom.yaml#
+$id: http://devicetree.org/schemas/arm/qcom.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: QCOM device tree bindings
@@ -24,28 +24,30 @@ description: |
 
   The 'SoC' element must be one of the following strings:
 
-       apq8016
-       apq8074
-       apq8084
-       apq8096
-       msm8916
-       msm8974
-       msm8992
-       msm8994
-       msm8996
-       mdm9615
-       ipq8074
-       sdm845
+        apq8016
+        apq8074
+        apq8084
+        apq8096
+        ipq8074
+        mdm9615
+        msm8916
+        msm8974
+        msm8992
+        msm8994
+        msm8996
+        sc7180
+        sdm845
 
   The 'board' element must be one of the following strings:
 
-       cdp
-       liquid
-       dragonboard
-       mtp
-       sbc
-       hk01
-       qrd
+        cdp
+        dragonboard
+        hk01
+        idp
+        liquid
+        mtp
+        qrd
+        sbc
 
   The 'soc_version' and 'board_version' elements take the form of v<Major>.<Minor>
   where the minor number may be omitted when it's zero, i.e.  v1.0 is the same
@@ -144,4 +146,8 @@ properties:
               - qcom,ipq8074-hk01
           - const: qcom,ipq8074
 
+      - items:
+          - enum:
+              - qcom,sc7180-idp
+          - const: qcom,sc7180
 ...
index d9847b3..874b0ea 100644 (file)
@@ -409,6 +409,9 @@ properties:
 
       - description: Pine64 RockPro64
         items:
+          - enum:
+              - pine64,rockpro64-v2.1
+              - pine64,rockpro64-v2.0
           - const: pine64,rockpro64
           - const: rockchip,rk3399
 
@@ -422,6 +425,12 @@ properties:
           - const: radxa,rockpi4
           - const: rockchip,rk3399
 
+      - description: Radxa ROCK Pi N10
+        items:
+          - const: radxa,rockpi-n10
+          - const: vamrs,rk3399pro-vmarc-som
+          - const: rockchip,rk3399pro
+
       - description: Radxa Rock2 Square
         items:
           - const: radxa,rock2-square
@@ -2,7 +2,7 @@
 # Copyright 2019 Unisoc Inc.
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/arm/sprd.yaml#
+$id: http://devicetree.org/schemas/arm/sprd/sprd.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Unisoc platforms device tree bindings
index cffe8bb..327ce67 100644 (file)
@@ -342,6 +342,16 @@ properties:
           - const: libretech,all-h3-cc-h5
           - const: allwinner,sun50i-h5
 
+      - description: Libre Computer Board ALL-H3-IT H5
+        items:
+          - const: libretech,all-h3-it-h5
+          - const: allwinner,sun50i-h5
+
+      - description: Libre Computer Board ALL-H5-CC H5
+        items:
+          - const: libretech,all-h5-cc-h5
+          - const: allwinner,sun50i-h5
+
       - description: Lichee Pi One
         items:
           - const: licheepi,licheepi-one
@@ -470,6 +480,12 @@ properties:
           - const: emlid,neutis-n5
           - const: allwinner,sun50i-h5
 
+      - description: Emlid Neutis N5H3 Developper Board
+        items:
+          - const: emlid,neutis-n5h3-devboard
+          - const: emlid,neutis-n5h3
+          - const: allwinner,sun8i-h3
+
       - description: NextThing Co. CHIP
         items:
           - const: nextthing,chip
@@ -599,11 +615,16 @@ properties:
           - const: pine64,pine64-plus
           - const: allwinner,sun50i-a64
 
-      - description: Pine64 PineH64
+      - description: Pine64 PineH64 model A
         items:
           - const: pine64,pine-h64
           - const: allwinner,sun50i-h6
 
+      - description: Pine64 PineH64 model B
+        items:
+          - const: pine64,pine-h64-model-b
+          - const: allwinner,sun50i-h6
+
       - description: Pine64 LTS
         items:
           - const: pine64,pine64-lts
diff --git a/Documentation/devicetree/bindings/arm/ux500.yaml b/Documentation/devicetree/bindings/arm/ux500.yaml
new file mode 100644 (file)
index 0000000..accaee9
--- /dev/null
@@ -0,0 +1,36 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/arm/ux500.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Ux500 platforms device tree bindings
+
+maintainers:
+  - Linus Walleij <linus.walleij@linaro.org>
+
+properties:
+  $nodename:
+    const: '/'
+  compatible:
+    oneOf:
+
+      - description: ST-Ericsson HREF (pre-v60)
+        items:
+          - const: st-ericsson,mop500
+          - const: st-ericsson,u8500
+
+      - description: ST-Ericsson HREF (v60+)
+        items:
+          - const: st-ericsson,hrefv60+
+          - const: st-ericsson,u8500
+
+      - description: Calao Systems Snowball
+        items:
+          - const: calaosystems,snowball-a9500
+          - const: st-ericsson,u9500
+
+      - description: Samsung Galaxy S III mini (GT-I8190)
+        items:
+          - const: samsung,golden
+          - const: st-ericsson,u8500
diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun8i-a83t-de2-clk.yaml
new file mode 100644 (file)
index 0000000..3f995d2
--- /dev/null
@@ -0,0 +1,76 @@
+# SPDX-License-Identifier: GPL-2.0+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/allwinner,sun8i-a83t-de2-clk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A83t Display Engine 2/3 Clock Controller Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <mripard@kernel.org>
+
+properties:
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  compatible:
+    oneOf:
+      - const: allwinner,sun8i-a83t-de2-clk
+      - const: allwinner,sun8i-h3-de2-clk
+      - const: allwinner,sun8i-v3s-de2-clk
+      - const: allwinner,sun50i-a64-de2-clk
+      - const: allwinner,sun50i-h5-de2-clk
+      - const: allwinner,sun50i-h6-de2-clk
+      - items:
+          - const: allwinner,sun8i-r40-de2-clk
+          - const: allwinner,sun8i-h3-de2-clk
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Bus Clock
+      - description: Module Clock
+
+  clock-names:
+    items:
+      - const: bus
+      - const: mod
+
+  resets:
+    maxItems: 1
+
+required:
+  - "#clock-cells"
+  - "#reset-cells"
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/sun8i-h3-ccu.h>
+    #include <dt-bindings/reset/sun8i-h3-ccu.h>
+
+    de2_clocks: clock@1000000 {
+        compatible = "allwinner,sun8i-h3-de2-clk";
+        reg = <0x01000000 0x100000>;
+        clocks = <&ccu CLK_BUS_DE>,
+                 <&ccu CLK_DE>;
+        clock-names = "bus",
+                      "mod";
+        resets = <&ccu RST_BUS_DE>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-de-clks.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-de-clks.yaml
new file mode 100644 (file)
index 0000000..a82c7c7
--- /dev/null
@@ -0,0 +1,67 @@
+# SPDX-License-Identifier: GPL-2.0+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/allwinner,sun9i-a80-de-clks.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A80 Display Engine Clock Controller Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <mripard@kernel.org>
+
+properties:
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  compatible:
+    const: allwinner,sun9i-a80-de-clks
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Bus Clock
+      - description: RAM Bus Clock
+      - description: Module Clock
+
+  clock-names:
+    items:
+      - const: mod
+      - const: dram
+      - const: bus
+
+  resets:
+    maxItems: 1
+
+required:
+  - "#clock-cells"
+  - "#reset-cells"
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/sun9i-a80-ccu.h>
+    #include <dt-bindings/reset/sun9i-a80-ccu.h>
+
+    de_clocks: clock@3000000 {
+        compatible = "allwinner,sun9i-a80-de-clks";
+        reg = <0x03000000 0x30>;
+        clocks = <&ccu CLK_DE>, <&ccu CLK_SDRAM>, <&ccu CLK_BUS_DE>;
+        clock-names = "mod", "dram", "bus";
+        resets = <&ccu RST_BUS_DE>;
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clocks.yaml b/Documentation/devicetree/bindings/clock/allwinner,sun9i-a80-usb-clocks.yaml
new file mode 100644 (file)
index 0000000..fa0ee03
--- /dev/null
@@ -0,0 +1,59 @@
+# SPDX-License-Identifier: GPL-2.0+
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/allwinner,sun9i-a80-usb-clocks.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Allwinner A80 USB Clock Controller Device Tree Bindings
+
+maintainers:
+  - Chen-Yu Tsai <wens@csie.org>
+  - Maxime Ripard <mripard@kernel.org>
+
+properties:
+  "#clock-cells":
+    const: 1
+
+  "#reset-cells":
+    const: 1
+
+  compatible:
+    const: allwinner,sun9i-a80-usb-clocks
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: Bus Clock
+      - description: High Frequency Oscillator
+
+  clock-names:
+    items:
+      - const: bus
+      - const: hosc
+
+required:
+  - "#clock-cells"
+  - "#reset-cells"
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/sun9i-a80-ccu.h>
+
+    usb_clocks: clock@a08000 {
+        compatible = "allwinner,sun9i-a80-usb-clks";
+        reg = <0x00a08000 0x8>;
+        clocks = <&ccu CLK_BUS_USB>, <&osc24M>;
+        clock-names = "bus", "hosc";
+        #clock-cells = <1>;
+        #reset-cells = <1>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson8-ddr-clkc.yaml b/Documentation/devicetree/bindings/clock/amlogic,meson8-ddr-clkc.yaml
new file mode 100644 (file)
index 0000000..4b8669f
--- /dev/null
@@ -0,0 +1,50 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/amlogic,meson8-ddr-clkc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Amlogic DDR Clock Controller Device Tree Bindings
+
+maintainers:
+  - Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+
+properties:
+  compatible:
+    enum:
+      - amlogic,meson8-ddr-clkc
+      - amlogic,meson8b-ddr-clkc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  clock-names:
+    items:
+      - const: xtal
+
+  "#clock-cells":
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - "#clock-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    ddr_clkc: clock-controller@400 {
+      compatible = "amlogic,meson8-ddr-clkc";
+      reg = <0x400 0x20>;
+      clocks = <&xtal>;
+      clock-names = "xtal";
+      #clock-cells = <1>;
+    };
+
+...
index 4d94091..cc51e47 100644 (file)
@@ -11,6 +11,11 @@ Required Properties:
        - "amlogic,meson8m2-clkc" for Meson8m2 (S812) SoCs
 - #clock-cells: should be 1.
 - #reset-cells: should be 1.
+- clocks: list of clock phandles, one for each entry in clock-names
+- clock-names: should contain the following:
+  * "xtal": the 24MHz system oscillator
+  * "ddr_pll": the DDR PLL clock
+  * "clk_32k": (if present) the 32kHz clock signal from GPIOAO_6 (CLK_32K_IN)
 
 Parent node should have the following properties :
 - compatible: "amlogic,meson-hhi-sysctrl", "simple-mfd", "syscon"
index e638273..8559fe8 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/clock/bitmain,bm1880-clk.yaml#
+$id: http://devicetree.org/schemas/clock/bitmain,bm1880-clk.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Bitmain BM1880 Clock Controller
diff --git a/Documentation/devicetree/bindings/clock/fsl,plldig.yaml b/Documentation/devicetree/bindings/clock/fsl,plldig.yaml
new file mode 100644 (file)
index 0000000..c835003
--- /dev/null
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/fsl,plldig.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP QorIQ Layerscape LS1028A Display PIXEL Clock Binding
+
+maintainers:
+  - Wen He <wen.he_1@nxp.com>
+
+description: |
+  NXP LS1028A has a clock domain PXLCLK0 used for the Display output
+  interface in the display core, as implemented in TSMC CLN28HPM PLL.
+  which generate and offers pixel clocks to Display.
+
+properties:
+  compatible:
+    const: fsl,ls1028a-plldig
+
+  reg:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 0
+
+  fsl,vco-hz:
+     description: Optional for VCO frequency of the PLL in Hertz.
+        The VCO frequency of this PLL cannot be changed during runtime
+        only at startup. Therefore, the output frequencies are very
+        limited and might not even closely match the requested frequency.
+        To work around this restriction the user may specify its own
+        desired VCO frequency for the PLL.
+     minimum: 650000000
+     maximum: 1300000000
+     default: 1188000000
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+
+examples:
+  # Display PIXEL Clock node:
+  - |
+    dpclk: clock-display@f1f0000 {
+        compatible = "fsl,ls1028a-plldig";
+        reg = <0x0 0xf1f0000 0x0 0xffff>;
+        #clock-cells = <0>;
+        clocks = <&osc_27m>;
+    };
+
+...
diff --git a/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml b/Documentation/devicetree/bindings/clock/fsl,sai-clock.yaml
new file mode 100644 (file)
index 0000000..fc3bdfd
--- /dev/null
@@ -0,0 +1,55 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/fsl,sai-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Freescale SAI bitclock-as-a-clock binding
+
+maintainers:
+  - Michael Walle <michael@walle.cc>
+
+description: |
+  It is possible to use the BCLK pin of a SAI module as a generic clock
+  output. Some SoC are very constrained in their pin multiplexer
+  configuration. Eg. pins can only be changed groups. For example, on the
+  LS1028A SoC you can only enable SAIs in pairs. If you use only one SAI,
+  the second pins are wasted. Using this binding it is possible to use the
+  clock of the second SAI as a MCLK clock for an audio codec, for example.
+
+  This is a composite of a gated clock and a divider clock.
+
+properties:
+  compatible:
+    const: fsl,vf610-sai-clock
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+  '#clock-cells':
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - '#clock-cells'
+
+additionalProperties: false
+
+examples:
+  - |
+    soc {
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        mclk: clock-mclk@f130080 {
+            compatible = "fsl,vf610-sai-clock";
+            reg = <0x0 0xf130080 0x0 0x80>;
+            #clock-cells = <0>;
+            clocks = <&parentclk>;
+        };
+    };
index 622f365..cd0b8a3 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/clock/imx8mn-clock.yaml#
+$id: http://devicetree.org/schemas/clock/imx8mn-clock.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: NXP i.MX8M Nano Clock Control Module Binding
diff --git a/Documentation/devicetree/bindings/clock/imx8mp-clock.yaml b/Documentation/devicetree/bindings/clock/imx8mp-clock.yaml
new file mode 100644 (file)
index 0000000..89aee63
--- /dev/null
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/imx8mp-clock.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP i.MX8M Plus Clock Control Module Binding
+
+maintainers:
+  - Anson Huang <Anson.Huang@nxp.com>
+
+description:
+  NXP i.MX8M Plus clock control module is an integrated clock controller, which
+  generates and supplies to all modules.
+
+properties:
+  compatible:
+    const: fsl,imx8mp-ccm
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: 32k osc
+      - description: 24m osc
+      - description: ext1 clock input
+      - description: ext2 clock input
+      - description: ext3 clock input
+      - description: ext4 clock input
+
+  clock-names:
+    items:
+      - const: osc_32k
+      - const: osc_24m
+      - const: clk_ext1
+      - const: clk_ext2
+      - const: clk_ext3
+      - const: clk_ext4
+
+  '#clock-cells':
+    const: 1
+    description:
+      The clock consumer should specify the desired clock by having the clock
+      ID in its "clocks" phandle cell. See include/dt-bindings/clock/imx8mp-clock.h
+      for the full list of i.MX8M Plus clock IDs.
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+
+examples:
+  # Clock Control Module node:
+  - |
+    clk: clock-controller@30380000 {
+        compatible = "fsl,imx8mp-ccm";
+        reg = <0x30380000 0x10000>;
+        #clock-cells = <1>;
+        clocks = <&osc_32k>, <&osc_24m>, <&clk_ext1>,
+                 <&clk_ext2>, <&clk_ext3>, <&clk_ext4>;
+        clock-names = "osc_32k", "osc_24m", "clk_ext1",
+                      "clk_ext2", "clk_ext3", "clk_ext4";
+    };
+
+...
index 5cf0b81..f0b804a 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/clock/milbeaut-clock.yaml#
+$id: http://devicetree.org/schemas/clock/milbeaut-clock.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Milbeaut SoCs Clock Controller Binding
diff --git a/Documentation/devicetree/bindings/clock/qcom,dispcc.txt b/Documentation/devicetree/bindings/clock/qcom,dispcc.txt
deleted file mode 100644 (file)
index d639e18..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-Qualcomm Technologies, Inc. Display Clock Controller Binding
-------------------------------------------------------------
-
-Required properties :
-
-- compatible : shall contain "qcom,sdm845-dispcc"
-- reg : shall contain base register location and length.
-- #clock-cells : from common clock binding, shall contain 1.
-- #reset-cells : from common reset binding, shall contain 1.
-- #power-domain-cells : from generic power domain binding, shall contain 1.
-
-Example:
-       dispcc: clock-controller@af00000 {
-               compatible = "qcom,sdm845-dispcc";
-               reg = <0xaf00000 0x100000>;
-               #clock-cells = <1>;
-               #reset-cells = <1>;
-               #power-domain-cells = <1>;
-       };
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-apq8064.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-apq8064.yaml
new file mode 100644 (file)
index 0000000..17f8717
--- /dev/null
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-apq8064.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for APQ8064
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on APQ8064.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-msm8960.h
+  - dt-bindings/reset/qcom,gcc-msm8960.h
+
+properties:
+  compatible:
+    const: qcom,gcc-apq8064
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  nvmem-cells:
+    minItems: 1
+    maxItems: 2
+    description:
+      Qualcomm TSENS (thermal sensor device) on some devices can
+      be part of GCC and hence the TSENS properties can also be part
+      of the GCC/clock-controller node.
+      For more details on the TSENS properties please refer
+      Documentation/devicetree/bindings/thermal/qcom-tsens.txt
+
+  nvmem-cell-names:
+    minItems: 1
+    maxItems: 2
+    items:
+      - const: calib
+      - const: calib_backup
+
+  '#thermal-sensor-cells':
+    const: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+  - nvmem-cells
+  - nvmem-cell-names
+  - '#thermal-sensor-cells'
+
+examples:
+  - |
+    clock-controller@900000 {
+      compatible = "qcom,gcc-apq8064";
+      reg = <0x00900000 0x4000>;
+      nvmem-cells = <&tsens_calib>, <&tsens_backup>;
+      nvmem-cell-names = "calib", "calib_backup";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      #thermal-sensor-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-ipq8074.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-ipq8074.yaml
new file mode 100644 (file)
index 0000000..89c6e07
--- /dev/null
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-ipq8074.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Bindingfor IPQ8074
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on IPQ8074.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-ipq8074.h
+
+properties:
+  compatible:
+    const: qcom,gcc-ipq8074
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+
+examples:
+  - |
+    clock-controller@1800000 {
+      compatible = "qcom,gcc-ipq8074";
+      reg = <0x01800000 0x80000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8996.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8996.yaml
new file mode 100644 (file)
index 0000000..18e4e77
--- /dev/null
@@ -0,0 +1,68 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-msm8996.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for MSM8996
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on MSM8996.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-msm8996.h
+
+properties:
+  compatible:
+    const: qcom,gcc-msm8996
+
+  clocks:
+    items:
+      - description: XO source
+      - description: Second XO source
+      - description: Sleep clock source
+
+  clock-names:
+    items:
+      - const: cxo
+      - const: cxo2
+      - const: sleep_clk
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    clock-controller@300000 {
+      compatible = "qcom,gcc-msm8996";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      reg = <0x300000 0x90000>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-msm8998.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-msm8998.yaml
new file mode 100644 (file)
index 0000000..1d3cae9
--- /dev/null
@@ -0,0 +1,93 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-msm8998.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for MSM8998
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on MSM8998.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-msm8998.h
+
+properties:
+  compatible:
+    const: qcom,gcc-msm8998
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Sleep clock source
+      - description: USB 3.0 phy pipe clock
+      - description: UFS phy rx symbol clock for pipe 0
+      - description: UFS phy rx symbol clock for pipe 1
+      - description: UFS phy tx symbol clock
+      - description: PCIE phy pipe clock
+
+  clock-names:
+    items:
+      - const: xo
+      - const: sleep_clk
+      - const: usb3_pipe
+      - const: ufs_rx_symbol0
+      - const: ufs_rx_symbol1
+      - const: ufs_tx_symbol0
+      - const: pcie0_pipe
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmcc.h>
+    clock-controller@100000 {
+      compatible = "qcom,gcc-msm8998";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      reg = <0x00100000 0xb0000>;
+      clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+               <&sleep>,
+               <0>,
+               <0>,
+               <0>,
+               <0>,
+               <0>;
+      clock-names = "xo",
+                    "sleep_clk",
+                    "usb3_pipe",
+                    "ufs_rx_symbol0",
+                    "ufs_rx_symbol1",
+                    "ufs_tx_symbol0",
+                    "pcie0_pipe";
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-qcs404.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-qcs404.yaml
new file mode 100644 (file)
index 0000000..8cdece3
--- /dev/null
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-qcs404.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Bindingfor QCS404
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on QCS404.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-qcs404.h
+
+properties:
+  compatible:
+    const: qcom,gcc-qcs404
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+
+examples:
+  - |
+    clock-controller@1800000 {
+      compatible = "qcom,gcc-qcs404";
+      reg = <0x01800000 0x80000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sc7180.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sc7180.yaml
new file mode 100644 (file)
index 0000000..ee4f968
--- /dev/null
@@ -0,0 +1,75 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-sc7180.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for SC7180
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on SC7180.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-sc7180.h
+
+properties:
+  compatible:
+    const: qcom,gcc-sc7180
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Board active XO source
+      - description: Sleep clock source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: bi_tcxo_ao
+      - const: sleep_clk
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@100000 {
+      compatible = "qcom,gcc-sc7180";
+      reg = <0 0x00100000 0 0x1f0000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&rpmhcc RPMH_CXO_CLK_A>,
+               <&sleep_clk>;
+      clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gcc-sm8150.yaml b/Documentation/devicetree/bindings/clock/qcom,gcc-sm8150.yaml
new file mode 100644 (file)
index 0000000..888e9a7
--- /dev/null
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,gcc-sm8150.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Global Clock & Reset Controller Binding for SM8150
+
+maintainers:
+  - Stephen Boyd <sboyd@kernel.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm global clock control module which supports the clocks, resets and
+  power domains on SM8150.
+
+  See also:
+  - dt-bindings/clock/qcom,gcc-sm8150.h
+
+properties:
+  compatible:
+    const: qcom,gcc-sm8150
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Sleep clock source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: sleep_clk
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+      Protected clock specifier list as per common clock binding.
+
+required:
+  - compatible
+  - clocks
+  - clock-names
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@100000 {
+      compatible = "qcom,gcc-sm8150";
+      reg = <0 0x00100000 0 0x1f0000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&sleep_clk>;
+      clock-names = "bi_tcxo", "sleep_clk";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
index e73a56f..d18f8ab 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/clock/qcom,gcc.yaml#
+$id: http://devicetree.org/schemas/clock/qcom,gcc.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Qualcomm Global Clock & Reset Controller Binding
@@ -14,46 +14,42 @@ description: |
   Qualcomm global clock control module which supports the clocks, resets and
   power domains.
 
+  See also:
+  - dt-bindings/clock/qcom,gcc-apq8084.h
+  - dt-bindings/reset/qcom,gcc-apq8084.h
+  - dt-bindings/clock/qcom,gcc-ipq4019.h
+  - dt-bindings/clock/qcom,gcc-ipq6018.h
+  - dt-bindings/reset/qcom,gcc-ipq6018.h
+  - dt-bindings/clock/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
+  - dt-bindings/reset/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
+  - dt-bindings/clock/qcom,gcc-msm8660.h
+  - dt-bindings/reset/qcom,gcc-msm8660.h
+  - dt-bindings/clock/qcom,gcc-msm8974.h
+  - dt-bindings/reset/qcom,gcc-msm8974.h
+  - dt-bindings/clock/qcom,gcc-msm8994.h
+  - dt-bindings/clock/qcom,gcc-mdm9615.h
+  - dt-bindings/reset/qcom,gcc-mdm9615.h
+  - dt-bindings/clock/qcom,gcc-sdm660.h  (qcom,gcc-sdm630 and qcom,gcc-sdm660)
+  - dt-bindings/clock/qcom,gcc-sdm845.h
+
 properties:
-  compatible :
+  compatible:
     enum:
-       - qcom,gcc-apq8064
-       - qcom,gcc-apq8084
-       - qcom,gcc-ipq8064
-       - qcom,gcc-ipq4019
-       - qcom,gcc-ipq8074
-       - qcom,gcc-msm8660
-       - qcom,gcc-msm8916
-       - qcom,gcc-msm8960
-       - qcom,gcc-msm8974
-       - qcom,gcc-msm8974pro
-       - qcom,gcc-msm8974pro-ac
-       - qcom,gcc-msm8994
-       - qcom,gcc-msm8996
-       - qcom,gcc-msm8998
-       - qcom,gcc-mdm9615
-       - qcom,gcc-qcs404
-       - qcom,gcc-sc7180
-       - qcom,gcc-sdm630
-       - qcom,gcc-sdm660
-       - qcom,gcc-sdm845
-       - qcom,gcc-sm8150
-
-  clocks:
-    minItems: 1
-    maxItems: 3
-    items:
-      - description: Board XO source
-      - description: Board active XO source
-      - description: Sleep clock source
-
-  clock-names:
-    minItems: 1
-    maxItems: 3
-    items:
-      - const: bi_tcxo
-      - const: bi_tcxo_ao
-      - const: sleep_clk
+      - qcom,gcc-apq8084
+      - qcom,gcc-ipq4019
+      - qcom,gcc-ipq6018
+      - qcom,gcc-ipq8064
+      - qcom,gcc-msm8660
+      - qcom,gcc-msm8916
+      - qcom,gcc-msm8960
+      - qcom,gcc-msm8974
+      - qcom,gcc-msm8974pro
+      - qcom,gcc-msm8974pro-ac
+      - qcom,gcc-msm8994
+      - qcom,gcc-mdm9615
+      - qcom,gcc-sdm630
+      - qcom,gcc-sdm660
+      - qcom,gcc-sdm845
 
   '#clock-cells':
     const: 1
@@ -67,31 +63,9 @@ properties:
   reg:
     maxItems: 1
 
-  nvmem-cells:
-    minItems: 1
-    maxItems: 2
-    description:
-      Qualcomm TSENS (thermal sensor device) on some devices can
-      be part of GCC and hence the TSENS properties can also be part
-      of the GCC/clock-controller node.
-      For more details on the TSENS properties please refer
-      Documentation/devicetree/bindings/thermal/qcom-tsens.txt
-
-  nvmem-cell-names:
-    minItems: 1
-    maxItems: 2
-    description:
-      Names for each nvmem-cells specified.
-    items:
-      - const: calib
-      - const: calib_backup
-
-  'thermal-sensor-cells':
-    const: 1
-
   protected-clocks:
     description:
-       Protected clock specifier list as per common clock binding
+      Protected clock specifier list as per common clock binding.
 
 required:
   - compatible
@@ -100,32 +74,6 @@ required:
   - '#reset-cells'
   - '#power-domain-cells'
 
-if:
-  properties:
-    compatible:
-      contains:
-        const: qcom,gcc-apq8064
-
-then:
-  required:
-    - nvmem-cells
-    - nvmem-cell-names
-    - '#thermal-sensor-cells'
-
-else:
-  if:
-    properties:
-      compatible:
-        contains:
-          enum:
-            - qcom,gcc-sm8150
-            - qcom,gcc-sc7180
-  then:
-    required:
-       - clocks
-       - clock-names
-
-
 examples:
   # Example for GCC for MSM8960:
   - |
@@ -136,53 +84,4 @@ examples:
       #reset-cells = <1>;
       #power-domain-cells = <1>;
     };
-
-
-  # Example of GCC with TSENS properties:
-  - |
-    clock-controller@900000 {
-      compatible = "qcom,gcc-apq8064";
-      reg = <0x00900000 0x4000>;
-      nvmem-cells = <&tsens_calib>, <&tsens_backup>;
-      nvmem-cell-names = "calib", "calib_backup";
-      #clock-cells = <1>;
-      #reset-cells = <1>;
-      #power-domain-cells = <1>;
-      #thermal-sensor-cells = <1>;
-    };
-
-  # Example of GCC with protected-clocks properties:
-  - |
-    clock-controller@100000 {
-      compatible = "qcom,gcc-sdm845";
-      reg = <0x100000 0x1f0000>;
-      protected-clocks = <187>, <188>, <189>, <190>, <191>;
-      #clock-cells = <1>;
-      #reset-cells = <1>;
-      #power-domain-cells = <1>;
-    };
-
-  # Example of GCC with clock node properties for SM8150:
-  - |
-    clock-controller@100000 {
-      compatible = "qcom,gcc-sm8150";
-      reg = <0x00100000 0x1f0000>;
-      clocks = <&rpmhcc 0>, <&rpmhcc 1>, <&sleep_clk>;
-      clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
-      #clock-cells = <1>;
-      #reset-cells = <1>;
-      #power-domain-cells = <1>;
-     };
-
-  # Example of GCC with clock nodes properties for SC7180:
-  - |
-    clock-controller@100000 {
-      compatible = "qcom,gcc-sc7180";
-      reg = <0x100000 0x1f0000>;
-      clocks = <&rpmhcc 0>, <&rpmhcc 1>;
-      clock-names = "bi_tcxo", "bi_tcxo_ao";
-      #clock-cells = <1>;
-      #reset-cells = <1>;
-      #power-domain-cells = <1>;
-    };
 ...
diff --git a/Documentation/devicetree/bindings/clock/qcom,gpucc.txt b/Documentation/devicetree/bindings/clock/qcom,gpucc.txt
deleted file mode 100644 (file)
index 269afe8..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-Qualcomm Graphics Clock & Reset Controller Binding
---------------------------------------------------
-
-Required properties :
-- compatible : shall contain "qcom,sdm845-gpucc" or "qcom,msm8998-gpucc"
-- reg : shall contain base register location and length
-- #clock-cells : from common clock binding, shall contain 1
-- #reset-cells : from common reset binding, shall contain 1
-- #power-domain-cells : from generic power domain binding, shall contain 1
-- clocks : shall contain the XO clock
-          shall contain the gpll0 out main clock (msm8998)
-- clock-names : shall be "xo"
-               shall be "gpll0" (msm8998)
-
-Example:
-       gpucc: clock-controller@5090000 {
-               compatible = "qcom,sdm845-gpucc";
-               reg = <0x5090000 0x9000>;
-               #clock-cells = <1>;
-               #reset-cells = <1>;
-               #power-domain-cells = <1>;
-               clocks = <&rpmhcc RPMH_CXO_CLK>;
-               clock-names = "xo";
-       };
diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
deleted file mode 100644 (file)
index 8b0f784..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-Qualcomm Multimedia Clock & Reset Controller Binding
-----------------------------------------------------
-
-Required properties :
-- compatible : shall contain only one of the following:
-
-                       "qcom,mmcc-apq8064"
-                       "qcom,mmcc-apq8084"
-                       "qcom,mmcc-msm8660"
-                       "qcom,mmcc-msm8960"
-                       "qcom,mmcc-msm8974"
-                       "qcom,mmcc-msm8996"
-
-- reg : shall contain base register location and length
-- #clock-cells : shall contain 1
-- #reset-cells : shall contain 1
-
-Optional properties :
-- #power-domain-cells : shall contain 1
-
-Example:
-       clock-controller@4000000 {
-               compatible = "qcom,mmcc-msm8960";
-               reg = <0x4000000 0x1000>;
-               #clock-cells = <1>;
-               #reset-cells = <1>;
-               #power-domain-cells = <1>;
-       };
diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml b/Documentation/devicetree/bindings/clock/qcom,mmcc.yaml
new file mode 100644 (file)
index 0000000..8551849
--- /dev/null
@@ -0,0 +1,98 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,mmcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Multimedia Clock & Reset Controller Binding
+
+maintainers:
+  - Jeffrey Hugo <jhugo@codeaurora.org>
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm multimedia clock control module which supports the clocks, resets and
+  power domains.
+
+properties:
+  compatible :
+    enum:
+       - qcom,mmcc-apq8064
+       - qcom,mmcc-apq8084
+       - qcom,mmcc-msm8660
+       - qcom,mmcc-msm8960
+       - qcom,mmcc-msm8974
+       - qcom,mmcc-msm8996
+       - qcom,mmcc-msm8998
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: Board sleep source
+      - description: Global PLL 0 clock
+      - description: DSI phy instance 0 dsi clock
+      - description: DSI phy instance 0 byte clock
+      - description: DSI phy instance 1 dsi clock
+      - description: DSI phy instance 1 byte clock
+      - description: HDMI phy PLL clock
+      - description: DisplayPort phy PLL vco clock
+      - description: DisplayPort phy PLL link clock
+
+  clock-names:
+    items:
+      - const: xo
+      - const: sleep
+      - const: gpll0
+      - const: dsi0dsi
+      - const: dsi0byte
+      - const: dsi1dsi
+      - const: dsi1byte
+      - const: hdmipll
+      - const: dpvco
+      - const: dplink
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+  protected-clocks:
+    description:
+       Protected clock specifier list as per common clock binding
+
+required:
+  - compatible
+  - reg
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+if:
+  properties:
+    compatible:
+      contains:
+        const: qcom,mmcc-msm8998
+
+then:
+  required:
+    - clocks
+    - clock-names
+
+examples:
+  # Example for MMCC for MSM8960:
+  - |
+    clock-controller@4000000 {
+      compatible = "qcom,mmcc-msm8960";
+      reg = <0x4000000 0x1000>;
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,msm8998-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,msm8998-gpucc.yaml
new file mode 100644 (file)
index 0000000..7d853c1
--- /dev/null
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,msm8998-gpucc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Graphics Clock & Reset Controller Binding for MSM8998
+
+maintainers:
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm graphics clock control module which supports the clocks, resets and
+  power domains on MSM8998.
+
+  See also dt-bindings/clock/qcom,gpucc-msm8998.h.
+
+properties:
+  compatible:
+    const: qcom,msm8998-gpucc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: GPLL0 main branch source (gcc_gpu_gpll0_clk_src)
+
+  clock-names:
+    items:
+      - const: xo
+      - const: gpll0
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-msm8998.h>
+    #include <dt-bindings/clock/qcom,rpmcc.h>
+    clock-controller@5065000 {
+      compatible = "qcom,msm8998-gpucc";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+      reg = <0x05065000 0x9000>;
+      clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, <&gcc GPLL0_OUT_MAIN>;
+      clock-names = "xo", "gpll0";
+    };
+...
index 94e2f14..2cd158f 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/clock/qcom,rpmhcc.yaml#
+$id: http://devicetree.org/schemas/clock/qcom,rpmhcc.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Qualcomm Technologies, Inc. RPMh Clocks Bindings
diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-dispcc.yaml
new file mode 100644 (file)
index 0000000..0429062
--- /dev/null
@@ -0,0 +1,84 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sc7180-dispcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display Clock & Reset Controller Binding for SC7180
+
+maintainers:
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm display clock control module which supports the clocks, resets and
+  power domains on SC7180.
+
+  See also dt-bindings/clock/qcom,dispcc-sc7180.h.
+
+properties:
+  compatible:
+    const: qcom,sc7180-dispcc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: GPLL0 source from GCC
+      - description: Byte clock from DSI PHY
+      - description: Pixel clock from DSI PHY
+      - description: Link clock from DP PHY
+      - description: VCO DIV clock from DP PHY
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: gcc_disp_gpll0_clk_src
+      - const: dsi0_phy_pll_out_byteclk
+      - const: dsi0_phy_pll_out_dsiclk
+      - const: dp_phy_pll_link_clk
+      - const: dp_phy_pll_vco_div_clk
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-sc7180.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@af00000 {
+      compatible = "qcom,sc7180-dispcc";
+      reg = <0 0x0af00000 0 0x200000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&gcc GCC_DISP_GPLL0_CLK_SRC>,
+               <&dsi_phy 0>,
+               <&dsi_phy 1>,
+               <&dp_phy 0>,
+               <&dp_phy 1>;
+      clock-names = "bi_tcxo",
+                    "gcc_disp_gpll0_clk_src",
+                    "dsi0_phy_pll_out_byteclk",
+                    "dsi0_phy_pll_out_dsiclk",
+                    "dp_phy_pll_link_clk",
+                    "dp_phy_pll_vco_div_clk";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-gpucc.yaml
new file mode 100644 (file)
index 0000000..5785192
--- /dev/null
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sc7180-gpucc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Graphics Clock & Reset Controller Binding for SC7180
+
+maintainers:
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm graphics clock control module which supports the clocks, resets and
+  power domains on SC7180.
+
+  See also dt-bindings/clock/qcom,gpucc-sc7180.h.
+
+properties:
+  compatible:
+    const: qcom,sc7180-gpucc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: GPLL0 main branch source
+      - description: GPLL0 div branch source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: gcc_gpu_gpll0_clk_src
+      - const: gcc_gpu_gpll0_div_clk_src
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-sc7180.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@5090000 {
+      compatible = "qcom,sc7180-gpucc";
+      reg = <0 0x05090000 0 0x9000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+               <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+      clock-names = "bi_tcxo",
+                    "gcc_gpu_gpll0_clk_src",
+                    "gcc_gpu_gpll0_div_clk_src";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,sc7180-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sc7180-videocc.yaml
new file mode 100644 (file)
index 0000000..31df901
--- /dev/null
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sc7180-videocc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Video Clock & Reset Controller Binding for SC7180
+
+maintainers:
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm video clock control module which supports the clocks, resets and
+  power domains on SC7180.
+
+  See also dt-bindings/clock/qcom,videocc-sc7180.h.
+
+properties:
+  compatible:
+    const: qcom,sc7180-videocc
+
+  clocks:
+    items:
+      - description: Board XO source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@ab00000 {
+      compatible = "qcom,sc7180-videocc";
+      reg = <0 0x0ab00000 0 0x10000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>;
+      clock-names = "bi_tcxo";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,sdm845-dispcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sdm845-dispcc.yaml
new file mode 100644 (file)
index 0000000..89269dd
--- /dev/null
@@ -0,0 +1,99 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sdm845-dispcc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Display Clock & Reset Controller Binding for SDM845
+
+maintainers:
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm display clock control module which supports the clocks, resets and
+  power domains on SDM845.
+
+  See also dt-bindings/clock/qcom,dispcc-sdm845.h.
+
+properties:
+  compatible:
+    const: qcom,sdm845-dispcc
+
+  # NOTE: sdm845.dtsi existed for quite some time and specified no clocks.
+  # The code had to use hardcoded mechanisms to find the input clocks.
+  # New dts files should have these clocks.
+  clocks:
+    items:
+      - description: Board XO source
+      - description: GPLL0 source from GCC
+      - description: GPLL0 div source from GCC
+      - description: Byte clock from DSI PHY0
+      - description: Pixel clock from DSI PHY0
+      - description: Byte clock from DSI PHY1
+      - description: Pixel clock from DSI PHY1
+      - description: Link clock from DP PHY
+      - description: VCO DIV clock from DP PHY
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: gcc_disp_gpll0_clk_src
+      - const: gcc_disp_gpll0_div_clk_src
+      - const: dsi0_phy_pll_out_byteclk
+      - const: dsi0_phy_pll_out_dsiclk
+      - const: dsi1_phy_pll_out_byteclk
+      - const: dsi1_phy_pll_out_dsiclk
+      - const: dp_link_clk_divsel_ten
+      - const: dp_vco_divided_clk_src_mux
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-sdm845.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@af00000 {
+      compatible = "qcom,sdm845-dispcc";
+      reg = <0 0x0af00000 0 0x10000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&gcc GCC_DISP_GPLL0_CLK_SRC>,
+               <&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>,
+               <&dsi0_phy 0>,
+               <&dsi0_phy 1>,
+               <&dsi1_phy 0>,
+               <&dsi1_phy 1>,
+               <&dp_phy 0>,
+               <&dp_phy 1>;
+      clock-names = "bi_tcxo",
+                    "gcc_disp_gpll0_clk_src",
+                    "gcc_disp_gpll0_div_clk_src",
+                    "dsi0_phy_pll_out_byteclk",
+                    "dsi0_phy_pll_out_dsiclk",
+                    "dsi1_phy_pll_out_byteclk",
+                    "dsi1_phy_pll_out_dsiclk",
+                    "dp_link_clk_divsel_ten",
+                    "dp_vco_divided_clk_src_mux";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,sdm845-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sdm845-gpucc.yaml
new file mode 100644 (file)
index 0000000..bac04f1
--- /dev/null
@@ -0,0 +1,72 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sdm845-gpucc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Graphics Clock & Reset Controller Binding for SDM845
+
+maintainers:
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm graphics clock control module which supports the clocks, resets and
+  power domains on SDM845.
+
+  See also dt-bindings/clock/qcom,gpucc-sdm845.h.
+
+properties:
+  compatible:
+    const: qcom,sdm845-gpucc
+
+  clocks:
+    items:
+      - description: Board XO source
+      - description: GPLL0 main branch source
+      - description: GPLL0 div branch source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+      - const: gcc_gpu_gpll0_clk_src
+      - const: gcc_gpu_gpll0_div_clk_src
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,gcc-sdm845.h>
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@5090000 {
+      compatible = "qcom,sdm845-gpucc";
+      reg = <0 0x05090000 0 0x9000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>,
+               <&gcc GCC_GPU_GPLL0_CLK_SRC>,
+               <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
+      clock-names = "bi_tcxo",
+                    "gcc_gpu_gpll0_clk_src",
+                    "gcc_gpu_gpll0_div_clk_src";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,sdm845-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sdm845-videocc.yaml
new file mode 100644 (file)
index 0000000..9d216c0
--- /dev/null
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/qcom,sdm845-videocc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm Video Clock & Reset Controller Binding for SDM845
+
+maintainers:
+  - Taniya Das <tdas@codeaurora.org>
+
+description: |
+  Qualcomm video clock control module which supports the clocks, resets and
+  power domains on SDM845.
+
+  See also dt-bindings/clock/qcom,videocc-sdm845.h.
+
+properties:
+  compatible:
+    const: qcom,sdm845-videocc
+
+  clocks:
+    items:
+      - description: Board XO source
+
+  clock-names:
+    items:
+      - const: bi_tcxo
+
+  '#clock-cells':
+    const: 1
+
+  '#reset-cells':
+    const: 1
+
+  '#power-domain-cells':
+    const: 1
+
+  reg:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - '#clock-cells'
+  - '#reset-cells'
+  - '#power-domain-cells'
+
+examples:
+  - |
+    #include <dt-bindings/clock/qcom,rpmh.h>
+    clock-controller@ab00000 {
+      compatible = "qcom,sdm845-videocc";
+      reg = <0 0x0ab00000 0 0x10000>;
+      clocks = <&rpmhcc RPMH_CXO_CLK>;
+      clock-names = "bi_tcxo";
+      #clock-cells = <1>;
+      #reset-cells = <1>;
+      #power-domain-cells = <1>;
+    };
+...
diff --git a/Documentation/devicetree/bindings/clock/qcom,videocc.txt b/Documentation/devicetree/bindings/clock/qcom,videocc.txt
deleted file mode 100644 (file)
index 8a8622c..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-Qualcomm Video Clock & Reset Controller Binding
------------------------------------------------
-
-Required properties :
-- compatible : shall contain "qcom,sdm845-videocc"
-- reg : shall contain base register location and length
-- #clock-cells : from common clock binding, shall contain 1.
-- #power-domain-cells : from generic power domain binding, shall contain 1.
-- #reset-cells : from common reset binding, shall contain 1.
-
-Example:
-       videocc: clock-controller@ab00000 {
-               compatible = "qcom,sdm845-videocc";
-               reg = <0xab00000 0x10000>;
-               #clock-cells = <1>;
-               #power-domain-cells = <1>;
-               #reset-cells = <1>;
-       };
index c7674d0..f4d153f 100644 (file)
@@ -19,7 +19,7 @@ Required Properties:
       - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E)
       - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C)
       - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M)
-      - "renesas,r8a774b1-cpg-mssr" for the r8a774a1 SoC (RZ/G2N)
+      - "renesas,r8a774b1-cpg-mssr" for the r8a774b1 SoC (RZ/G2N)
       - "renesas,r8a774c0-cpg-mssr" for the r8a774c0 SoC (RZ/G2E)
       - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2)
       - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W)
index b8f91e4..4e38550 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/clock/st,stm32mp1-rcc.yaml#
+$id: http://devicetree.org/schemas/clock/st,stm32mp1-rcc.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Reset Clock Controller Binding
diff --git a/Documentation/devicetree/bindings/clock/sun8i-de2.txt b/Documentation/devicetree/bindings/clock/sun8i-de2.txt
deleted file mode 100644 (file)
index 41a52c2..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-Allwinner Display Engine 2.0/3.0 Clock Control Binding
-------------------------------------------------------
-
-Required properties :
-- compatible: must contain one of the following compatibles:
-               - "allwinner,sun8i-a83t-de2-clk"
-               - "allwinner,sun8i-h3-de2-clk"
-               - "allwinner,sun8i-v3s-de2-clk"
-               - "allwinner,sun50i-a64-de2-clk"
-               - "allwinner,sun50i-h5-de2-clk"
-               - "allwinner,sun50i-h6-de3-clk"
-
-- reg: Must contain the registers base address and length
-- clocks: phandle to the clocks feeding the display engine subsystem.
-         Three are needed:
-  - "mod": the display engine module clock (on A83T it's the DE PLL)
-  - "bus": the bus clock for the whole display engine subsystem
-- clock-names: Must contain the clock names described just above
-- resets: phandle to the reset control for the display engine subsystem.
-- #clock-cells : must contain 1
-- #reset-cells : must contain 1
-
-Example:
-de2_clocks: clock@1000000 {
-       compatible = "allwinner,sun8i-h3-de2-clk";
-       reg = <0x01000000 0x100000>;
-       clocks = <&ccu CLK_BUS_DE>,
-                <&ccu CLK_DE>;
-       clock-names = "bus",
-                     "mod";
-       resets = <&ccu RST_BUS_DE>;
-       #clock-cells = <1>;
-       #reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/sun9i-de.txt b/Documentation/devicetree/bindings/clock/sun9i-de.txt
deleted file mode 100644 (file)
index fb18f32..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-Allwinner A80 Display Engine Clock Control Binding
---------------------------------------------------
-
-Required properties :
-- compatible: must contain one of the following compatibles:
-               - "allwinner,sun9i-a80-de-clks"
-
-- reg: Must contain the registers base address and length
-- clocks: phandle to the clocks feeding the display engine subsystem.
-         Three are needed:
-  - "mod": the display engine module clock
-  - "dram": the DRAM bus clock for the system
-  - "bus": the bus clock for the whole display engine subsystem
-- clock-names: Must contain the clock names described just above
-- resets: phandle to the reset control for the display engine subsystem.
-- #clock-cells : must contain 1
-- #reset-cells : must contain 1
-
-Example:
-de_clocks: clock@3000000 {
-       compatible = "allwinner,sun9i-a80-de-clks";
-       reg = <0x03000000 0x30>;
-       clocks = <&ccu CLK_DE>, <&ccu CLK_SDRAM>, <&ccu CLK_BUS_DE>;
-       clock-names = "mod", "dram", "bus";
-       resets = <&ccu RST_BUS_DE>;
-       #clock-cells = <1>;
-       #reset-cells = <1>;
-};
diff --git a/Documentation/devicetree/bindings/clock/sun9i-usb.txt b/Documentation/devicetree/bindings/clock/sun9i-usb.txt
deleted file mode 100644 (file)
index 3564bd4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-Allwinner A80 USB Clock Control Binding
----------------------------------------
-
-Required properties :
-- compatible: must contain one of the following compatibles:
-               - "allwinner,sun9i-a80-usb-clocks"
-
-- reg: Must contain the registers base address and length
-- clocks: phandle to the clocks feeding the USB subsystem. Two are needed:
-  - "bus": the bus clock for the whole USB subsystem
-  - "hosc": the high frequency oscillator (usually at 24MHz)
-- clock-names: Must contain the clock names described just above
-- #clock-cells : must contain 1
-- #reset-cells : must contain 1
-
-Example:
-usb_clocks: clock@a08000 {
-       compatible = "allwinner,sun9i-a80-usb-clks";
-       reg = <0x00a08000 0x8>;
-       clocks = <&ccu CLK_BUS_USB>, <&osc24M>;
-       clock-names = "bus", "hosc";
-       #clock-cells = <1>;
-       #reset-cells = <1>;
-};
index 48ee699..18af6b9 100644 (file)
@@ -16,18 +16,23 @@ For more information, please see the Linux clock framework binding at
 Documentation/devicetree/bindings/clock/clock-bindings.txt.
 
 Required properties :
-- compatible : shall be "ti,clkctrl"
+- compatible : shall be "ti,clkctrl" or a clock domain specific name:
+              "ti,clkctrl-l4-cfg"
+              "ti,clkctrl-l4-per"
+              "ti,clkctrl-l4-secure"
+              "ti,clkctrl-l4-wkup"
 - #clock-cells : shall contain 2 with the first entry being the instance
                 offset from the clock domain base and the second being the
                 clock index
+- reg : clock registers
 
 Example: Clock controller node on omap 4430:
 
 &cm2 {
        l4per: cm@1400 {
                cm_l4per@0 {
-                       cm_l4per_clkctrl: clk@20 {
-                               compatible = "ti,clkctrl";
+                       cm_l4per_clkctrl: clock@20 {
+                               compatible = "ti,clkctrl-l4-per", "ti,clkctrl";
                                reg = <0x20 0x1b0>;
                                #clock-cells = <2>;
                        };
index 10f7047..21c002d 100644 (file)
@@ -43,7 +43,7 @@ Configuration of ATL instances:
        - aws : Audio word select signal selection
 };
 
-For valid word select signals, see the dt-bindings/clk/ti-dra7-atl.h include
+For valid word select signals, see the dt-bindings/clock/ti-dra7-atl.h include
 file.
 
 Examples:
@@ -83,7 +83,7 @@ atl: atl@4843c000 {
        clock-names = "fck";
 };
 
-#include <dt-bindings/clk/ti-dra7-atl.h>
+#include <dt-bindings/clock/ti-dra7-atl.h>
 
 &atl {
 
diff --git a/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml b/Documentation/devicetree/bindings/clock/xlnx,versal-clk.yaml
new file mode 100644 (file)
index 0000000..229af98
--- /dev/null
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/xlnx,versal-clk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Xilinx Versal clock controller
+
+maintainers:
+  - Michal Simek <michal.simek@xilinx.com>
+  - Jolly Shah <jolly.shah@xilinx.com>
+  - Rajan Vaja <rajan.vaja@xilinx.com>
+
+description: |
+  The clock controller is a hardware block of Xilinx versal clock tree. It
+  reads required input clock frequencies from the devicetree and acts as clock
+  provider for all clock consumers of PS clocks.
+
+select: false
+
+properties:
+  compatible:
+    const: xlnx,versal-clk
+
+  "#clock-cells":
+    const: 1
+
+  clocks:
+    description: List of clock specifiers which are external input
+      clocks to the given clock controller.
+    items:
+      - description: reference clock
+      - description: alternate reference clock
+      - description: alternate reference clock for programmable logic
+
+  clock-names:
+    items:
+      - const: ref
+      - const: alt_ref
+      - const: pl_alt_ref
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+  - clock-names
+
+additionalProperties: false
+
+examples:
+  - |
+    firmware {
+      zynqmp_firmware: zynqmp-firmware {
+        compatible = "xlnx,zynqmp-firmware";
+        method = "smc";
+        versal_clk: clock-controller {
+          #clock-cells = <1>;
+          compatible = "xlnx,versal-clk";
+          clocks = <&ref>, <&alt_ref>, <&pl_alt_ref>;
+          clock-names = "ref", "alt_ref", "pl_alt_ref";
+        };
+      };
+    };
+...
index 472e1ea..c985871 100644 (file)
@@ -6,6 +6,7 @@ Required properties:
 - compatible:  Should be "fsl,imx23-lcdif" for i.MX23.
                Should be "fsl,imx28-lcdif" for i.MX28.
                Should be "fsl,imx6sx-lcdif" for i.MX6SX.
+               Should be "fsl,imx8mq-lcdif" for i.MX8MQ.
 - reg:         Address and length of the register set for LCDIF
 - interrupts:  Should contain LCDIF interrupt
 - clocks:      A list of phandle + clock-specifier pairs, one for each
index 0eb2b32..4dc398e 100644 (file)
@@ -2,9 +2,7 @@
 
 * XDMA Controller
 Required properties:
-- compatible: Should be "atmel,<chip>-dma".
-  <chip> compatible description:
-  - sama5d4: first SoC adding the XDMAC
+- compatible: Should be "atmel,sama5d4-dma" or "microchip,sam9x60-dma".
 - reg: Should contain DMA registers location and length.
 - interrupts: Should contain DMA interrupt.
 - #dma-cells: Must be <1>, used to represent the number of integer cells in
index e877856..0f6d8db 100644 (file)
@@ -145,10 +145,7 @@ properties:
       over reads to the next slave address. Please consult the manual of
       your device.
 
-  wp-gpios:
-    description:
-      GPIO to which the write-protect pin of the chip is connected.
-    maxItems: 1
+  wp-gpios: true
 
   address-width:
     allOf:
@@ -167,6 +164,10 @@ properties:
     minimum: 1
     maximum: 8
 
+  vcc-supply:
+    description:
+      phandle of the regulator that provides the supply voltage.
+
 required:
   - compatible
   - reg
index 42577dd..fcacd97 100644 (file)
@@ -20,6 +20,7 @@ Optional properties:
 - spi-cpha : SPI shifted clock phase, as per spi-bus bindings.
 - spi-cpol : SPI inverse clock polarity, as per spi-bus bindings.
 - read-only : this parameter-less property disables writes to the eeprom
+- wp-gpios : GPIO to which the write-protect pin of the chip is connected
 
 Obsolete legacy properties can be used in place of "size", "pagesize",
 "address-width", and "read-only":
@@ -36,6 +37,7 @@ Example:
                spi-max-frequency = <5000000>;
                spi-cpha;
                spi-cpol;
+               wp-gpios = <&gpio1 3 0>;
 
                pagesize = <64>;
                size = <32768>;
index 0c426e3..4ea6a87 100644 (file)
@@ -18,6 +18,7 @@ properties:
       - enum:
           - amlogic,meson-g12a-mali
           - realtek,rtd1619-mali
+          - rockchip,px30-mali
       - const: arm,mali-bifrost # Mali Bifrost GPU model/revision is fully discoverable
 
   reg:
index ae04903..6a742a5 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/hwmon/adi,ltc2947.yaml#
+$id: http://devicetree.org/schemas/hwmon/adi,ltc2947.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Analog Devices LTC2947 high precision power and energy monitor
index 8347b1e..d4bad86 100644 (file)
@@ -1,10 +1,16 @@
 I2C for Atmel platforms
 
 Required properties :
-- compatible : Must be "atmel,at91rm9200-i2c", "atmel,at91sam9261-i2c",
-     "atmel,at91sam9260-i2c", "atmel,at91sam9g20-i2c", "atmel,at91sam9g10-i2c",
-     "atmel,at91sam9x5-i2c", "atmel,sama5d4-i2c", "atmel,sama5d2-i2c" or
-     "microchip,sam9x60-i2c"
+- compatible : Must be one of:
+       "atmel,at91rm9200-i2c",
+       "atmel,at91sam9261-i2c",
+       "atmel,at91sam9260-i2c",
+       "atmel,at91sam9g20-i2c",
+       "atmel,at91sam9g10-i2c",
+       "atmel,at91sam9x5-i2c",
+       "atmel,sama5d4-i2c",
+       "atmel,sama5d2-i2c",
+       "microchip,sam9x60-i2c".
 - reg: physical base address of the controller and length of memory mapped
      region.
 - interrupts: interrupt number to the cpu.
index 3738cfb..d229eff 100644 (file)
@@ -1,7 +1,9 @@
 * Ingenic JZ4780 I2C Bus controller
 
 Required properties:
-- compatible: should be "ingenic,jz4780-i2c"
+- compatible: should be one of the following:
+  - "ingenic,jz4780-i2c" for the JZ4780
+  - "ingenic,x1000-i2c" for the X1000
 - reg: Should contain the address & size of the I2C controller registers.
 - interrupts: Should specify the interrupt provided by parent.
 - clocks: Should contain a single clock specifier for the JZ4780 I2C clock.
index 30ac6a6..7abda50 100644 (file)
@@ -25,6 +25,8 @@ Required Properties:
 Optional Properties:
 
   - reset-gpios: Reference to the GPIO connected to the reset input.
+  - idle-state: if present, overrides i2c-mux-idle-disconnect,
+    Please refer to Documentation/devicetree/bindings/mux/mux-controller.txt
   - i2c-mux-idle-disconnect: Boolean; if defined, forces mux to disconnect all
     children in idle state. This is necessary for example, if there are several
     multiplexers on the bus and the devices behind them use same I2C addresses.
index 0660a3e..c359965 100644 (file)
@@ -17,7 +17,8 @@ Required properties:
        "renesas,i2c-r8a7793" if the device is a part of a R8A7793 SoC.
        "renesas,i2c-r8a7794" if the device is a part of a R8A7794 SoC.
        "renesas,i2c-r8a7795" if the device is a part of a R8A7795 SoC.
-       "renesas,i2c-r8a7796" if the device is a part of a R8A7796 SoC.
+       "renesas,i2c-r8a7796" if the device is a part of a R8A77960 SoC.
+       "renesas,i2c-r8a77961" if the device is a part of a R8A77961 SoC.
        "renesas,i2c-r8a77965" if the device is a part of a R8A77965 SoC.
        "renesas,i2c-r8a77970" if the device is a part of a R8A77970 SoC.
        "renesas,i2c-r8a77980" if the device is a part of a R8A77980 SoC.
index 64d11ff..ffe085c 100644 (file)
@@ -17,6 +17,7 @@ Required properties:
                        - "renesas,iic-r8a7794" (R-Car E2)
                        - "renesas,iic-r8a7795" (R-Car H3)
                        - "renesas,iic-r8a7796" (R-Car M3-W)
+                       - "renesas,iic-r8a77961" (R-Car M3-W+)
                        - "renesas,iic-r8a77965" (R-Car M3-N)
                        - "renesas,iic-r8a77990" (R-Car E3)
                        - "renesas,iic-sh73a0" (SH-Mobile AG5)
index e932d5a..f0934b2 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright 2019 Analog Devices Inc.
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/iio/adc/adi,ad7124.yaml#
+$id: http://devicetree.org/schemas/iio/adc/adi,ad7124.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Analog Devices AD7124 ADC device driver
index 567a33a..84d25bd 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright 2019 Analog Devices Inc.
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/iio/adc/adi,ad7192.yaml#
+$id: http://devicetree.org/schemas/iio/adc/adi,ad7192.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: Analog Devices AD7192 ADC device driver
index 4a3c1d4..07c59f3 100644 (file)
@@ -1,7 +1,7 @@
 * AT91 SAMA5D2 Analog to Digital Converter (ADC)
 
 Required properties:
-  - compatible: Should be "atmel,sama5d2-adc".
+  - compatible: Should be "atmel,sama5d2-adc" or "microchip,sam9x60-adc".
   - reg: Should contain ADC registers location and length.
   - interrupts: Should contain the IRQ line for the ADC.
   - clocks: phandle to device clock.
index 881059b..0ce2904 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright 2019 Marcus Folkesson <marcus.folkesson@gmail.com>
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/bindings/iio/adc/microchip,mcp3911.yaml#"
+$id: "http://devicetree.org/schemas/iio/adc/microchip,mcp3911.yaml#"
 $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 
 title: Microchip MCP3911 Dual channel analog front end (ADC)
index c914070..acf36ee 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/st,stm32-dfsdm-adc.yaml#
+$id: http://devicetree.org/schemas/iio/adc/st,stm32-dfsdm-adc.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: STMicroelectronics STM32 DFSDM ADC device driver
index 13d005b..a285eab 100644 (file)
@@ -2,7 +2,7 @@
 # Copyright 2019 Marcus Folkesson <marcus.folkesson@gmail.com>
 %YAML 1.2
 ---
-$id: "http://devicetree.org/schemas/bindings/iio/dac/lltc,ltc1660.yaml#"
+$id: "http://devicetree.org/schemas/iio/dac/lltc,ltc1660.yaml#"
 $schema: "http://devicetree.org/meta-schemas/core.yaml#"
 
 title: Linear Technology Micropower octal 8-Bit and 10-Bit DACs
index 903475f..b98bf93 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 %YAML 1.2
 ---
-$id: http://devicetree.org/schemas/bindings/input/gpio-vibrator.yaml#
+$id: http://devicetree.org/schemas/input/gpio-vibrator.yaml#
 $schema: http://devicetree.org/meta-schemas/core.yaml#
 
 title: GPIO vibrator
index 0f69500..0e57315 100644 (file)
@@ -36,6 +36,8 @@ Optional properties:
  - pinctrl-0:   a phandle pointing to the pin settings for the
                 control gpios
 
+ - wakeup-source: If present the device will act as wakeup-source
+
  - threshold:   allows setting the "click"-threshold in the range
                 from 0 to 80.
 
diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.txt b/Documentation/devicetree/bindings/input/touchscreen/goodix.txt
deleted file mode 100644 (file)
index fc03ea4..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-Device tree bindings for Goodix GT9xx series touchscreen controller
-
-Required properties:
-
- - compatible          : Should be "goodix,gt1151"
-                                or "goodix,gt5663"
-                                or "goodix,gt5688"
-                                or "goodix,gt911"
-                                or "goodix,gt9110"
-                                or "goodix,gt912"
-                                or "goodix,gt927"
-                                or "goodix,gt9271"
-                                or "goodix,gt928"
-                                or "goodix,gt967"
- - reg                 : I2C address of the chip. Should be 0x5d or 0x14
- - interrupts          : Interrupt to which the chip is connected
-
-Optional properties:
-
- - irq-gpios           : GPIO pin used for IRQ. The driver uses the
-                         interrupt gpio pin as output to reset the device.
- - reset-gpios         : GPIO pin used for reset
- - AVDD28-supply       : Analog power supply regulator on AVDD28 pin
- - VDDIO-supply                : GPIO power supply regulator on VDDIO pin
- - touchscreen-inverted-x
- - touchscreen-inverted-y
- - touchscreen-size-x
- - touchscreen-size-y
- - touchscreen-swapped-x-y
-
-The touchscreen-* properties are documented in touchscreen.txt in this
-directory.
-
-Example:
-
-       i2c@00000000 {
-               /* ... */
-
-               gt928@5d {
-                       compatible = "goodix,gt928";
-                       reg = <0x5d>;
-                       interrupt-parent = <&gpio>;
-                       interrupts = <0 0>;
-
-                       irq-gpios = <&gpio1 0 0>;
-                       reset-gpios = <&gpio1 1 0>;
-               };
-
-               /* ... */
-       };
diff --git a/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml b/Documentation/devicetree/bindings/input/touchscreen/goodix.yaml
new file mode 100644 (file)
index 0000000..d7c3262
--- /dev/null
@@ -0,0 +1,78 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/goodix.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Goodix GT9xx series touchscreen controller Bindings
+
+maintainers:
+  - Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+allOf:
+  - $ref: touchscreen.yaml#
+
+properties:
+  compatible:
+    enum:
+      - goodix,gt1151
+      - goodix,gt5663
+      - goodix,gt5688
+      - goodix,gt911
+      - goodix,gt9110
+      - goodix,gt912
+      - goodix,gt927
+      - goodix,gt9271
+      - goodix,gt928
+      - goodix,gt967
+
+  reg:
+    enum: [ 0x5d, 0x14 ]
+
+  interrupts:
+    maxItems: 1
+
+  irq-gpios:
+    description: GPIO pin used for IRQ.
+                 The driver uses the interrupt gpio pin as
+                 output to reset the device.
+    maxItems: 1
+
+  reset-gpios:
+    maxItems: 1
+
+  AVDD28-supply:
+    description: Analog power supply regulator on AVDD28 pin
+
+  VDDIO-supply:
+    description: GPIO power supply regulator on VDDIO pin
+
+  touchscreen-inverted-x: true
+  touchscreen-inverted-y: true
+  touchscreen-size-x: true
+  touchscreen-size-y: true
+  touchscreen-swapped-x-y: true
+
+additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - interrupts
+
+examples:
+- |
+    i2c@00000000 {
+      #address-cells = <1>;
+      #size-cells = <0>;
+      gt928@5d {
+        compatible = "goodix,gt928";
+        reg = <0x5d>;
+        interrupt-parent = <&gpio>;
+        interrupts = <0 0>;
+        irq-gpios = <&gpio1 0 0>;
+        reset-gpios = <&gpio1 1 0>;
+      };
+    };
+
+...
index 8641a2d..e1adb90 100644 (file)
@@ -1,39 +1 @@
-General Touchscreen Properties:
-
-Optional properties for Touchscreens:
- - touchscreen-min-x           : minimum x coordinate reported (0 if not set)
- - touchscreen-min-y           : minimum y coordinate reported (0 if not set)
- - touchscreen-size-x          : horizontal resolution of touchscreen
-                                 (maximum x coordinate reported + 1)
- - touchscreen-size-y          : vertical resolution of touchscreen
-                                 (maximum y coordinate reported + 1)
- - touchscreen-max-pressure    : maximum reported pressure (arbitrary range
-                                 dependent on the controller)
- - touchscreen-min-pressure    : minimum pressure on the touchscreen to be
-                                 achieved in order for the touchscreen
-                                 driver to report a touch event.
- - touchscreen-fuzz-x          : horizontal noise value of the absolute input
-                                 device (in pixels)
- - touchscreen-fuzz-y          : vertical noise value of the absolute input
-                                 device (in pixels)
- - touchscreen-fuzz-pressure   : pressure noise value of the absolute input
-                                 device (arbitrary range dependent on the
-                                 controller)
- - touchscreen-average-samples : Number of data samples which are averaged
-                                 for each read (valid values dependent on the
-                                 controller)
- - touchscreen-inverted-x      : X axis is inverted (boolean)
- - touchscreen-inverted-y      : Y axis is inverted (boolean)
- - touchscreen-swapped-x-y     : X and Y axis are swapped (boolean)
-                                 Swapping is done after inverting the axis
- - touchscreen-x-mm            : horizontal length in mm of the touchscreen
- - touchscreen-y-mm            : vertical length in mm of the touchscreen
-
-Deprecated properties for Touchscreens:
- - x-size                      : deprecated name for touchscreen-size-x
- - y-size                      : deprecated name for touchscreen-size-y
- - moving-threshold            : deprecated name for a combination of
-                                 touchscreen-fuzz-x and touchscreen-fuzz-y
- - contact-threshold           : deprecated name for touchscreen-fuzz-pressure
- - x-invert                    : deprecated name for touchscreen-inverted-x
- - y-invert                    : deprecated name for touchscreen-inverted-y
+See touchscreen.yaml
diff --git a/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml b/Documentation/devicetree/bindings/input/touchscreen/touchscreen.yaml
new file mode 100644 (file)
index 0000000..d7dac16
--- /dev/null
@@ -0,0 +1,83 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/input/touchscreen/touchscreen.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Common touchscreen Bindings
+
+maintainers:
+  - Dmitry Torokhov <dmitry.torokhov@gmail.com>
+
+properties:
+  touchscreen-min-x:
+    description: minimum x coordinate reported
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  touchscreen-min-y:
+    description: minimum y coordinate reported
+    $ref: /schemas/types.yaml#/definitions/uint32
+    default: 0
+
+  touchscreen-size-x:
+    description: horizontal resolution of touchscreen (maximum x coordinate reported + 1)
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-size-y:
+    description: vertical resolution of touchscreen (maximum y coordinate reported + 1)
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-max-pressure:
+    description: maximum reported pressure (arbitrary range dependent on the controller)
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-min-pressure:
+    description: minimum pressure on the touchscreen to be achieved in order for the
+                 touchscreen driver to report a touch event.
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-fuzz-x:
+    description: horizontal noise value of the absolute input device (in pixels)
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-fuzz-y:
+    description: vertical noise value of the absolute input device (in pixels)
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-fuzz-pressure:
+    description: pressure noise value of the absolute input device (arbitrary range
+                 dependent on the controller)
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-average-samples:
+    description: Number of data samples which are averaged for each read (valid values
+                 dependent on the controller)
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-inverted-x:
+    description: X axis is inverted
+    type: boolean
+
+  touchscreen-inverted-y:
+    description: Y axis is inverted
+    type: boolean
+
+  touchscreen-swapped-x-y:
+    description: X and Y axis are swapped
+                 Swapping is done after inverting the axis
+    type: boolean
+
+  touchscreen-x-mm:
+    description: horizontal length in mm of the touchscreen
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+  touchscreen-y-mm:
+    description: vertical length in mm of the touchscreen
+    $ref: /schemas/types.yaml#/definitions/uint32
+
+dependencies:
+  touchscreen-size-x: [ touchscreen-size-y ]
+  touchscreen-size-y: [ touchscreen-size-x ]
+  touchscreen-x-mm: [ touchscreen-y-mm ]
+  touchscreen-y-mm: [ touchscreen-x-mm ]
index 5a8b462..3c36334 100644 (file)
@@ -86,6 +86,12 @@ have a means to turn off translation. But it is invalid in such cases to
 disable the IOMMU's device tree node in the first place because it would
 prevent any driver from properly setting up the translations.
 
+Optional properties:
+--------------------
+- pasid-num-bits: Some masters support multiple address spaces for DMA, by
+  tagging DMA transactions with an address space identifier. By default,
+  this is 0, which means that the device only has one address space.
+
 
 Notes:
 ======
index 4c2d923..501468a 100644 (file)
@@ -18,6 +18,10 @@ Required properties:
 Optional properties:
        - enable-gpios : gpio pin to enable/disable the device.
        - vled-supply : LED supply
+       - ti,ovp-microvolt: Overvoltage protection in
+           micro-volt, can be 17000000, 21000000, 25000000 or
+           29000000. If ti,ovp-microvolt is not specified it
+           defaults to 29000000.
 
 Required child properties:
        - reg : 0 - Will enable all LED sync paths
@@ -31,6 +35,8 @@ Optional child properties:
        - label : see Documentation/devicetree/bindings/leds/common.txt (deprecated)
        - linux,default-trigger :
           see Documentation/devicetree/bindings/leds/common.txt
+       - led-max-microamp :
+          see Documentation/devicetree/bindings/leds/common.txt
 
 Example:
 
@@ -44,12 +50,14 @@ led-controller@36 {
 
        enable-gpios = <&gpio1 28 GPIO_ACTIVE_HIGH>;
        vled-supply = <&vbatt>;
+       ti,ovp-microvolt = <29000000>;
 
        led@0 {
                reg = <0>;
                function = LED_FUNCTION_BACKLIGHT;
                color = <LED_COLOR_ID_WHITE>;
                linux,default-trigger = "backlight";
+               led-max-microamp = <20000>;
        };
 }
 
diff --git a/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml b/Documentation/devicetree/bindings/leds/rohm,bd71828-leds.yaml
new file mode 100644 (file)
index 0000000..b50f4bc
--- /dev/null
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/leds/rohm,bd71828-leds.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ROHM BD71828 Power Management Integrated Circuit LED driver
+
+maintainers:
+  - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+
+description: |
+  This module is part of the ROHM BD71828 MFD device. For more details
+  see Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml.
+
+  The LED controller is represented as a sub-node of the PMIC node on the device
+  tree.
+
+  The device has two LED outputs referred as GRNLED and AMBLED in data-sheet.
+
+select: false
+
+properties:
+  compatible:
+    const: rohm,bd71828-leds
+
+patternProperties:
+  "^led-[1-2]$":
+    type: object
+    description:
+      Properties for a single LED.
+    properties:
+      #allOf:
+        #- $ref: "common.yaml#"
+      rohm,led-compatible:
+        description: LED identification string
+        allOf:
+          - $ref: "/schemas/types.yaml#/definitions/string"
+          - enum:
+            - bd71828-ambled
+            - bd71828-grnled
+      function:
+        description:
+          Purpose of LED as defined in dt-bindings/leds/common.h
+        $ref: "/schemas/types.yaml#/definitions/string"
+      color:
+        description:
+          LED colour as defined in dt-bindings/leds/common.h
+        $ref: "/schemas/types.yaml#/definitions/uint32"
+
+required:
+  - compatible
index 0278482..beec612 100644 (file)
@@ -21,10 +21,11 @@ platforms.
        Usage: required
        Value type: <prop-encoded-array>
        Definition: must specify the base address and size of the global block
+
 - clocks:
-       Usage: required if #clocks-cells property is present
-       Value type: <phandle>
-       Definition: phandle to the input PLL, which feeds the APCS mux/divider
+       Usage: required if #clock-names property is present
+       Value type: <phandle array>
+       Definition: phandles to the two parent clocks of the clock driver.
 
 - #mbox-cells:
        Usage: required
@@ -36,6 +37,12 @@ platforms.
        Value type: <u32>
        Definition: as described in clock.txt, must be 0
 
+- clock-names:
+       Usage: required if the platform data based clock driver needs to
+       retrieve the parent clock names from device tree.
+       This will requires two mandatory clocks to be defined.
+       Value type: <string-array>
+       Definition: must be "pll" and "aux"
 
 = EXAMPLE
 The following example describes the APCS HMSS found in MSM8996 and part of the
@@ -68,3 +75,14 @@ Below is another example of the APCS binding on MSM8916 platforms:
                clocks = <&a53pll>;
                #clock-cells = <0>;
        };
+
+Below is another example of the APCS binding on QCS404 platforms:
+
+       apcs_glb: mailbox@b011000 {
+               compatible = "qcom,qcs404-apcs-apps-global", "syscon";
+               reg = <0x0b011000 0x1000>;
+               #mbox-cells = <1>;
+               clocks = <&apcs_hfpll>, <&gcc GCC_GPLL0_AO_OUT_MAIN>;
+               clock-names = "pll", "aux";
+               #clock-cells = <0>;
+       };
index 332513a..8924c75 100644 (file)
@@ -2,7 +2,7 @@ Atmel Image Sensor Interface (ISI)
 ----------------------------------
 
 Required properties for ISI:
-- compatible: must be "atmel,at91sam9g45-isi".
+- compatible: must be "atmel,at91sam9g45-isi" or "microchip,sam9x60-isi".
 - reg: physical base address and length of the registers set for the device.
 - interrupts: should contain IRQ line for the ISI.
 - clocks: list of clock specifiers, corresponding to entries in the clock-names
index 2477e7f..f8090e0 100644 (file)
@@ -8,7 +8,7 @@ i.MX SoCs from i.MX23 to i.MX7.
 
 Required properties:
 - compatible: should be "fsl,<soc>-pxp", where SoC can be one of imx23, imx28,
-  imx6dl, imx6sl, imx6ul, imx6sx, imx6ull, or imx7d.
+  imx6dl, imx6sl, imx6sll, imx6ul, imx6sx, imx6ull, or imx7d.
 - reg: the register base and size for the device registers
 - interrupts: the PXP interrupt, two interrupts for imx6ull and imx7d.
 - clock-names: should be "axi"
index d113807..a64ee03 100644 (file)
@@ -123,6 +123,7 @@ properties:
           - rc-su3000
           - rc-tango
           - rc-tanix-tx3mini
+          - rc-tanix-tx5max
           - rc-tbs-nec
           - rc-technisat-ts35
           - rc-technisat-usb2
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.txt b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.txt
deleted file mode 100644 (file)
index ba0bc3f..0000000
+++ /dev/null
@@ -1,374 +0,0 @@
-NVIDIA Tegra124 SoC EMC (external memory controller)
-====================================================
-
-Required properties :
-- compatible : Should be "nvidia,tegra124-emc".
-- reg : physical base address and length of the controller's registers.
-- nvidia,memory-controller : phandle of the MC driver.
-
-The node should contain a "emc-timings" subnode for each supported RAM type
-(see field RAM_CODE in register PMC_STRAPPING_OPT_A), with its unit address
-being its RAM_CODE.
-
-Required properties for "emc-timings" nodes :
-- nvidia,ram-code : Should contain the value of RAM_CODE this timing set is
-used for.
-
-Each "emc-timings" node should contain a "timing" subnode for every supported
-EMC clock rate. The "timing" subnodes should have the clock rate in Hz as
-their unit address.
-
-Required properties for "timing" nodes :
-- clock-frequency : Should contain the memory clock rate in Hz.
-- The following properties contain EMC timing characterization values
-(specified in the board documentation) :
-  - nvidia,emc-auto-cal-config : EMC_AUTO_CAL_CONFIG
-  - nvidia,emc-auto-cal-config2 : EMC_AUTO_CAL_CONFIG2
-  - nvidia,emc-auto-cal-config3 : EMC_AUTO_CAL_CONFIG3
-  - nvidia,emc-auto-cal-interval : EMC_AUTO_CAL_INTERVAL
-  - nvidia,emc-bgbias-ctl0 : EMC_BGBIAS_CTL0
-  - nvidia,emc-cfg : EMC_CFG
-  - nvidia,emc-cfg-2 : EMC_CFG_2
-  - nvidia,emc-ctt-term-ctrl : EMC_CTT_TERM_CTRL
-  - nvidia,emc-mode-1 : Mode Register 1
-  - nvidia,emc-mode-2 : Mode Register 2
-  - nvidia,emc-mode-4 : Mode Register 4
-  - nvidia,emc-mode-reset : Mode Register 0
-  - nvidia,emc-mrs-wait-cnt : EMC_MRS_WAIT_CNT
-  - nvidia,emc-sel-dpd-ctrl : EMC_SEL_DPD_CTRL
-  - nvidia,emc-xm2dqspadctrl2 : EMC_XM2DQSPADCTRL2
-  - nvidia,emc-zcal-cnt-long : EMC_ZCAL_WAIT_CNT after clock change
-  - nvidia,emc-zcal-interval : EMC_ZCAL_INTERVAL
-- nvidia,emc-configuration : EMC timing characterization data. These are the
-registers (see section "15.6.2 EMC Registers" in the TRM) whose values need to
-be specified, according to the board documentation:
-
-       EMC_RC
-       EMC_RFC
-       EMC_RFC_SLR
-       EMC_RAS
-       EMC_RP
-       EMC_R2W
-       EMC_W2R
-       EMC_R2P
-       EMC_W2P
-       EMC_RD_RCD
-       EMC_WR_RCD
-       EMC_RRD
-       EMC_REXT
-       EMC_WEXT
-       EMC_WDV
-       EMC_WDV_MASK
-       EMC_QUSE
-       EMC_QUSE_WIDTH
-       EMC_IBDLY
-       EMC_EINPUT
-       EMC_EINPUT_DURATION
-       EMC_PUTERM_EXTRA
-       EMC_PUTERM_WIDTH
-       EMC_PUTERM_ADJ
-       EMC_CDB_CNTL_1
-       EMC_CDB_CNTL_2
-       EMC_CDB_CNTL_3
-       EMC_QRST
-       EMC_QSAFE
-       EMC_RDV
-       EMC_RDV_MASK
-       EMC_REFRESH
-       EMC_BURST_REFRESH_NUM
-       EMC_PRE_REFRESH_REQ_CNT
-       EMC_PDEX2WR
-       EMC_PDEX2RD
-       EMC_PCHG2PDEN
-       EMC_ACT2PDEN
-       EMC_AR2PDEN
-       EMC_RW2PDEN
-       EMC_TXSR
-       EMC_TXSRDLL
-       EMC_TCKE
-       EMC_TCKESR
-       EMC_TPD
-       EMC_TFAW
-       EMC_TRPAB
-       EMC_TCLKSTABLE
-       EMC_TCLKSTOP
-       EMC_TREFBW
-       EMC_FBIO_CFG6
-       EMC_ODT_WRITE
-       EMC_ODT_READ
-       EMC_FBIO_CFG5
-       EMC_CFG_DIG_DLL
-       EMC_CFG_DIG_DLL_PERIOD
-       EMC_DLL_XFORM_DQS0
-       EMC_DLL_XFORM_DQS1
-       EMC_DLL_XFORM_DQS2
-       EMC_DLL_XFORM_DQS3
-       EMC_DLL_XFORM_DQS4
-       EMC_DLL_XFORM_DQS5
-       EMC_DLL_XFORM_DQS6
-       EMC_DLL_XFORM_DQS7
-       EMC_DLL_XFORM_DQS8
-       EMC_DLL_XFORM_DQS9
-       EMC_DLL_XFORM_DQS10
-       EMC_DLL_XFORM_DQS11
-       EMC_DLL_XFORM_DQS12
-       EMC_DLL_XFORM_DQS13
-       EMC_DLL_XFORM_DQS14
-       EMC_DLL_XFORM_DQS15
-       EMC_DLL_XFORM_QUSE0
-       EMC_DLL_XFORM_QUSE1
-       EMC_DLL_XFORM_QUSE2
-       EMC_DLL_XFORM_QUSE3
-       EMC_DLL_XFORM_QUSE4
-       EMC_DLL_XFORM_QUSE5
-       EMC_DLL_XFORM_QUSE6
-       EMC_DLL_XFORM_QUSE7
-       EMC_DLL_XFORM_ADDR0
-       EMC_DLL_XFORM_ADDR1
-       EMC_DLL_XFORM_ADDR2
-       EMC_DLL_XFORM_ADDR3
-       EMC_DLL_XFORM_ADDR4
-       EMC_DLL_XFORM_ADDR5
-       EMC_DLL_XFORM_QUSE8
-       EMC_DLL_XFORM_QUSE9
-       EMC_DLL_XFORM_QUSE10
-       EMC_DLL_XFORM_QUSE11
-       EMC_DLL_XFORM_QUSE12
-       EMC_DLL_XFORM_QUSE13
-       EMC_DLL_XFORM_QUSE14
-       EMC_DLL_XFORM_QUSE15
-       EMC_DLI_TRIM_TXDQS0
-       EMC_DLI_TRIM_TXDQS1
-       EMC_DLI_TRIM_TXDQS2
-       EMC_DLI_TRIM_TXDQS3
-       EMC_DLI_TRIM_TXDQS4
-       EMC_DLI_TRIM_TXDQS5
-       EMC_DLI_TRIM_TXDQS6
-       EMC_DLI_TRIM_TXDQS7
-       EMC_DLI_TRIM_TXDQS8
-       EMC_DLI_TRIM_TXDQS9
-       EMC_DLI_TRIM_TXDQS10
-       EMC_DLI_TRIM_TXDQS11
-       EMC_DLI_TRIM_TXDQS12
-       EMC_DLI_TRIM_TXDQS13
-       EMC_DLI_TRIM_TXDQS14
-       EMC_DLI_TRIM_TXDQS15
-       EMC_DLL_XFORM_DQ0
-       EMC_DLL_XFORM_DQ1
-       EMC_DLL_XFORM_DQ2
-       EMC_DLL_XFORM_DQ3
-       EMC_DLL_XFORM_DQ4
-       EMC_DLL_XFORM_DQ5
-       EMC_DLL_XFORM_DQ6
-       EMC_DLL_XFORM_DQ7
-       EMC_XM2CMDPADCTRL
-       EMC_XM2CMDPADCTRL4
-       EMC_XM2CMDPADCTRL5
-       EMC_XM2DQPADCTRL2
-       EMC_XM2DQPADCTRL3
-       EMC_XM2CLKPADCTRL
-       EMC_XM2CLKPADCTRL2
-       EMC_XM2COMPPADCTRL
-       EMC_XM2VTTGENPADCTRL
-       EMC_XM2VTTGENPADCTRL2
-       EMC_XM2VTTGENPADCTRL3
-       EMC_XM2DQSPADCTRL3
-       EMC_XM2DQSPADCTRL4
-       EMC_XM2DQSPADCTRL5
-       EMC_XM2DQSPADCTRL6
-       EMC_DSR_VTTGEN_DRV
-       EMC_TXDSRVTTGEN
-       EMC_FBIO_SPARE
-       EMC_ZCAL_WAIT_CNT
-       EMC_MRS_WAIT_CNT2
-       EMC_CTT
-       EMC_CTT_DURATION
-       EMC_CFG_PIPE
-       EMC_DYN_SELF_REF_CONTROL
-       EMC_QPOP
-
-Example SoC include file:
-
-/ {
-       emc@7001b000 {
-               compatible = "nvidia,tegra124-emc";
-               reg = <0x0 0x7001b000 0x0 0x1000>;
-
-               nvidia,memory-controller = <&mc>;
-       };
-};
-
-Example board file:
-
-/ {
-       emc@7001b000 {
-               emc-timings-3 {
-                       nvidia,ram-code = <3>;
-
-                       timing-12750000 {
-                               clock-frequency = <12750000>;
-
-                               nvidia,emc-zcal-cnt-long = <0x00000042>;
-                               nvidia,emc-auto-cal-interval = <0x001fffff>;
-                               nvidia,emc-ctt-term-ctrl = <0x00000802>;
-                               nvidia,emc-cfg = <0x73240000>;
-                               nvidia,emc-cfg-2 = <0x000008c5>;
-                               nvidia,emc-sel-dpd-ctrl = <0x00040128>;
-                               nvidia,emc-bgbias-ctl0 = <0x00000008>;
-                               nvidia,emc-auto-cal-config = <0xa1430000>;
-                               nvidia,emc-auto-cal-config2 = <0x00000000>;
-                               nvidia,emc-auto-cal-config3 = <0x00000000>;
-                               nvidia,emc-mode-reset = <0x80001221>;
-                               nvidia,emc-mode-1 = <0x80100003>;
-                               nvidia,emc-mode-2 = <0x80200008>;
-                               nvidia,emc-mode-4 = <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 */
-                                       0x00000000 /* EMC_DLL_XFORM_ADDR2 */
-                                       0x00000000 /* EMC_DLL_XFORM_ADDR3 */
-                                       0x00000000 /* 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 */
-                                       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 */
-                                       0x00000e0e /* 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 */
-                               >;
-                       };
-               };
-       };
-};
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
new file mode 100644 (file)
index 0000000..dd18434
--- /dev/null
@@ -0,0 +1,528 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra124-emc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra124 SoC External Memory Controller
+
+maintainers:
+  - Thierry Reding <thierry.reding@gmail.com>
+  - Jon Hunter <jonathanh@nvidia.com>
+
+description: |
+  The EMC interfaces with the off-chip SDRAM to service the request stream
+  sent from the memory controller.
+
+properties:
+  compatible:
+    const: nvidia,tegra124-emc
+
+  reg:
+    maxItems: 1
+
+  clocks:
+    items:
+      - description: external memory clock
+
+  clock-names:
+    items:
+      - const: emc
+
+  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 the RAM_CODE field in the PMC_STRAPPING_OPT_A register that
+          this timing set is used for
+
+    patternProperties:
+      "^timing-[0-9]+$":
+        type: object
+        properties:
+          clock-frequency:
+            description:
+              external memory clock rate in Hz
+            minimum: 1000000
+            maximum: 1000000000
+
+          nvidia,emc-auto-cal-config:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_AUTO_CAL_CONFIG register for this set of
+              timings
+
+          nvidia,emc-auto-cal-config2:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_AUTO_CAL_CONFIG2 register for this set of
+              timings
+
+          nvidia,emc-auto-cal-config3:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_AUTO_CAL_CONFIG3 register for this set of
+              timings
+
+          nvidia,emc-auto-cal-interval:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              pad calibration interval in microseconds
+            minimum: 0
+            maximum: 2097151
+
+          nvidia,emc-bgbias-ctl0:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_BGBIAS_CTL0 register for this set of timings
+
+          nvidia,emc-cfg:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_CFG register for this set of timings
+
+          nvidia,emc-cfg-2:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_CFG_2 register for this set of timings
+
+          nvidia,emc-ctt-term-ctrl:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_CTT_TERM_CTRL register for this set of timings
+
+          nvidia,emc-mode-1:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_MRW register for this set of timings
+
+          nvidia,emc-mode-2:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_MRW2 register for this set of timings
+
+          nvidia,emc-mode-4:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_MRW4 register for this set of timings
+
+          nvidia,emc-mode-reset:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              reset value of the EMC_MRS register for this set of timings
+
+          nvidia,emc-mrs-wait-cnt:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMR_MRS_WAIT_CNT register for this set of timings
+
+          nvidia,emc-sel-dpd-ctrl:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_SEL_DPD_CTRL register for this set of timings
+
+          nvidia,emc-xm2dqspadctrl2:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_XM2DQSPADCTRL2 register for this set of timings
+
+          nvidia,emc-zcal-cnt-long:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              number of EMC clocks to wait before issuing any commands after
+              clock change
+            minimum: 0
+            maximum: 1023
+
+          nvidia,emc-zcal-interval:
+            $ref: /schemas/types.yaml#/definitions/uint32
+            description:
+              value of the EMC_ZCAL_INTERVAL register for this set of timings
+
+          nvidia,emc-configuration:
+            allOf:
+              - $ref: /schemas/types.yaml#/definitions/uint32-array
+            description:
+              EMC timing characterization data. These are the registers (see
+              section "15.6.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_RFC_SLR
+              - 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_WDV_MASK
+              - description: EMC_QUSE
+              - description: EMC_QUSE_WIDTH
+              - description: EMC_IBDLY
+              - description: EMC_EINPUT
+              - description: EMC_EINPUT_DURATION
+              - description: EMC_PUTERM_EXTRA
+              - description: EMC_PUTERM_WIDTH
+              - description: EMC_PUTERM_ADJ
+              - description: EMC_CDB_CNTL_1
+              - description: EMC_CDB_CNTL_2
+              - description: EMC_CDB_CNTL_3
+              - description: EMC_QRST
+              - description: EMC_QSAFE
+              - description: EMC_RDV
+              - description: EMC_RDV_MASK
+              - 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_TCKESR
+              - description: EMC_TPD
+              - description: EMC_TFAW
+              - description: EMC_TRPAB
+              - description: EMC_TCLKSTABLE
+              - description: EMC_TCLKSTOP
+              - description: EMC_TREFBW
+              - 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_DQS8
+              - description: EMC_DLL_XFORM_DQS9
+              - description: EMC_DLL_XFORM_DQS10
+              - description: EMC_DLL_XFORM_DQS11
+              - description: EMC_DLL_XFORM_DQS12
+              - description: EMC_DLL_XFORM_DQS13
+              - description: EMC_DLL_XFORM_DQS14
+              - description: EMC_DLL_XFORM_DQS15
+              - 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_DLL_XFORM_ADDR0
+              - description: EMC_DLL_XFORM_ADDR1
+              - description: EMC_DLL_XFORM_ADDR2
+              - description: EMC_DLL_XFORM_ADDR3
+              - description: EMC_DLL_XFORM_ADDR4
+              - description: EMC_DLL_XFORM_ADDR5
+              - description: EMC_DLL_XFORM_QUSE8
+              - description: EMC_DLL_XFORM_QUSE9
+              - description: EMC_DLL_XFORM_QUSE10
+              - description: EMC_DLL_XFORM_QUSE11
+              - description: EMC_DLL_XFORM_QUSE12
+              - description: EMC_DLL_XFORM_QUSE13
+              - description: EMC_DLL_XFORM_QUSE14
+              - description: EMC_DLL_XFORM_QUSE15
+              - 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_DLI_TRIM_TXDQS8
+              - description: EMC_DLI_TRIM_TXDQS9
+              - description: EMC_DLI_TRIM_TXDQS10
+              - description: EMC_DLI_TRIM_TXDQS11
+              - description: EMC_DLI_TRIM_TXDQS12
+              - description: EMC_DLI_TRIM_TXDQS13
+              - description: EMC_DLI_TRIM_TXDQS14
+              - description: EMC_DLI_TRIM_TXDQS15
+              - description: EMC_DLL_XFORM_DQ0
+              - description: EMC_DLL_XFORM_DQ1
+              - description: EMC_DLL_XFORM_DQ2
+              - description: EMC_DLL_XFORM_DQ3
+              - description: EMC_DLL_XFORM_DQ4
+              - description: EMC_DLL_XFORM_DQ5
+              - description: EMC_DLL_XFORM_DQ6
+              - description: EMC_DLL_XFORM_DQ7
+              - description: EMC_XM2CMDPADCTRL
+              - description: EMC_XM2CMDPADCTRL4
+              - description: EMC_XM2CMDPADCTRL5
+              - description: EMC_XM2DQPADCTRL2
+              - description: EMC_XM2DQPADCTRL3
+              - description: EMC_XM2CLKPADCTRL
+              - description: EMC_XM2CLKPADCTRL2
+              - description: EMC_XM2COMPPADCTRL
+              - description: EMC_XM2VTTGENPADCTRL
+              - description: EMC_XM2VTTGENPADCTRL2
+              - description: EMC_XM2VTTGENPADCTRL3
+              - description: EMC_XM2DQSPADCTRL3
+              - description: EMC_XM2DQSPADCTRL4
+              - description: EMC_XM2DQSPADCTRL5
+              - description: EMC_XM2DQSPADCTRL6
+              - description: EMC_DSR_VTTGEN_DRV
+              - description: EMC_TXDSRVTTGEN
+              - description: EMC_FBIO_SPARE
+              - description: EMC_ZCAL_WAIT_CNT
+              - description: EMC_MRS_WAIT_CNT2
+              - description: EMC_CTT
+              - description: EMC_CTT_DURATION
+              - description: EMC_CFG_PIPE
+              - description: EMC_DYN_SELF_REF_CONTROL
+              - description: EMC_QPOP
+
+        required:
+          - clock-frequency
+          - nvidia,emc-auto-cal-config
+          - nvidia,emc-auto-cal-config2
+          - nvidia,emc-auto-cal-config3
+          - nvidia,emc-auto-cal-interval
+          - nvidia,emc-bgbias-ctl0
+          - nvidia,emc-cfg
+          - nvidia,emc-cfg-2
+          - nvidia,emc-ctt-term-ctrl
+          - nvidia,emc-mode-1
+          - nvidia,emc-mode-2
+          - nvidia,emc-mode-4
+          - nvidia,emc-mode-reset
+          - nvidia,emc-mrs-wait-cnt
+          - nvidia,emc-sel-dpd-ctrl
+          - nvidia,emc-xm2dqspadctrl2
+          - nvidia,emc-zcal-cnt-long
+          - nvidia,emc-zcal-interval
+          - nvidia,emc-configuration
+
+        additionalProperties: false
+
+required:
+  - compatible
+  - reg
+  - clocks
+  - clock-names
+  - nvidia,memory-controller
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/tegra124-car.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    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>;
+    };
+
+    external-memory-controller@7001b000 {
+        compatible = "nvidia,tegra124-emc";
+        reg = <0x0 0x7001b000 0x0 0x1000>;
+        clocks = <&car TEGRA124_CLK_EMC>;
+        clock-names = "emc";
+
+        nvidia,memory-controller = <&mc>;
+
+        emc-timings-0 {
+            nvidia,ram-code = <3>;
+
+            timing-0 {
+                clock-frequency = <12750000>;
+
+                nvidia,emc-zcal-cnt-long = <0x00000042>;
+                nvidia,emc-auto-cal-interval = <0x001fffff>;
+                nvidia,emc-ctt-term-ctrl = <0x00000802>;
+                nvidia,emc-cfg = <0x73240000>;
+                nvidia,emc-cfg-2 = <0x000008c5>;
+                nvidia,emc-sel-dpd-ctrl = <0x00040128>;
+                nvidia,emc-bgbias-ctl0 = <0x00000008>;
+                nvidia,emc-auto-cal-config = <0xa1430000>;
+                nvidia,emc-auto-cal-config2 = <0x00000000>;
+                nvidia,emc-auto-cal-config3 = <0x00000000>;
+                nvidia,emc-mode-reset = <0x80001221>;
+                nvidia,emc-mode-1 = <0x80100003>;
+                nvidia,emc-mode-2 = <0x80200008>;
+                nvidia,emc-mode-4 = <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 */
+                    0x00000000 /* EMC_DLL_XFORM_ADDR2 */
+                    0x00000000 /* EMC_DLL_XFORM_ADDR3 */
+                    0x00000000 /* 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 */
+                    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 */
+                    0x00000e0e /* 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 */
+                >;
+            };
+        };
+    };
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra186-mc.yaml
new file mode 100644 (file)
index 0000000..12516bd
--- /dev/null
@@ -0,0 +1,130 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/memory-controllers/nvidia,tegra186-mc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NVIDIA Tegra186 (and later) SoC Memory Controller
+
+maintainers:
+  - Jon Hunter <jonathanh@nvidia.com>
+  - Thierry Reding <thierry.reding@gmail.com>
+
+description: |
+  The NVIDIA Tegra186 SoC features a 128 bit memory controller that is split
+  into four 32 bit channels to support LPDDR4 with x16 subpartitions. The MC
+  handles memory requests for 40-bit virtual addresses from internal clients
+  and arbitrates among them to allocate memory bandwidth.
+
+  Up to 15 GiB of physical memory can be supported. Security features such as
+  encryption of traffic to and from DRAM via general security apertures are
+  available for video and other secure applications, as well as DRAM ECC for
+  automotive safety applications (single bit error correction and double bit
+  error detection).
+
+properties:
+  $nodename:
+    pattern: "^memory-controller@[0-9a-f]+$"
+
+  compatible:
+    items:
+      - enum:
+          - nvidia,tegra186-mc
+          - nvidia,tegra194-mc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  "#address-cells":
+    const: 2
+
+  "#size-cells":
+    const: 2
+
+  ranges: true
+
+  dma-ranges: true
+
+patternProperties:
+  "^external-memory-controller@[0-9a-f]+$":
+    description:
+      The bulk of the work involved in controlling the external memory
+      controller on NVIDIA Tegra186 and later is performed on the BPMP. This
+      coprocessor exposes the EMC clock that is used to set the frequency at
+      which the external memory is clocked and a remote procedure call that
+      can be used to obtain the set of available frequencies.
+    type: object
+    properties:
+      compatible:
+        items:
+          - enum:
+              - nvidia,tegra186-emc
+              - nvidia,tegra194-emc
+
+      reg:
+        maxItems: 1
+
+      interrupts:
+        maxItems: 1
+
+      clocks:
+        items:
+          - description: external memory clock
+
+      clock-names:
+        items:
+          - const: emc
+
+      nvidia,bpmp:
+        $ref: /schemas/types.yaml#/definitions/phandle
+        description:
+          phandle of the node representing the BPMP
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - "#address-cells"
+  - "#size-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    #include <dt-bindings/clock/tegra186-clock.h>
+    #include <dt-bindings/interrupt-controller/arm-gic.h>
+
+    memory-controller@2c00000 {
+        compatible = "nvidia,tegra186-mc";
+        reg = <0x0 0x02c00000 0x0 0xb0000>;
+        interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
+
+        #address-cells = <2>;
+        #size-cells = <2>;
+
+        ranges = <0x0 0x02c00000 0x02c00000 0x0 0xb0000>;
+
+        /*
+         * Memory clients have access to all 40 bits that the memory
+         * controller can address.
+         */
+        dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
+
+        external-memory-controller@2c60000 {
+            compatible = "nvidia,tegra186-emc";
+            reg = <0x0 0x02c60000 0x0 0x50000>;
+            interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+            clocks = <&bpmp TEGRA186_CLK_EMC>;
+            clock-names = "emc";
+
+            nvidia,bpmp = <&bpmp>;
+        };
+    };
+
+    bpmp: bpmp {
+        compatible = "nvidia,tegra186-bpmp";
+        #clock-cells = <1>;
+    };
index b6bc30d..5c6eabe 100644 (file)
@@ -1,7 +1,7 @@
 * AB8500 Multi-Functional Device (MFD)
 
 Required parent device properties:
-- compatible             : contains "stericsson,ab8500";
+- compatible             : contains "stericsson,ab8500" or "stericsson,ab8505";
 - interrupts             : contains the IRQ line for the AB8500
 - interrupt-controller   : describes the AB8500 as an Interrupt Controller (has its own domain)
 - #interrupt-cells       : should be 2, for 2-cell format
@@ -49,11 +49,13 @@ ab8500-charger               :                      : vddadc       : Charger interface
                         : CH_WD_EXP            :              : Charger watchdog detected
 ab8500-gpadc             : HW_CONV_END          : vddadc       : Analogue to Digital Converter
                            SW_CONV_END          :              :
-ab8500-gpio              :                      :              : GPIO Controller
+ab8500-gpio              :                      :              : GPIO Controller (AB8500)
+ab8505-gpio              :                      :              : GPIO Controller (AB8505)
 ab8500-ponkey            : ONKEY_DBF            :              : Power-on Key
                            ONKEY_DBR            :              :
 ab8500-pwm               :                      :              : Pulse Width Modulator
-ab8500-regulator         :                      :              : Regulators
+ab8500-regulator         :                      :              : Regulators (AB8500)
+ab8505-regulator         :                      :              : Regulators (AB8505)
 ab8500-rtc               : 60S                  :              : Real Time Clock
                          : ALARM                :              :
 ab8500-sysctrl           :                      :              : System Control
index a285695..e8c5255 100644 (file)
@@ -3,7 +3,9 @@
 The GPBR are a set of battery-backed registers.
 
 Required properties:
-- compatible:          "atmel,at91sam9260-gpbr", "syscon"
+- compatible:          Should be one of the following:
+                       "atmel,at91sam9260-gpbr", "syscon"
+                       "microchip,sam9x60-gpbr", "syscon"
 - reg:                 contains offset/length value of the GPBR memory
                        region.
 
index e3ef50c..89d05c6 100644 (file)
@@ -13,6 +13,7 @@ Required properties:
                        "atmel,at91sam9n12-matrix", "syscon"
                        "atmel,at91sam9x5-matrix", "syscon"
                        "atmel,sama5d3-matrix", "syscon"
+                       "microchip,sam9x60-matrix", "syscon"
 - reg:                 Contains offset/length value of the Bus Matrix
                        memory region.
 
index 1103ce2..5696d9f 100644 (file)
@@ -9,6 +9,7 @@ Required properties:
                        "atmel,at91sam9260-smc", "syscon"
                        "atmel,sama5d3-smc", "syscon"
                        "atmel,sama5d2-smc", "syscon"
+                       "microchip,sam9x60-smc", "syscon"
 - reg:                 Contains offset/length value of the SMC memory
                        region.
 
index 699fd3c..a091330 100644 (file)
@@ -1,10 +1,13 @@
 * Atmel Universal Synchronous Asynchronous Receiver/Transmitter (USART)
 
 Required properties for USART:
-- compatible: Should be "atmel,<chip>-usart" or "atmel,<chip>-dbgu"
-  The compatible <chip> indicated will be the first SoC to support an
-  additional mode or an USART new feature.
-  For the dbgu UART, use "atmel,<chip>-dbgu", "atmel,<chip>-usart"
+- compatible: Should be one of the following:
+       - "atmel,at91rm9200-usart"
+       - "atmel,at91sam9260-usart"
+       - "microchip,sam9x60-usart"
+       - "atmel,at91rm9200-dbgu", "atmel,at91rm9200-usart"
+       - "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart"
+       - "microchip,sam9x60-dbgu", "microchip,sam9x60-usart"
 - reg: Should contain registers location and length
 - interrupts: Should contain interrupt
 - clock-names: tuple listing input clock names.
index bc4b59d..857af98 100644 (file)
@@ -13,6 +13,7 @@ da9062-rtc              :               : Real-Time Clock
 da9062-onkey            :               : On Key
 da9062-watchdog         :               : Watchdog Timer
 da9062-thermal          :               : Thermal
+da9062-gpio             :               : GPIOs
 
 The DA9061 PMIC consists of:
 
@@ -38,6 +39,15 @@ Required properties:
 See Documentation/devicetree/bindings/interrupt-controller/interrupts.txt for
 further information on IRQ bindings.
 
+Optional properties:
+
+- gpio-controller : Marks the device as a gpio controller.
+- #gpio-cells     : Should be two. The first cell is the pin number and the
+                    second cell is used to specify the gpio polarity.
+
+See Documentation/devicetree/bindings/gpio/gpio.txt for further information on
+GPIO bindings.
+
 Sub-nodes:
 
 - regulators : This node defines the settings for the LDOs and BUCKs.
index fc6f0f4..92070b3 100644 (file)
@@ -5,6 +5,8 @@ Battery Charger and SFOUT LDO output for powering USB devices. It is
 interfaced to host controller using I2C.
 
 MAX77836 additionally contains PMIC (with two LDO regulators) and Fuel Gauge.
+For the description of Fuel Gauge low SOC alert interrupt see:
+../power/supply/max17040_battery.txt
 
 
 Required properties:
diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
new file mode 100644 (file)
index 0000000..4fbb9e7
--- /dev/null
@@ -0,0 +1,193 @@
+# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/mfd/rohm,bd71828-pmic.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: ROHM BD71828 Power Management Integrated Circuit bindings
+
+maintainers:
+  - Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>
+
+description: |
+  BD71828GW is a single-chip power management IC for battery-powered portable
+  devices. The IC integrates 7 buck converters, 7 LDOs, and a 1500 mA
+  single-cell linear charger. Also included is a Coulomb counter, a real-time
+  clock (RTC), and a 32.768 kHz clock gate.
+
+properties:
+  compatible:
+    const: rohm,bd71828
+
+  reg:
+    description:
+      I2C slave address.
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  gpio-controller: true
+
+  "#gpio-cells":
+    const: 2
+    description: |
+      The first cell is the pin number and the second cell is used to specify
+      flags. See ../gpio/gpio.txt for more information.
+
+  clocks:
+    maxItems: 1
+
+  "#clock-cells":
+    const: 0
+
+  rohm,charger-sense-resistor-ohms:
+    minimum: 10000000
+    maximum: 50000000
+    description: |
+      BD71827 and BD71828 have SAR ADC for measuring charging currents.
+      External sense resistor (RSENSE in data sheet) should be used. If some
+      other but 30MOhm resistor is used the resistance value should be given
+      here in Ohms.
+
+  regulators:
+    $ref: ../regulator/rohm,bd71828-regulator.yaml
+    description:
+      List of child nodes that specify the regulators.
+
+  leds:
+    $ref: ../leds/rohm,bd71828-leds.yaml
+
+  gpio-reserved-ranges:
+    description: |
+      Usage of BD71828 GPIO pins can be changed via OTP. This property can be
+      used to mark the pins which should not be configured for GPIO. Please see
+      the ../gpio/gpio.txt for more information.
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+  - "#clock-cells"
+  - regulators
+  - gpio-controller
+  - "#gpio-cells"
+
+examples:
+  - |
+    #include <dt-bindings/interrupt-controller/irq.h>
+    #include <dt-bindings/leds/common.h>
+    i2c {
+        #address-cells = <1>;
+        #size-cells = <0>;
+        pmic: pmic@4b {
+            compatible = "rohm,bd71828";
+            reg = <0x4b>;
+
+            interrupt-parent = <&gpio1>;
+            interrupts = <29 IRQ_TYPE_LEVEL_LOW>;
+
+            clocks = <&osc 0>;
+            #clock-cells = <0>;
+            clock-output-names = "bd71828-32k-out";
+
+            gpio-controller;
+            #gpio-cells = <2>;
+            gpio-reserved-ranges = <0 1>, <2 1>;
+
+            rohm,charger-sense-resistor-ohms = <10000000>;
+
+            regulators {
+                buck1: BUCK1 {
+                    regulator-name = "buck1";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <2500>;
+                };
+                buck2: BUCK2 {
+                    regulator-name = "buck2";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <2500>;
+                };
+                buck3: BUCK3 {
+                    regulator-name = "buck3";
+                    regulator-min-microvolt = <1200000>;
+                    regulator-max-microvolt = <2000000>;
+                };
+                buck4: BUCK4 {
+                    regulator-name = "buck4";
+                    regulator-min-microvolt = <1000000>;
+                    regulator-max-microvolt = <1800000>;
+                };
+                buck5: BUCK5 {
+                    regulator-name = "buck5";
+                    regulator-min-microvolt = <2500000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+                buck6: BUCK6 {
+                    regulator-name = "buck6";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <2500>;
+                };
+                buck7: BUCK7 {
+                    regulator-name = "buck7";
+                    regulator-min-microvolt = <500000>;
+                    regulator-max-microvolt = <2000000>;
+                    regulator-ramp-delay = <2500>;
+                };
+                ldo1: LDO1 {
+                    regulator-name = "ldo1";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+                ldo2: LDO2 {
+                    regulator-name = "ldo2";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+                ldo3: LDO3 {
+                    regulator-name = "ldo3";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+                ldo4: LDO4 {
+                    regulator-name = "ldo4";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+                ldo5: LDO5 {
+                    regulator-name = "ldo5";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+                ldo6: LDO6 {
+                    regulator-name = "ldo6";
+                    regulator-min-microvolt = <1800000>;
+                    regulator-max-microvolt = <1800000>;
+                };
+                ldo7_reg: LDO7 {
+                    regulator-name = "ldo7";
+                    regulator-min-microvolt = <800000>;
+                    regulator-max-microvolt = <3300000>;
+                };
+            };
+
+            leds {
+                compatible = "rohm,bd71828-leds";
+
+                led-1 {
+                    rohm,led-compatible = "bd71828-grnled";
+                    function = LED_FUNCTION_INDICATOR;
+                    color = <LED_COLOR_ID_GREEN>;
+                };
+                led-2 {
+                    rohm,led-compatible = "bd71828-ambled";
+                    function = LED_FUNCTION_CHARGING;
+                    color = <LED_COLOR_ID_AMBER>;
+                };
+            };
+        };
+    };
index 93602c7..dc448a9 100644 (file)
@@ -7,11 +7,56 @@ Required properties:
 - compatible:          "ti,tps61050" or "ti,tps61052"
 - reg:                 Specifies the I2C slave address
 
-Example:
+Optional sub-node:
+
+This subnode selects the chip's operational mode.
+There can be at most one single available subnode.
+
+- regulator: presence of this sub-node puts the chip in regulator mode.
+       see ../regulator/regulator.yaml
+
+- led: presence of this sub-node puts the chip in led mode.
+       Optional properties:
+       - function : see ../leds/common.txt
+       - color    : see ../leds/common.txt
+       - label    : see ../leds/common.txt
+                       (deprecated)
+
+Example (GPIO operation only):
+
+i2c0 {
+       tps61052@33 {
+               compatible = "ti,tps61052";
+               reg = <0x33>;
+       };
+};
+
+Example (GPIO + regulator operation):
 
 i2c0 {
        tps61052@33 {
                compatible = "ti,tps61052";
                reg = <0x33>;
+
+               regulator {
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+       };
+};
+
+Example (GPIO + led operation):
+
+#include <dt-bindings/leds/common.h>
+
+i2c0 {
+       tps61052@33 {
+               compatible = "ti,tps61052";
+               reg = <0x33>;
+
+               led {
+                       color = <LED_COLOR_ID_WHITE>;
+               };
        };
 };
index 0e1fa5b..f2e2e28 100644 (file)
@@ -18,6 +18,7 @@ Required properties:
 Optional properties:
 ===================
 
+- reg: A hint for the memory regions associated with the P2A controller
 - memory-region: A phandle to a reserved_memory region to be used for the PCI
                to AHB mapping
 
index 68b51dc..3aa297c 100644 (file)
@@ -57,6 +57,7 @@ Required properties:
        "atmel,at91sam9g45-pmecc"
        "atmel,sama5d4-pmecc"
        "atmel,sama5d2-pmecc"
+       "microchip,sam9x60-pmecc"
 - reg: should contain 2 register ranges. The first one is pointing to the PMECC
        block, and the second one to the PMECC_ERRLOC block.
 
index 14e52a0..218a3b3 100644 (file)
@@ -1,7 +1,8 @@
 * AT91 CAN *
 
 Required properties:
-  - compatible: Should be "atmel,at91sam9263-can" or "atmel,at91sam9x5-can"
+  - compatible: Should be "atmel,at91sam9263-can", "atmel,at91sam9x5-can" or
+    "microchip,sam9x60-can"
   - reg: Should contain CAN controller registers location and length
   - interrupts: Should contain IRQ line for the CAN controller
 
index 19e4a7d..85c6551 100644 (file)
@@ -7,6 +7,7 @@ Required properties:
              "renesas,can-r8a7745" if CAN controller is a part of R8A7745 SoC.
              "renesas,can-r8a77470" if CAN controller is a part of R8A77470 SoC.
              "renesas,can-r8a774a1" if CAN controller is a part of R8A774A1 SoC.
+             "renesas,can-r8a774b1" if CAN controller is a part of R8A774B1 SoC.
              "renesas,can-r8a774c0" if CAN controller is a part of R8A774C0 SoC.
              "renesas,can-r8a7778" if CAN controller is a part of R8A7778 SoC.
              "renesas,can-r8a7779" if CAN controller is a part of R8A7779 SoC.
@@ -36,8 +37,8 @@ Required properties:
 - pinctrl-0: pin control group to be used for this controller.
 - pinctrl-names: must be "default".
 
-Required properties for R8A774A1, R8A774C0, R8A7795, R8A7796, R8A77965,
-R8A77990, and R8A77995:
+Required properties for R8A774A1, R8A774B1, R8A774C0, R8A7795, R8A7796,
+R8A77965, R8A77990, and R8A77995:
 For the denoted SoCs, "clkp2" can be CANFD clock. This is a div6 clock and can
 be used by both CAN and CAN FD controller at the same time. It needs to be
 scaled to maximum frequency if any of these controllers use it. This is done
index a901cd9..13a4e34 100644 (file)
@@ -5,6 +5,7 @@ Required properties:
 - compatible: Must contain one or more of the following:
   - "renesas,rcar-gen3-canfd" for R-Car Gen3 and RZ/G2 compatible controllers.
   - "renesas,r8a774a1-canfd" for R8A774A1 (RZ/G2M) compatible controller.
+  - "renesas,r8a774b1-canfd" for R8A774B1 (RZ/G2N) compatible controller.
   - "renesas,r8a774c0-canfd" for R8A774C0 (RZ/G2E) compatible controller.
   - "renesas,r8a7795-canfd" for R8A7795 (R-Car H3) compatible controller.
   - "renesas,r8a7796-canfd" for R8A7796 (R-Car M3-W) compatible controller.
@@ -31,8 +32,8 @@ The name of the child nodes are "channel0" and "channel1" respectively. Each
 child node supports the "status" property only, which is used to
 enable/disable the respective channel.
 
-Required properties for R8A774A1, R8A774C0, R8A7795, R8A7796, R8A77965,
-R8A77990, and R8A77995:
+Required properties for R8A774A1, R8A774B1, R8A774C0, R8A7795, R8A7796,
+R8A77965, R8A77990, and R8A77995:
 In the denoted SoCs, canfd clock is a div6 clock and can be used by both CAN
 and CAN FD controller at the same time. It needs to be scaled to maximum
 frequency if any of these controllers use it. This is done using the below
index 1c75a05..b43c6c6 100644 (file)
@@ -34,6 +34,14 @@ properties:
     description:
       Mark the provider as read only.
 
+  wp-gpios:
+    description:
+      GPIO to which the write-protect pin of the chip is connected.
+      The write-protect GPIO is asserted, when it's driven high
+      (logical '1') to block the write operation. It's deasserted,
+      when it's driven low (logical '0') to allow writing.
+    maxItems: 1
+
 patternProperties:
   "^.*@[0-9a-f]+$":
     type: object
@@ -63,9 +71,12 @@ patternProperties:
 
 examples:
   - |
+      #include <dt-bindings/gpio/gpio.h>
+
       qfprom: eeprom@700000 {
           #address-cells = <1>;
           #size-cells = <1>;
+          wp-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
 
           /* ... */
 
index db605d8..48a98da 100644 (file)
@@ -107,7 +107,6 @@ additionalProperties: false
 examples:
   - |
     #include <dt-bindings/gpio/gpio.h>
-    #include <dt-bindings/clock/intel,lgm-clk.h>
     pcie10: pcie@d0e00000 {
       compatible = "intel,lgm-pcie", "snps,dw-pcie";
       device_type = "pci";
@@ -120,7 +119,6 @@ examples:
       linux,pci-domain = <0>;
       max-link-speed = <4>;
       bus-range = <0x00 0x08>;
-      interrupt-parent = <&ioapic1>;
       #interrupt-cells = <1>;
       interrupt-map-mask = <0 0 0 0x7>;
       interrupt-map = <0 0 0 1 &ioapic1 27 1>,
@@ -129,7 +127,7 @@ examples:
                       <0 0 0 4 &ioapic1 30 1>;
       ranges = <0x02000000 0 0xd4000000 0xd4000000 0 0x04000000>;
       resets = <&rcu0 0x50 0>;
-      clocks = <&cgu0 LGM_GCLK_PCIE10>;
+      clocks = <&cgu0 120>;
       phys = <&cb0phy0>;
       phy-names = "pcie";
       reset-assert-ms = <500>;
index ff7959c..0ccee64 100644 (file)
@@ -45,8 +45,10 @@ examples:
     sysconf: chiptop@e0200000 {
       compatible = "intel,lgm-syscon", "syscon";
       reg = <0xe0200000 0x100>;
+      #address-cells = <1>;
+      #size-cells = <1>;
 
-      emmc-phy: emmc-phy@a8 {
+      emmc_phy: emmc-phy@a8 {
         compatible = "intel,lgm-emmc-phy";
         reg = <0x00a8 0x10>;
         clocks = <&emmc>;
diff --git a/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml b/Documentation/devicetree/bindings/phy/marvell,mmp3-hsic-phy.yaml
new file mode 100644 (file)
index 0000000..5ab4361
--- /dev/null
@@ -0,0 +1,42 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright 2019 Lubomir Rintel <lkundrak@v3.sk>
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/phy/marvell,mmp3-hsic-phy.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Marvell MMP3 HSIC PHY
+
+maintainers:
+  - Lubomir Rintel <lkundrak@v3.sk>
+
+properties:
+  compatible:
+    const: marvell,mmp3-hsic-phy
+
+  reg:
+    maxItems: 1
+    description: base address of the device
+
+  reset-gpios:
+    maxItems: 1
+    description: GPIO connected to reset
+
+  "#phy-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - reset-gpios
+  - "#phy-cells"
+
+examples:
+  - |
+    #include <dt-bindings/gpio/gpio.h>
+    hsic-phy@f0001800 {
+            compatible = "marvell,mmp3-hsic-phy";
+            reg = <0xf0001800 0x40>;
+            reset-gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
+            #phy-cells = <0>;
+    };
index 39ad865..bb690e2 100644 (file)
@@ -22,6 +22,9 @@ description: |+
 properties:
   compatible:
     const: aspeed,ast2400-pinctrl
+  reg:
+    description: |
+      A hint for the memory regions associated with the pin-controller
 
 patternProperties:
   '^.*$':
index 3c6405b..f7f5d57 100644 (file)
@@ -23,6 +23,9 @@ description: |+
 properties:
   compatible:
     const: aspeed,ast2500-pinctrl
+  reg:
+    description: |
+      A hint for the memory regions associated with the pin-controller
   aspeed,external-nodes:
     minItems: 2
     maxItems: 2
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.txt b/Documentation/devicetree/bindings/power/qcom,rpmpd.txt
deleted file mode 100644 (file)
index bc75bf4..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-Qualcomm RPM/RPMh Power domains
-
-For RPM/RPMh Power domains, we communicate a performance state to RPM/RPMh
-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
-       * qcom,sdm845-rpmhpd: RPMh Power domain for the sdm845 family of SoC
- - #power-domain-cells: number of cells in Power domain specifier
-       must be 1.
- - operating-points-v2: Phandle to the OPP table for the Power domain.
-       Refer to Documentation/devicetree/bindings/power/power_domain.txt
-       and Documentation/devicetree/bindings/opp/opp.txt for more details
-
-Refer to <dt-bindings/power/qcom-rpmpd.h> for the level values for
-various OPPs for different platforms as well as Power domain indexes
-
-Example: rpmh power domain controller and OPP table
-
-#include <dt-bindings/power/qcom-rpmhpd.h>
-
-opp-level values specified in the OPP tables for RPMh power domains
-should use the RPMH_REGULATOR_LEVEL_* constants from
-<dt-bindings/power/qcom-rpmhpd.h>
-
-       rpmhpd: power-controller {
-               compatible = "qcom,sdm845-rpmhpd";
-               #power-domain-cells = <1>;
-               operating-points-v2 = <&rpmhpd_opp_table>;
-
-               rpmhpd_opp_table: opp-table {
-                       compatible = "operating-points-v2";
-
-                       rpmhpd_opp_ret: opp1 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
-                       };
-
-                       rpmhpd_opp_min_svs: opp2 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
-                       };
-
-                       rpmhpd_opp_low_svs: opp3 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
-                       };
-
-                       rpmhpd_opp_svs: opp4 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
-                       };
-
-                       rpmhpd_opp_svs_l1: opp5 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
-                       };
-
-                       rpmhpd_opp_nom: opp6 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
-                       };
-
-                       rpmhpd_opp_nom_l1: opp7 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
-                       };
-
-                       rpmhpd_opp_nom_l2: opp8 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
-                       };
-
-                       rpmhpd_opp_turbo: opp9 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
-                       };
-
-                       rpmhpd_opp_turbo_l1: opp10 {
-                               opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
-                       };
-               };
-       };
-
-Example: rpm power domain controller and OPP table
-
-       rpmpd: power-controller {
-               compatible = "qcom,msm8996-rpmpd";
-               #power-domain-cells = <1>;
-               operating-points-v2 = <&rpmpd_opp_table>;
-
-               rpmpd_opp_table: opp-table {
-                       compatible = "operating-points-v2";
-
-                       rpmpd_opp_low: opp1 {
-                               opp-level = <1>;
-                       };
-
-                       rpmpd_opp_ret: opp2 {
-                               opp-level = <2>;
-                       };
-
-                       rpmpd_opp_svs: opp3 {
-                               opp-level = <3>;
-                       };
-
-                       rpmpd_opp_normal: opp4 {
-                               opp-level = <4>;
-                       };
-
-                       rpmpd_opp_high: opp5 {
-                               opp-level = <5>;
-                       };
-
-                       rpmpd_opp_turbo: opp6 {
-                               opp-level = <6>;
-                       };
-               };
-       };
-
-Example: Client/Consumer device using OPP table
-
-       leaky-device0@12350000 {
-               compatible = "foo,i-leak-current";
-               reg = <0x12350000 0x1000>;
-               power-domains = <&rpmhpd SDM845_MX>;
-               operating-points-v2 = <&leaky_opp_table>;
-       };
-
-
-       leaky_opp_table: opp-table {
-               compatible = "operating-points-v2";
-
-               opp1 {
-                       opp-hz = /bits/ 64 <144000>;
-                       required-opps = <&rpmhpd_opp_low>;
-               };
-
-               opp2 {
-                       opp-hz = /bits/ 64 <400000>;
-                       required-opps = <&rpmhpd_opp_ret>;
-               };
-
-               opp3 {
-                       opp-hz = /bits/ 64 <20000000>;
-                       required-opps = <&rpmpd_opp_svs>;
-               };
-
-               opp4 {
-                       opp-hz = /bits/ 64 <25000000>;
-                       required-opps = <&rpmpd_opp_normal>;
-               };
-       };
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
new file mode 100644 (file)
index 0000000..ba60531
--- /dev/null
@@ -0,0 +1,170 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/power/qcom,rpmpd.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm RPM/RPMh Power domains
+
+maintainers:
+  - Rajendra Nayak <rnayak@codeaurora.org>
+
+description:
+  For RPM/RPMh Power domains, we communicate a performance state to RPM/RPMh
+  which then translates it into a corresponding voltage on a rail.
+
+properties:
+  compatible:
+    enum:
+      - qcom,msm8976-rpmpd
+      - qcom,msm8996-rpmpd
+      - qcom,msm8998-rpmpd
+      - qcom,qcs404-rpmpd
+      - qcom,sc7180-rpmhpd
+      - qcom,sdm845-rpmhpd
+      - qcom,sm8150-rpmhpd
+
+  '#power-domain-cells':
+    const: 1
+
+  operating-points-v2: true
+
+  opp-table:
+    type: object
+
+required:
+  - compatible
+  - '#power-domain-cells'
+  - operating-points-v2
+
+additionalProperties: false
+
+examples:
+  - |
+
+    // Example 1 (rpmh power domain controller and OPP table):
+
+    #include <dt-bindings/power/qcom-rpmpd.h>
+
+    rpmhpd: power-controller {
+      compatible = "qcom,sdm845-rpmhpd";
+      #power-domain-cells = <1>;
+      operating-points-v2 = <&rpmhpd_opp_table>;
+
+      rpmhpd_opp_table: opp-table {
+        compatible = "operating-points-v2";
+
+        rpmhpd_opp_ret: opp1 {
+          opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
+        };
+
+        rpmhpd_opp_min_svs: opp2 {
+          opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+        };
+
+        rpmhpd_opp_low_svs: opp3 {
+          opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+        };
+
+        rpmhpd_opp_svs: opp4 {
+          opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+        };
+
+        rpmhpd_opp_svs_l1: opp5 {
+          opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+        };
+
+        rpmhpd_opp_nom: opp6 {
+          opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+        };
+
+        rpmhpd_opp_nom_l1: opp7 {
+          opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+        };
+
+        rpmhpd_opp_nom_l2: opp8 {
+          opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
+        };
+
+        rpmhpd_opp_turbo: opp9 {
+          opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+        };
+
+        rpmhpd_opp_turbo_l1: opp10 {
+          opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+        };
+      };
+    };
+
+  - |
+
+    // Example 2 (rpm power domain controller and OPP table):
+
+    rpmpd: power-controller {
+      compatible = "qcom,msm8996-rpmpd";
+      #power-domain-cells = <1>;
+      operating-points-v2 = <&rpmpd_opp_table>;
+
+      rpmpd_opp_table: opp-table {
+        compatible = "operating-points-v2";
+
+        rpmpd_opp_low: opp1 {
+          opp-level = <1>;
+        };
+
+        rpmpd_opp_ret: opp2 {
+          opp-level = <2>;
+        };
+
+        rpmpd_opp_svs: opp3 {
+          opp-level = <3>;
+        };
+
+        rpmpd_opp_normal: opp4 {
+          opp-level = <4>;
+        };
+
+        rpmpd_opp_high: opp5 {
+          opp-level = <5>;
+        };
+
+        rpmpd_opp_turbo: opp6 {
+          opp-level = <6>;
+        };
+      };
+    };
+
+  - |
+
+    // Example 3 (Client/Consumer device using OPP table):
+
+    leaky-device0@12350000 {
+      compatible = "foo,i-leak-current";
+      reg = <0x12350000 0x1000>;
+      power-domains = <&rpmhpd 0>;
+      operating-points-v2 = <&leaky_opp_table>;
+    };
+
+    leaky_opp_table: opp-table {
+      compatible = "operating-points-v2";
+      opp1 {
+        opp-hz = /bits/ 64 <144000>;
+        required-opps = <&rpmhpd_opp_low>;
+      };
+
+      opp2 {
+        opp-hz = /bits/ 64 <400000>;
+        required-opps = <&rpmhpd_opp_ret>;
+      };
+
+      opp3 {
+        opp-hz = /bits/ 64 <20000000>;
+        required-opps = <&rpmpd_opp_svs>;
+      };
+
+      opp4 {
+        opp-hz = /bits/ 64 <25000000>;
+        required-opps = <&rpmpd_opp_normal>;
+      };
+    };
+...
index d366f1e..bb529ec 100644 (file)
@@ -8,9 +8,41 @@ Required properties:
  - compatible:         Must contain:   "xlnx,zynqmp-power"
  - interrupts:         Interrupt specifier
 
--------
-Example
--------
+Optional properties:
+ - mbox-names  : Name given to channels seen in the 'mboxes' property.
+                 "tx" - Mailbox corresponding to transmit path
+                 "rx" - Mailbox corresponding to receive path
+ - mboxes      : Standard property to specify a Mailbox. Each value of
+                 the mboxes property should contain a phandle to the
+                 mailbox controller device node and an args specifier
+                 that will be the phandle to the intended sub-mailbox
+                 child node to be used for communication. See
+                 Documentation/devicetree/bindings/mailbox/mailbox.txt
+                 for more details about the generic mailbox controller
+                 and client driver bindings. Also see
+                 Documentation/devicetree/bindings/mailbox/ \
+                 xlnx,zynqmp-ipi-mailbox.txt for typical controller that
+                 is used to communicate with this System controllers.
+
+--------
+Examples
+--------
+
+Example with interrupt method:
+
+firmware {
+       zynqmp_firmware: zynqmp-firmware {
+               compatible = "xlnx,zynqmp-firmware";
+               method = "smc";
+
+               zynqmp_power: zynqmp-power {
+                       compatible = "xlnx,zynqmp-power";
+                       interrupts = <0 35 4>;
+               };
+       };
+};
+
+Example with IPI mailbox method:
 
 firmware {
        zynqmp_firmware: zynqmp-firmware {
@@ -19,7 +51,11 @@ firmware {
 
                zynqmp_power: zynqmp-power {
                        compatible = "xlnx,zynqmp-power";
+                       interrupt-parent = <&gic>;
                        interrupts = <0 35 4>;
+                       mboxes = <&ipi_mailbox_pmu0 0>,
+                                <&ipi_mailbox_pmu0 1>;
+                       mbox-names = "tx", "rx";
                };
        };
 };
index 4a21fe7..7dcab2b 100644 (file)
@@ -30,13 +30,51 @@ properties:
       - items:
           - const: allwinner,sun50i-h5-pwm
           - const: allwinner,sun5i-a13-pwm
+      - const: allwinner,sun50i-h6-pwm
 
   reg:
     maxItems: 1
 
   clocks:
+    minItems: 1
+    maxItems: 2
+    items:
+      - description: Module Clock
+      - description: Bus Clock
+
+  # Even though it only applies to subschemas under the conditionals,
+  # not listing them here will trigger a warning because of the
+  # additionalsProperties set to false.
+  clock-names: true
+
+  resets:
     maxItems: 1
 
+if:
+  properties:
+    compatible:
+      contains:
+        const: allwinner,sun50i-h6-pwm
+
+then:
+  properties:
+    clocks:
+      maxItems: 2
+
+    clock-names:
+      items:
+        - const: mod
+        - const: bus
+
+  required:
+    - clock-names
+    - resets
+
+else:
+  properties:
+    clocks:
+      maxItems: 1
+
 required:
   - "#pwm-cells"
   - compatible
@@ -54,4 +92,17 @@ examples:
         #pwm-cells = <3>;
     };
 
+  - |
+    #include <dt-bindings/clock/sun50i-h6-ccu.h>
+    #include <dt-bindings/reset/sun50i-h6-ccu.h>
+
+    pwm@300a000 {
+      compatible = "allwinner,sun50i-h6-pwm";
+      reg = <0x0300a000 0x400>;
+      clocks = <&osc24M>, <&ccu CLK_BUS_PWM>;
+      clock-names = "mod", "bus";
+      resets = <&ccu RST_BUS_PWM>;
+      #pwm-cells = <3>;
+    };
+
 ...
index 1b06f86..a1b8a48 100644 (file)
@@ -3,7 +3,7 @@ Freescale MXS PWM controller
 Required properties:
 - compatible: should be "fsl,imx23-pwm"
 - reg: physical base address and length of the controller's registers
-- #pwm-cells: should be 2. See pwm.yaml in this directory for a description of
+- #pwm-cells: should be 3. See pwm.yaml in this directory for a description of
   the cells format.
 - fsl,pwm-number: the number of PWM devices
 
@@ -12,6 +12,6 @@ Example:
 pwm: pwm@80064000 {
        compatible = "fsl,imx28-pwm", "fsl,imx23-pwm";
        reg = <0x80064000 0x2000>;
-       #pwm-cells = <2>;
+       #pwm-cells = <3>;
        fsl,pwm-number = <8>;
 };
diff --git a/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt b/Documentation/devicetree/bindings/remoteproc/mtk,scp.txt
new file mode 100644 (file)
index 0000000..3ba668b
--- /dev/null
@@ -0,0 +1,36 @@
+Mediatek SCP Bindings
+----------------------------------------
+
+This binding provides support for ARM Cortex M4 Co-processor found on some
+Mediatek SoCs.
+
+Required properties:
+- compatible           Should be "mediatek,mt8183-scp"
+- reg                  Should contain the address ranges for the two memory
+                       regions, SRAM and CFG.
+- reg-names            Contains the corresponding names for the two memory
+                       regions. These should be named "sram" & "cfg".
+- clocks               Clock for co-processor (See: ../clock/clock-bindings.txt)
+- clock-names          Contains the corresponding name for the clock. This
+                       should be named "main".
+
+Subnodes
+--------
+
+Subnodes of the SCP represent rpmsg devices. The names of the devices are not
+important. The properties of these nodes are defined by the individual bindings
+for the rpmsg devices - but must contain the following property:
+
+- mtk,rpmsg-name       Contains the name for the rpmsg device. Used to match
+                       the subnode to rpmsg device announced by SCP.
+
+Example:
+
+       scp: scp@10500000 {
+               compatible = "mediatek,mt8183-scp";
+               reg = <0 0x10500000 0 0x80000>,
+                     <0 0x105c0000 0 0x5000>;
+               reg-names = "sram", "cfg";
+               clocks = <&infracfg CLK_INFRA_SCPSYS>;
+               clock-names = "main";
+       };
index 292dfda..9938918 100644 (file)
@@ -10,11 +10,17 @@ on the Qualcomm ADSP Hexagon core.
                    "qcom,msm8974-adsp-pil"
                    "qcom,msm8996-adsp-pil"
                    "qcom,msm8996-slpi-pil"
+                   "qcom,msm8998-adsp-pas"
+                   "qcom,msm8998-slpi-pas"
                    "qcom,qcs404-adsp-pas"
                    "qcom,qcs404-cdsp-pas"
                    "qcom,qcs404-wcss-pas"
                    "qcom,sdm845-adsp-pas"
                    "qcom,sdm845-cdsp-pas"
+                   "qcom,sm8150-adsp-pas"
+                   "qcom,sm8150-cdsp-pas"
+                   "qcom,sm8150-mpss-pas"
+                   "qcom,sm8150-slpi-pas"
 
 - interrupts-extended:
        Usage: required
@@ -29,12 +35,18 @@ on the Qualcomm ADSP Hexagon core.
        qcom,msm8974-adsp-pil:
        qcom,msm8996-adsp-pil:
        qcom,msm8996-slpi-pil:
+       qcom,msm8998-adsp-pas:
+       qcom,msm8998-slpi-pas:
        qcom,qcs404-adsp-pas:
        qcom,qcs404-cdsp-pas:
        qcom,sdm845-adsp-pas:
        qcom,sdm845-cdsp-pas:
+       qcom,sm8150-adsp-pas:
+       qcom,sm8150-cdsp-pas:
+       qcom,sm8150-slpi-pas:
                    must be "wdog", "fatal", "ready", "handover", "stop-ack"
        qcom,qcs404-wcss-pas:
+       qcom,sm8150-mpss-pas:
                    must be "wdog", "fatal", "ready", "handover", "stop-ack",
                    "shutdown-ack"
 
@@ -67,6 +79,38 @@ on the Qualcomm ADSP Hexagon core.
        Definition: reference to the px regulator to be held on behalf of the
                    booting Hexagon core
 
+- power-domains:
+       Usage: required
+       Value type: <phandle>
+       Definition: reference to power-domains that match the power-domain-names
+
+- power-domain-names:
+       Usage: required
+       Value type: <stringlist>
+       Definition: The power-domains needed depend on the compatible string:
+       qcom,msm8974-adsp-pil:
+       qcom,msm8996-adsp-pil:
+       qcom,msm8998-adsp-pas:
+                   must be "cx"
+       qcom,msm8996-slpi-pil:
+                   must be "ss_cx"
+       qcom,msm8998-slpi-pas:
+                   must be "ssc_cx"
+       qcom,qcs404-adsp-pas:
+                   must be "lpi_cx"
+       qcom,qcs404-cdsp-pas:
+       qcom,qcs404-wcss-pas:
+                   must be "mx"
+       qcom,sdm845-adsp-pas:
+       qcom,sdm845-cdsp-pas:
+       qcom,sm8150-adsp-pas:
+       qcom,sm8150-cdsp-pas:
+                   must be "cx", "load_state"
+       qcom,sm8150-mpss-pas:
+                   must be "cx", "load_state", "mss"
+       qcom,sm8150-slpi-pas:
+                   must be "lcx", "lmx", "load_state"
+
 - memory-region:
        Usage: required
        Value type: <phandle>
index c416746..88dfa3f 100644 (file)
@@ -13,6 +13,7 @@ on the Qualcomm Hexagon core.
                    "qcom,msm8974-mss-pil"
                    "qcom,msm8996-mss-pil"
                    "qcom,msm8998-mss-pil"
+                   "qcom,sc7180-mss-pil"
                    "qcom,sdm845-mss-pil"
 
 - reg:
@@ -43,6 +44,7 @@ on the Qualcomm Hexagon core.
                    must be "wdog", "fatal", "ready", "handover", "stop-ack"
        qcom,msm8996-mss-pil:
        qcom,msm8998-mss-pil:
+       qcom,sc7180-mss-pil:
        qcom,sdm845-mss-pil:
                    must be "wdog", "fatal", "ready", "handover", "stop-ack",
                    "shutdown-ack"
@@ -75,6 +77,9 @@ on the Qualcomm Hexagon core.
        qcom,msm8998-mss-pil:
                    must be "iface", "bus", "mem", "xo", "gpll0_mss",
                    "snoc_axi", "mnoc_axi", "qdss"
+       qcom,sc7180-mss-pil:
+                   must be "iface", "bus", "xo", "snoc_axi", "mnoc_axi",
+                   "mss_crypto", "mss_nav", "nav"
        qcom,sdm845-mss-pil:
                    must be "iface", "bus", "mem", "xo", "gpll0_mss",
                    "snoc_axi", "mnoc_axi", "prng"
@@ -86,7 +91,7 @@ on the Qualcomm Hexagon core.
                    reference to the list of 3 reset-controllers for the
                    wcss sub-system
                    reference to the list of 2 reset-controllers for the modem
-                   sub-system on SDM845 SoCs
+                   sub-system on SC7180, SDM845 SoCs
 
 - reset-names:
        Usage: required
@@ -95,7 +100,7 @@ on the Qualcomm Hexagon core.
                    must be "wcss_aon_reset", "wcss_reset", "wcss_q6_reset"
                    for the wcss sub-system
                    must be "mss_restart", "pdc_reset" for the modem
-                   sub-system on SDM845 SoCs
+                   sub-system on SC7180, SDM845 SoCs
 
 For the compatible strings below the following supplies are required:
   "qcom,q6v5-pil"
@@ -144,6 +149,7 @@ For the compatible string below the following supplies are required:
        qcom,msm8996-mss-pil:
        qcom,msm8998-mss-pil:
                    must be "cx", "mx"
+       qcom,sc7180-mss-pil:
        qcom,sdm845-mss-pil:
                    must be "cx", "mx", "mss", "load_state"
 
@@ -165,6 +171,19 @@ For the compatible string below the following supplies are required:
                    by the three offsets within syscon for q6, modem and nc
                    halt registers.
 
+For the compatible strings below the following phandle references are required:
+  "qcom,sc7180-mss-pil"
+- qcom,halt-nav-regs:
+       Usage: required
+       Value type: <prop-encoded-array>
+       Definition: reference to a list of 2 phandles with one offset each for
+                   the modem sub-system running on SC7180 SoC. The first
+                   phandle reference is to the mss clock node followed by the
+                   offset within register space for nav halt register. The
+                   second phandle reference is to a syscon representing TCSR
+                   followed by the offset within syscon for conn_box_spare0
+                   register.
+
 = SUBNODES:
 The Hexagon node must contain two subnodes, named "mba" and "mpss" representing
 the memory regions used by the Hexagon firmware. Each sub-node must contain:
diff --git a/Documentation/devicetree/bindings/reset/brcm,bcm7216-pcie-sata-rescal.yaml b/Documentation/devicetree/bindings/reset/brcm,bcm7216-pcie-sata-rescal.yaml
new file mode 100644 (file)
index 0000000..411bd76
--- /dev/null
@@ -0,0 +1,37 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright 2020 Broadcom
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/reset/brcm,bcm7216-pcie-sata-rescal.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: BCM7216 RESCAL reset controller
+
+description: This document describes the BCM7216 RESCAL reset controller which is responsible for controlling the reset of the SATA and PCIe0/1 instances on BCM7216.
+
+maintainers:
+  - Florian Fainelli <f.fainelli@gmail.com>
+  - Jim Quinlan <jim2101024@gmail.com>
+
+properties:
+  compatible:
+    const: brcm,bcm7216-pcie-sata-rescal
+
+  reg:
+    maxItems: 1
+
+  "#reset-cells":
+    const: 0
+
+required:
+  - compatible
+  - reg
+  - "#reset-cells"
+
+examples:
+  - |
+    reset-controller@8b2c800 {
+          compatible = "brcm,bcm7216-pcie-sata-rescal";
+          reg = <0x8b2c800 0x10>;
+          #reset-cells = <0>;
+    };
diff --git a/Documentation/devicetree/bindings/reset/intel,rcu-gw.yaml b/Documentation/devicetree/bindings/reset/intel,rcu-gw.yaml
new file mode 100644 (file)
index 0000000..246dea8
--- /dev/null
@@ -0,0 +1,63 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/reset/intel,rcu-gw.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: System Reset Controller on Intel Gateway SoCs
+
+maintainers:
+  - Dilip Kota <eswara.kota@linux.intel.com>
+
+properties:
+  compatible:
+    enum:
+      - intel,rcu-lgm
+      - intel,rcu-xrx200
+
+  reg:
+    description: Reset controller registers.
+    maxItems: 1
+
+  intel,global-reset:
+    description: Global reset register offset and bit offset.
+    allOf:
+      - $ref: /schemas/types.yaml#/definitions/uint32-array
+      - maxItems: 2
+
+  "#reset-cells":
+    minimum: 2
+    maximum: 3
+    description: |
+      First cell is reset request register offset.
+      Second cell is bit offset in reset request register.
+      Third cell is bit offset in reset status register.
+      For LGM SoC, reset cell count is 2 as bit offset in
+      reset request and reset status registers is same. Whereas
+      3 for legacy SoCs as bit offset differs.
+
+required:
+  - compatible
+  - reg
+  - intel,global-reset
+  - "#reset-cells"
+
+additionalProperties: false
+
+examples:
+  - |
+    rcu0: reset-controller@e0000000 {
+        compatible = "intel,rcu-lgm";
+        reg = <0xe0000000 0x20000>;
+        intel,global-reset = <0x10 30>;
+        #reset-cells = <2>;
+    };
+
+    pwm: pwm@e0d00000 {
+        status = "disabled";
+        compatible = "intel,lgm-pwm";
+        reg = <0xe0d00000 0x30>;
+        clocks = <&cgu0 1>;
+        #pwm-cells = <2>;
+        resets = <&rcu0 0x30 21>;
+    };
diff --git a/Documentation/devicetree/bindings/reset/nuvoton,npcm-reset.txt b/Documentation/devicetree/bindings/reset/nuvoton,npcm-reset.txt
new file mode 100644 (file)
index 0000000..6e80270
--- /dev/null
@@ -0,0 +1,32 @@
+Nuvoton NPCM Reset controller
+
+Required properties:
+- compatible : "nuvoton,npcm750-reset" for NPCM7XX BMC
+- reg : specifies physical base address and size of the register.
+- #reset-cells: must be set to 2
+
+Optional property:
+- nuvoton,sw-reset-number - Contains the software reset number to restart the SoC.
+  NPCM7xx contain four software reset that represent numbers 1 to 4.
+
+  If 'nuvoton,sw-reset-number' is not specfied software reset is disabled.
+
+Example:
+       rstc: rstc@f0801000 {
+               compatible = "nuvoton,npcm750-reset";
+               reg = <0xf0801000 0x70>;
+               #reset-cells = <2>;
+               nuvoton,sw-reset-number = <2>;
+       };
+
+Specifying reset lines connected to IP NPCM7XX modules
+======================================================
+example:
+
+        spi0: spi@..... {
+                ...
+                resets = <&rstc NPCM7XX_RESET_IPSRST2 NPCM7XX_RESET_PSPI1>;
+                ...
+        };
+
+The index could be found in <dt-bindings/reset/nuvoton,npcm7xx-reset.h>.
diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.txt
deleted file mode 100644 (file)
index 5d3791e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Atmel AT91RM9200 Real Time Clock
-
-Required properties:
-- compatible: should be: "atmel,at91rm9200-rtc" or "atmel,at91sam9x5-rtc"
-- reg: physical base address of the controller and length of memory mapped
-  region.
-- interrupts: rtc alarm/event interrupt
-- clocks: phandle to input clock.
-
-Example:
-
-rtc@fffffe00 {
-       compatible = "atmel,at91rm9200-rtc";
-       reg = <0xfffffe00 0x100>;
-       interrupts = <1 4 7>;
-       clocks = <&clk32k>;
-};
diff --git a/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml b/Documentation/devicetree/bindings/rtc/atmel,at91rm9200-rtc.yaml
new file mode 100644 (file)
index 0000000..02bbfe7
--- /dev/null
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: GPL-2.0
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/rtc/atmel,at91rm9200-rtc.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Atmel AT91 RTC Device Tree Bindings
+
+allOf:
+  - $ref: "rtc.yaml#"
+
+maintainers:
+  - Alexandre Belloni <alexandre.belloni@bootlin.com>
+
+properties:
+  compatible:
+    enum:
+      - atmel,at91rm9200-rtc
+      - atmel,at91sam9x5-rtc
+      - atmel,sama5d4-rtc
+      - atmel,sama5d2-rtc
+      - microchip,sam9x60-rtc
+
+  reg:
+    maxItems: 1
+
+  interrupts:
+    maxItems: 1
+
+  clocks:
+    maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - interrupts
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    rtc@fffffe00 {
+        compatible = "atmel,at91rm9200-rtc";
+        reg = <0xfffffe00 0x100>;
+        interrupts = <1 4 7>;
+        clocks = <&clk32k>;
+    };
+...
index 8f469d8..2bc3677 100644 (file)
@@ -11,6 +11,7 @@ The driver implements the Generic PM domain bindings described in
 power/power-domain.yaml. It provides the power domains defined in
 - include/dt-bindings/power/mt8173-power.h
 - include/dt-bindings/power/mt6797-power.h
+- include/dt-bindings/power/mt6765-power.h
 - include/dt-bindings/power/mt2701-power.h
 - include/dt-bindings/power/mt2712-power.h
 - include/dt-bindings/power/mt7622-power.h
@@ -19,6 +20,7 @@ Required properties:
 - compatible: Should be one of:
        - "mediatek,mt2701-scpsys"
        - "mediatek,mt2712-scpsys"
+       - "mediatek,mt6765-scpsys"
        - "mediatek,mt6797-scpsys"
        - "mediatek,mt7622-scpsys"
        - "mediatek,mt7623-scpsys", "mediatek,mt2701-scpsys": For MT7623 SoC
@@ -33,6 +35,10 @@ Required properties:
                       enabled before enabling certain power domains.
        Required clocks for MT2701 or MT7623: "mm", "mfg", "ethif"
        Required clocks for MT2712: "mm", "mfg", "venc", "jpgdec", "audio", "vdec"
+       Required clocks for MT6765: MUX: "mm", "mfg"
+                                   CG: "mm-0", "mm-1", "mm-2", "mm-3", "isp-0",
+                                       "isp-1", "cam-0", "cam-1", "cam-2",
+                                       "cam-3","cam-4"
        Required clocks for MT6797: "mm", "mfg", "vdec"
        Required clocks for MT7622 or MT7629: "hif_sel"
        Required clocks for MT7623A: "ethif"
index 411375e..0654380 100644 (file)
@@ -15,13 +15,13 @@ Required properties:
 - clock-frequency : input clock frequency to non FSL_SOC cores
 
 Optional properties:
-- gpios : specifies the gpio pins to be used for chipselects.
+- cs-gpios : specifies the gpio pins to be used for chipselects.
   The gpios will be referred to as reg = <index> in the SPI child nodes.
   If unspecified, a single SPI device without a chip select can be used.
 - fsl,spisel_boot : for the MPC8306 and MPC8309, specifies that the
   SPISEL_BOOT signal is used as chip select for a slave device. Use
   reg = <number of gpios> in the corresponding child node, i.e. 0 if
-  the gpios property is not present.
+  the cs-gpios property is not present.
 
 Example:
        spi@4c0 {
@@ -31,8 +31,8 @@ Example:
                interrupts = <82 0>;
                interrupt-parent = <700>;
                mode = "cpu";
-               gpios = <&gpio 18 1     // device reg=<0>
-                        &gpio 19 1>;   // device reg=<1>
+               cs-gpios = <&gpio 18 1          // device reg=<0>
+                           &gpio 19 1>;        // device reg=<1>
        };
 
 
index 9dff7e5..29159f4 100644 (file)
@@ -11,6 +11,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-r8a774b1" for the r8a774B1 TMU
     - "renesas,tmu-r8a774c0" for the r8a774C0 TMU
     - "renesas,tmu-r8a7778" for the r8a7778 TMU
     - "renesas,tmu-r8a7779" for the r8a7779 TMU
index 7fcd48a..9e67944 100644 (file)
@@ -1034,6 +1034,8 @@ patternProperties:
     description: Variscite Ltd.
   "^via,.*":
     description: VIA Technologies, Inc.
+  "^videostrong,.*":
+    description: Videostrong Technology Co., Ltd.
   "^virtio,.*":
     description: Virtual I/O Device Specification, developed by the OASIS consortium
   "^vishay,.*":
index b935b52..950e4fb 100644 (file)
@@ -6,6 +6,11 @@ Required properties:
        "dlg,da9061-watchdog", "dlg,da9062-watchdog"
        "dlg,da9062-watchdog"
 
+Optional properties:
+- dlg,use-sw-pm: Add this property to disable the watchdog during suspend.
+       Only use this option if you can't use the watchdog automatic suspend
+       function during a suspend (see register CONTROL_B).
+
 Example: DA9062
 
        pmic0: da9062@58 {
index fd380eb..4dd36bd 100644 (file)
@@ -4,22 +4,27 @@ Required properties:
 
 - compatible should contain:
        "mediatek,mt2701-wdt", "mediatek,mt6589-wdt": for MT2701
+       "mediatek,mt2712-wdt", "mediatek,mt6589-wdt": for MT2712
        "mediatek,mt6589-wdt": for MT6589
        "mediatek,mt6797-wdt", "mediatek,mt6589-wdt": for MT6797
        "mediatek,mt7622-wdt", "mediatek,mt6589-wdt": for MT7622
        "mediatek,mt7623-wdt", "mediatek,mt6589-wdt": for MT7623
        "mediatek,mt7629-wdt", "mediatek,mt6589-wdt": for MT7629
+       "mediatek,mt8183-wdt", "mediatek,mt6589-wdt": for MT8183
        "mediatek,mt8516-wdt", "mediatek,mt6589-wdt": for MT8516
 
 - reg : Specifies base physical address and size of the registers.
 
 Optional properties:
 - timeout-sec: contains the watchdog timeout in seconds.
+- #reset-cells: Should be 1.
 
 Example:
 
-wdt: watchdog@10000000 {
-       compatible = "mediatek,mt6589-wdt";
-       reg = <0x10000000 0x18>;
+watchdog: watchdog@10007000 {
+       compatible = "mediatek,mt8183-wdt",
+                    "mediatek,mt6589-wdt";
+       reg = <0 0x10007000 0 0x100>;
        timeout-sec = <10>;
+       #reset-cells = <1>;
 };
index 1095658..67ee369 100644 (file)
@@ -1,4 +1,5 @@
 .. SPDX-License-Identifier: GPL-2.0
+
 How to help improve kernel documentation
 ========================================
 
index aee2f50..5afc0dd 100644 (file)
@@ -1,4 +1,5 @@
 .. SPDX-License-Identifier: GPL-2.0
+
 Documentation subsystem maintainer entry profile
 ================================================
 
index a9a7a3c..e5953e7 100644 (file)
@@ -151,8 +151,8 @@ The details of these operations are:
      Note that callbacks will always be invoked from the DMA
      engines tasklet, never from interrupt context.
 
-  Optional: per descriptor metadata
-  ---------------------------------
+Optional: per descriptor metadata
+---------------------------------
   DMAengine provides two ways for metadata support.
 
   DESC_METADATA_CLIENT
index 4fae046..32b2972 100644 (file)
@@ -24,7 +24,7 @@
     |      parisc: |  ok  |
     |     powerpc: |  ok  |
     |       riscv: | TODO |
-    |        s390: | TODO |
+    |        s390: |  ok  |
     |          sh: | TODO |
     |       sparc: | TODO |
     |          um: | TODO |
similarity index 80%
rename from Documentation/filesystems/fuse.txt
rename to Documentation/filesystems/fuse.rst
index 13af4a4..8e45506 100644 (file)
@@ -1,41 +1,40 @@
+.. SPDX-License-Identifier: GPL-2.0
+==============
+FUSE
+==============
+
 Definitions
-~~~~~~~~~~~
+===========
 
 Userspace filesystem:
-
   A filesystem in which data and metadata are provided by an ordinary
   userspace process.  The filesystem can be accessed normally through
   the kernel interface.
 
 Filesystem daemon:
-
   The process(es) providing the data and metadata of the filesystem.
 
 Non-privileged mount (or user mount):
-
   A userspace filesystem mounted by a non-privileged (non-root) user.
   The filesystem daemon is running with the privileges of the mounting
   user.  NOTE: this is not the same as mounts allowed with the "user"
   option in /etc/fstab, which is not discussed here.
 
 Filesystem connection:
-
   A connection between the filesystem daemon and the kernel.  The
   connection exists until either the daemon dies, or the filesystem is
   umounted.  Note that detaching (or lazy umounting) the filesystem
-  does _not_ break the connection, in this case it will exist until
+  does *not* break the connection, in this case it will exist until
   the last reference to the filesystem is released.
 
 Mount owner:
-
   The user who does the mounting.
 
 User:
-
   The user who is performing filesystem operations.
 
 What is FUSE?
-~~~~~~~~~~~~~
+=============
 
 FUSE is a userspace filesystem framework.  It consists of a kernel
 module (fuse.ko), a userspace library (libfuse.*) and a mount utility
@@ -46,50 +45,41 @@ non-privileged mounts.  This opens up new possibilities for the use of
 filesystems.  A good example is sshfs: a secure network filesystem
 using the sftp protocol.
 
-The userspace library and utilities are available from the FUSE
-homepage:
-
-  http://fuse.sourceforge.net/
+The userspace library and utilities are available from the
+`FUSE homepage: <http://fuse.sourceforge.net/>`_
 
 Filesystem type
-~~~~~~~~~~~~~~~
+===============
 
 The filesystem type given to mount(2) can be one of the following:
 
-'fuse'
-
-  This is the usual way to mount a FUSE filesystem.  The first
-  argument of the mount system call may contain an arbitrary string,
-  which is not interpreted by the kernel.
+    fuse
+      This is the usual way to mount a FUSE filesystem.  The first
+      argument of the mount system call may contain an arbitrary string,
+      which is not interpreted by the kernel.
 
-'fuseblk'
-
-  The filesystem is block device based.  The first argument of the
-  mount system call is interpreted as the name of the device.
+    fuseblk
+      The filesystem is block device based.  The first argument of the
+      mount system call is interpreted as the name of the device.
 
 Mount options
-~~~~~~~~~~~~~
-
-'fd=N'
+=============
 
+fd=N
   The file descriptor to use for communication between the userspace
   filesystem and the kernel.  The file descriptor must have been
   obtained by opening the FUSE device ('/dev/fuse').
 
-'rootmode=M'
-
+rootmode=M
   The file mode of the filesystem's root in octal representation.
 
-'user_id=N'
-
+user_id=N
   The numeric user id of the mount owner.
 
-'group_id=N'
-
+group_id=N
   The numeric group id of the mount owner.
 
-'default_permissions'
-
+default_permissions
   By default FUSE doesn't check file access permissions, the
   filesystem is free to implement its access policy or leave it to
   the underlying file access mechanism (e.g. in case of network
@@ -97,28 +87,25 @@ Mount options
   access based on file mode.  It is usually useful together with the
   'allow_other' mount option.
 
-'allow_other'
-
+allow_other
   This option overrides the security measure restricting file access
   to the user mounting the filesystem.  This option is by default only
   allowed to root, but this restriction can be removed with a
   (userspace) configuration option.
 
-'max_read=N'
-
+max_read=N
   With this option the maximum size of read operations can be set.
   The default is infinite.  Note that the size of read requests is
   limited anyway to 32 pages (which is 128kbyte on i386).
 
-'blksize=N'
-
+blksize=N
   Set the block size for the filesystem.  The default is 512.  This
   option is only valid for 'fuseblk' type mounts.
 
 Control filesystem
-~~~~~~~~~~~~~~~~~~
+==================
 
-There's a control filesystem for FUSE, which can be mounted by:
+There's a control filesystem for FUSE, which can be mounted by::
 
   mount -t fusectl none /sys/fs/fuse/connections
 
@@ -130,53 +117,51 @@ named by a unique number.
 
 For each connection the following files exist within this directory:
 
- 'waiting'
-
-  The number of requests which are waiting to be transferred to
-  userspace or being processed by the filesystem daemon.  If there is
-  no filesystem activity and 'waiting' is non-zero, then the
-  filesystem is hung or deadlocked.
-
- 'abort'
+       waiting
+         The number of requests which are waiting to be transferred to
+         userspace or being processed by the filesystem daemon.  If there is
+         no filesystem activity and 'waiting' is non-zero, then the
+         filesystem is hung or deadlocked.
 
-  Writing anything into this file will abort the filesystem
-  connection.  This means that all waiting requests will be aborted an
-  error returned for all aborted and new requests.
+       abort
+         Writing anything into this file will abort the filesystem
+         connection.  This means that all waiting requests will be aborted an
+         error returned for all aborted and new requests.
 
 Only the owner of the mount may read or write these files.
 
 Interrupting filesystem operations
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+##################################
 
 If a process issuing a FUSE filesystem request is interrupted, the
 following will happen:
 
-  1) If the request is not yet sent to userspace AND the signal is
+   If the request is not yet sent to userspace AND the signal is
      fatal (SIGKILL or unhandled fatal signal), then the request is
      dequeued and returns immediately.
 
-  2) If the request is not yet sent to userspace AND the signal is not
-     fatal, then an 'interrupted' flag is set for the request.  When
+   If the request is not yet sent to userspace AND the signal is not
+     fatal, then an interrupted flag is set for the request.  When
      the request has been successfully transferred to userspace and
      this flag is set, an INTERRUPT request is queued.
 
-  3) If the request is already sent to userspace, then an INTERRUPT
+   If the request is already sent to userspace, then an INTERRUPT
      request is queued.
 
 INTERRUPT requests take precedence over other requests, so the
 userspace filesystem will receive queued INTERRUPTs before any others.
 
 The userspace filesystem may ignore the INTERRUPT requests entirely,
-or may honor them by sending a reply to the _original_ request, with
+or may honor them by sending a reply to the *original* request, with
 the error set to EINTR.
 
 It is also possible that there's a race between processing the
 original request and its INTERRUPT request.  There are two possibilities:
 
-  1) The INTERRUPT request is processed before the original request is
+  1. The INTERRUPT request is processed before the original request is
      processed
 
-  2) The INTERRUPT request is processed after the original request has
+  2. The INTERRUPT request is processed after the original request has
      been answered
 
 If the filesystem cannot find the original request, it should wait for
@@ -186,7 +171,7 @@ should reply to the INTERRUPT request with an EAGAIN error.  In case
 reply will be ignored.
 
 Aborting a filesystem connection
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+================================
 
 It is possible to get into certain situations where the filesystem is
 not responding.  Reasons for this may be:
@@ -216,7 +201,7 @@ the filesystem.  There are several ways to do this:
     powerful method, always works.
 
 How do non-privileged mounts work?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+==================================
 
 Since the mount() system call is a privileged operation, a helper
 program (fusermount) is needed, which is installed setuid root.
@@ -235,15 +220,13 @@ system.  Obvious requirements arising from this are:
     other users' or the super user's processes
 
 How are requirements fulfilled?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+===============================
 
  A) The mount owner could gain elevated privileges by either:
 
-     1) creating a filesystem containing a device file, then opening
-       this device
+    1. creating a filesystem containing a device file, then opening this device
 
-     2) creating a filesystem containing a suid or sgid application,
-       then executing this application
+    2. creating a filesystem containing a suid or sgid application, then executing this application
 
     The solution is not to allow opening device files and ignore
     setuid and setgid bits when executing programs.  To ensure this
@@ -275,16 +258,16 @@ How are requirements fulfilled?
         of other users' processes.
 
          i) It can slow down or indefinitely delay the execution of a
-           filesystem operation creating a DoS against the user or the
-           whole system.  For example a suid application locking a
-           system file, and then accessing a file on the mount owner's
-           filesystem could be stopped, and thus causing the system
-           file to be locked forever.
+            filesystem operation creating a DoS against the user or the
+            whole system.  For example a suid application locking a
+            system file, and then accessing a file on the mount owner's
+            filesystem could be stopped, and thus causing the system
+            file to be locked forever.
 
          ii) It can present files or directories of unlimited length, or
-           directory structures of unlimited depth, possibly causing a
-           system process to eat up diskspace, memory or other
-           resources, again causing DoS.
+             directory structures of unlimited depth, possibly causing a
+             system process to eat up diskspace, memory or other
+             resources, again causing *DoS*.
 
        The solution to this as well as B) is not to allow processes
        to access the filesystem, which could otherwise not be
@@ -294,28 +277,27 @@ How are requirements fulfilled?
        ptrace can be used to check if a process is allowed to access
        the filesystem or not.
 
-       Note that the ptrace check is not strictly necessary to
+       Note that the *ptrace* check is not strictly necessary to
        prevent B/2/i, it is enough to check if mount owner has enough
        privilege to send signal to the process accessing the
-       filesystem, since SIGSTOP can be used to get a similar effect.
+       filesystem, since *SIGSTOP* can be used to get a similar effect.
 
 I think these limitations are unacceptable?
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+===========================================
 
 If a sysadmin trusts the users enough, or can ensure through other
 measures, that system processes will never enter non-privileged
-mounts, it can relax the last limitation with a "user_allow_other"
+mounts, it can relax the last limitation with a 'user_allow_other'
 config option.  If this config option is set, the mounting user can
-add the "allow_other" mount option which disables the check for other
+add the 'allow_other' mount option which disables the check for other
 users' processes.
 
 Kernel - userspace interface
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+============================
 
 The following diagram shows how a filesystem operation (in this
-example unlink) is performed in FUSE.
+example unlink) is performed in FUSE. ::
 
-NOTE: everything in this description is greatly simplified
 
  |  "rm /mnt/fuse/file"               |  FUSE filesystem daemon
  |                                    |
@@ -357,12 +339,13 @@ NOTE: everything in this description is greatly simplified
  |    <fuse_unlink()                  |
  |  <sys_unlink()                     |
 
+.. note:: Everything in the description above is greatly simplified
+
 There are a couple of ways in which to deadlock a FUSE filesystem.
 Since we are talking about unprivileged userspace programs,
 something must be done about these.
 
-Scenario 1 -  Simple deadlock
------------------------------
+**Scenario 1 -  Simple deadlock**::
 
  |  "rm /mnt/fuse/file"               |  FUSE filesystem daemon
  |                                    |
@@ -379,12 +362,12 @@ Scenario 1 -  Simple deadlock
 
 The solution for this is to allow the filesystem to be aborted.
 
-Scenario 2 - Tricky deadlock
-----------------------------
+**Scenario 2 - Tricky deadlock**
+
 
 This one needs a carefully crafted filesystem.  It's a variation on
 the above, only the call back to the filesystem is not explicit,
-but is caused by a pagefault.
+but is caused by a pagefault. ::
 
  |  Kamikaze filesystem thread 1      |  Kamikaze filesystem thread 2
  |                                    |
@@ -410,7 +393,7 @@ but is caused by a pagefault.
  |                                    |           [lock page]
  |                                    |           * DEADLOCK *
 
-Solution is basically the same as above.
+The solution is basically the same as above.
 
 An additional problem is that while the write buffer is being copied
 to the request, the request must not be interrupted/aborted.  This is
index 824a3ec..386eaad 100644 (file)
@@ -47,6 +47,7 @@ Documentation for filesystem implementations.
    :maxdepth: 2
 
    autofs
+   fuse
    overlayfs
    virtiofs
    vfat
index 00ff0cf..87c14bb 100644 (file)
@@ -427,7 +427,6 @@ returned.
        fs_value_is_string,             Value is a string
        fs_value_is_blob,               Value is a binary blob
        fs_value_is_filename,           Value is a filename* + dirfd
-       fs_value_is_filename_empty,     Value is a filename* + dirfd + AT_EMPTY_PATH
        fs_value_is_file,               Value is an open file (file*)
 
      If there is a value, that value is stored in a union in the struct in one
@@ -519,7 +518,6 @@ Parameters are described using structures defined in linux/fs_parser.h.
 There's a core description struct that links everything together:
 
        struct fs_parameter_description {
-               const char      name[16];
                const struct fs_parameter_spec *specs;
                const struct fs_parameter_enum *enums;
        };
@@ -535,19 +533,13 @@ For example:
        };
 
        static const struct fs_parameter_description afs_fs_parameters = {
-               .name           = "kAFS",
                .specs          = afs_param_specs,
                .enums          = afs_param_enums,
        };
 
 The members are as follows:
 
- (1) const char name[16];
-
-     The name to be used in error messages generated by the parse helper
-     functions.
-
- (2) const struct fs_parameter_specification *specs;
+ (1) const struct fs_parameter_specification *specs;
 
      Table of parameter specifications, terminated with a null entry, where the
      entries are of type:
@@ -626,7 +618,7 @@ The members are as follows:
      of arguments to specify the type and the flags for anything that doesn't
      match one of the above macros.
 
- (6) const struct fs_parameter_enum *enums;
+ (2) const struct fs_parameter_enum *enums;
 
      Table of enum value names to integer mappings, terminated with a null
      entry.  This is of type:
diff --git a/Documentation/i2c/busses/i2c-parport-light.rst b/Documentation/i2c/busses/i2c-parport-light.rst
deleted file mode 100644 (file)
index e73af97..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-===============================
-Kernel driver i2c-parport-light
-===============================
-
-Author: Jean Delvare <jdelvare@suse.de>
-
-This driver is a light version of i2c-parport. It doesn't depend
-on the parport driver, and uses direct I/O access instead. This might be
-preferred on embedded systems where wasting memory for the clean but heavy
-parport handling is not an option. The drawback is a reduced portability
-and the impossibility to daisy-chain other parallel port devices.
-
-Please see i2c-parport for documentation.
-
-Module parameters:
-
-* type: type of adapter (see i2c-parport or modinfo)
-
-* base: base I/O address
-  Default is 0x378 which is fairly common for parallel ports, at least on PC.
-
-* irq: optional IRQ
-  This must be passed if you want SMBus alert support, assuming your adapter
-  actually supports this.
index 2a26e25..5e4077b 100644 (file)
@@ -20,7 +20,6 @@ I2C Bus Drivers
    i2c-nforce2
    i2c-nvidia-gpu
    i2c-ocores
-   i2c-parport-light
    i2c-parport
    i2c-pca-isa
    i2c-piix4
index 69c23a3..bdb247f 100644 (file)
@@ -1,27 +1,27 @@
-====================
-I2C Device Interface
-====================
+============================================
+Implementing I2C device drivers in userspace
+============================================
 
-Usually, i2c devices are controlled by a kernel driver. But it is also
+Usually, I2C devices are controlled by a kernel driver. But it is also
 possible to access all devices on an adapter from userspace, through
 the /dev interface. You need to load module i2c-dev for this.
 
-Each registered i2c adapter gets a number, counting from 0. You can
+Each registered I2C adapter gets a number, counting from 0. You can
 examine /sys/class/i2c-dev/ to see what number corresponds to which adapter.
 Alternatively, you can run "i2cdetect -l" to obtain a formatted list of all
-i2c adapters present on your system at a given time. i2cdetect is part of
+I2C adapters present on your system at a given time. i2cdetect is part of
 the i2c-tools package.
 
 I2C device files are character device files with major device number 89
 and a minor device number corresponding to the number assigned as
 explained above. They should be called "i2c-%d" (i2c-0, i2c-1, ...,
-i2c-10, ...). All 256 minor device numbers are reserved for i2c.
+i2c-10, ...). All 256 minor device numbers are reserved for I2C.
 
 
 C example
 =========
 
-So let's say you want to access an i2c adapter from a C program.
+So let's say you want to access an I2C adapter from a C program.
 First, you need to include these two headers::
 
   #include <linux/i2c-dev.h>
@@ -66,7 +66,7 @@ the device supports them. Both are illustrated below::
   /* Using SMBus commands */
   res = i2c_smbus_read_word_data(file, reg);
   if (res < 0) {
-    /* ERROR HANDLING: i2c transaction failed */
+    /* ERROR HANDLING: I2C transaction failed */
   } else {
     /* res contains the read word */
   }
@@ -79,12 +79,12 @@ the device supports them. Both are illustrated below::
   buf[1] = 0x43;
   buf[2] = 0x65;
   if (write(file, buf, 3) != 3) {
-    /* ERROR HANDLING: i2c transaction failed */
+    /* ERROR HANDLING: I2C transaction failed */
   }
 
   /* Using I2C Read, equivalent of i2c_smbus_read_byte(file) */
   if (read(file, buf, 1) != 1) {
-    /* ERROR HANDLING: i2c transaction failed */
+    /* ERROR HANDLING: I2C transaction failed */
   } else {
     /* buf[0] contains the read byte */
   }
@@ -144,7 +144,7 @@ The following IOCTLs are defined:
   If possible, use the provided ``i2c_smbus_*`` methods described below instead
   of issuing direct ioctls.
 
-You can do plain i2c transactions by using read(2) and write(2) calls.
+You can do plain I2C transactions by using read(2) and write(2) calls.
 You do not need to pass the address byte; instead, set it through
 ioctl I2C_SLAVE before you try to access the device.
 
index 2030020..142d52c 100644 (file)
@@ -2,7 +2,7 @@
 Linux I2C and DMA
 =================
 
-Given that i2c is a low-speed bus, over which the majority of messages
+Given that I2C is a low-speed bus, over which the majority of messages
 transferred are small, it is not considered a prime user of DMA access. At this
 time of writing, only 10% of I2C bus master drivers have DMA support
 implemented. And the vast majority of transactions are so small that setting up
index 2f8fcf6..b2092f8 100644 (file)
@@ -1,26 +1,26 @@
-============
-I2C Protocol
-============
+================
+The I2C Protocol
+================
 
-This document describes the i2c protocol. Or will, when it is finished :-)
+This document describes the I2C protocol. Or will, when it is finished :-)
 
 Key to symbols
 ==============
 
 =============== =============================================================
-S     (1 bit) : Start bit
-P     (1 bit) : Stop bit
-Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
-A, NA (1 bit) : Accept and reverse accept bit.
-Addr  (7 bits): I2C 7 bit address. Note that this can be expanded as usual to
+S               Start condition
+P               Stop condition
+Rd/Wr (1 bit)   Read/Write bit. Rd equals 1, Wr equals 0.
+A, NA (1 bit)   Acknowledge (ACK) and Not Acknowledge (NACK) bit
+Addr  (7 bits)  I2C 7 bit address. Note that this can be expanded as usual to
                 get a 10 bit I2C address.
-Comm  (8 bits): Command byte, a data byte which often selects a register on
+Comm  (8 bits)  Command byte, a data byte which often selects a register on
                 the device.
-Data  (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh
+Data  (8 bits)  A plain data byte. Sometimes, I write DataLow, DataHigh
                 for 16 bit data.
-Count (8 bits): A data byte containing the length of a block operation.
+Count (8 bits)  A data byte containing the length of a block operation.
 
-[..]:           Data sent by I2C device, as opposed to data sent by the
+[..]            Data sent by I2C device, as opposed to data sent by the
                 host adapter.
 =============== =============================================================
 
@@ -28,7 +28,7 @@ Count (8 bits): A data byte containing the length of a block operation.
 Simple send transaction
 =======================
 
-This corresponds to i2c_master_send::
+Implemented by i2c_master_send()::
 
   S Addr Wr [A] Data [A] Data [A] ... [A] Data [A] P
 
@@ -36,7 +36,7 @@ This corresponds to i2c_master_send::
 Simple receive transaction
 ==========================
 
-This corresponds to i2c_master_recv::
+Implemented by i2c_master_recv()::
 
   S Addr Rd [A] [Data] A [Data] A ... A [Data] NA P
 
@@ -44,11 +44,11 @@ This corresponds to i2c_master_recv::
 Combined transactions
 =====================
 
-This corresponds to i2c_transfer
+Implemented by i2c_transfer().
 
-They are just like the above transactions, but instead of a stop bit P
-a start bit S is sent and the transaction continues. An example of
-a byte read, followed by a byte write::
+They are just like the above transactions, but instead of a stop
+condition P a start condition S is sent and the transaction continues.
+An example of a byte read, followed by a byte write::
 
   S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P
 
@@ -57,7 +57,7 @@ Modified transactions
 =====================
 
 The following modifications to the I2C protocol can also be generated by
-setting these flags for i2c messages. With the exception of I2C_M_NOSTART, they
+setting these flags for I2C messages. With the exception of I2C_M_NOSTART, they
 are usually only needed to work around device issues:
 
 I2C_M_IGNORE_NAK:
@@ -77,8 +77,9 @@ I2C_M_NOSTART:
       S Addr Rd [A] [Data] NA Data [A] P
 
     If you set the I2C_M_NOSTART variable for the first partial message,
-    we do not generate Addr, but we do generate the startbit S. This will
-    probably confuse all other clients on your bus, so don't try this.
+    we do not generate Addr, but we do generate the start condition S.
+    This will probably confuse all other clients on your bus, so don't
+    try this.
 
     This is often used to gather transmits from multiple data buffers in
     system memory into something that appears as a single transfer to the
index 0c1ae95..7cb5381 100644 (file)
@@ -1,9 +1,9 @@
-============
-I2C topology
-============
+================================
+I2C muxes and complex topologies
+================================
 
-There are a couple of reasons for building more complex i2c topologies
-than a straight-forward i2c bus with one adapter and one or more devices.
+There are a couple of reasons for building more complex I2C topologies
+than a straight-forward I2C bus with one adapter and one or more devices.
 
 1. A mux may be needed on the bus to prevent address collisions.
 
@@ -11,20 +11,20 @@ than a straight-forward i2c bus with one adapter and one or more devices.
    may be needed to determine if it is ok to access the bus.
 
 3. A device (particularly RF tuners) may want to avoid the digital noise
-   from the i2c bus, at least most of the time, and sits behind a gate
+   from the I2C bus, at least most of the time, and sits behind a gate
    that has to be operated before the device can be accessed.
 
 Etc
 ===
 
-These constructs are represented as i2c adapter trees by Linux, where
+These constructs are represented as I2C adapter trees by Linux, where
 each adapter has a parent adapter (except the root adapter) and zero or
 more child adapters. The root adapter is the actual adapter that issues
-i2c transfers, and all adapters with a parent are part of an "i2c-mux"
+I2C transfers, and all adapters with a parent are part of an "i2c-mux"
 object (quoted, since it can also be an arbitrator or a gate).
 
 Depending of the particular mux driver, something happens when there is
-an i2c transfer on one of its child adapters. The mux driver can
+an I2C transfer on one of its child adapters. The mux driver can
 obviously operate a mux, but it can also do arbitration with an external
 bus master or open a gate. The mux driver has two operations for this,
 select and deselect. select is called before the transfer and (the
@@ -34,7 +34,7 @@ optional) deselect is called after the transfer.
 Locking
 =======
 
-There are two variants of locking available to i2c muxes, they can be
+There are two variants of locking available to I2C muxes, they can be
 mux-locked or parent-locked muxes. As is evident from below, it can be
 useful to know if a mux is mux-locked or if it is parent-locked. The
 following list was correct at the time of writing:
@@ -45,7 +45,7 @@ In drivers/i2c/muxes/:
 i2c-arb-gpio-challenge    Parent-locked
 i2c-mux-gpio              Normally parent-locked, mux-locked iff
                           all involved gpio pins are controlled by the
-                          same i2c root adapter that they mux.
+                          same I2C root adapter that they mux.
 i2c-mux-gpmux             Normally parent-locked, mux-locked iff
                           specified in device-tree.
 i2c-mux-ltc4306           Mux-locked
@@ -54,7 +54,7 @@ i2c-mux-pca9541           Parent-locked
 i2c-mux-pca954x           Parent-locked
 i2c-mux-pinctrl           Normally parent-locked, mux-locked iff
                           all involved pinctrl devices are controlled
-                          by the same i2c root adapter that they mux.
+                          by the same I2C root adapter that they mux.
 i2c-mux-reg               Parent-locked
 ======================    =============================================
 
@@ -83,9 +83,9 @@ Mux-locked muxes
 Mux-locked muxes does not lock the entire parent adapter during the
 full select-transfer-deselect transaction, only the muxes on the parent
 adapter are locked. Mux-locked muxes are mostly interesting if the
-select and/or deselect operations must use i2c transfers to complete
+select and/or deselect operations must use I2C transfers to complete
 their tasks. Since the parent adapter is not fully locked during the
-full transaction, unrelated i2c transfers may interleave the different
+full transaction, unrelated I2C transfers may interleave the different
 stages of the transaction. This has the benefit that the mux driver
 may be easier and cleaner to implement, but it has some caveats.
 
@@ -109,14 +109,14 @@ ML2. It is not safe to build arbitrary topologies with two (or more)
 
 ML3. A mux-locked mux cannot be used by a driver for auto-closing
      gates/muxes, i.e. something that closes automatically after a given
-     number (one, in most cases) of i2c transfers. Unrelated i2c transfers
+     number (one, in most cases) of I2C transfers. Unrelated I2C transfers
      may creep in and close prematurely.
 
-ML4. If any non-i2c operation in the mux driver changes the i2c mux state,
+ML4. If any non-I2C operation in the mux driver changes the I2C mux state,
      the driver has to lock the root adapter during that operation.
      Otherwise garbage may appear on the bus as seen from devices
-     behind the mux, when an unrelated i2c transfer is in flight during
-     the non-i2c mux-changing operation.
+     behind the mux, when an unrelated I2C transfer is in flight during
+     the non-I2C mux-changing operation.
 ==== =====================================================================
 
 
@@ -137,14 +137,14 @@ Mux-locked Example
 
 When there is an access to D1, this happens:
 
- 1. Someone issues an i2c-transfer to D1.
+ 1. Someone issues an I2C transfer to D1.
  2. M1 locks muxes on its parent (the root adapter in this case).
  3. M1 calls ->select to ready the mux.
- 4. M1 (presumably) does some i2c-transfers as part of its select.
-    These transfers are normal i2c-transfers that locks the parent
+ 4. M1 (presumably) does some I2C transfers as part of its select.
+    These transfers are normal I2C transfers that locks the parent
     adapter.
- 5. M1 feeds the i2c-transfer from step 1 to its parent adapter as a
-    normal i2c-transfer that locks the parent adapter.
+ 5. M1 feeds the I2C transfer from step 1 to its parent adapter as a
+    normal I2C transfer that locks the parent adapter.
  6. M1 calls ->deselect, if it has one.
  7. Same rules as in step 4, but for ->deselect.
  8. M1 unlocks muxes on its parent.
@@ -159,8 +159,8 @@ Parent-locked muxes
 
 Parent-locked muxes lock the parent adapter during the full select-
 transfer-deselect transaction. The implication is that the mux driver
-has to ensure that any and all i2c transfers through that parent
-adapter during the transaction are unlocked i2c transfers (using e.g.
+has to ensure that any and all I2C transfers through that parent
+adapter during the transaction are unlocked I2C transfers (using e.g.
 __i2c_transfer), or a deadlock will follow. There are a couple of
 caveats.
 
@@ -169,12 +169,12 @@ PL1. If you build a topology with a parent-locked mux being the child
      of another mux, this might break a possible assumption from the
      child mux that the root adapter is unused between its select op
      and the actual transfer (e.g. if the child mux is auto-closing
-     and the parent mux issus i2c-transfers as part of its select).
+     and the parent mux issues I2C transfers as part of its select).
      This is especially the case if the parent mux is mux-locked, but
      it may also happen if the parent mux is parent-locked.
 
 PL2. If select/deselect calls out to other subsystems such as gpio,
-     pinctrl, regmap or iio, it is essential that any i2c transfers
+     pinctrl, regmap or iio, it is essential that any I2C transfers
      caused by these subsystems are unlocked. This can be convoluted to
      accomplish, maybe even impossible if an acceptably clean solution
      is sought.
@@ -197,15 +197,15 @@ Parent-locked Example
 
 When there is an access to D1, this happens:
 
- 1.  Someone issues an i2c-transfer to D1.
+ 1.  Someone issues an I2C transfer to D1.
  2.  M1 locks muxes on its parent (the root adapter in this case).
  3.  M1 locks its parent adapter.
  4.  M1 calls ->select to ready the mux.
- 5.  If M1 does any i2c-transfers (on this root adapter) as part of
-     its select, those transfers must be unlocked i2c-transfers so
+ 5.  If M1 does any I2C transfers (on this root adapter) as part of
+     its select, those transfers must be unlocked I2C transfers so
      that they do not deadlock the root adapter.
- 6.  M1 feeds the i2c-transfer from step 1 to the root adapter as an
-     unlocked i2c-transfer, so that it does not deadlock the parent
+ 6.  M1 feeds the I2C transfer from step 1 to the root adapter as an
+     unlocked I2C transfer, so that it does not deadlock the parent
      adapter.
  7.  M1 calls ->deselect, if it has one.
  8.  Same rules as in step 5, but for ->deselect.
@@ -240,7 +240,7 @@ and specifically when M2 requests its parent to lock, M1 passes
 the buck to the root adapter).
 
 This topology is bad if M2 is an auto-closing mux and M1->select
-issues any unlocked i2c transfers on the root adapter that may leak
+issues any unlocked I2C transfers on the root adapter that may leak
 through and be seen by the M2 adapter, thus closing M2 prematurely.
 
 
@@ -286,14 +286,14 @@ point.
 
 This kind of topology is generally not suitable and should probably
 be avoided. The reason is that M2 probably assumes that there will
-be no i2c transfers during its calls to ->select and ->deselect, and
+be no I2C transfers during its calls to ->select and ->deselect, and
 if there are, any such transfers might appear on the slave side of M2
-as partial i2c transfers, i.e. garbage or worse. This might cause
+as partial I2C transfers, i.e. garbage or worse. This might cause
 device lockups and/or other problems.
 
 The topology is especially troublesome if M2 is an auto-closing
 mux. In that case, any interleaved accesses to D4 might close M2
-prematurely, as might any i2c-transfers part of M1->select.
+prematurely, as might any I2C transfers part of M1->select.
 
 But if M2 is not making the above stated assumption, and if M2 is not
 auto-closing, the topology is fine.
diff --git a/Documentation/i2c/i2c.svg b/Documentation/i2c/i2c.svg
new file mode 100644 (file)
index 0000000..5979405
--- /dev/null
@@ -0,0 +1,1341 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   sodipodi:docname="i2c.svg"
+   inkscape:version="0.92.3 (2405546, 2018-03-11)"
+   version="1.1"
+   id="svg2"
+   viewBox="0 0 813.34215 261.01596"
+   height="73.664505mm"
+   width="229.54323mm">
+  <defs
+     id="defs4">
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8861"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path8859"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker6165"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DotM"
+       inkscape:collect="always">
+      <path
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         id="path6163"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker2713"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DotM">
+      <path
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         id="path2711"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM"
+       style="overflow:visible"
+       inkscape:isstock="true"
+       inkscape:collect="always">
+      <path
+         id="path1795"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker6389"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="Arrow2Mend">
+      <path
+         transform="scale(-0.6)"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         id="path6387"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="TriangleOutM"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4107"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="scale(0.4)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker5333"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5335"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="scale(0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="TriangleOutL"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path5049"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="scale(0.8)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="DotS"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotS"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path9326"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill:#404040;fill-opacity:1;fill-rule:evenodd;stroke:#404040;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.2,0,0,0.2,1.48,0.2)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mstart"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path9283"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path9097"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8935"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path8937"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker8781"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path8783"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Lend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Lend"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4700"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         id="path4502"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)"
+         inkscape:connector-curvature="0" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL-4"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4502-7"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL-4-4"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4502-7-5"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL-7"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4502-5"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4502-2"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL-78"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4502-57"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL-1"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4502-8"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL-9"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4502-75"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="EmptyTriangleOutL"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="EmptyTriangleOutL-78-2"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4502-57-6"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#ffffff;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.8,0,0,0.8,-4.8,0)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3-5"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6-3"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3-5-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6-3-2"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3-5-6-1"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6-3-2-2"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3-5-7"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6-3-0"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3-9"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6-36"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-31"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-9"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3-5-7-5"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6-3-0-4"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3-9-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6-36-5"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mend-3-5-7-3"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4369-6-3-0-5"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-3"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-1"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-3-7"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-1-8"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-3"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-2"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-0"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-5"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-5"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-4"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-7"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-5-9"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-5-3"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-5-4"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-5-5"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-5-4-4"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-5-5-3"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-5-4-4-9"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-5-5-3-2"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-5-4-4-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-5-5-3-8"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-5-4-4-2"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-5-5-3-7"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-3"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-6"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-6-5-4-4-6-5"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-1-5-5-3-8-3"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-27"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-09"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-27-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-09-2"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-27-0"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-09-23"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-9"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-7"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-4-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-7-7"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-4-6-3"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-7-7-5"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-4-6-2"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-7-7-9"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="TriangleOutM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="TriangleOutM-2"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path4107-7"
+         d="M 5.77,0 -2.88,5 V -5 Z"
+         style="fill:#008000;fill-opacity:1;fill-rule:evenodd;stroke:#008000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="scale(0.4)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mstart"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="Arrow2Mstart-9"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9283-3"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="Arrow2Mend"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="marker9095-1-5-4-6-6"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path9097-2-0-7-7-0"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
+         d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+         transform="scale(-0.6)" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-3"
+       style="overflow:visible"
+       inkscape:isstock="true">
+      <path
+         inkscape:connector-curvature="0"
+         id="path1795-7"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker2713-9"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DotM">
+      <path
+         inkscape:connector-curvature="0"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         id="path2711-2" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-2"
+       style="overflow:visible"
+       inkscape:isstock="true"
+       inkscape:collect="always">
+      <path
+         inkscape:connector-curvature="0"
+         id="path1795-8"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker2713-3"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DotM">
+      <path
+         inkscape:connector-curvature="0"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         id="path2711-6" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-1"
+       style="overflow:visible"
+       inkscape:isstock="true"
+       inkscape:collect="always">
+      <path
+         inkscape:connector-curvature="0"
+         id="path1795-2"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker2713-94"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DotM">
+      <path
+         inkscape:connector-curvature="0"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         id="path2711-7" />
+    </marker>
+    <marker
+       inkscape:stockid="DotM"
+       orient="auto"
+       refY="0"
+       refX="0"
+       id="DotM-8"
+       style="overflow:visible"
+       inkscape:isstock="true"
+       inkscape:collect="always">
+      <path
+         inkscape:connector-curvature="0"
+         id="path1795-4"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker2713-36"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DotM">
+      <path
+         inkscape:connector-curvature="0"
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         id="path2711-1" />
+    </marker>
+    <marker
+       inkscape:isstock="true"
+       style="overflow:visible"
+       id="marker6165-5"
+       refX="0"
+       refY="0"
+       orient="auto"
+       inkscape:stockid="DotM">
+      <path
+         transform="matrix(0.4,0,0,0.4,2.96,0.4)"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
+         d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
+         id="path6163-5"
+         inkscape:connector-curvature="0" />
+    </marker>
+  </defs>
+  <sodipodi:namedview
+     showguides="true"
+     inkscape:window-maximized="1"
+     inkscape:window-y="0"
+     inkscape:window-x="0"
+     inkscape:window-height="1015"
+     inkscape:window-width="1920"
+     showgrid="true"
+     inkscape:current-layer="layer1"
+     inkscape:document-units="px"
+     inkscape:cy="214.66765"
+     inkscape:cx="-167.56857"
+     inkscape:zoom="0.70710678"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:snap-to-guides="true"
+     inkscape:snap-grids="true"
+     inkscape:snap-bbox="false"
+     inkscape:object-nodes="true"
+     fit-margin-top="5"
+     fit-margin-left="5"
+     fit-margin-right="5"
+     fit-margin-bottom="5">
+    <inkscape:grid
+       type="xygrid"
+       id="grid4451"
+       originx="-93.377219"
+       originy="-347.2523" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Luca Ceresoli</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:date>2020</dc:date>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Reproduction" />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#Distribution" />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Notice" />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#Attribution" />
+        <cc:permits
+           rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
+        <cc:requires
+           rdf:resource="http://creativecommons.org/ns#ShareAlike" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Livello 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-93.377215,-444.09395)">
+    <rect
+       style="opacity:1;fill:#ffb9b9;fill-opacity:1;stroke:#f00000;stroke-width:2.8125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       id="rect4424-3-2-9-7"
+       width="112.5"
+       height="113.75008"
+       x="112.5"
+       y="471.11221"
+       rx="0"
+       ry="0" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="167.5354"
+       y="521.46259"
+       id="text4349"><tspan
+         sodipodi:role="line"
+         x="167.5354"
+         y="521.46259"
+         style="font-size:25px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle"
+         id="tspan1273">I2C</tspan><tspan
+         sodipodi:role="line"
+         x="167.5354"
+         y="552.71259"
+         style="font-size:25px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle"
+         id="tspan1285">Master</tspan></text>
+    <rect
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;fill:#b9ffb9;fill-opacity:1;fill-rule:nonzero;stroke:#006400;stroke-width:2.8125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="rect4424-3-2-9-7-3-3-5-3"
+       width="112.49998"
+       height="112.50001"
+       x="262.5"
+       y="471.11218"
+       rx="0"
+       ry="0" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968767;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 112.50002,639.86223 c 712.50002,0 712.50002,0 712.50002,0"
+       id="path4655-9-3-65-5-6"
+       inkscape:connector-curvature="0" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="318.59131"
+       y="520.83752"
+       id="text4349-26"><tspan
+         sodipodi:role="line"
+         x="318.59131"
+         y="520.83752"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px"
+         id="tspan1273-8">I2C</tspan><tspan
+         sodipodi:role="line"
+         x="318.59131"
+         y="552.08752"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px"
+         id="tspan1287">Slave</tspan></text>
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968767;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 112.49995,677.36223 c 712.50005,0 712.50005,0 712.50005,0"
+       id="path4655-9-3-65-5-6-2"
+       inkscape:connector-curvature="0" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="861.07312"
+       y="687.03937"
+       id="text4349-7"><tspan
+         sodipodi:role="line"
+         x="861.07312"
+         y="687.03937"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;writing-mode:lr-tb;direction:ltr;text-anchor:middle;stroke-width:1px"
+         id="tspan1285-9">SCL</tspan></text>
+    <flowRoot
+       xml:space="preserve"
+       id="flowRoot1627"
+       style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><flowRegion
+         id="flowRegion1629"><rect
+           id="rect1631"
+           width="220"
+           height="120"
+           x="140"
+           y="-126.29921" /></flowRegion><flowPara
+         id="flowPara1633" /></flowRoot>    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="863.31921"
+       y="648.96735"
+       id="text4349-7-3"><tspan
+         sodipodi:role="line"
+         x="863.31921"
+         y="648.96735"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px"
+         id="tspan1285-9-6">SDA</tspan></text>
+    <rect
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#b9ffb9;fill-opacity:1;fill-rule:nonzero;stroke:#006400;stroke-width:2.8125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="rect4424-3-2-9-7-3-3-5-3-0"
+       width="112.49998"
+       height="112.50002"
+       x="412.5"
+       y="471.11215"
+       rx="0"
+       ry="0" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="468.59131"
+       y="520.83746"
+       id="text4349-26-6"><tspan
+         sodipodi:role="line"
+         x="468.59131"
+         y="520.83746"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px"
+         id="tspan1273-8-2">I2C</tspan><tspan
+         sodipodi:role="line"
+         x="468.59131"
+         y="552.08746"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px"
+         id="tspan1287-6">Slave</tspan></text>
+    <rect
+       style="color:#000000;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#b9ffb9;fill-opacity:1;fill-rule:nonzero;stroke:#006400;stroke-width:2.8125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate"
+       id="rect4424-3-2-9-7-3-3-5-3-1"
+       width="112.49998"
+       height="112.50002"
+       x="562.5"
+       y="471.11215"
+       rx="0"
+       ry="0" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="618.59131"
+       y="520.83746"
+       id="text4349-26-8"><tspan
+         sodipodi:role="line"
+         x="618.59131"
+         y="520.83746"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px"
+         id="tspan1273-8-7">I2C</tspan><tspan
+         sodipodi:role="line"
+         x="618.59131"
+         y="552.08746"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px"
+         id="tspan1287-9">Slave</tspan></text>
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#DotM)"
+       d="m 150,583.61221 v 93.75"
+       id="path4655-9-3-65-5-6-20"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker2713)"
+       d="m 187.5,583.61221 v 56.25"
+       id="path4655-9-3-65-5-6-20-2"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#DotM-2)"
+       d="m 300,583.61221 v 93.75"
+       id="path4655-9-3-65-5-6-20-9"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker2713-9)"
+       d="m 337.5,583.61221 v 56.25"
+       id="path4655-9-3-65-5-6-20-2-7"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#DotM-1)"
+       d="m 450,583.61221 v 93.75"
+       id="path4655-9-3-65-5-6-20-93"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker2713-3)"
+       d="m 487.5,583.61221 v 56.25"
+       id="path4655-9-3-65-5-6-20-2-1"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#DotM-8)"
+       d="m 600,583.61221 v 93.75"
+       id="path4655-9-3-65-5-6-20-5"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker2713-94)"
+       d="m 637.5,583.61221 v 56.25"
+       id="path4655-9-3-65-5-6-20-2-0"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc" />
+    <path
+       style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#marker6165);marker-end:url(#marker6165)"
+       d="m 750,471.11221 v 28.125 l 9.375,9.375 -18.74999,18.75 18.74999,18.75 -18.74999,18.75 18.74999,18.75 -9.375,9.375 v 28.125 0 0 56.25"
+       id="path6135"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccc" />
+    <path
+       style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968743;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-start:url(#marker8861);marker-end:url(#marker6165-5)"
+       d="m 787.49999,471.11221 v 28.125 l 9.375,9.375 -18.74999,18.75 18.74999,18.75 -18.74999,18.75 18.74999,18.75 -9.375,9.375 v 28.125 0 0 18.75001"
+       id="path6135-4"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccccccccccc" />
+    <path
+       style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.99968719;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="m 712.5,471.11221 c 112.49999,0 112.49999,0 112.49999,0"
+       id="path4655-9-3-65-5-6-7"
+       inkscape:connector-curvature="0" />
+    <text
+       xml:space="preserve"
+       style="font-style:normal;font-weight:normal;font-size:12px;line-height:0%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+       x="859.94275"
+       y="480.03558"
+       id="text4349-7-3-6"><tspan
+         sodipodi:role="line"
+         x="859.94275"
+         y="480.03558"
+         style="font-size:25.00000191px;line-height:1.25;font-family:sans-serif;text-align:center;text-anchor:middle;stroke-width:1px"
+         id="tspan1285-9-6-5">V<tspan
+   style="font-size:64.99999762%;baseline-shift:sub"
+   id="tspan9307">DD</tspan></tspan></text>
+  </g>
+</svg>
index a0fbaf6..fee4744 100644 (file)
@@ -4,30 +4,66 @@
 I2C/SMBus Subsystem
 ===================
 
+Introduction
+============
+
 .. toctree::
    :maxdepth: 1
 
+   summary
+   i2c-protocol
+   smbus-protocol
+   instantiating-devices
+   busses/index
+   i2c-topology
+   muxes/i2c-mux-gpio
+
+Writing device drivers
+======================
+
+.. toctree::
+   :maxdepth: 1
+
+   writing-clients
    dev-interface
    dma-considerations
    fault-codes
    functionality
+
+Debugging
+=========
+
+.. toctree::
+   :maxdepth: 1
+
    gpio-fault-injection
-   i2c-protocol
    i2c-stub
-   i2c-topology
-   instantiating-devices
-   old-module-parameters
-   slave-eeprom-backend
+
+Slave I2C
+=========
+
+.. toctree::
+   :maxdepth: 1
+
    slave-interface
-   smbus-protocol
-   summary
+   slave-eeprom-backend
+
+Advanced topics
+===============
+
+.. toctree::
+   :maxdepth: 1
+
    ten-bit-addresses
-   upgrading-clients
-   writing-clients
 
-   muxes/i2c-mux-gpio
+Legacy documentation
+====================
 
-   busses/index
+.. toctree::
+   :maxdepth: 1
+
+   upgrading-clients
+   old-module-parameters
 
 .. only::  subproject and html
 
index 875ebe9..e558e0a 100644 (file)
@@ -9,54 +9,27 @@ reason, the kernel code must instantiate I2C devices explicitly. There are
 several ways to achieve this, depending on the context and requirements.
 
 
-Method 1a: Declare the I2C devices by bus number
-------------------------------------------------
+Method 1: Declare the I2C devices statically
+--------------------------------------------
 
 This method is appropriate when the I2C bus is a system bus as is the case
-for many embedded systems. On such systems, each I2C bus has a number
-which is known in advance. It is thus possible to pre-declare the I2C
-devices which live on this bus. This is done with an array of struct
-i2c_board_info which is registered by calling i2c_register_board_info().
+for many embedded systems. On such systems, each I2C bus has a number which
+is known in advance. It is thus possible to pre-declare the I2C devices
+which live on this bus.
 
-Example (from omap2 h4)::
+This information is provided to the kernel in a different way on different
+architectures: device tree, ACPI or board files.
 
-  static struct i2c_board_info h4_i2c_board_info[] __initdata = {
-       {
-               I2C_BOARD_INFO("isp1301_omap", 0x2d),
-               .irq            = OMAP_GPIO_IRQ(125),
-       },
-       {       /* EEPROM on mainboard */
-               I2C_BOARD_INFO("24c01", 0x52),
-               .platform_data  = &m24c01,
-       },
-       {       /* EEPROM on cpu card */
-               I2C_BOARD_INFO("24c01", 0x57),
-               .platform_data  = &m24c01,
-       },
-  };
-
-  static void __init omap_h4_init(void)
-  {
-       (...)
-       i2c_register_board_info(1, h4_i2c_board_info,
-                       ARRAY_SIZE(h4_i2c_board_info));
-       (...)
-  }
-
-The above code declares 3 devices on I2C bus 1, including their respective
-addresses and custom data needed by their drivers. When the I2C bus in
-question is registered, the I2C devices will be instantiated automatically
-by i2c-core.
+When the I2C bus in question is registered, the I2C devices will be
+instantiated automatically by i2c-core. The devices will be automatically
+unbound and destroyed when the I2C bus they sit on goes away (if ever).
 
-The devices will be automatically unbound and destroyed when the I2C bus
-they sit on goes away (if ever.)
 
+Declare the I2C devices via devicetree
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Method 1b: Declare the I2C devices via devicetree
--------------------------------------------------
-
-This method has the same implications as method 1a. The declaration of I2C
-devices is here done via devicetree as subnodes of the master controller.
+On platforms using devicetree, the declaration of I2C devices is done in
+subnodes of the master controller.
 
 Example::
 
@@ -82,11 +55,49 @@ additional properties which might be needed to set up the device, please refer
 to its devicetree documentation in Documentation/devicetree/bindings/.
 
 
-Method 1c: Declare the I2C devices via ACPI
--------------------------------------------
+Declare the I2C devices via ACPI
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 ACPI can also describe I2C devices. There is special documentation for this
-which is currently located at Documentation/firmware-guide/acpi/enumeration.rst.
+which is currently located at :doc:`../firmware-guide/acpi/enumeration`.
+
+
+Declare the I2C devices in board files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+In many embedded architectures, devicetree has replaced the old hardware
+description based on board files, but the latter are still used in old
+code. Instantiating I2C devices via board files is done with an array of
+struct i2c_board_info which is registered by calling
+i2c_register_board_info().
+
+Example (from omap2 h4)::
+
+  static struct i2c_board_info h4_i2c_board_info[] __initdata = {
+       {
+               I2C_BOARD_INFO("isp1301_omap", 0x2d),
+               .irq            = OMAP_GPIO_IRQ(125),
+       },
+       {       /* EEPROM on mainboard */
+               I2C_BOARD_INFO("24c01", 0x52),
+               .platform_data  = &m24c01,
+       },
+       {       /* EEPROM on cpu card */
+               I2C_BOARD_INFO("24c01", 0x57),
+               .platform_data  = &m24c01,
+       },
+  };
+
+  static void __init omap_h4_init(void)
+  {
+       (...)
+       i2c_register_board_info(1, h4_i2c_board_info,
+                       ARRAY_SIZE(h4_i2c_board_info));
+       (...)
+  }
+
+The above code declares 3 devices on I2C bus 1, including their respective
+addresses and custom data needed by their drivers.
 
 
 Method 2: Instantiate the devices explicitly
@@ -98,7 +109,7 @@ tuner, a video decoder, an audio decoder, etc. usually connected to the
 main chip by the means of an I2C bus. You won't know the number of the I2C
 bus in advance, so the method 1 described above can't be used. Instead,
 you can instantiate your I2C devices explicitly. This is done by filling
-a struct i2c_board_info and calling i2c_new_device().
+a struct i2c_board_info and calling i2c_new_client_device().
 
 Example (from the sfe4001 network driver)::
 
@@ -110,7 +121,7 @@ Example (from the sfe4001 network driver)::
   {
        (...)
        efx->board_info.hwmon_client =
-               i2c_new_device(&efx->i2c_adap, &sfe4001_hwmon_info);
+               i2c_new_client_device(&efx->i2c_adap, &sfe4001_hwmon_info);
 
        (...)
   }
@@ -123,7 +134,7 @@ present or not (for example for an optional feature which is not present
 on cheap variants of a board but you have no way to tell them apart), or
 it may have different addresses from one board to the next (manufacturer
 changing its design without notice). In this case, you can call
-i2c_new_scanned_device() instead of i2c_new_device().
+i2c_new_scanned_device() instead of i2c_new_client_device().
 
 Example (from the nxp OHCI driver)::
 
@@ -152,7 +163,7 @@ simply gives up.
 
 The driver which instantiated the I2C device is responsible for destroying
 it on cleanup. This is done by calling i2c_unregister_device() on the
-pointer that was earlier returned by i2c_new_device() or
+pointer that was earlier returned by i2c_new_client_device() or
 i2c_new_scanned_device().
 
 
@@ -188,7 +199,7 @@ destroyed automatically when the driver which detected them is removed,
 or when the underlying I2C bus is itself destroyed, whichever happens
 first.
 
-Those of you familiar with the i2c subsystem of 2.4 kernels and early 2.6
+Those of you familiar with the I2C subsystem of 2.4 kernels and early 2.6
 kernels will find out that this method 3 is essentially similar to what
 was done there. Two significant differences are:
 
@@ -214,15 +225,15 @@ In general, the kernel should know which I2C devices are connected and
 what addresses they live at. However, in certain cases, it does not, so a
 sysfs interface was added to let the user provide the information. This
 interface is made of 2 attribute files which are created in every I2C bus
-directory: new_device and delete_device. Both files are write only and you
-must write the right parameters to them in order to properly instantiate,
-respectively delete, an I2C device.
+directory: ``new_device`` and ``delete_device``. Both files are write
+only and you must write the right parameters to them in order to properly
+instantiate, respectively delete, an I2C device.
 
-File new_device takes 2 parameters: the name of the I2C device (a string)
-and the address of the I2C device (a number, typically expressed in
-hexadecimal starting with 0x, but can also be expressed in decimal.)
+File ``new_device`` takes 2 parameters: the name of the I2C device (a
+string) and the address of the I2C device (a number, typically expressed
+in hexadecimal starting with 0x, but can also be expressed in decimal.)
 
-File delete_device takes a single parameter: the address of the I2C
+File ``delete_device`` takes a single parameter: the address of the I2C
 device. As no two devices can live at the same address on a given I2C
 segment, the address is sufficient to uniquely identify the device to be
 deleted.
index a193951..38e5582 100644 (file)
@@ -1,19 +1,24 @@
-=================================================
-I2C device driver binding control from user-space
-=================================================
+================================================================
+I2C device driver binding control from user-space in old kernels
+================================================================
 
-Up to kernel 2.6.32, many i2c drivers used helper macros provided by
+.. NOTE::
+   Note: this section is only relevant if you are handling some old code
+   found in kernel 2.6. If you work with more recent kernels, you can
+   safely skip this section.
+
+Up to kernel 2.6.32, many I2C drivers used helper macros provided by
 <linux/i2c.h> which created standard module parameters to let the user
-control how the driver would probe i2c buses and attach to devices. These
-parameters were known as "probe" (to let the driver probe for an extra
-address), "force" (to forcibly attach the driver to a given device) and
-"ignore" (to prevent a driver from probing a given address).
+control how the driver would probe I2C buses and attach to devices. These
+parameters were known as ``probe`` (to let the driver probe for an extra
+address), ``force`` (to forcibly attach the driver to a given device) and
+``ignore`` (to prevent a driver from probing a given address).
 
-With the conversion of the i2c subsystem to the standard device driver
+With the conversion of the I2C subsystem to the standard device driver
 binding model, it became clear that these per-module parameters were no
 longer needed, and that a centralized implementation was possible. The new,
-sysfs-based interface is described in the documentation file
-"instantiating-devices", section "Method 4: Instantiate from user-space".
+sysfs-based interface is described in :doc:`instantiating-devices`, section
+"Method 4: Instantiate from user-space".
 
 Below is a mapping from the old module parameters to the new interface.
 
@@ -42,8 +47,8 @@ New method (sysfs interface)::
   # echo dummy 0x2f > /sys/bus/i2c/devices/i2c-1/new_device
   # modprobe <driver>
 
-Of course, it is important to instantiate the "dummy" device before loading
+Of course, it is important to instantiate the ``dummy`` device before loading
 the driver. The dummy device will be handled by i2c-core itself, preventing
 other drivers from binding to it later on. If there is a real device at the
 problematic address, and you want another driver to bind to it, then simply
-pass the name of the device in question instead of "dummy".
+pass the name of the device in question instead of ``dummy``.
index c769bd6..82ea3e1 100644 (file)
@@ -59,7 +59,7 @@ The bus driver sends an event to the backend using the following function::
 
        ret = i2c_slave_event(client, event, &val)
 
-'client' describes the i2c slave device. 'event' is one of the special event
+'client' describes the I2C slave device. 'event' is one of the special event
 types described hereafter. 'val' holds an u8 value for the data byte to be
 read/written and is thus bidirectional. The pointer to val must always be
 provided even if val is not used for an event, i.e. don't use NULL here. 'ret'
@@ -143,7 +143,7 @@ Bus driver support
 If you want to add slave support to the bus driver:
 
 * implement calls to register/unregister the slave and add those to the
-  struct i2c_algorithm. When registering, you probably need to set the i2c
+  struct i2c_algorithm. When registering, you probably need to set the I2C
   slave address and enable slave specific interrupts. If you use runtime pm, you
   should use pm_runtime_get_sync() because your device usually needs to be
   powered on always to be able to detect its slave address. When unregistering,
index e30eb1d..c122ed2 100644 (file)
@@ -1,6 +1,6 @@
-======================
-SMBus Protocol Summary
-======================
+==================
+The SMBus Protocol
+==================
 
 The following is a summary of the SMBus protocol. It applies to
 all revisions of the protocol (1.0, 1.1, and 2.0).
@@ -27,27 +27,27 @@ a different protocol operation entirely.
 Each transaction type corresponds to a functionality flag. Before calling a
 transaction function, a device driver should always check (just once) for
 the corresponding functionality flag to ensure that the underlying I2C
-adapter supports the transaction in question. See
-<file:Documentation/i2c/functionality.rst> for the details.
+adapter supports the transaction in question. See :doc:`functionality` for
+the details.
 
 
 Key to symbols
 ==============
 
 =============== =============================================================
-S     (1 bit) : Start bit
-P     (1 bit) : Stop bit
-Rd/Wr (1 bit) : Read/Write bit. Rd equals 1, Wr equals 0.
-A, NA (1 bit) : Accept and reverse accept bit.
-Addr  (7 bits): I2C 7 bit address. Note that this can be expanded as usual to
+S               Start condition
+P               Stop condition
+Rd/Wr (1 bit)   Read/Write bit. Rd equals 1, Wr equals 0.
+A, NA (1 bit)   Acknowledge (ACK) and Not Acknowledge (NACK) bit
+Addr  (7 bits)  I2C 7 bit address. Note that this can be expanded as usual to
                 get a 10 bit I2C address.
-Comm  (8 bits): Command byte, a data byte which often selects a register on
+Comm  (8 bits)  Command byte, a data byte which often selects a register on
                 the device.
-Data  (8 bits): A plain data byte. Sometimes, I write DataLow, DataHigh
+Data  (8 bits)  A plain data byte. Sometimes, I write DataLow, DataHigh
                 for 16 bit data.
-Count (8 bits): A data byte containing the length of a block operation.
+Count (8 bits)  A data byte containing the length of a block operation.
 
-[..]:           Data sent by I2C device, as opposed to data sent by the host
+[..]            Data sent by I2C device, as opposed to data sent by the host
                 adapter.
 =============== =============================================================
 
@@ -62,8 +62,10 @@ This sends a single bit to the device, at the place of the Rd/Wr bit::
 Functionality flag: I2C_FUNC_SMBUS_QUICK
 
 
-SMBus Receive Byte:  i2c_smbus_read_byte()
-==========================================
+SMBus Receive Byte
+==================
+
+Implemented by i2c_smbus_read_byte()
 
 This reads a single byte from a device, without specifying a device
 register. Some devices are so simple that this interface is enough; for
@@ -75,8 +77,10 @@ the previous SMBus command::
 Functionality flag: I2C_FUNC_SMBUS_READ_BYTE
 
 
-SMBus Send Byte:  i2c_smbus_write_byte()
-========================================
+SMBus Send Byte
+===============
+
+Implemented by i2c_smbus_write_byte()
 
 This operation is the reverse of Receive Byte: it sends a single byte
 to a device.  See Receive Byte for more information.
@@ -88,8 +92,10 @@ to a device.  See Receive Byte for more information.
 Functionality flag: I2C_FUNC_SMBUS_WRITE_BYTE
 
 
-SMBus Read Byte:  i2c_smbus_read_byte_data()
-============================================
+SMBus Read Byte
+===============
+
+Implemented by i2c_smbus_read_byte_data()
 
 This reads a single byte from a device, from a designated register.
 The register is specified through the Comm byte::
@@ -99,8 +105,10 @@ The register is specified through the Comm byte::
 Functionality flag: I2C_FUNC_SMBUS_READ_BYTE_DATA
 
 
-SMBus Read Word:  i2c_smbus_read_word_data()
-============================================
+SMBus Read Word
+===============
+
+Implemented by i2c_smbus_read_word_data()
 
 This operation is very like Read Byte; again, data is read from a
 device, from a designated register that is specified through the Comm
@@ -110,13 +118,15 @@ byte. But this time, the data is a complete word (16 bits)::
 
 Functionality flag: I2C_FUNC_SMBUS_READ_WORD_DATA
 
-Note the convenience function i2c_smbus_read_word_swapped is
+Note the convenience function i2c_smbus_read_word_swapped() is
 available for reads where the two data bytes are the other way
 around (not SMBus compliant, but very popular.)
 
 
-SMBus Write Byte:  i2c_smbus_write_byte_data()
-==============================================
+SMBus Write Byte
+================
+
+Implemented by i2c_smbus_write_byte_data()
 
 This writes a single byte to a device, to a designated register. The
 register is specified through the Comm byte. This is the opposite of
@@ -129,24 +139,26 @@ the Read Byte operation.
 Functionality flag: I2C_FUNC_SMBUS_WRITE_BYTE_DATA
 
 
-SMBus Write Word:  i2c_smbus_write_word_data()
-==============================================
+SMBus Write Word
+================
+
+Implemented by i2c_smbus_write_word_data()
 
 This is the opposite of the Read Word operation. 16 bits
-of data is written to a device, to the designated register that is
-specified through the Comm byte.::
+of data are written to a device, to the designated register that is
+specified through the Comm byte::
 
   S Addr Wr [A] Comm [A] DataLow [A] DataHigh [A] P
 
 Functionality flag: I2C_FUNC_SMBUS_WRITE_WORD_DATA
 
-Note the convenience function i2c_smbus_write_word_swapped is
+Note the convenience function i2c_smbus_write_word_swapped() is
 available for writes where the two data bytes are the other way
 around (not SMBus compliant, but very popular.)
 
 
-SMBus Process Call:
-===================
+SMBus Process Call
+==================
 
 This command selects a device register (through the Comm byte), sends
 16 bits of data to it, and reads 16 bits of data in return::
@@ -157,8 +169,10 @@ This command selects a device register (through the Comm byte), sends
 Functionality flag: I2C_FUNC_SMBUS_PROC_CALL
 
 
-SMBus Block Read:  i2c_smbus_read_block_data()
-==============================================
+SMBus Block Read
+================
+
+Implemented by i2c_smbus_read_block_data()
 
 This command reads a block of up to 32 bytes from a device, from a
 designated register that is specified through the Comm byte. The amount
@@ -172,8 +186,10 @@ of data is specified by the device in the Count byte.
 Functionality flag: I2C_FUNC_SMBUS_READ_BLOCK_DATA
 
 
-SMBus Block Write:  i2c_smbus_write_block_data()
-================================================
+SMBus Block Write
+=================
+
+Implemented by i2c_smbus_write_block_data()
 
 The opposite of the Block Read command, this writes up to 32 bytes to
 a device, to a designated register that is specified through the
@@ -266,16 +282,19 @@ This is implemented the following way in the Linux kernel:
 I2C Block Transactions
 ======================
 
-The following I2C block transactions are supported by the
-SMBus layer and are described here for completeness.
-They are *NOT* defined by the SMBus specification.
+The following I2C block transactions are similar to the SMBus Block Read
+and Write operations, except these do not have a Count byte. They are
+supported by the SMBus layer and are described here for completeness, but
+they are *NOT* defined by the SMBus specification.
 
 I2C block transactions do not limit the number of bytes transferred
 but the SMBus layer places a limit of 32 bytes.
 
 
-I2C Block Read:  i2c_smbus_read_i2c_block_data()
-================================================
+I2C Block Read
+==============
+
+Implemented by i2c_smbus_read_i2c_block_data()
 
 This command reads a block of bytes from a device, from a
 designated register that is specified through the Comm byte::
@@ -286,8 +305,10 @@ designated register that is specified through the Comm byte::
 Functionality flag: I2C_FUNC_SMBUS_READ_I2C_BLOCK
 
 
-I2C Block Write:  i2c_smbus_write_i2c_block_data()
-==================================================
+I2C Block Write
+===============
+
+Implemented by i2c_smbus_write_i2c_block_data()
 
 The opposite of the Block Read command, this writes bytes to
 a device, to a designated register that is specified through the
index 3a24eac..ce72300 100644 (file)
@@ -1,13 +1,19 @@
-=============
-I2C and SMBus
-=============
-
-I2C (pronounce: I squared C) is a protocol developed by Philips. It is a
-slow two-wire protocol (variable speed, up to 400 kHz), with a high speed
-extension (3.4 MHz).  It provides an inexpensive bus for connecting many
-types of devices with infrequent or low bandwidth communications needs.
-I2C is widely used with embedded systems.  Some systems use variants that
-don't meet branding requirements, and so are not advertised as being I2C.
+=============================
+Introduction to I2C and SMBus
+=============================
+
+I²C (pronounce: I squared C and written I2C in the kernel documentation) is
+a protocol developed by Philips. It is a slow two-wire protocol (variable
+speed, up to 400 kHz), with a high speed extension (3.4 MHz).  It provides
+an inexpensive bus for connecting many types of devices with infrequent or
+low bandwidth communications needs.  I2C is widely used with embedded
+systems.  Some systems use variants that don't meet branding requirements,
+and so are not advertised as being I2C but come under different names,
+e.g. TWI (Two Wire Interface), IIC.
+
+The official I2C specification is the `"I2C-bus specification and user
+manual" (UM10204) <https://www.nxp.com/docs/en/user-guide/UM10204.pdf>`_
+published by NXP Semiconductors.
 
 SMBus (System Management Bus) is based on the I2C protocol, and is mostly
 a subset of I2C protocols and signaling.  Many I2C devices will work on an
@@ -25,21 +31,29 @@ implement all the common SMBus protocol semantics or messages.
 Terminology
 ===========
 
-When we talk about I2C, we use the following terms::
+Using the terminology from the official documentation, the I2C bus connects
+one or more *master* chips and one or more *slave* chips.
+
+.. kernel-figure::  i2c.svg
+   :alt:    Simple I2C bus with one master and 3 slaves
+
+   Simple I2C bus
 
-  Bus    -> Algorithm
-            Adapter
-  Device -> Driver
-            Client
+A **master** chip is a node that starts communications with slaves. In the
+Linux kernel implementation it is called an **adapter** or bus. Adapter
+drivers are in the ``drivers/i2c/busses/`` subdirectory.
 
-An Algorithm driver contains general code that can be used for a whole class
-of I2C adapters. Each specific adapter driver either depends on one algorithm
-driver, or includes its own implementation.
+An **algorithm** contains general code that can be used to implement a
+whole class of I2C adapters. Each specific adapter driver either depends on
+an algorithm driver in the ``drivers/i2c/algos/`` subdirectory, or includes
+its own implementation.
 
-A Driver driver (yes, this sounds ridiculous, sorry) contains the general
-code to access some type of device. Each detected device gets its own
-data in the Client structure. Usually, Driver and Client are more closely
-integrated than Algorithm and Adapter.
+A **slave** chip is a node that responds to communications when addressed
+by the master. In Linux it is called a **client**. Client drivers are kept
+in a directory specific to the feature they provide, for example
+``drivers/media/gpio/`` for GPIO expanders and ``drivers/media/i2c/`` for
+video-related chips.
 
-For a given configuration, you will need a driver for your I2C bus, and
-drivers for your I2C devices (usually one driver for each device).
+For the example configuration in figure, you will need a driver for your
+I2C adapter, and drivers for your I2C devices (usually one driver for each
+device).
index ced309b..978cc82 100644 (file)
@@ -1,6 +1,6 @@
-===================
-Writing I2C Clients
-===================
+===============================
+Implementing I2C device drivers
+===============================
 
 This is a small guide for those who want to write kernel drivers for I2C
 or SMBus devices, using Linux as the protocol host/master (not slave).
@@ -95,7 +95,7 @@ to gather information from the client, or write new information to the
 client.
 
 I have found it useful to define foo_read and foo_write functions for this.
-For some cases, it will be easier to call the i2c functions directly,
+For some cases, it will be easier to call the I2C functions directly,
 but many chips have some kind of register-value idea that can easily
 be encapsulated.
 
@@ -175,8 +175,8 @@ Device Creation
 If you know for a fact that an I2C device is connected to a given I2C bus,
 you can instantiate that device by simply filling an i2c_board_info
 structure with the device address and driver name, and calling
-i2c_new_device().  This will create the device, then the driver core will
-take care of finding the right driver and will call its probe() method.
+i2c_new_client_device().  This will create the device, then the driver core
+will take care of finding the right driver and will call its probe() method.
 If a driver supports different device types, you can specify the type you
 want using the type field.  You can also specify an IRQ and platform data
 if needed.
@@ -186,14 +186,14 @@ don't know the exact address it uses.  This happens on TV adapters for
 example, where the same driver supports dozens of slightly different
 models, and I2C device addresses change from one model to the next.  In
 that case, you can use the i2c_new_scanned_device() variant, which is
-similar to i2c_new_device(), except that it takes an additional list of
-possible I2C addresses to probe.  A device is created for the first
+similar to i2c_new_client_device(), except that it takes an additional list
+of possible I2C addresses to probe.  A device is created for the first
 responsive address in the list.  If you expect more than one device to be
 present in the address range, simply call i2c_new_scanned_device() that
 many times.
 
-The call to i2c_new_device() or i2c_new_scanned_device() typically happens
-in the I2C bus driver. You may want to save the returned i2c_client
+The call to i2c_new_client_device() or i2c_new_scanned_device() typically
+happens in the I2C bus driver. You may want to save the returned i2c_client
 reference for later use.
 
 
@@ -236,11 +236,11 @@ possible.
 Device Deletion
 ---------------
 
-Each I2C device which has been created using i2c_new_device() or
-i2c_new_scanned_device() can be unregistered by calling
+Each I2C device which has been created using i2c_new_client_device()
+or i2c_new_scanned_device() can be unregistered by calling
 i2c_unregister_device().  If you don't call it explicitly, it will be
-called automatically before the underlying I2C bus itself is removed, as a
-device can't survive its parent in the device driver model.
+called automatically before the underlying I2C bus itself is removed,
+as a device can't survive its parent in the device driver model.
 
 
 Initializing the driver
@@ -344,7 +344,7 @@ Plain I2C communication
        int i2c_master_recv(struct i2c_client *client, char *buf, int count);
 
 These routines read and write some bytes from/to a client. The client
-contains the i2c address, so you do not have to include it. The second
+contains the I2C address, so you do not have to include it. The second
 parameter contains the bytes to read/write, the third the number of bytes
 to read/write (must be less than the length of the buffer, also should be
 less than 64k since msg.len is u16.) Returned is the actual number of bytes
@@ -357,9 +357,9 @@ read/written.
 
 This sends a series of messages. Each message can be a read or write,
 and they can be mixed in any way. The transactions are combined: no
-stop bit is sent between transaction. The i2c_msg structure contains
-for each message the client address, the number of bytes of the message
-and the message data itself.
+stop condition is issued between transaction. The i2c_msg structure
+contains for each message the client address, the number of bytes of the
+message and the message data itself.
 
 You can read the file ``i2c-protocol`` for more information about the
 actual I2C protocol.
index 66e3792..bec96f7 100644 (file)
@@ -25,9 +25,9 @@ worry about UP vs SMP issues: the spinlocks work correctly under both.
 
      Documentation/memory-barriers.txt
 
-       (5) LOCK operations.
+       (5) ACQUIRE operations.
 
-       (6) UNLOCK operations.
+       (6) RELEASE operations.
 
 The above is usually pretty simple (you usually need and want only one
 spinlock for most things - using more than one spinlock can make things a
index ec3b586..7146da0 100644 (file)
@@ -1868,12 +1868,16 @@ There are some more advanced barrier functions:
  (*) smp_mb__before_atomic();
  (*) smp_mb__after_atomic();
 
-     These are for use with atomic (such as add, subtract, increment and
-     decrement) functions that don't return a value, especially when used for
-     reference counting.  These functions do not imply memory barriers.
-
-     These are also used for atomic bitop functions that do not return a
-     value (such as set_bit and clear_bit).
+     These are for use with atomic RMW functions that do not imply memory
+     barriers, but where the code needs a memory barrier. Examples for atomic
+     RMW functions that do not imply are memory barrier are e.g. add,
+     subtract, (failed) conditional operations, _relaxed functions,
+     but not atomic_read or atomic_set. A common example where a memory
+     barrier may be required is when atomic ops are used for reference
+     counting.
+
+     These are also used for atomic RMW bitop functions that do not imply a
+     memory barrier (such as set_bit and clear_bit).
 
      As an example, consider a piece of code that marks an object as being dead
      and then decrements the object's reference count:
index ca2136c..0bf32d1 100644 (file)
@@ -76,7 +76,7 @@ flowtable and add one rule to your forward chain.
 
         table inet x {
                flowtable f {
-                       hook ingress priority 0 devices = { eth0, eth1 };
+                       hook ingress priority 0; devices = { eth0, eth1 };
                }
                 chain y {
                         type filter hook forward priority 0; policy accept;
diff --git a/Documentation/power/interface.rst b/Documentation/power/interface.rst
deleted file mode 100644 (file)
index 8d270ed..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-===========================================
-Power Management Interface for System Sleep
-===========================================
-
-Copyright (c) 2016 Intel Corp., Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-
-The power management subsystem provides userspace with a unified sysfs interface
-for system sleep regardless of the underlying system architecture or platform.
-The interface is located in the /sys/power/ directory (assuming that sysfs is
-mounted at /sys).
-
-/sys/power/state is the system sleep state control file.
-
-Reading from it returns a list of supported sleep states, encoded as:
-
-- 'freeze' (Suspend-to-Idle)
-- 'standby' (Power-On Suspend)
-- 'mem' (Suspend-to-RAM)
-- 'disk' (Suspend-to-Disk)
-
-Suspend-to-Idle is always supported.  Suspend-to-Disk is always supported
-too as long the kernel has been configured to support hibernation at all
-(ie. CONFIG_HIBERNATION is set in the kernel configuration file).  Support
-for Suspend-to-RAM and Power-On Suspend depends on the capabilities of the
-platform.
-
-If one of the strings listed in /sys/power/state is written to it, the system
-will attempt to transition into the corresponding sleep state.  Refer to
-Documentation/admin-guide/pm/sleep-states.rst for a description of each of
-those states.
-
-/sys/power/disk controls the operating mode of hibernation (Suspend-to-Disk).
-Specifically, it tells the kernel what to do after creating a hibernation image.
-
-Reading from it returns a list of supported options encoded as:
-
-- 'platform' (put the system into sleep using a platform-provided method)
-- 'shutdown' (shut the system down)
-- 'reboot' (reboot the system)
-- 'suspend' (trigger a Suspend-to-RAM transition)
-- 'test_resume' (resume-after-hibernation test mode)
-
-The currently selected option is printed in square brackets.
-
-The 'platform' option is only available if the platform provides a special
-mechanism to put the system to sleep after creating a hibernation image (ACPI
-does that, for example).  The 'suspend' option is available if Suspend-to-RAM
-is supported.  Refer to Documentation/power/basic-pm-debugging.rst for the
-description of the 'test_resume' option.
-
-To select an option, write the string representing it to /sys/power/disk.
-
-/sys/power/image_size controls the size of hibernation images.
-
-It can be written a string representing a non-negative integer that will be
-used as a best-effort upper limit of the image size, in bytes.  The hibernation
-core will do its best to ensure that the image size will not exceed that number.
-However, if that turns out to be impossible to achieve, a hibernation image will
-still be created and its size will be as small as possible.  In particular,
-writing '0' to this file will enforce hibernation images to be as small as
-possible.
-
-Reading from this file returns the current image size limit, which is set to
-around 2/5 of available RAM by default.
-
-/sys/power/pm_trace controls the PM trace mechanism saving the last suspend
-or resume event point in the RTC across reboots.
-
-It helps to debug hard lockups or reboots due to device driver failures that
-occur during system suspend or resume (which is more common) more effectively.
-
-If /sys/power/pm_trace contains '1', the fingerprint of each suspend/resume
-event point in turn will be stored in the RTC memory (overwriting the actual
-RTC information), so it will survive a system crash if one occurs right after
-storing it and it can be used later to identify the driver that caused the crash
-to happen (see Documentation/power/s2ram.rst for more information).
-
-Initially it contains '0' which may be changed to '1' by writing a string
-representing a nonzero integer into it.
diff --git a/Documentation/powerpc/imc.rst b/Documentation/powerpc/imc.rst
new file mode 100644 (file)
index 0000000..633bcee
--- /dev/null
@@ -0,0 +1,199 @@
+.. SPDX-License-Identifier: GPL-2.0
+.. _imc:
+
+===================================
+IMC (In-Memory Collection Counters)
+===================================
+
+Anju T Sudhakar, 10 May 2019
+
+.. contents::
+    :depth: 3
+
+
+Basic overview
+==============
+
+IMC (In-Memory collection counters) is a hardware monitoring facility that
+collects large numbers of hardware performance events at Nest level (these are
+on-chip but off-core), Core level and Thread level.
+
+The Nest PMU counters are handled by a Nest IMC microcode which runs in the OCC
+(On-Chip Controller) complex. The microcode collects the counter data and moves
+the nest IMC counter data to memory.
+
+The Core and Thread IMC PMU counters are handled in the core. Core level PMU
+counters give us the IMC counters' data per core and thread level PMU counters
+give us the IMC counters' data per CPU thread.
+
+OPAL obtains the IMC PMU and supported events information from the IMC Catalog
+and passes on to the kernel via the device tree. The event's information
+contains:
+
+- Event name
+- Event Offset
+- Event description
+
+and possibly also:
+
+- Event scale
+- Event unit
+
+Some PMUs may have a common scale and unit values for all their supported
+events. For those cases, the scale and unit properties for those events must be
+inherited from the PMU.
+
+The event offset in the memory is where the counter data gets accumulated.
+
+IMC catalog is available at:
+       https://github.com/open-power/ima-catalog
+
+The kernel discovers the IMC counters information in the device tree at the
+`imc-counters` device node which has a compatible field
+`ibm,opal-in-memory-counters`. From the device tree, the kernel parses the PMUs
+and their event's information and register the PMU and its attributes in the
+kernel.
+
+IMC example usage
+=================
+
+.. code-block:: sh
+
+  # perf list
+  [...]
+  nest_mcs01/PM_MCS01_64B_RD_DISP_PORT01/            [Kernel PMU event]
+  nest_mcs01/PM_MCS01_64B_RD_DISP_PORT23/            [Kernel PMU event]
+  [...]
+  core_imc/CPM_0THRD_NON_IDLE_PCYC/                  [Kernel PMU event]
+  core_imc/CPM_1THRD_NON_IDLE_INST/                  [Kernel PMU event]
+  [...]
+  thread_imc/CPM_0THRD_NON_IDLE_PCYC/                [Kernel PMU event]
+  thread_imc/CPM_1THRD_NON_IDLE_INST/                [Kernel PMU event]
+
+To see per chip data for nest_mcs0/PM_MCS_DOWN_128B_DATA_XFER_MC0/:
+
+.. code-block:: sh
+
+  # ./perf stat -e "nest_mcs01/PM_MCS01_64B_WR_DISP_PORT01/" -a --per-socket
+
+To see non-idle instructions for core 0:
+
+.. code-block:: sh
+
+  # ./perf stat -e "core_imc/CPM_NON_IDLE_INST/" -C 0 -I 1000
+
+To see non-idle instructions for a "make":
+
+.. code-block:: sh
+
+  # ./perf stat -e "thread_imc/CPM_NON_IDLE_PCYC/" make
+
+
+IMC Trace-mode
+===============
+
+POWER9 supports two modes for IMC which are the Accumulation mode and Trace
+mode. In Accumulation mode, event counts are accumulated in system Memory.
+Hypervisor then reads the posted counts periodically or when requested. In IMC
+Trace mode, the 64 bit trace SCOM value is initialized with the event
+information. The CPMCxSEL and CPMC_LOAD in the trace SCOM, specifies the event
+to be monitored and the sampling duration. On each overflow in the CPMCxSEL,
+hardware snapshots the program counter along with event counts and writes into
+memory pointed by LDBAR.
+
+LDBAR is a 64 bit special purpose per thread register, it has bits to indicate
+whether hardware is configured for accumulation or trace mode.
+
+LDBAR Register Layout
+---------------------
+
+  +-------+----------------------+
+  | 0     | Enable/Disable       |
+  +-------+----------------------+
+  | 1     | 0: Accumulation Mode |
+  |       +----------------------+
+  |       | 1: Trace Mode        |
+  +-------+----------------------+
+  | 2:3   | Reserved             |
+  +-------+----------------------+
+  | 4-6   | PB scope             |
+  +-------+----------------------+
+  | 7     | Reserved             |
+  +-------+----------------------+
+  | 8:50  | Counter Address      |
+  +-------+----------------------+
+  | 51:63 | Reserved             |
+  +-------+----------------------+
+
+TRACE_IMC_SCOM bit representation
+---------------------------------
+
+  +-------+------------+
+  | 0:1   | SAMPSEL    |
+  +-------+------------+
+  | 2:33  | CPMC_LOAD  |
+  +-------+------------+
+  | 34:40 | CPMC1SEL   |
+  +-------+------------+
+  | 41:47 | CPMC2SEL   |
+  +-------+------------+
+  | 48:50 | BUFFERSIZE |
+  +-------+------------+
+  | 51:63 | RESERVED   |
+  +-------+------------+
+
+CPMC_LOAD contains the sampling duration. SAMPSEL and CPMCxSEL determines the
+event to count. BUFFERSIZE indicates the memory range. On each overflow,
+hardware snapshots the program counter along with event counts and updates the
+memory and reloads the CMPC_LOAD value for the next sampling duration. IMC
+hardware does not support exceptions, so it quietly wraps around if memory
+buffer reaches the end.
+
+*Currently the event monitored for trace-mode is fixed as cycle.*
+
+Trace IMC example usage
+=======================
+
+.. code-block:: sh
+
+  # perf list
+  [....]
+  trace_imc/trace_cycles/                            [Kernel PMU event]
+
+To record an application/process with trace-imc event:
+
+.. code-block:: sh
+
+  # perf record -e trace_imc/trace_cycles/ yes > /dev/null
+  [ perf record: Woken up 1 times to write data ]
+  [ perf record: Captured and wrote 0.012 MB perf.data (21 samples) ]
+
+The `perf.data` generated, can be read using perf report.
+
+Benefits of using IMC trace-mode
+================================
+
+PMI (Performance Monitoring Interrupts) interrupt handling is avoided, since IMC
+trace mode snapshots the program counter and updates to the memory. And this
+also provide a way for the operating system to do instruction sampling in real
+time without PMI processing overhead.
+
+Performance data using `perf top` with and without trace-imc event.
+
+PMI interrupts count when `perf top` command is executed without trace-imc event.
+
+.. code-block:: sh
+
+  # grep PMI /proc/interrupts
+  PMI:          0          0          0          0   Performance monitoring interrupts
+  # ./perf top
+  ...
+  # grep PMI /proc/interrupts
+  PMI:      39735       8710      17338      17801   Performance monitoring interrupts
+  # ./perf top -e trace_imc/trace_cycles/
+  ...
+  # grep PMI /proc/interrupts
+  PMI:      39735       8710      17338      17801   Performance monitoring interrupts
+
+
+That is, the PMI interrupt counts do not increment when using the `trace_imc` event.
index ba5edb3..0d45f0f 100644 (file)
@@ -18,9 +18,11 @@ powerpc
     elfnote
     firmware-assisted-dump
     hvcs
+    imc
     isa-versions
     kaslr-booke32
     mpc52xx
+    papr_hcalls
     pci_iov_resource_on_powernv
     pmu-ebb
     ptrace
diff --git a/Documentation/powerpc/papr_hcalls.rst b/Documentation/powerpc/papr_hcalls.rst
new file mode 100644 (file)
index 0000000..3493631
--- /dev/null
@@ -0,0 +1,250 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+===========================
+Hypercall Op-codes (hcalls)
+===========================
+
+Overview
+=========
+
+Virtualization on 64-bit Power Book3S Platforms is based on the PAPR
+specification [1]_ which describes the run-time environment for a guest
+operating system and how it should interact with the hypervisor for
+privileged operations. Currently there are two PAPR compliant hypervisors:
+
+- **IBM PowerVM (PHYP)**: IBM's proprietary hypervisor that supports AIX,
+  IBM-i and  Linux as supported guests (termed as Logical Partitions
+  or LPARS). It supports the full PAPR specification.
+
+- **Qemu/KVM**: Supports PPC64 linux guests running on a PPC64 linux host.
+  Though it only implements a subset of PAPR specification called LoPAPR [2]_.
+
+On PPC64 arch a guest kernel running on top of a PAPR hypervisor is called
+a *pSeries guest*. A pseries guest runs in a supervisor mode (HV=0) and must
+issue hypercalls to the hypervisor whenever it needs to perform an action
+that is hypervisor priviledged [3]_ or for other services managed by the
+hypervisor.
+
+Hence a Hypercall (hcall) is essentially a request by the pseries guest
+asking hypervisor to perform a privileged operation on behalf of the guest. The
+guest issues a with necessary input operands. The hypervisor after performing
+the privilege operation returns a status code and output operands back to the
+guest.
+
+HCALL ABI
+=========
+The ABI specification for a hcall between a pseries guest and PAPR hypervisor
+is covered in section 14.5.3 of ref [2]_. Switch to the  Hypervisor context is
+done via the instruction **HVCS** that expects the Opcode for hcall is set in *r3*
+and any in-arguments for the hcall are provided in registers *r4-r12*. If values
+have to be passed through a memory buffer, the data stored in that buffer should be
+in Big-endian byte order.
+
+Once control is returns back to the guest after hypervisor has serviced the
+'HVCS' instruction the return value of the hcall is available in *r3* and any
+out values are returned in registers *r4-r12*. Again like in case of in-arguments,
+any out values stored in a memory buffer will be in Big-endian byte order.
+
+Powerpc arch code provides convenient wrappers named **plpar_hcall_xxx** defined
+in a arch specific header [4]_ to issue hcalls from the linux kernel
+running as pseries guest.
+
+Register Conventions
+====================
+
+Any hcall should follow same register convention as described in section 2.2.1.1
+of "64-Bit ELF V2 ABI Specification: Power Architecture"[5]_. Table below
+summarizes these conventions:
+
++----------+----------+-------------------------------------------+
+| Register |Volatile  |  Purpose                                  |
+| Range    |(Y/N)     |                                           |
++==========+==========+===========================================+
+|   r0     |    Y     |  Optional-usage                           |
++----------+----------+-------------------------------------------+
+|   r1     |    N     |  Stack Pointer                            |
++----------+----------+-------------------------------------------+
+|   r2     |    N     |  TOC                                      |
++----------+----------+-------------------------------------------+
+|   r3     |    Y     |  hcall opcode/return value                |
++----------+----------+-------------------------------------------+
+|  r4-r10  |    Y     |  in and out values                        |
++----------+----------+-------------------------------------------+
+|   r11    |    Y     |  Optional-usage/Environmental pointer     |
++----------+----------+-------------------------------------------+
+|   r12    |    Y     |  Optional-usage/Function entry address at |
+|          |          |  global entry point                       |
++----------+----------+-------------------------------------------+
+|   r13    |    N     |  Thread-Pointer                           |
++----------+----------+-------------------------------------------+
+|  r14-r31 |    N     |  Local Variables                          |
++----------+----------+-------------------------------------------+
+|    LR    |    Y     |  Link Register                            |
++----------+----------+-------------------------------------------+
+|   CTR    |    Y     |  Loop Counter                             |
++----------+----------+-------------------------------------------+
+|   XER    |    Y     |  Fixed-point exception register.          |
++----------+----------+-------------------------------------------+
+|  CR0-1   |    Y     |  Condition register fields.               |
++----------+----------+-------------------------------------------+
+|  CR2-4   |    N     |  Condition register fields.               |
++----------+----------+-------------------------------------------+
+|  CR5-7   |    Y     |  Condition register fields.               |
++----------+----------+-------------------------------------------+
+|  Others  |    N     |                                           |
++----------+----------+-------------------------------------------+
+
+DRC & DRC Indexes
+=================
+::
+
+     DR1                                  Guest
+     +--+        +------------+         +---------+
+     |  | <----> |            |         |  User   |
+     +--+  DRC1  |            |   DRC   |  Space  |
+                 |    PAPR    |  Index  +---------+
+     DR2         | Hypervisor |         |         |
+     +--+        |            | <-----> |  Kernel |
+     |  | <----> |            |  Hcall  |         |
+     +--+  DRC2  +------------+         +---------+
+
+PAPR hypervisor terms shared hardware resources like PCI devices, NVDIMMs etc
+available for use by LPARs as Dynamic Resource (DR). When a DR is allocated to
+an LPAR, PHYP creates a data-structure called Dynamic Resource Connector (DRC)
+to manage LPAR access. An LPAR refers to a DRC via an opaque 32-bit number
+called DRC-Index. The DRC-index value is provided to the LPAR via device-tree
+where its present as an attribute in the device tree node associated with the
+DR.
+
+HCALL Return-values
+===================
+
+After servicing the hcall, hypervisor sets the return-value in *r3* indicating
+success or failure of the hcall. In case of a failure an error code indicates
+the cause for error. These codes are defined and documented in arch specific
+header [4]_.
+
+In some cases a hcall can potentially take a long time and need to be issued
+multiple times in order to be completely serviced. These hcalls will usually
+accept an opaque value *continue-token* within there argument list and a
+return value of *H_CONTINUE* indicates that hypervisor hasn't still finished
+servicing the hcall yet.
+
+To make such hcalls the guest need to set *continue-token == 0* for the
+initial call and use the hypervisor returned value of *continue-token*
+for each subsequent hcall until hypervisor returns a non *H_CONTINUE*
+return value.
+
+HCALL Op-codes
+==============
+
+Below is a partial list of HCALLs that are supported by PHYP. For the
+corresponding opcode values please look into the arch specific header [4]_:
+
+**H_SCM_READ_METADATA**
+
+| Input: *drcIndex, offset, buffer-address, numBytesToRead*
+| Out: *numBytesRead*
+| Return Value: *H_Success, H_Parameter, H_P2, H_P3, H_Hardware*
+
+Given a DRC Index of an NVDIMM, read N-bytes from the the metadata area
+associated with it, at a specified offset and copy it to provided buffer.
+The metadata area stores configuration information such as label information,
+bad-blocks etc. The metadata area is located out-of-band of NVDIMM storage
+area hence a separate access semantics is provided.
+
+**H_SCM_WRITE_METADATA**
+
+| Input: *drcIndex, offset, data, numBytesToWrite*
+| Out: *None*
+| Return Value: *H_Success, H_Parameter, H_P2, H_P4, H_Hardware*
+
+Given a DRC Index of an NVDIMM, write N-bytes to the metadata area
+associated with it, at the specified offset and from the provided buffer.
+
+**H_SCM_BIND_MEM**
+
+| Input: *drcIndex, startingScmBlockIndex, numScmBlocksToBind,*
+| *targetLogicalMemoryAddress, continue-token*
+| Out: *continue-token, targetLogicalMemoryAddress, numScmBlocksToBound*
+| Return Value: *H_Success, H_Parameter, H_P2, H_P3, H_P4, H_Overlap,*
+| *H_Too_Big, H_P5, H_Busy*
+
+Given a DRC-Index of an NVDIMM, map a continuous SCM blocks range
+*(startingScmBlockIndex, startingScmBlockIndex+numScmBlocksToBind)* to the guest
+at *targetLogicalMemoryAddress* within guest physical address space. In
+case *targetLogicalMemoryAddress == 0xFFFFFFFF_FFFFFFFF* then hypervisor
+assigns a target address to the guest. The HCALL can fail if the Guest has
+an active PTE entry to the SCM block being bound.
+
+**H_SCM_UNBIND_MEM**
+| Input: drcIndex, startingScmLogicalMemoryAddress, numScmBlocksToUnbind
+| Out: numScmBlocksUnbound
+| Return Value: *H_Success, H_Parameter, H_P2, H_P3, H_In_Use, H_Overlap,*
+| *H_Busy, H_LongBusyOrder1mSec, H_LongBusyOrder10mSec*
+
+Given a DRC-Index of an NVDimm, unmap *numScmBlocksToUnbind* SCM blocks starting
+at *startingScmLogicalMemoryAddress* from guest physical address space. The
+HCALL can fail if the Guest has an active PTE entry to the SCM block being
+unbound.
+
+**H_SCM_QUERY_BLOCK_MEM_BINDING**
+
+| Input: *drcIndex, scmBlockIndex*
+| Out: *Guest-Physical-Address*
+| Return Value: *H_Success, H_Parameter, H_P2, H_NotFound*
+
+Given a DRC-Index and an SCM Block index return the guest physical address to
+which the SCM block is mapped to.
+
+**H_SCM_QUERY_LOGICAL_MEM_BINDING**
+
+| Input: *Guest-Physical-Address*
+| Out: *drcIndex, scmBlockIndex*
+| Return Value: *H_Success, H_Parameter, H_P2, H_NotFound*
+
+Given a guest physical address return which DRC Index and SCM block is mapped
+to that address.
+
+**H_SCM_UNBIND_ALL**
+
+| Input: *scmTargetScope, drcIndex*
+| Out: *None*
+| Return Value: *H_Success, H_Parameter, H_P2, H_P3, H_In_Use, H_Busy,*
+| *H_LongBusyOrder1mSec, H_LongBusyOrder10mSec*
+
+Depending on the Target scope unmap all SCM blocks belonging to all NVDIMMs
+or all SCM blocks belonging to a single NVDIMM identified by its drcIndex
+from the LPAR memory.
+
+**H_SCM_HEALTH**
+
+| Input: drcIndex
+| Out: *health-bitmap, health-bit-valid-bitmap*
+| Return Value: *H_Success, H_Parameter, H_Hardware*
+
+Given a DRC Index return the info on predictive failure and overall health of
+the NVDIMM. The asserted bits in the health-bitmap indicate a single predictive
+failure and health-bit-valid-bitmap indicate which bits in health-bitmap are
+valid.
+
+**H_SCM_PERFORMANCE_STATS**
+
+| Input: drcIndex, resultBuffer Addr
+| Out: None
+| Return Value:  *H_Success, H_Parameter, H_Unsupported, H_Hardware, H_Authority, H_Privilege*
+
+Given a DRC Index collect the performance statistics for NVDIMM and copy them
+to the resultBuffer.
+
+References
+==========
+.. [1] "Power Architecture Platform Reference"
+       https://en.wikipedia.org/wiki/Power_Architecture_Platform_Reference
+.. [2] "Linux on Power Architecture Platform Reference"
+       https://members.openpowerfoundation.org/document/dl/469
+.. [3] "Definitions and Notation" Book III-Section 14.5.3
+       https://openpowerfoundation.org/?resource_lib=power-isa-version-3-0
+.. [4] arch/powerpc/include/asm/hvcall.h
+.. [5] "64-Bit ELF V2 ABI Specification: Power Architecture"
+       https://openpowerfoundation.org/?resource_lib=64-bit-elf-v2-abi-specification-power-architecture
index 2284f22..e478635 100644 (file)
@@ -383,7 +383,8 @@ Mkinitrd
 E2fsprogs
 ---------
 
-- <http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.29.tar.gz>
+- <https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/>
+- <https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/>
 
 JFSutils
 --------
@@ -393,12 +394,13 @@ JFSutils
 Reiserfsprogs
 -------------
 
-- <http://www.kernel.org/pub/linux/utils/fs/reiserfs/>
+- <https://git.kernel.org/pub/scm/linux/kernel/git/jeffm/reiserfsprogs.git/>
 
 Xfsprogs
 --------
 
-- <ftp://oss.sgi.com/projects/xfs/>
+- <https://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git>
+- <https://www.kernel.org/pub/linux/utils/fs/xfs/xfsprogs/>
 
 Pcmciautils
 -----------
@@ -437,7 +439,9 @@ Networking
 PPP
 ---
 
-- <ftp://ftp.samba.org/pub/ppp/>
+- <https://download.samba.org/pub/ppp/>
+- <https://git.ozlabs.org/?p=ppp.git>
+- <https://github.com/paulusmack/ppp/>
 
 NFS-utils
 ---------
@@ -447,7 +451,7 @@ NFS-utils
 Iptables
 --------
 
-- <http://www.iptables.org/downloads.html>
+- <https://netfilter.org/projects/iptables/index.html>
 
 Ip-route2
 ---------
diff --git a/Documentation/trace/boottime-trace.rst b/Documentation/trace/boottime-trace.rst
new file mode 100644 (file)
index 0000000..dcb3900
--- /dev/null
@@ -0,0 +1,184 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+=================
+Boot-time tracing
+=================
+
+:Author: Masami Hiramatsu <mhiramat@kernel.org>
+
+Overview
+========
+
+Boot-time tracing allows users to trace boot-time process including
+device initialization with full features of ftrace including per-event
+filter and actions, histograms, kprobe-events and synthetic-events,
+and trace instances.
+Since kernel command line is not enough to control these complex features,
+this uses bootconfig file to describe tracing feature programming.
+
+Options in the Boot Config
+==========================
+
+Here is the list of available options list for boot time tracing in
+boot config file [1]_. All options are under "ftrace." or "kernel."
+prefix. See kernel parameters for the options which starts
+with "kernel." prefix [2]_.
+
+.. [1] See :ref:`Documentation/admin-guide/bootconfig.rst <bootconfig>`
+.. [2] See :ref:`Documentation/admin-guide/kernel-parameters.rst <kernelparameters>`
+
+Ftrace Global Options
+---------------------
+
+Ftrace global options have "kernel." prefix in boot config, which means
+these options are passed as a part of kernel legacy command line.
+
+kernel.tp_printk
+   Output trace-event data on printk buffer too.
+
+kernel.dump_on_oops [= MODE]
+   Dump ftrace on Oops. If MODE = 1 or omitted, dump trace buffer
+   on all CPUs. If MODE = 2, dump a buffer on a CPU which kicks Oops.
+
+kernel.traceoff_on_warning
+   Stop tracing if WARN_ON() occurs.
+
+kernel.fgraph_max_depth = MAX_DEPTH
+   Set MAX_DEPTH to maximum depth of fgraph tracer.
+
+kernel.fgraph_filters = FILTER[, FILTER2...]
+   Add fgraph tracing function filters.
+
+kernel.fgraph_notraces = FILTER[, FILTER2...]
+   Add fgraph non-tracing function filters.
+
+
+Ftrace Per-instance Options
+---------------------------
+
+These options can be used for each instance including global ftrace node.
+
+ftrace.[instance.INSTANCE.]options = OPT1[, OPT2[...]]
+   Enable given ftrace options.
+
+ftrace.[instance.INSTANCE.]trace_clock = CLOCK
+   Set given CLOCK to ftrace's trace_clock.
+
+ftrace.[instance.INSTANCE.]buffer_size = SIZE
+   Configure ftrace buffer size to SIZE. You can use "KB" or "MB"
+   for that SIZE.
+
+ftrace.[instance.INSTANCE.]alloc_snapshot
+   Allocate snapshot buffer.
+
+ftrace.[instance.INSTANCE.]cpumask = CPUMASK
+   Set CPUMASK as trace cpu-mask.
+
+ftrace.[instance.INSTANCE.]events = EVENT[, EVENT2[...]]
+   Enable given events on boot. You can use a wild card in EVENT.
+
+ftrace.[instance.INSTANCE.]tracer = TRACER
+   Set TRACER to current tracer on boot. (e.g. function)
+
+ftrace.[instance.INSTANCE.]ftrace.filters
+   This will take an array of tracing function filter rules.
+
+ftrace.[instance.INSTANCE.]ftrace.notraces
+   This will take an array of NON-tracing function filter rules.
+
+
+Ftrace Per-Event Options
+------------------------
+
+These options are setting per-event options.
+
+ftrace.[instance.INSTANCE.]event.GROUP.EVENT.enable
+   Enable GROUP:EVENT tracing.
+
+ftrace.[instance.INSTANCE.]event.GROUP.EVENT.filter = FILTER
+   Set FILTER rule to the GROUP:EVENT.
+
+ftrace.[instance.INSTANCE.]event.GROUP.EVENT.actions = ACTION[, ACTION2[...]]
+   Set ACTIONs to the GROUP:EVENT.
+
+ftrace.[instance.INSTANCE.]event.kprobes.EVENT.probes = PROBE[, PROBE2[...]]
+   Defines new kprobe event based on PROBEs. It is able to define
+   multiple probes on one event, but those must have same type of
+   arguments. This option is available only for the event which
+   group name is "kprobes".
+
+ftrace.[instance.INSTANCE.]event.synthetic.EVENT.fields = FIELD[, FIELD2[...]]
+   Defines new synthetic event with FIELDs. Each field should be
+   "type varname".
+
+Note that kprobe and synthetic event definitions can be written under
+instance node, but those are also visible from other instances. So please
+take care for event name conflict.
+
+
+Examples
+========
+
+For example, to add filter and actions for each event, define kprobe
+events, and synthetic events with histogram, write a boot config like
+below::
+
+  ftrace.event {
+        task.task_newtask {
+                filter = "pid < 128"
+                enable
+        }
+        kprobes.vfs_read {
+                probes = "vfs_read $arg1 $arg2"
+                filter = "common_pid < 200"
+                enable
+        }
+        synthetic.initcall_latency {
+                fields = "unsigned long func", "u64 lat"
+                actions = "hist:keys=func.sym,lat:vals=lat:sort=lat"
+        }
+        initcall.initcall_start {
+                actions = "hist:keys=func:ts0=common_timestamp.usecs"
+        }
+        initcall.initcall_finish {
+                actions = "hist:keys=func:lat=common_timestamp.usecs-$ts0:onmatch(initcall.initcall_start).initcall_latency(func,$lat)"
+        }
+  }
+
+Also, boot-time tracing supports "instance" node, which allows us to run
+several tracers for different purpose at once. For example, one tracer
+is for tracing functions starting with "user\_", and others tracing
+"kernel\_" functions, you can write boot config as below::
+
+  ftrace.instance {
+        foo {
+                tracer = "function"
+                ftrace.filters = "user_*"
+        }
+        bar {
+                tracer = "function"
+                ftrace.filters = "kernel_*"
+        }
+  }
+
+The instance node also accepts event nodes so that each instance
+can customize its event tracing.
+
+This boot-time tracing also supports ftrace kernel parameters via boot
+config.
+For example, following kernel parameters::
+
+ trace_options=sym-addr trace_event=initcall:* tp_printk trace_buf_size=1M ftrace=function ftrace_filter="vfs*"
+
+This can be written in boot config like below::
+
+  kernel {
+        trace_options = sym-addr
+        trace_event = "initcall:*"
+        tp_printk
+        trace_buf_size = 1M
+        ftrace = function
+        ftrace_filter = "vfs*"
+  }
+
+Note that parameters start with "kernel" prefix instead of "ftrace".
index f7e1fcc..ed79b22 100644 (file)
@@ -525,3 +525,518 @@ The following commands are supported:
   event counts (hitcount).
 
   See Documentation/trace/histogram.rst for details and examples.
+
+6.3 In-kernel trace event API
+-----------------------------
+
+In most cases, the command-line interface to trace events is more than
+sufficient.  Sometimes, however, applications might find the need for
+more complex relationships than can be expressed through a simple
+series of linked command-line expressions, or putting together sets of
+commands may be simply too cumbersome.  An example might be an
+application that needs to 'listen' to the trace stream in order to
+maintain an in-kernel state machine detecting, for instance, when an
+illegal kernel state occurs in the scheduler.
+
+The trace event subsystem provides an in-kernel API allowing modules
+or other kernel code to generate user-defined 'synthetic' events at
+will, which can be used to either augment the existing trace stream
+and/or signal that a particular important state has occurred.
+
+A similar in-kernel API is also available for creating kprobe and
+kretprobe events.
+
+Both the synthetic event and k/ret/probe event APIs are built on top
+of a lower-level "dynevent_cmd" event command API, which is also
+available for more specialized applications, or as the basis of other
+higher-level trace event APIs.
+
+The API provided for these purposes is describe below and allows the
+following:
+
+  - dynamically creating synthetic event definitions
+  - dynamically creating kprobe and kretprobe event definitions
+  - tracing synthetic events from in-kernel code
+  - the low-level "dynevent_cmd" API
+
+6.3.1 Dyamically creating synthetic event definitions
+-----------------------------------------------------
+
+There are a couple ways to create a new synthetic event from a kernel
+module or other kernel code.
+
+The first creates the event in one step, using synth_event_create().
+In this method, the name of the event to create and an array defining
+the fields is supplied to synth_event_create().  If successful, a
+synthetic event with that name and fields will exist following that
+call.  For example, to create a new "schedtest" synthetic event:
+
+  ret = synth_event_create("schedtest", sched_fields,
+                           ARRAY_SIZE(sched_fields), THIS_MODULE);
+
+The sched_fields param in this example points to an array of struct
+synth_field_desc, each of which describes an event field by type and
+name:
+
+  static struct synth_field_desc sched_fields[] = {
+        { .type = "pid_t",              .name = "next_pid_field" },
+        { .type = "char[16]",           .name = "next_comm_field" },
+        { .type = "u64",                .name = "ts_ns" },
+        { .type = "u64",                .name = "ts_ms" },
+        { .type = "unsigned int",       .name = "cpu" },
+        { .type = "char[64]",           .name = "my_string_field" },
+        { .type = "int",                .name = "my_int_field" },
+  };
+
+See synth_field_size() for available types. If field_name contains [n]
+the field is considered to be an array.
+
+If the event is created from within a module, a pointer to the module
+must be passed to synth_event_create().  This will ensure that the
+trace buffer won't contain unreadable events when the module is
+removed.
+
+At this point, the event object is ready to be used for generating new
+events.
+
+In the second method, the event is created in several steps.  This
+allows events to be created dynamically and without the need to create
+and populate an array of fields beforehand.
+
+To use this method, an empty or partially empty synthetic event should
+first be created using synth_event_gen_cmd_start() or
+synth_event_gen_cmd_array_start().  For synth_event_gen_cmd_start(),
+the name of the event along with one or more pairs of args each pair
+representing a 'type field_name;' field specification should be
+supplied.  For synth_event_gen_cmd_array_start(), the name of the
+event along with an array of struct synth_field_desc should be
+supplied. Before calling synth_event_gen_cmd_start() or
+synth_event_gen_cmd_array_start(), the user should create and
+initialize a dynevent_cmd object using synth_event_cmd_init().
+
+For example, to create a new "schedtest" synthetic event with two
+fields:
+
+  struct dynevent_cmd cmd;
+  char *buf;
+
+  /* Create a buffer to hold the generated command */
+  buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
+
+  /* Before generating the command, initialize the cmd object */
+  synth_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
+
+  ret = synth_event_gen_cmd_start(&cmd, "schedtest", THIS_MODULE,
+                                  "pid_t", "next_pid_field",
+                                  "u64", "ts_ns");
+
+Alternatively, using an array of struct synth_field_desc fields
+containing the same information:
+
+  ret = synth_event_gen_cmd_array_start(&cmd, "schedtest", THIS_MODULE,
+                                        fields, n_fields);
+
+Once the synthetic event object has been created, it can then be
+populated with more fields.  Fields are added one by one using
+synth_event_add_field(), supplying the dynevent_cmd object, a field
+type, and a field name.  For example, to add a new int field named
+"intfield", the following call should be made:
+
+  ret = synth_event_add_field(&cmd, "int", "intfield");
+
+See synth_field_size() for available types. If field_name contains [n]
+the field is considered to be an array.
+
+A group of fields can also be added all at once using an array of
+synth_field_desc with add_synth_fields().  For example, this would add
+just the first four sched_fields:
+
+  ret = synth_event_add_fields(&cmd, sched_fields, 4);
+
+If you already have a string of the form 'type field_name',
+synth_event_add_field_str() can be used to add it as-is; it will
+also automatically append a ';' to the string.
+
+Once all the fields have been added, the event should be finalized and
+registered by calling the synth_event_gen_cmd_end() function:
+
+  ret = synth_event_gen_cmd_end(&cmd);
+
+At this point, the event object is ready to be used for tracing new
+events.
+
+6.3.3 Tracing synthetic events from in-kernel code
+--------------------------------------------------
+
+To trace a synthetic event, there are several options.  The first
+option is to trace the event in one call, using synth_event_trace()
+with a variable number of values, or synth_event_trace_array() with an
+array of values to be set.  A second option can be used to avoid the
+need for a pre-formed array of values or list of arguments, via
+synth_event_trace_start() and synth_event_trace_end() along with
+synth_event_add_next_val() or synth_event_add_val() to add the values
+piecewise.
+
+6.3.3.1 Tracing a synthetic event all at once
+---------------------------------------------
+
+To trace a synthetic event all at once, the synth_event_trace() or
+synth_event_trace_array() functions can be used.
+
+The synth_event_trace() function is passed the trace_event_file
+representing the synthetic event (which can be retrieved using
+trace_get_event_file() using the synthetic event name, "synthetic" as
+the system name, and the trace instance name (NULL if using the global
+trace array)), along with an variable number of u64 args, one for each
+synthetic event field, and the number of values being passed.
+
+So, to trace an event corresponding to the synthetic event definition
+above, code like the following could be used:
+
+  ret = synth_event_trace(create_synth_test, 7, /* number of values */
+                          444,             /* next_pid_field */
+                          (u64)"clackers", /* next_comm_field */
+                          1000000,         /* ts_ns */
+                          1000,            /* ts_ms */
+                          smp_processor_id(),/* cpu */
+                          (u64)"Thneed",   /* my_string_field */
+                          999);            /* my_int_field */
+
+All vals should be cast to u64, and string vals are just pointers to
+strings, cast to u64.  Strings will be copied into space reserved in
+the event for the string, using these pointers.
+
+Alternatively, the synth_event_trace_array() function can be used to
+accomplish the same thing.  It is passed the trace_event_file
+representing the synthetic event (which can be retrieved using
+trace_get_event_file() using the synthetic event name, "synthetic" as
+the system name, and the trace instance name (NULL if using the global
+trace array)), along with an array of u64, one for each synthetic
+event field.
+
+To trace an event corresponding to the synthetic event definition
+above, code like the following could be used:
+
+  u64 vals[7];
+
+  vals[0] = 777;                  /* next_pid_field */
+  vals[1] = (u64)"tiddlywinks";   /* next_comm_field */
+  vals[2] = 1000000;              /* ts_ns */
+  vals[3] = 1000;                 /* ts_ms */
+  vals[4] = smp_processor_id();   /* cpu */
+  vals[5] = (u64)"thneed";        /* my_string_field */
+  vals[6] = 398;                  /* my_int_field */
+
+The 'vals' array is just an array of u64, the number of which must
+match the number of field in the synthetic event, and which must be in
+the same order as the synthetic event fields.
+
+All vals should be cast to u64, and string vals are just pointers to
+strings, cast to u64.  Strings will be copied into space reserved in
+the event for the string, using these pointers.
+
+In order to trace a synthetic event, a pointer to the trace event file
+is needed.  The trace_get_event_file() function can be used to get
+it - it will find the file in the given trace instance (in this case
+NULL since the top trace array is being used) while at the same time
+preventing the instance containing it from going away:
+
+       schedtest_event_file = trace_get_event_file(NULL, "synthetic",
+                                                   "schedtest");
+
+Before tracing the event, it should be enabled in some way, otherwise
+the synthetic event won't actually show up in the trace buffer.
+
+To enable a synthetic event from the kernel, trace_array_set_clr_event()
+can be used (which is not specific to synthetic events, so does need
+the "synthetic" system name to be specified explicitly).
+
+To enable the event, pass 'true' to it:
+
+       trace_array_set_clr_event(schedtest_event_file->tr,
+                                 "synthetic", "schedtest", true);
+
+To disable it pass false:
+
+       trace_array_set_clr_event(schedtest_event_file->tr,
+                                 "synthetic", "schedtest", false);
+
+Finally, synth_event_trace_array() can be used to actually trace the
+event, which should be visible in the trace buffer afterwards:
+
+       ret = synth_event_trace_array(schedtest_event_file, vals,
+                                     ARRAY_SIZE(vals));
+
+To remove the synthetic event, the event should be disabled, and the
+trace instance should be 'put' back using trace_put_event_file():
+
+       trace_array_set_clr_event(schedtest_event_file->tr,
+                                 "synthetic", "schedtest", false);
+       trace_put_event_file(schedtest_event_file);
+
+If those have been successful, synth_event_delete() can be called to
+remove the event:
+
+       ret = synth_event_delete("schedtest");
+
+6.3.3.1 Tracing a synthetic event piecewise
+-------------------------------------------
+
+To trace a synthetic using the piecewise method described above, the
+synth_event_trace_start() function is used to 'open' the synthetic
+event trace:
+
+       struct synth_trace_state trace_state;
+
+       ret = synth_event_trace_start(schedtest_event_file, &trace_state);
+
+It's passed the trace_event_file representing the synthetic event
+using the same methods as described above, along with a pointer to a
+struct synth_trace_state object, which will be zeroed before use and
+used to maintain state between this and following calls.
+
+Once the event has been opened, which means space for it has been
+reserved in the trace buffer, the individual fields can be set.  There
+are two ways to do that, either one after another for each field in
+the event, which requires no lookups, or by name, which does.  The
+tradeoff is flexibility in doing the assignments vs the cost of a
+lookup per field.
+
+To assign the values one after the other without lookups,
+synth_event_add_next_val() should be used.  Each call is passed the
+same synth_trace_state object used in the synth_event_trace_start(),
+along with the value to set the next field in the event.  After each
+field is set, the 'cursor' points to the next field, which will be set
+by the subsequent call, continuing until all the fields have been set
+in order.  The same sequence of calls as in the above examples using
+this method would be (without error-handling code):
+
+       /* next_pid_field */
+       ret = synth_event_add_next_val(777, &trace_state);
+
+       /* next_comm_field */
+       ret = synth_event_add_next_val((u64)"slinky", &trace_state);
+
+       /* ts_ns */
+       ret = synth_event_add_next_val(1000000, &trace_state);
+
+       /* ts_ms */
+       ret = synth_event_add_next_val(1000, &trace_state);
+
+       /* cpu */
+       ret = synth_event_add_next_val(smp_processor_id(), &trace_state);
+
+       /* my_string_field */
+       ret = synth_event_add_next_val((u64)"thneed_2.01", &trace_state);
+
+       /* my_int_field */
+       ret = synth_event_add_next_val(395, &trace_state);
+
+To assign the values in any order, synth_event_add_val() should be
+used.  Each call is passed the same synth_trace_state object used in
+the synth_event_trace_start(), along with the field name of the field
+to set and the value to set it to.  The same sequence of calls as in
+the above examples using this method would be (without error-handling
+code):
+
+       ret = synth_event_add_val("next_pid_field", 777, &trace_state);
+       ret = synth_event_add_val("next_comm_field", (u64)"silly putty",
+                                 &trace_state);
+       ret = synth_event_add_val("ts_ns", 1000000, &trace_state);
+       ret = synth_event_add_val("ts_ms", 1000, &trace_state);
+       ret = synth_event_add_val("cpu", smp_processor_id(), &trace_state);
+       ret = synth_event_add_val("my_string_field", (u64)"thneed_9",
+                                 &trace_state);
+       ret = synth_event_add_val("my_int_field", 3999, &trace_state);
+
+Note that synth_event_add_next_val() and synth_event_add_val() are
+incompatible if used within the same trace of an event - either one
+can be used but not both at the same time.
+
+Finally, the event won't be actually traced until it's 'closed',
+which is done using synth_event_trace_end(), which takes only the
+struct synth_trace_state object used in the previous calls:
+
+       ret = synth_event_trace_end(&trace_state);
+
+Note that synth_event_trace_end() must be called at the end regardless
+of whether any of the add calls failed (say due to a bad field name
+being passed in).
+
+6.3.4 Dyamically creating kprobe and kretprobe event definitions
+----------------------------------------------------------------
+
+To create a kprobe or kretprobe trace event from kernel code, the
+kprobe_event_gen_cmd_start() or kretprobe_event_gen_cmd_start()
+functions can be used.
+
+To create a kprobe event, an empty or partially empty kprobe event
+should first be created using kprobe_event_gen_cmd_start().  The name
+of the event and the probe location should be specfied along with one
+or args each representing a probe field should be supplied to this
+function.  Before calling kprobe_event_gen_cmd_start(), the user
+should create and initialize a dynevent_cmd object using
+kprobe_event_cmd_init().
+
+For example, to create a new "schedtest" kprobe event with two fields:
+
+  struct dynevent_cmd cmd;
+  char *buf;
+
+  /* Create a buffer to hold the generated command */
+  buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
+
+  /* Before generating the command, initialize the cmd object */
+  kprobe_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
+
+  /*
+   * Define the gen_kprobe_test event with the first 2 kprobe
+   * fields.
+   */
+  ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test", "do_sys_open",
+                                   "dfd=%ax", "filename=%dx");
+
+Once the kprobe event object has been created, it can then be
+populated with more fields.  Fields can be added using
+kprobe_event_add_fields(), supplying the dynevent_cmd object along
+with a variable arg list of probe fields.  For example, to add a
+couple additional fields, the following call could be made:
+
+  ret = kprobe_event_add_fields(&cmd, "flags=%cx", "mode=+4($stack)");
+
+Once all the fields have been added, the event should be finalized and
+registered by calling the kprobe_event_gen_cmd_end() or
+kretprobe_event_gen_cmd_end() functions, depending on whether a kprobe
+or kretprobe command was started:
+
+  ret = kprobe_event_gen_cmd_end(&cmd);
+
+or
+
+  ret = kretprobe_event_gen_cmd_end(&cmd);
+
+At this point, the event object is ready to be used for tracing new
+events.
+
+Similarly, a kretprobe event can be created using
+kretprobe_event_gen_cmd_start() with a probe name and location and
+additional params such as $retval:
+
+  ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",
+                                      "do_sys_open", "$retval");
+
+Similar to the synthetic event case, code like the following can be
+used to enable the newly created kprobe event:
+
+  gen_kprobe_test = trace_get_event_file(NULL, "kprobes", "gen_kprobe_test");
+
+  ret = trace_array_set_clr_event(gen_kprobe_test->tr,
+                                  "kprobes", "gen_kprobe_test", true);
+
+Finally, also similar to synthetic events, the following code can be
+used to give the kprobe event file back and delete the event:
+
+  trace_put_event_file(gen_kprobe_test);
+
+  ret = kprobe_event_delete("gen_kprobe_test");
+
+6.3.4 The "dynevent_cmd" low-level API
+--------------------------------------
+
+Both the in-kernel synthetic event and kprobe interfaces are built on
+top of a lower-level "dynevent_cmd" interface.  This interface is
+meant to provide the basis for higher-level interfaces such as the
+synthetic and kprobe interfaces, which can be used as examples.
+
+The basic idea is simple and amounts to providing a general-purpose
+layer that can be used to generate trace event commands.  The
+generated command strings can then be passed to the command-parsing
+and event creation code that already exists in the trace event
+subystem for creating the corresponding trace events.
+
+In a nutshell, the way it works is that the higher-level interface
+code creates a struct dynevent_cmd object, then uses a couple
+functions, dynevent_arg_add() and dynevent_arg_pair_add() to build up
+a command string, which finally causes the command to be executed
+using the dynevent_create() function.  The details of the interface
+are described below.
+
+The first step in building a new command string is to create and
+initialize an instance of a dynevent_cmd.  Here, for instance, we
+create a dynevent_cmd on the stack and initialize it:
+
+  struct dynevent_cmd cmd;
+  char *buf;
+  int ret;
+
+  buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
+
+  dynevent_cmd_init(cmd, buf, maxlen, DYNEVENT_TYPE_FOO,
+                    foo_event_run_command);
+
+The dynevent_cmd initialization needs to be given a user-specified
+buffer and the length of the buffer (MAX_DYNEVENT_CMD_LEN can be used
+for this purpose - at 2k it's generally too big to be comfortably put
+on the stack, so is dynamically allocated), a dynevent type id, which
+is meant to be used to check that further API calls are for the
+correct command type, and a pointer to an event-specific run_command()
+callback that will be called to actually execute the event-specific
+command function.
+
+Once that's done, the command string can by built up by successive
+calls to argument-adding functions.
+
+To add a single argument, define and initialize a struct dynevent_arg
+or struct dynevent_arg_pair object.  Here's an example of the simplest
+possible arg addition, which is simply to append the given string as
+a whitespace-separated argument to the command:
+
+  struct dynevent_arg arg;
+
+  dynevent_arg_init(&arg, NULL, 0);
+
+  arg.str = name;
+
+  ret = dynevent_arg_add(cmd, &arg);
+
+The arg object is first initialized using dynevent_arg_init() and in
+this case the parameters are NULL or 0, which means there's no
+optional sanity-checking function or separator appended to the end of
+the arg.
+
+Here's another more complicated example using an 'arg pair', which is
+used to create an argument that consists of a couple components added
+together as a unit, for example, a 'type field_name;' arg or a simple
+expression arg e.g. 'flags=%cx':
+
+  struct dynevent_arg_pair arg_pair;
+
+  dynevent_arg_pair_init(&arg_pair, dynevent_foo_check_arg_fn, 0, ';');
+
+  arg_pair.lhs = type;
+  arg_pair.rhs = name;
+
+  ret = dynevent_arg_pair_add(cmd, &arg_pair);
+
+Again, the arg_pair is first initialized, in this case with a callback
+function used to check the sanity of the args (for example, that
+neither part of the pair is NULL), along with a character to be used
+to add an operator between the pair (here none) and a separator to be
+appended onto the end of the arg pair (here ';').
+
+There's also a dynevent_str_add() function that can be used to simply
+add a string as-is, with no spaces, delimeters, or arg check.
+
+Any number of dynevent_*_add() calls can be made to build up the string
+(until its length surpasses cmd->maxlen).  When all the arguments have
+been added and the command string is complete, the only thing left to
+do is run the command, which happens by simply calling
+dynevent_create():
+
+  ret = dynevent_create(&cmd);
+
+At that point, if the return value is 0, the dynamic event has been
+created and is ready to use.
+
+See the dynevent_cmd function definitions themselves for the details
+of the API.
index 04acd27..fa9e1c7 100644 (file)
@@ -19,6 +19,7 @@ Linux Tracing Technologies
    events-msr
    mmiotrace
    histogram
+   boottime-trace
    hwlat_detector
    intel_th
    stm
index 5599305..cc4c5fc 100644 (file)
@@ -97,6 +97,7 @@ which shows given pointer in "symbol+offset" style.
 For $comm, the default type is "string"; any other type is invalid.
 
 .. _user_mem_access:
+
 User Memory Access
 ------------------
 Kprobe events supports user-space memory access. For that purpose, you can use
@@ -252,4 +253,3 @@ And you can see the traced information via /sys/kernel/debug/tracing/trace.
 Each line shows when the kernel hits an event, and <- SYMBOL means kernel
 returns from SYMBOL(e.g. "sys_open+0x1b/0x1d <- do_sys_open" means kernel
 returns from do_sys_open to sys_open+0x1b).
-
index 94a6499..37da444 100644 (file)
@@ -390,7 +390,8 @@ Mkinitrd
 E2fsprogs
 ---------
 
-- <http://prdownloads.sourceforge.net/e2fsprogs/e2fsprogs-1.29.tar.gz>
+- <https://www.kernel.org/pub/linux/kernel/people/tytso/e2fsprogs/>
+- <https://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git/>
 
 JFSutils
 --------
@@ -400,12 +401,13 @@ JFSutils
 Reiserfsprogs
 -------------
 
-- <http://www.kernel.org/pub/linux/utils/fs/reiserfs/>
+- <https://git.kernel.org/pub/scm/linux/kernel/git/jeffm/reiserfsprogs.git/>
 
 Xfsprogs
 --------
 
-- <ftp://oss.sgi.com/projects/xfs/>
+- <https://git.kernel.org/pub/scm/fs/xfs/xfsprogs-dev.git>
+- <https://www.kernel.org/pub/linux/utils/fs/xfs/xfsprogs/>
 
 Pcmciautils
 -----------
@@ -444,7 +446,9 @@ Rete
 PPP
 ---
 
-- <ftp://ftp.samba.org/pub/ppp/>
+- <https://download.samba.org/pub/ppp/>
+- <https://git.ozlabs.org/?p=ppp.git>
+- <https://github.com/paulusmack/ppp/>
 
 
 NFS-utils
@@ -455,7 +459,7 @@ NFS-utils
 Iptables
 --------
 
-- <http://www.iptables.org/downloads.html>
+- <https://netfilter.org/projects/iptables/index.html>
 
 Ip-route2
 ---------
index ae3ad89..71d4823 100644 (file)
@@ -318,8 +318,8 @@ Andrew Morton의 글이 있다.
 리뷰 프로세스는 patchwork라는 도구를 통해 추적된다. patchwork은 등록된 패치와
 패치에 대한 코멘트, 패치의 버전을 볼 수 있는 웹 인터페이스를 제공하고,
 메인테이너는 패치를 리뷰 중, 리뷰 통과, 또는 반려됨으로 표시할 수 있다.
-대부분의 이러한 patchwork 사이트는 https://patchwork.kernel.org/ 또는
-http://patchwork.ozlabs.org/ 에 나열되어 있다.
+대부분의 이러한 patchwork 사이트는 https://patchwork.kernel.org/ 에 나열되어
+있다.
 
 통합 테스트를 위한 linux-next 커널 트리
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -328,7 +328,7 @@ http://patchwork.ozlabs.org/ 에 나열되어 있다.
 거쳐야 한다. 이런 목적으로, 모든 서브시스템 트리의 변경사항을 거의 매일
 받아가는 특수한 테스트 저장소가 존재한다:
 
-       https://git.kernel.org/?p=linux/kernel/git/sfr/linux-next.git
+       https://git.kernel.org/?p=linux/kernel/git/next/linux-next.git
 
 이런 식으로, linux-next 커널을 통해 다음 머지 기간에 메인라인 커널에 어떤
 변경이 가해질 것인지 간략히 알 수 있다. 모험심 강한 테스터라면 linux-next
index 3a0c819..c6e1ce5 100644 (file)
@@ -4177,6 +4177,42 @@ 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.
 
+4.122 KVM_S390_NORMAL_RESET
+
+Capability: KVM_CAP_S390_VCPU_RESETS
+Architectures: s390
+Type: vcpu ioctl
+Parameters: none
+Returns: 0
+
+This ioctl resets VCPU registers and control structures according to
+the cpu reset definition in the POP (Principles Of Operation).
+
+4.123 KVM_S390_INITIAL_RESET
+
+Capability: none
+Architectures: s390
+Type: vcpu ioctl
+Parameters: none
+Returns: 0
+
+This ioctl resets VCPU registers and control structures according to
+the initial cpu reset definition in the POP. However, the cpu is not
+put into ESA mode. This reset is a superset of the normal reset.
+
+4.124 KVM_S390_CLEAR_RESET
+
+Capability: KVM_CAP_S390_VCPU_RESETS
+Architectures: s390
+Type: vcpu ioctl
+Parameters: none
+Returns: 0
+
+This ioctl resets VCPU registers and control structures according to
+the clear cpu reset definition in the POP. However, the cpu is not put
+into ESA mode. This reset is a superset of the initial reset.
+
+
 5. The kvm_run structure
 ------------------------
 
@@ -5405,3 +5441,10 @@ handling by KVM (as some KVM hypercall may be mistakenly treated as TLB
 flush hypercalls by Hyper-V) so userspace should disable KVM identification
 in CPUID and only exposes Hyper-V identification. In this case, guest
 thinks it's running on Hyper-V and only use Hyper-V hypercalls.
+
+8.22 KVM_CAP_S390_VCPU_RESETS
+
+Architectures: s390
+
+This capability indicates that the KVM_S390_NORMAL_RESET and
+KVM_S390_CLEAR_RESET ioctls are available.
index 1f77fb8..575d386 100644 (file)
@@ -2092,6 +2092,7 @@ F:        drivers/rtc/rtc-pl031.c
 F:     drivers/watchdog/coh901327_wdt.c
 F:     Documentation/devicetree/bindings/arm/ste-*
 F:     Documentation/devicetree/bindings/arm/ux500/
+F:     Documentation/devicetree/bindings/arm/ux500.yaml
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git
 
 ARM/NUVOTON NPCM ARCHITECTURE
@@ -3288,6 +3289,8 @@ S:        Maintained
 N:     bcm2711
 N:     bcm2835
 F:     drivers/staging/vc04_services
+F:     Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
+F:     drivers/pci/controller/pcie-brcmstb.c
 
 BROADCOM BCM47XX MIPS ARCHITECTURE
 M:     Hauke Mehrtens <hauke@hauke-m.de>
@@ -3343,6 +3346,8 @@ F:        drivers/bus/brcmstb_gisb.c
 F:     arch/arm/mm/cache-b15-rac.c
 F:     arch/arm/include/asm/hardware/cache-b15-rac.h
 N:     brcmstb
+F:     Documentation/devicetree/bindings/pci/brcm,stb-pcie.yaml
+F:     drivers/pci/controller/pcie-brcmstb.c
 
 BROADCOM BMIPS CPUFREQ DRIVER
 M:     Markus Mayer <mmayer@broadcom.com>
@@ -6903,7 +6908,7 @@ T:        git git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse.git
 S:     Maintained
 F:     fs/fuse/
 F:     include/uapi/linux/fuse.h
-F:     Documentation/filesystems/fuse.txt
+F:     Documentation/filesystems/fuse.rst
 
 FUTEX SUBSYSTEM
 M:     Thomas Gleixner <tglx@linutronix.de>
@@ -7378,6 +7383,7 @@ F:        drivers/hwtracing/
 HARDWARE SPINLOCK CORE
 M:     Ohad Ben-Cohen <ohad@wizery.com>
 M:     Bjorn Andersson <bjorn.andersson@linaro.org>
+R:     Baolin Wang <baolin.wang7@gmail.com>
 L:     linux-remoteproc@vger.kernel.org
 S:     Maintained
 T:     git git://git.kernel.org/pub/scm/linux/kernel/git/andersson/remoteproc.git hwspinlock-next
@@ -7657,9 +7663,8 @@ S:        Orphan
 F:     drivers/net/usb/hso.c
 
 HSR NETWORK PROTOCOL
-M:     Arvid Brodin <arvid.brodin@alten.se>
 L:     netdev@vger.kernel.org
-S:     Maintained
+S:     Orphan
 F:     net/hsr/
 
 HT16K33 LED CONTROLLER DRIVER
@@ -7814,9 +7819,7 @@ M:        Jean Delvare <jdelvare@suse.com>
 L:     linux-i2c@vger.kernel.org
 S:     Maintained
 F:     Documentation/i2c/busses/i2c-parport.rst
-F:     Documentation/i2c/busses/i2c-parport-light.rst
 F:     drivers/i2c/busses/i2c-parport.c
-F:     drivers/i2c/busses/i2c-parport-light.c
 
 I2C SUBSYSTEM
 M:     Wolfram Sang <wsa@the-dreams.de>
@@ -8908,8 +8911,10 @@ L:       isdn4linux@listserv.isdn4linux.de (subscribers-only)
 L:     netdev@vger.kernel.org
 W:     http://www.isdn4linux.de
 S:     Maintained
-F:     drivers/isdn/mISDN
-F:     drivers/isdn/hardware
+F:     drivers/isdn/mISDN/
+F:     drivers/isdn/hardware/
+F:     drivers/isdn/Kconfig
+F:     drivers/isdn/Makefile
 
 ISDN/CMTP OVER BLUETOOTH
 M:     Karsten Keil <isdn@linux-pingi.de>
@@ -13355,7 +13360,7 @@ S:      Maintained
 F:     fs/timerfd.c
 F:     include/linux/timer*
 F:     include/linux/time_namespace.h
-F:     kernel/time_namespace.c
+F:     kernel/time/namespace.c
 F:     kernel/time/*timer*
 
 POWER MANAGEMENT CORE
@@ -14104,7 +14109,6 @@ F:      include/linux/platform_data/rtc-*
 F:     tools/testing/selftests/rtc/
 
 REALTEK AUDIO CODECS
-M:     Bard Liao <bardliao@realtek.com>
 M:     Oder Chiou <oder_chiou@realtek.com>
 S:     Maintained
 F:     sound/soc/codecs/rt*
@@ -14945,8 +14949,8 @@ S:      Maintained
 F:     drivers/mmc/host/sdhci-omap.c
 
 SECURE ENCRYPTING DEVICE (SED) OPAL DRIVER
-M:     Scott Bauer <scott.bauer@intel.com>
 M:     Jonathan Derrick <jonathan.derrick@intel.com>
+M:     Revanth Rajashekar <revanth.rajashekar@intel.com>
 L:     linux-block@vger.kernel.org
 S:     Supported
 F:     block/sed*
@@ -15932,6 +15936,15 @@ S:     Supported
 F:     Documentation/networking/device_drivers/stmicro/
 F:     drivers/net/ethernet/stmicro/stmmac/
 
+EXTRA BOOT CONFIG
+M:     Masami Hiramatsu <mhiramat@kernel.org>
+S:     Maintained
+F:     lib/bootconfig.c
+F:     fs/proc/bootconfig.c
+F:     include/linux/bootconfig.h
+F:     tools/bootconfig/*
+F:     Documentation/admin-guide/bootconfig.rst
+
 SUN3/3X
 M:     Sam Creasey <sammy@sammy.net>
 W:     http://sammy.net/sun3/
@@ -16139,6 +16152,7 @@ F:      drivers/firmware/arm_scpi.c
 F:     drivers/firmware/arm_scmi/
 F:     drivers/reset/reset-scmi.c
 F:     include/linux/sc[mp]i_protocol.h
+F:     include/trace/events/scmi.h
 
 SYSTEM RESET/SHUTDOWN DRIVERS
 M:     Sebastian Reichel <sre@kernel.org>
@@ -17124,7 +17138,6 @@ F:      drivers/staging/unisys/
 UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER
 R:     Alim Akhtar <alim.akhtar@samsung.com>
 R:     Avri Altman <avri.altman@wdc.com>
-R:     Pedro Sousa <pedrom.sousa@synopsys.com>
 L:     linux-scsi@vger.kernel.org
 S:     Supported
 F:     Documentation/scsi/ufs.txt
@@ -17778,6 +17791,12 @@ F:     include/linux/vbox_utils.h
 F:     include/uapi/linux/vbox*.h
 F:     drivers/virt/vboxguest/
 
+VIRTUAL BOX SHARED FOLDER VFS DRIVER:
+M:     Hans de Goede <hdegoede@redhat.com>
+L:     linux-fsdevel@vger.kernel.org
+S:     Maintained
+F:     fs/vboxsf/*
+
 VIRTUAL SERIO DEVICE DRIVER
 M:     Stephen Chandler Paul <thatslyude@gmail.com>
 S:     Maintained
index 48b5e10..98de654 100644 (file)
@@ -393,18 +393,23 @@ config HAVE_ARCH_JUMP_LABEL
 config HAVE_ARCH_JUMP_LABEL_RELATIVE
        bool
 
-config HAVE_RCU_TABLE_FREE
+config MMU_GATHER_TABLE_FREE
        bool
 
-config HAVE_RCU_TABLE_NO_INVALIDATE
+config MMU_GATHER_RCU_TABLE_FREE
        bool
+       select MMU_GATHER_TABLE_FREE
 
-config HAVE_MMU_GATHER_PAGE_SIZE
+config MMU_GATHER_PAGE_SIZE
        bool
 
-config HAVE_MMU_GATHER_NO_GATHER
+config MMU_GATHER_NO_RANGE
        bool
 
+config MMU_GATHER_NO_GATHER
+       bool
+       depends on MMU_GATHER_TABLE_FREE
+
 config ARCH_HAVE_NMI_SAFE_CMPXCHG
        bool
 
index 7268222..528d2be 100644 (file)
@@ -119,13 +119,12 @@ static ssize_t srm_env_proc_write(struct file *file, const char __user *buffer,
        return res;
 }
 
-static const struct file_operations srm_env_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = srm_env_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = srm_env_proc_write,
+static const struct proc_ops srm_env_proc_ops = {
+       .proc_open      = srm_env_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = srm_env_proc_write,
 };
 
 static int __init
@@ -182,7 +181,7 @@ srm_env_init(void)
        entry = srm_named_entries;
        while (entry->name && entry->id) {
                if (!proc_create_data(entry->name, 0644, named_dir,
-                            &srm_env_proc_fops, (void *)entry->id))
+                            &srm_env_proc_ops, (void *)entry->id))
                        goto cleanup;
                entry++;
        }
@@ -194,7 +193,7 @@ srm_env_init(void)
                char name[4];
                sprintf(name, "%ld", var_num);
                if (!proc_create_data(name, 0644, numbered_dir,
-                            &srm_env_proc_fops, (void *)var_num))
+                            &srm_env_proc_ops, (void *)var_num))
                        goto cleanup;
        }
 
index 9019ed9..12be7e1 100644 (file)
@@ -273,6 +273,7 @@ static inline void pmd_set(pmd_t *pmdp, pte_t *ptep)
 #define pmd_none(x)                    (!pmd_val(x))
 #define        pmd_bad(x)                      ((pmd_val(x) & ~PAGE_MASK))
 #define pmd_present(x)                 (pmd_val(x))
+#define pmd_leaf(x)                    (pmd_val(x) & _PAGE_HW_SZ)
 #define pmd_clear(xp)                  do { pmd_val(*(xp)) = 0; } while (0)
 
 #define pte_page(pte)          pfn_to_page(pte_pfn(pte))
index 0b1b1c6..97864aa 100644 (file)
@@ -74,7 +74,7 @@ config ARM
        select HAVE_CONTEXT_TRACKING
        select HAVE_COPY_THREAD_TLS
        select HAVE_C_RECORDMCOUNT
-       select HAVE_DEBUG_KMEMLEAK
+       select HAVE_DEBUG_KMEMLEAK if !XIP_KERNEL
        select HAVE_DMA_CONTIGUOUS if MMU
        select HAVE_DYNAMIC_FTRACE if !XIP_KERNEL && !CPU_ENDIAN_BE32 && MMU
        select HAVE_DYNAMIC_FTRACE_WITH_REGS if HAVE_DYNAMIC_FTRACE
@@ -102,7 +102,7 @@ config ARM
        select HAVE_PERF_EVENTS
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
-       select HAVE_RCU_TABLE_FREE if SMP && ARM_LPAE
+       select MMU_GATHER_RCU_TABLE_FREE if SMP && ARM_LPAE
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RSEQ
        select HAVE_STACKPROTECTOR
@@ -1905,7 +1905,7 @@ config XIP_DEFLATED_DATA
 config KEXEC
        bool "Kexec system call (EXPERIMENTAL)"
        depends on (!SMP || PM_SLEEP_SMP)
-       depends on !CPU_V7M
+       depends on MMU
        select KEXEC_CORE
        help
          kexec is a system call that implements the ability to shutdown your
index 8bcbd0c..b70d7de 100644 (file)
@@ -147,14 +147,14 @@ choice
                    0x80024000      | 0xf0024000     | UART9
 
        config DEBUG_AT91_RM9200_DBGU
-               bool "Kernel low-level debugging on AT91RM9200, AT91SAM9 DBGU"
+               bool "Kernel low-level debugging on AT91RM9200, AT91SAM9, SAM9X60 DBGU"
                select DEBUG_AT91_UART
-               depends on SOC_AT91RM9200 || SOC_AT91SAM9
+               depends on SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAM9X60
                help
                  Say Y here if you want kernel low-level debugging support
                  on the DBGU port of:
                    at91rm9200, at91sam9260, at91sam9g20, at91sam9261,
-                   at91sam9g10, at91sam9n12, at91sam9rl64, at91sam9x5
+                   at91sam9g10, at91sam9n12, at91sam9rl64, at91sam9x5, sam9x60
 
        config DEBUG_AT91_SAM9263_DBGU
                bool "Kernel low-level debugging on AT91SAM{9263,9G45,A5D3} DBGU"
index a1e883c..da599c3 100644 (file)
@@ -110,12 +110,12 @@ endif
 
 # -fstack-protector-strong triggers protection checks in this code,
 # but it is being used too early to link to meaningful stack_chk logic.
-nossp_flags := $(call cc-option, -fno-stack-protector)
-CFLAGS_atags_to_fdt.o := $(nossp_flags)
-CFLAGS_fdt.o := $(nossp_flags)
-CFLAGS_fdt_ro.o := $(nossp_flags)
-CFLAGS_fdt_rw.o := $(nossp_flags)
-CFLAGS_fdt_wip.o := $(nossp_flags)
+nossp-flags-$(CONFIG_CC_HAS_STACKPROTECTOR_NONE) := -fno-stack-protector
+CFLAGS_atags_to_fdt.o := $(nossp-flags-y)
+CFLAGS_fdt.o := $(nossp-flags-y)
+CFLAGS_fdt_ro.o := $(nossp-flags-y)
+CFLAGS_fdt_rw.o := $(nossp-flags-y)
+CFLAGS_fdt_wip.o := $(nossp-flags-y)
 
 ccflags-y := -fpic $(call cc-option,-mno-single-pic-base,) -fno-builtin -I$(obj)
 asflags-y := -DZIMAGE
index ead21e5..088b0a0 100644 (file)
 #endif
                .endm
 
+               .macro  enable_cp15_barriers, reg
+               mrc     p15, 0, \reg, c1, c0, 0 @ read SCTLR
+               tst     \reg, #(1 << 5)         @ CP15BEN bit set?
+               bne     .L_\@
+               orr     \reg, \reg, #(1 << 5)   @ CP15 barrier instructions
+               mcr     p15, 0, \reg, c1, c0, 0 @ write SCTLR
+ ARM(          .inst   0xf57ff06f              @ v7+ isb       )
+ THUMB(                isb                                             )
+.L_\@:
+               .endm
+
                .section ".start", "ax"
 /*
  * sort out different calling conventions
@@ -820,6 +831,7 @@ __armv4_mmu_cache_on:
                mov     pc, r12
 
 __armv7_mmu_cache_on:
+               enable_cp15_barriers    r11
                mov     r12, lr
 #ifdef CONFIG_MMU
                mrc     p15, 0, r11, c0, c1, 4  @ read ID_MMFR0
@@ -1209,6 +1221,7 @@ __armv6_mmu_cache_flush:
                mov     pc, lr
 
 __armv7_mmu_cache_flush:
+               enable_cp15_barriers    r10
                tst     r4, #1
                bne     iflush
                mrc     p15, 0, r10, c0, c1, 5  @ read ID_MMFR1
@@ -1447,21 +1460,7 @@ ENTRY(efi_stub_entry)
 
                @ Preserve return value of efi_entry() in r4
                mov     r4, r0
-
-               @ our cache maintenance code relies on CP15 barrier instructions
-               @ but since we arrived here with the MMU and caches configured
-               @ by UEFI, we must check that the CP15BEN bit is set in SCTLR.
-               @ Note that this bit is RAO/WI on v6 and earlier, so the ISB in
-               @ the enable path will be executed on v7+ only.
-               mrc     p15, 0, r1, c1, c0, 0   @ read SCTLR
-               tst     r1, #(1 << 5)           @ CP15BEN bit set?
-               bne     0f
-               orr     r1, r1, #(1 << 5)       @ CP15 barrier instructions
-               mcr     p15, 0, r1, c1, c0, 0   @ write SCTLR
- ARM(          .inst   0xf57ff06f              @ v7+ isb       )
- THUMB(                isb                                             )
-
-0:             bl      cache_clean_flush
+               bl      cache_clean_flush
                bl      cache_off
 
                @ Set parameters for booting zImage according to boot protocol
index 08011dc..d6546d2 100644 (file)
@@ -37,18 +37,24 @@ dtb-$(CONFIG_SOC_AT91SAM9) += \
        at91-ariag25.dtb \
        at91-ariettag25.dtb \
        at91-cosino_mega2560.dtb \
-       at91-kizboxmini.dtb \
+       at91-kizboxmini-base.dtb \
+       at91-kizboxmini-mb.dtb \
+       at91-kizboxmini-rd.dtb \
+       at91-smartkiz.dtb \
        at91-wb45n.dtb \
        at91sam9g15ek.dtb \
        at91sam9g25ek.dtb \
        at91sam9g35ek.dtb \
        at91sam9x25ek.dtb \
        at91sam9x35ek.dtb
+dtb-$(CONFIG_SOC_SAM9X60) += \
+       at91-sam9x60ek.dtb
 dtb-$(CONFIG_SOC_SAM_V7) += \
        at91-kizbox2-2.dtb \
        at91-kizbox3-hs.dtb \
        at91-nattis-2-natte-2.dtb \
        at91-sama5d27_som1_ek.dtb \
+       at91-sama5d27_wlsom1_ek.dtb \
        at91-sama5d2_ptc_ek.dtb \
        at91-sama5d2_xplained.dtb \
        at91-sama5d3_xplained.dtb \
@@ -422,6 +428,10 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
        imx6dl-gw560x.dtb \
        imx6dl-gw5903.dtb \
        imx6dl-gw5904.dtb \
+       imx6dl-gw5907.dtb \
+       imx6dl-gw5910.dtb \
+       imx6dl-gw5912.dtb \
+       imx6dl-gw5913.dtb \
        imx6dl-hummingboard.dtb \
        imx6dl-hummingboard-emmc-som-v15.dtb \
        imx6dl-hummingboard-som-v15.dtb \
@@ -493,6 +503,10 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
        imx6q-gw560x.dtb \
        imx6q-gw5903.dtb \
        imx6q-gw5904.dtb \
+       imx6q-gw5907.dtb \
+       imx6q-gw5910.dtb \
+       imx6q-gw5912.dtb \
+       imx6q-gw5913.dtb \
        imx6q-h100.dtb \
        imx6q-hummingboard.dtb \
        imx6q-hummingboard-emmc-som-v15.dtb \
@@ -554,6 +568,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
        imx6qp-zii-rdu2.dtb
 dtb-$(CONFIG_SOC_IMX6SL) += \
        imx6sl-evk.dtb \
+       imx6sl-tolino-shine3.dtb \
        imx6sl-warp.dtb
 dtb-$(CONFIG_SOC_IMX6SLL) += \
        imx6sll-evk.dtb \
@@ -612,6 +627,7 @@ dtb-$(CONFIG_SOC_IMX7D) += \
        imx7s-mba7.dtb \
        imx7s-warp.dtb
 dtb-$(CONFIG_SOC_IMX7ULP) += \
+       imx7ulp-com.dtb \
        imx7ulp-evk.dtb
 dtb-$(CONFIG_SOC_LS1021A) += \
        ls1021a-moxa-uc-8410a.dtb \
@@ -691,6 +707,7 @@ dtb-$(CONFIG_ARCH_OMAP3) += \
        omap3-devkit8000.dtb \
        omap3-devkit8000-lcd43.dtb \
        omap3-devkit8000-lcd70.dtb \
+       omap3-echo.dtb \
        omap3-evm.dtb \
        omap3-evm-37xx.dtb \
        omap3-gta04a3.dtb \
@@ -1129,6 +1146,7 @@ dtb-$(CONFIG_MACH_SUN8I) += \
        sun8i-h3-orangepi-plus2e.dtb \
        sun8i-h3-orangepi-zero-plus2.dtb \
        sun8i-h3-rervision-dvk.dtb \
+       sun8i-h3-emlid-neutis-n5h3-devboard.dtb \
        sun8i-r16-bananapi-m2m.dtb \
        sun8i-r16-nintendo-nes-classic.dtb \
        sun8i-r16-nintendo-super-nes-classic.dtb \
@@ -1182,7 +1200,9 @@ dtb-$(CONFIG_ARCH_U8500) += \
        ste-hrefprev60-stuib.dtb \
        ste-hrefprev60-tvk.dtb \
        ste-hrefv60plus-stuib.dtb \
-       ste-hrefv60plus-tvk.dtb
+       ste-hrefv60plus-tvk.dtb \
+       ste-href520-tvk.dtb \
+       ste-ux500-samsung-golden.dtb
 dtb-$(CONFIG_ARCH_UNIPHIER) += \
        uniphier-ld4-ref.dtb \
        uniphier-ld6b-ref.dtb \
@@ -1238,6 +1258,8 @@ dtb-$(CONFIG_MACH_ARMADA_370) += \
 dtb-$(CONFIG_MACH_ARMADA_375) += \
        armada-375-db.dtb
 dtb-$(CONFIG_MACH_ARMADA_38X) += \
+       armada-385-clearfog-gtr-s4.dtb \
+       armada-385-clearfog-gtr-l8.dtb \
        armada-385-db-88f6820-amc.dtb \
        armada-385-db-ap.dtb \
        armada-385-linksys-caiman.dtb \
index 6f0a6be..68252da 100644 (file)
                };
        };
 
-       backlight {
+       backlight: backlight {
                compatible = "pwm-backlight";
                pwms = <&ecap0 0 50000 0>;
                brightness-levels = <0 51 53 56 62 75 101 152 255>;
        };
 
        panel {
-               compatible = "ti,tilcdc,panel";
-               status = "okay";
+               compatible = "tfc,s9700rtwv43tr-01b";
+
                pinctrl-names = "default";
                pinctrl-0 = <&lcd_pins_s0>;
-               panel-info {
-                       ac-bias           = <255>;
-                       ac-bias-intrpt    = <0>;
-                       dma-burst-sz      = <16>;
-                       bpp               = <32>;
-                       fdd               = <0x80>;
-                       sync-edge         = <0>;
-                       sync-ctrl         = <1>;
-                       raster-order      = <0>;
-                       fifo-th           = <0>;
-               };
+               backlight = <&backlight>;
 
-               display-timings {
-                       800x480p62 {
-                               clock-frequency = <30000000>;
-                               hactive = <800>;
-                               vactive = <480>;
-                               hfront-porch = <39>;
-                               hback-porch = <39>;
-                               hsync-len = <47>;
-                               vback-porch = <29>;
-                               vfront-porch = <13>;
-                               vsync-len = <2>;
-                               hsync-active = <1>;
-                               vsync-active = <1>;
+               port {
+                       panel_0: endpoint@0 {
+                               remote-endpoint = <&lcdc_0>;
                        };
                };
        };
        status = "okay";
 
        blue-and-red-wiring = "crossed";
+
+       port {
+               lcdc_0: endpoint@0 {
+                       remote-endpoint = <&panel_0>;
+               };
+       };
 };
 
 &elm {
index a97f9df..32f515a 100644 (file)
        };
 
        panel {
-               compatible = "ti,tilcdc,panel";
+               compatible = "newhaven,nhd-4.3-480272ef-atxl";
+
                pinctrl-names = "default", "sleep";
                pinctrl-0 = <&lcd_pins_default>;
                pinctrl-1 = <&lcd_pins_sleep>;
                backlight = <&lcd_bl>;
-               status = "okay";
-               panel-info {
-                       ac-bias         = <255>;
-                       ac-bias-intrpt  = <0>;
-                       dma-burst-sz    = <16>;
-                       bpp             = <32>;
-                       fdd             = <0x80>;
-                       sync-edge       = <0>;
-                       sync-ctrl       = <1>;
-                       raster-order    = <0>;
-                       fifo-th         = <0>;
-               };
-               display-timings {
-                       480x272 {
-                               hactive         = <480>;
-                               vactive         = <272>;
-                               hback-porch     = <43>;
-                               hfront-porch    = <8>;
-                               hsync-len       = <4>;
-                               vback-porch     = <12>;
-                               vfront-porch    = <4>;
-                               vsync-len       = <10>;
-                               clock-frequency = <9000000>;
-                               hsync-active    = <0>;
-                               vsync-active    = <0>;
+
+               port {
+                       panel_0: endpoint@0 {
+                               remote-endpoint = <&lcdc_0>;
                        };
                };
        };
        status = "okay";
 
        blue-and-red-wiring = "crossed";
+
+       port {
+               lcdc_0: endpoint@0 {
+                       remote-endpoint = <&panel_0>;
+               };
+       };
 };
 
 &rtc {
index 204bccf..021eb57 100644 (file)
                gpio-controller;
                #gpio-cells = <2>;
        };
+
+       /* osd9616p0899-10 */
+       display@3c {
+               compatible = "solomon,ssd1306fb-i2c";
+               reg = <0x3c>;
+               solomon,height = <16>;
+               solomon,width = <96>;
+               solomon,com-seq;
+               solomon,com-invdir;
+               solomon,page-offset = <0>;
+               solomon,prechargep1 = <2>;
+               solomon,prechargep2 = <13>;
+       };
 };
 
 &spi0 {
index 3a8a205..4e2986f 100644 (file)
 
                target-module@d000 {                    /* 0x44e0d000, ap 20 38.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "adc_tsc";
                        reg = <0xd000 0x4>,
                              <0xd010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@30000 {                   /* 0x48030000, ap 77 08.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spi0";
                        reg = <0x30000 0x4>,
                              <0x30110 0x4>,
                              <0x30114 0x4>;
 
                target-module@42000 {                   /* 0x48042000, ap 24 1c.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer3";
                        reg = <0x42000 0x4>,
                              <0x42010 0x4>,
                              <0x42014 0x4>;
 
                target-module@44000 {                   /* 0x48044000, ap 26 26.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer4";
                        reg = <0x44000 0x4>,
                              <0x44010 0x4>,
                              <0x44014 0x4>;
 
                target-module@46000 {                   /* 0x48046000, ap 28 28.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer5";
                        reg = <0x46000 0x4>,
                              <0x46010 0x4>,
                              <0x46014 0x4>;
 
                target-module@48000 {                   /* 0x48048000, ap 30 22.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer6";
                        reg = <0x48000 0x4>,
                              <0x48010 0x4>,
                              <0x48014 0x4>;
 
                target-module@4a000 {                   /* 0x4804a000, ap 85 60.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer7";
                        reg = <0x4a000 0x4>,
                              <0x4a010 0x4>,
                              <0x4a014 0x4>;
 
                target-module@80000 {                   /* 0x48080000, ap 38 18.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "elm";
                        reg = <0x80000 0x4>,
                              <0x80010 0x4>,
                              <0x80014 0x4>;
 
                target-module@ca000 {                   /* 0x480ca000, ap 91 40.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spinlock";
                        reg = <0xca000 0x4>,
                              <0xca010 0x4>,
                              <0xca014 0x4>;
 
                target-module@a0000 {                   /* 0x481a0000, ap 79 24.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spi1";
                        reg = <0xa0000 0x4>,
                              <0xa0110 0x4>,
                              <0xa0114 0x4>;
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        reg = <0xcc020 0x4>;
                        reg-names = "rev";
-                       ti,hwmods = "d_can0";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM3_L4LS_D_CAN0_CLKCTRL 0>,
                                 <&dcan0_fck>;
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        reg = <0xd0020 0x4>;
                        reg-names = "rev";
-                       ti,hwmods = "d_can1";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM3_L4LS_D_CAN1_CLKCTRL 0>,
                                 <&dcan1_fck>;
 
                target-module@0 {                       /* 0x48300000, ap 66 48.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss0";
                        reg = <0x0 0x4>,
                              <0x4 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@2000 {                    /* 0x48302000, ap 68 52.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss1";
                        reg = <0x2000 0x4>,
                              <0x2004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@4000 {                    /* 0x48304000, ap 70 44.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss2";
                        reg = <0x4000 0x4>,
                              <0x4004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@e000 {                    /* 0x4830e000, ap 72 4a.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "lcdc";
                        reg = <0xe000 0x4>,
                              <0xe054 0x4>;
                        reg-names = "rev", "sysc";
index 646f114..41dcfb3 100644 (file)
                        status = "disabled";
                };
 
-               sham: sham@53100000 {
-                       compatible = "ti,omap4-sham";
-                       ti,hwmods = "sham";
-                       reg = <0x53100000 0x200>;
-                       interrupts = <109>;
-                       dmas = <&edma 36 0>;
-                       dma-names = "rx";
+               sham_target: target-module@53100000 {
+                       compatible = "ti,sysc-omap3-sham", "ti,sysc";
+                       reg = <0x53100100 0x4>,
+                             <0x53100110 0x4>,
+                             <0x53100114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): per_pwrdm, l3_clkdm */
+                       clocks = <&l3_clkctrl AM3_L3_SHAM_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x53100000 0x1000>;
+
+                       sham: sham@0 {
+                               compatible = "ti,omap4-sham";
+                               reg = <0 0x200>;
+                               interrupts = <109>;
+                               dmas = <&edma 36 0>;
+                               dma-names = "rx";
+                       };
+               };
+
+               aes_target: target-module@53500000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x53500080 0x4>,
+                             <0x53500084 0x4>,
+                             <0x53500088 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): per_pwrdm, l3_clkdm */
+                       clocks = <&l3_clkctrl AM3_L3_AES_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x53500000 0x1000>;
+
+                       aes: aes@0 {
+                               compatible = "ti,omap4-aes";
+                               reg = <0 0xa0>;
+                               interrupts = <103>;
+                               dmas = <&edma 6 0>,
+                                      <&edma 5 0>;
+                               dma-names = "tx", "rx";
+                       };
                };
 
-               aes: aes@53500000 {
-                       compatible = "ti,omap4-aes";
-                       ti,hwmods = "aes";
-                       reg = <0x53500000 0xa0>;
-                       interrupts = <103>;
-                       dmas = <&edma 6 0>,
-                              <&edma 5 0>;
-                       dma-names = "tx", "rx";
+               target-module@56000000 {
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x5600fe00 0x4>,
+                             <0x5600fe10 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       clocks = <&gfx_l3_clkctrl AM3_GFX_L3_GFX_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_gfx 0>;
+                       reset-names = "rstctrl";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x56000000 0x1000000>;
+
+                       /*
+                        * Closed source PowerVR driver, no child device
+                        * binding or driver in mainline
+                        */
                };
        };
 };
index 125379e..e0b5a00 100644 (file)
@@ -74,7 +74,7 @@
                        clock-names = "ick";
                };
 
-               davinci_mdio: ethernet@5c030000 {
+               davinci_mdio: mdio@5c030000 {
                        compatible = "ti,davinci_mdio";
                        ti,hwmods = "davinci_mdio";
                        status = "disabled";
diff --git a/arch/arm/boot/dts/am3703.dtsi b/arch/arm/boot/dts/am3703.dtsi
new file mode 100644 (file)
index 0000000..2b994ae
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 André Hentschel <nerv@dawncrow.de>
+ */
+
+#include "omap36xx.dtsi"
+
+&iva {
+       status = "disabled";
+};
+
+&sgx_module {
+       status = "disabled";
+};
diff --git a/arch/arm/boot/dts/am3715.dtsi b/arch/arm/boot/dts/am3715.dtsi
new file mode 100644 (file)
index 0000000..ab328e8
--- /dev/null
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 André Hentschel <nerv@dawncrow.de>
+ */
+
+#include "omap36xx.dtsi"
+
+&iva {
+       status = "disabled";
+};
index ca0aa3f..faa14dc 100644 (file)
                        };
                };
 
-               sham: sham@53100000 {
-                       compatible = "ti,omap5-sham";
-                       ti,hwmods = "sham";
-                       reg = <0x53100000 0x300>;
-                       dmas = <&edma 36 0>;
-                       dma-names = "rx";
-                       interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+               sham_target: target-module@53100000 {
+                       compatible = "ti,sysc-omap3-sham", "ti,sysc";
+                       reg = <0x53100100 0x4>,
+                             <0x53100110 0x4>,
+                             <0x53100114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): per_pwrdm, l3_clkdm */
+                       clocks = <&l3_clkctrl AM4_L3_SHAM_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x53100000 0x1000>;
+
+                       sham: sham@0 {
+                               compatible = "ti,omap5-sham";
+                               reg = <0 0x300>;
+                               dmas = <&edma 36 0>;
+                               dma-names = "rx";
+                               interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+                       };
                };
 
-               aes: aes@53501000 {
-                       compatible = "ti,omap4-aes";
-                       ti,hwmods = "aes";
-                       reg = <0x53501000 0xa0>;
-                       interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&edma 6 0>,
-                               <&edma 5 0>;
-                       dma-names = "tx", "rx";
+               aes_target: target-module@53501000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x53501080 0x4>,
+                             <0x53501084 0x4>,
+                             <0x53501088 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): per_pwrdm, l3_clkdm */
+                       clocks = <&l3_clkctrl AM4_L3_AES_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x53501000 0x1000>;
+
+                       aes: aes@0 {
+                               compatible = "ti,omap4-aes";
+                               reg = <0 0xa0>;
+                               interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&edma 6 0>,
+                                     <&edma 5 0>;
+                               dma-names = "tx", "rx";
+                       };
                };
 
-               des: des@53701000 {
-                       compatible = "ti,omap4-des";
-                       ti,hwmods = "des";
-                       reg = <0x53701000 0xa0>;
-                       interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&edma 34 0>,
-                               <&edma 33 0>;
-                       dma-names = "tx", "rx";
+               des_target: target-module@53701000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x53701030 0x4>,
+                             <0x53701034 0x4>,
+                             <0x53701038 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): per_pwrdm, l3_clkdm */
+                       clocks = <&l3_clkctrl AM4_L3_DES_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x53701000 0x1000>;
+
+                       des: des@0 {
+                               compatible = "ti,omap4-des";
+                               reg = <0 0xa0>;
+                               interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&edma 34 0>,
+                                      <&edma 33 0>;
+                               dma-names = "tx", "rx";
+                       };
                };
 
                gpmc: gpmc@50000000 {
                        status = "disabled";
                };
 
-               qspi: spi@47900000 {
-                       compatible = "ti,am4372-qspi";
-                       reg = <0x47900000 0x100>,
-                             <0x30000000 0x4000000>;
-                       reg-names = "qspi_base", "qspi_mmap";
+               target-module@47900000 {
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x47900000 0x4>,
+                             <0x47900010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       clocks = <&l3s_clkctrl AM4_L3S_QSPI_CLKCTRL 0>;
+                       clock-names = "fck";
                        #address-cells = <1>;
-                       #size-cells = <0>;
-                       ti,hwmods = "qspi";
-                       interrupts = <0 138 0x4>;
-                       num-cs = <4>;
-                       status = "disabled";
+                       #size-cells = <1>;
+                       ranges = <0x0 0x47900000 0x1000>,
+                                <0x30000000 0x30000000 0x4000000>;
+
+                       qspi: spi@0 {
+                               compatible = "ti,am4372-qspi";
+                               reg = <0 0x100>,
+                                     <0x30000000 0x4000000>;
+                               reg-names = "qspi_base", "qspi_mmap";
+                               clocks = <&dpll_per_m2_div4_ck>;
+                               clock-names = "fck";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               interrupts = <0 138 0x4>;
+                               num-cs = <4>;
+                       };
                };
 
                dss: dss@4832a000 {
                                pool;
                        };
                };
+
+               target-module@56000000 {
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x5600fe00 0x4>,
+                             <0x5600fe10 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       clocks = <&gfx_l3_clkctrl AM4_GFX_L3_GFX_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_gfx 0>;
+                       reset-names = "rstctrl";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x56000000 0x1000000>;
+               };
        };
 };
 
index 0dd59ee..e18e17d 100644 (file)
 
                target-module@d000 {                    /* 0x44e0d000, ap 20 38.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "adc_tsc";
                        reg = <0xd000 0x4>,
                              <0xd010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@30000 {                   /* 0x48030000, ap 65 08.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spi0";
                        reg = <0x30000 0x4>,
                              <0x30110 0x4>,
                              <0x30114 0x4>;
 
                target-module@42000 {                   /* 0x48042000, ap 20 24.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer3";
                        reg = <0x42000 0x4>,
                              <0x42010 0x4>,
                              <0x42014 0x4>;
 
                target-module@44000 {                   /* 0x48044000, ap 22 26.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer4";
                        reg = <0x44000 0x4>,
                              <0x44010 0x4>,
                              <0x44014 0x4>;
 
                target-module@46000 {                   /* 0x48046000, ap 24 28.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer5";
                        reg = <0x46000 0x4>,
                              <0x46010 0x4>,
                              <0x46014 0x4>;
 
                target-module@48000 {                   /* 0x48048000, ap 26 1a.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer6";
                        reg = <0x48000 0x4>,
                              <0x48010 0x4>,
                              <0x48014 0x4>;
 
                target-module@4a000 {                   /* 0x4804a000, ap 71 48.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer7";
                        reg = <0x4a000 0x4>,
                              <0x4a010 0x4>,
                              <0x4a014 0x4>;
 
                target-module@80000 {                   /* 0x48080000, ap 32 18.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "elm";
                        reg = <0x80000 0x4>,
                              <0x80010 0x4>,
                              <0x80014 0x4>;
 
                target-module@ca000 {                   /* 0x480ca000, ap 77 38.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spinlock";
                        reg = <0xca000 0x4>,
                              <0xca010 0x4>,
                              <0xca014 0x4>;
 
                target-module@a0000 {                   /* 0x481a0000, ap 67 2c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spi1";
                        reg = <0xa0000 0x4>,
                              <0xa0110 0x4>,
                              <0xa0114 0x4>;
 
                target-module@a2000 {                   /* 0x481a2000, ap 69 2e.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spi2";
                        reg = <0xa2000 0x4>,
                              <0xa2110 0x4>,
                              <0xa2114 0x4>;
 
                target-module@a4000 {                   /* 0x481a4000, ap 92 62.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spi3";
                        reg = <0xa4000 0x4>,
                              <0xa4110 0x4>,
                              <0xa4114 0x4>;
 
                target-module@c1000 {                   /* 0x481c1000, ap 94 68.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer8";
                        reg = <0xc1000 0x4>,
                              <0xc1010 0x4>,
                              <0xc1014 0x4>;
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        reg = <0xcc020 0x4>;
                        reg-names = "rev";
-                       ti,hwmods = "d_can0";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN0_CLKCTRL 0>;
                        clock-names = "fck";
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        reg = <0xd0020 0x4>;
                        reg-names = "rev";
-                       ti,hwmods = "d_can1";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
                        clocks = <&l4ls_clkctrl AM4_L4LS_D_CAN1_CLKCTRL 0>;
                        clock-names = "fck";
 
                target-module@0 {                       /* 0x48300000, ap 56 40.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss0";
                        reg = <0x0 0x4>,
                              <0x4 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@2000 {                    /* 0x48302000, ap 58 4a.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss1";
                        reg = <0x2000 0x4>,
                              <0x2004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@4000 {                    /* 0x48304000, ap 60 44.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss2";
                        reg = <0x4000 0x4>,
                              <0x4004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@6000 {                    /* 0x48306000, ap 96 58.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss3";
                        reg = <0x6000 0x4>,
                              <0x6004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@8000 {                    /* 0x48308000, ap 98 54.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss4";
                        reg = <0x8000 0x4>,
                              <0x8004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@a000 {                    /* 0x4830a000, ap 100 60.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss5";
                        reg = <0xa000 0x4>,
                              <0xa004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@26000 {                   /* 0x48326000, ap 86 66.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "vpfe0";
                        reg = <0x26000 0x4>,
                              <0x26104 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@28000 {                   /* 0x48328000, ap 75 0e.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "vpfe1";
                        reg = <0x28000 0x4>,
                              <0x28104 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3d000 {                   /* 0x4833d000, ap 102 6e.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer9";
                        reg = <0x3d000 0x4>,
                              <0x3d010 0x4>,
                              <0x3d014 0x4>;
 
                target-module@3f000 {                   /* 0x4833f000, ap 104 5c.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer10";
                        reg = <0x3f000 0x4>,
                              <0x3f010 0x4>,
                              <0x3f014 0x4>;
 
                target-module@41000 {                   /* 0x48341000, ap 106 76.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer11";
                        reg = <0x41000 0x4>,
                              <0x41010 0x4>,
                              <0x41014 0x4>;
 
                target-module@45000 {                   /* 0x48345000, ap 108 6a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spi4";
                        reg = <0x45000 0x4>,
                              <0x45110 0x4>,
                              <0x45114 0x4>;
 
                target-module@a8000 {                   /* 0x483a8000, ap 125 6c.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "ocp2scp0";
                        reg = <0xa8000 0x4>;
                        reg-names = "rev";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
 
                target-module@e8000 {                   /* 0x483e8000, ap 129 78.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "ocp2scp1";
                        reg = <0xe8000 0x4>;
                        reg-names = "rev";
                        /* Domains (P, C): per_pwrdm, l4ls_clkdm */
index 74eaa6a..2522249 100644 (file)
                >;
        };
 
+       clkout1_pin: pinmux_clkout1_pin {
+               pinctrl-single,pins = <
+                       0x270 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* XDMA_EVENT_INTR0/CLKOUT1 */
+               >;
+       };
+
        cpsw_default: cpsw_default {
                pinctrl-single,pins = <
                        /* Slave 1 */
        pinctrl-0 = <&i2c1_pins>;
        clock-frequency = <400000>;
 
+       ov2659@30 {
+               compatible = "ovti,ov2659";
+               reg = <0x30>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&clkout1_pin>;
+
+               clocks = <&clkout1_mux_ck>;
+               clock-names = "xvclk";
+               assigned-clocks = <&clkout1_mux_ck>;
+               assigned-clock-parents = <&clkout1_osc_div_ck>;
+
+               port {
+                       ov2659_1: endpoint {
+                               remote-endpoint = <&vpfe0_ep>;
+                               link-frequencies = /bits/ 64 <70000000>;
+                       };
+               };
+       };
+
        edt-ft5306@38 {
                status = "okay";
                compatible = "edt,edt-ft5306", "edt,edt-ft5x06";
        /* Camera port */
        port {
                vpfe0_ep: endpoint {
-                       /* remote-endpoint = <&sensor>; add once we have it */
+                       remote-endpoint = <&ov2659_1>;
                        ti,am437x-vpfe-interface = <0>;
                        bus-width = <8>;
                        hsync-active = <0>;
index a6fbc08..27259fd 100644 (file)
                        system-clock-frequency = <12000000>;
                };
        };
+
+       audio_mstrclk: clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <12000000>;
+       };
 };
 
 &am43xx_pinmux {
                IOVDD-supply = <&dcdc4>; /* V3_3D -> DCDC4 */
                DVDD-supply = <&ldo1>; /* V1_8AUD -> V1_8D -> LDO1 */
        };
+
+       ov2659@30 {
+               compatible = "ovti,ov2659";
+               reg = <0x30>;
+
+               clocks = <&audio_mstrclk>;
+               clock-names = "xvclk";
+
+               port {
+                       ov2659_1: endpoint {
+                               remote-endpoint = <&vpfe1_ep>;
+                               link-frequencies = /bits/ 64 <70000000>;
+                       };
+               };
+       };
 };
 
 &i2c2 {
 
        port {
                vpfe1_ep: endpoint {
-                       /* remote-endpoint = <&sensor>; add once we have it */
+                       remote-endpoint = <&ov2659_1>;
                        ti,am437x-vpfe-interface = <0>;
                        bus-width = <8>;
                        hsync-active = <0>;
index 091356f..c726cd8 100644 (file)
                ti,bit-shift = <8>;
                reg = <0x2a48>;
        };
+
+       clkout1_osc_div_ck: clkout1-osc-div-ck {
+               #clock-cells = <0>;
+               compatible = "ti,divider-clock";
+               clocks = <&sys_clkin_ck>;
+               ti,bit-shift = <20>;
+               ti,max-div = <4>;
+               reg = <0x4100>;
+       };
+
+       clkout1_src2_mux_ck: clkout1-src2-mux-ck {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&clk_rc32k_ck>, <&sysclk_div>, <&dpll_ddr_m2_ck>,
+                        <&dpll_per_m2_ck>, <&dpll_disp_m2_ck>,
+                        <&dpll_mpu_m2_ck>;
+               reg = <0x4100>;
+       };
+
+       clkout1_src2_pre_div_ck: clkout1-src2-pre-div-ck {
+               #clock-cells = <0>;
+               compatible = "ti,divider-clock";
+               clocks = <&clkout1_src2_mux_ck>;
+               ti,bit-shift = <4>;
+               ti,max-div = <8>;
+               reg = <0x4100>;
+       };
+
+       clkout1_src2_post_div_ck: clkout1-src2-post-div-ck {
+               #clock-cells = <0>;
+               compatible = "ti,divider-clock";
+               clocks = <&clkout1_src2_pre_div_ck>;
+               ti,bit-shift = <8>;
+               ti,max-div = <32>;
+               ti,index-power-of-two;
+               reg = <0x4100>;
+       };
+
+       clkout1_mux_ck: clkout1-mux-ck {
+               #clock-cells = <0>;
+               compatible = "ti,mux-clock";
+               clocks = <&clkout1_osc_div_ck>, <&clk_rc32k_ck>,
+                        <&clkout1_src2_post_div_ck>, <&dpll_extdev_m2_ck>;
+               ti,bit-shift = <16>;
+               reg = <0x4100>;
+       };
+
+       clkout1_ck: clkout1-ck {
+               #clock-cells = <0>;
+               compatible = "ti,gate-clock";
+               clocks = <&clkout1_mux_ck>;
+               ti,bit-shift = <23>;
+               reg = <0x4100>;
+       };
 };
 
 &prcm {
index 398721c..aa5e55f 100644 (file)
@@ -9,6 +9,7 @@
        aliases {
                rtc0 = &tps659038_rtc;
                rtc1 = &rtc;
+               display0 = &hdmi0;
        };
 
        chosen {
                        default-state = "off";
                };
        };
+
+       hdmi0: connector@0 {
+               compatible = "hdmi-connector";
+               label = "hdmi";
+
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&tpd12s015_out>;
+                       };
+               };
+       };
+
+       tpd12s015: encoder@0 {
+               compatible = "ti,tpd12s016", "ti,tpd12s015";
+
+               gpios = <0>, /* optional CT_CP_HPD */
+                       <0>, /* optional LS_OE */
+                       <&gpio7 12 GPIO_ACTIVE_HIGH>;   /* HPD */
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tpd12s015_in: endpoint@0 {
+                                       remote-endpoint = <&hdmi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tpd12s015_out: endpoint@0 {
+                                       remote-endpoint = <&hdmi_connector_in>;
+                               };
+                       };
+               };
+       };
 };
 
 &dra7_pmx_core {
 &cpu0 {
        vdd-supply = <&smps12_reg>;
 };
+
+&hdmi {
+       status = "okay";
+
+       vdda-supply = <&ldo4_reg>;
+
+       port {
+               hdmi_out: endpoint {
+                       remote-endpoint = <&tpd12s015_in>;
+               };
+       };
+};
+
+&dss {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/armada-385-clearfog-gtr-l8.dts b/arch/arm/boot/dts/armada-385-clearfog-gtr-l8.dts
new file mode 100644 (file)
index 0000000..c9ac630
--- /dev/null
@@ -0,0 +1,115 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+#include "armada-385-clearfog-gtr.dtsi"
+
+/ {
+       model = "SolidRun Clearfog GTR L8";
+};
+
+&mdio {
+       switch0: switch0@4 {
+               compatible = "marvell,mv88e6190";
+               reg = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&cf_gtr_switch_reset_pins>;
+               reset-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@1 {
+                               reg = <1>;
+                               label = "lan8";
+                               phy-handle = <&switch0phy0>;
+                       };
+
+                       port@2 {
+                               reg = <2>;
+                               label = "lan7";
+                               phy-handle = <&switch0phy1>;
+                       };
+
+                       port@3 {
+                               reg = <3>;
+                               label = "lan6";
+                               phy-handle = <&switch0phy2>;
+                       };
+
+                       port@4 {
+                               reg = <4>;
+                               label = "lan5";
+                               phy-handle = <&switch0phy3>;
+                       };
+
+                       port@5 {
+                               reg = <5>;
+                               label = "lan4";
+                               phy-handle = <&switch0phy4>;
+                       };
+
+                       port@6 {
+                               reg = <6>;
+                               label = "lan3";
+                               phy-handle = <&switch0phy5>;
+                       };
+
+                       port@7 {
+                               reg = <7>;
+                               label = "lan2";
+                               phy-handle = <&switch0phy6>;
+                       };
+
+                       port@8 {
+                               reg = <8>;
+                               label = "lan1";
+                               phy-handle = <&switch0phy7>;
+                       };
+
+                       port@10 {
+                               reg = <10>;
+                               label = "cpu";
+                               ethernet = <&eth1>;
+                       };
+
+               };
+
+               mdio {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       switch0phy0: switch0phy0@1 {
+                               reg = <0x1>;
+                       };
+
+                       switch0phy1: switch0phy1@2 {
+                               reg = <0x2>;
+                       };
+
+                       switch0phy2: switch0phy2@3 {
+                               reg = <0x3>;
+                       };
+
+                       switch0phy3: switch0phy3@4 {
+                               reg = <0x4>;
+                       };
+
+                       switch0phy4: switch0phy4@5 {
+                               reg = <0x5>;
+                       };
+
+                       switch0phy5: switch0phy5@6 {
+                               reg = <0x6>;
+                       };
+
+                       switch0phy6: switch0phy6@7 {
+                               reg = <0x7>;
+                       };
+
+                       switch0phy7: switch0phy7@8 {
+                               reg = <0x8>;
+                       };
+               };
+
+       };
+};
diff --git a/arch/arm/boot/dts/armada-385-clearfog-gtr-s4.dts b/arch/arm/boot/dts/armada-385-clearfog-gtr-s4.dts
new file mode 100644 (file)
index 0000000..fa653b3
--- /dev/null
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+
+#include "armada-385-clearfog-gtr.dtsi"
+
+/ {
+       model = "SolidRun Clearfog GTR S4";
+};
+
+&sfp0 {
+       tx-fault-gpio = <&gpio0 24 GPIO_ACTIVE_HIGH>;
+};
+
+&mdio {
+       switch0: switch0@4 {
+               compatible = "marvell,mv88e6085";
+               reg = <4>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&cf_gtr_switch_reset_pins>;
+               reset-gpios = <&gpio0 18 GPIO_ACTIVE_LOW>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@1 {
+                               reg = <1>;
+                               label = "lan2";
+                               phy-handle = <&switch0phy0>;
+                       };
+
+                       port@2 {
+                               reg = <2>;
+                               label = "lan1";
+                               phy-handle = <&switch0phy1>;
+                       };
+
+                       port@3 {
+                               reg = <3>;
+                               label = "lan4";
+                               phy-handle = <&switch0phy2>;
+                       };
+
+                       port@4 {
+                               reg = <4>;
+                               label = "lan3";
+                               phy-handle = <&switch0phy3>;
+                       };
+
+                       port@5 {
+                               reg = <5>;
+                               label = "cpu";
+                               ethernet = <&eth1>;
+                       };
+
+               };
+
+               mdio {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       switch0phy0: switch0phy0@11 {
+                               reg = <0x11>;
+                       };
+
+                       switch0phy1: switch0phy1@12 {
+                               reg = <0x12>;
+                       };
+
+                       switch0phy2: switch0phy2@13 {
+                               reg = <0x13>;
+                       };
+
+                       switch0phy3: switch0phy3@14 {
+                               reg = <0x14>;
+                       };
+               };
+
+       };
+};
diff --git a/arch/arm/boot/dts/armada-385-clearfog-gtr.dtsi b/arch/arm/boot/dts/armada-385-clearfog-gtr.dtsi
new file mode 100644 (file)
index 0000000..624bbca
--- /dev/null
@@ -0,0 +1,450 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Device Tree file for Clearfog GTR machines rev 1.0 (88F6825)
+ *
+ *  Rabeeh Khoury <rabeeh@solid-run.com>, based on Russell King clearfog work
+ */
+
+/*
+       SERDES mapping -
+       0. SATA1 on CON18, or optionally mini PCIe CON3 - PCIe0
+       1. 6141 switch (2.5Gbps capable)
+       2. SATA0 on CON17, or optionally mini PCIe CON4 - PCIe1
+       3. USB 3.0 Host
+       4. mini PCIe CON2 - PCIe2
+       5. SFP connector, or optionally SGMII Ethernet 1512 PHY
+
+       USB 2.0 mapping -
+       0. USB 2.0 - 0 USB pins header CON12
+       1. USB 2.0 - 1 mini PCIe CON2
+       2. USB 2.0 - 2 to USB 3.0 connector (used with SERDES #3)
+
+       Pin mapping -
+       0,1 - console UART
+       2,3 - I2C0 - connected to I2C EEPROM, two temperature sensors,
+             front panel and PSE controller
+       4,5 - MDC/MDIO
+       6..17 - RGMII
+       18 - Topaz switch reset (active low)
+       19 - 1512 phy reset
+       20 - 1512 phy reset (eth2, optional)
+       21,28,37,38,39,40 - SD0
+       22 - USB 3.0 current limiter enable (active high)
+       24 - SFP TX fault (input active high)
+       25 - SFP present (input active low)
+       26,27 - I2C1 - connected to SFP
+       29 - Fan PWM
+       30 - CON4 mini PCIe wifi disable
+       31 - CON3 mini PCIe wifi disable
+       32 - Fuse programming power toggle (1.8v)
+       33 - CON4 mini PCIe reset
+       34 - CON2 mini PCIe wifi disable
+       35 - CON3 mini PCIe reset
+       36 - Rear button (GPIO active low)
+       41 - CON1 front panel connector
+       42 - Front LED1, or front panel CON1
+       43 - Micron L-PBGA 24 ball SPI (1Gb) CS, or TPM SPI CS
+       44 - CON2 mini PCIe reset
+       45 - TPM PIRQ signal, or front panel CON1
+       46 - SFP TX disable
+       47 - Control isolation of boot sensitive SAR signals
+       48 - PSE reset
+       49 - PSE OSS signal
+       50 - PSE interrupt
+       52 - Front LED2, or front panel
+       53 - Front button
+       54 - SFP LOS (input active high)
+       55 - Fan sense
+       56(mosi),57(clk),58(miso) - SPI interface - 32Mb SPI, 1Gb SPI and TPM
+       59 - SPI 32Mb W25Q32BVZPIG CS0 chip select (bootable)
+*/
+
+/dts-v1/;
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/leds/common.h>
+#include "armada-385.dtsi"
+
+/ {
+       compatible = "marvell,armada385", "marvell,armada380";
+
+       aliases {
+               /* So that mvebu u-boot can update the MAC addresses */
+               ethernet1 = &eth0;
+               ethernet2 = &eth1;
+               ethernet3 = &eth2;
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x00000000 0x10000000>; /* 256 MB */
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_5p0v: regulator-5p0v {
+               compatible = "regulator-fixed";
+               regulator-name = "5P0V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       v_usb3_con: regulator-v-usb3-con {
+               compatible = "regulator-fixed";
+               gpio = <&gpio0 22 GPIO_ACTIVE_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&cf_gtr_usb3_con_vbus>;
+               regulator-max-microvolt = <5000000>;
+               regulator-min-microvolt = <5000000>;
+               regulator-name = "v_usb3_con";
+               vin-supply = <&reg_5p0v>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       soc {
+               ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000
+                         MBUS_ID(0x01, 0x1d) 0 0xfff00000 0x100000
+                         MBUS_ID(0x09, 0x19) 0 0xf1100000 0x10000
+                         MBUS_ID(0x09, 0x15) 0 0xf1110000 0x10000
+                         MBUS_ID(0x0c, 0x04) 0 0xf1200000 0x100000>;
+
+               internal-regs {
+
+                       rtc@a3800 {
+                               status = "okay";
+                       };
+
+                       i2c@11000 { /* ROM, temp sensor and front panel */
+                               pinctrl-0 = <&i2c0_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                       };
+
+                       i2c@11100 { /* SFP (CON5/CON6) */
+                               pinctrl-0 = <&cf_gtr_i2c1_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                       };
+
+                       pinctrl@18000 {
+                               cf_gtr_switch_reset_pins: cf-gtr-switch-reset-pins {
+                                       marvell,pins = "mpp18";
+                                       marvell,function = "gpio";
+                               };
+
+                               cf_gtr_usb3_con_vbus: cf-gtr-usb3-con-vbus {
+                                       marvell,pins = "mpp22";
+                                       marvell,function = "gpio";
+                               };
+
+                               cf_gtr_fan_pwm: cf-gtr-fan-pwm {
+                                       marvell,pins = "mpp23";
+                                       marvell,function = "gpio";
+                               };
+
+                               cf_gtr_i2c1_pins: i2c1-pins {
+                                       /* SFP */
+                                       marvell,pins = "mpp26", "mpp27";
+                                       marvell,function = "i2c1";
+                               };
+
+                               cf_gtr_sdhci_pins: cf-gtr-sdhci-pins {
+                                       marvell,pins = "mpp21", "mpp28",
+                                                      "mpp37", "mpp38",
+                                                      "mpp39", "mpp40";
+                                       marvell,function = "sd0";
+                               };
+
+                               cf_gtr_isolation_pins: cf-gtr-isolation-pins {
+                                       marvell,pins = "mpp47";
+                                       marvell,function = "gpio";
+                               };
+
+                               cf_gtr_poe_reset_pins: cf-gtr-poe-reset-pins {
+                                       marvell,pins = "mpp48";
+                                       marvell,function = "gpio";
+                               };
+
+                               cf_gtr_spi1_cs_pins: spi1-cs-pins {
+                                       marvell,pins = "mpp59";
+                                       marvell,function = "spi1";
+                               };
+
+                               cf_gtr_front_button_pins: cf-gtr-front-button-pins {
+                                       marvell,pins = "mpp53";
+                                       marvell,function = "gpio";
+                               };
+
+                               cf_gtr_rear_button_pins: cf-gtr-rear-button-pins {
+                                       marvell,pins = "mpp36";
+                                       marvell,function = "gpio";
+                               };
+                       };
+
+                       sdhci@d8000 {
+                               bus-width = <4>;
+                               no-1-8-v;
+                               non-removable;
+                               pinctrl-0 = <&cf_gtr_sdhci_pins>;
+                               pinctrl-names = "default";
+                               status = "okay";
+                               vmmc = <&reg_3p3v>;
+                               wp-inverted;
+                       };
+
+                       usb@58000 {
+                               status = "okay";
+                       };
+
+                       usb3@f0000 {
+                               status = "okay";
+                       };
+
+                       usb3@f8000 {
+                               vbus-supply = <&v_usb3_con>;
+                               status = "okay";
+                       };
+               };
+
+               pcie {
+                       status = "okay";
+                       /*
+                        * The PCIe units are accessible through
+                        * the mini-PCIe connectors on the board.
+                        */
+                       pcie@1,0 {
+                               reset-gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
+                               status = "okay";
+                       };
+
+                       pcie@2,0 {
+                               reset-gpios = <&gpio1 1 GPIO_ACTIVE_LOW>;
+                               status = "okay";
+                       };
+
+                       pcie@3,0 {
+                               reset-gpios = <&gpio1 12 GPIO_ACTIVE_LOW>;
+                               status = "okay";
+                       };
+               };
+       };
+
+       sfp0: sfp {
+               compatible = "sff,sfp";
+               i2c-bus = <&i2c1>;
+               los-gpio = <&gpio1 22 GPIO_ACTIVE_HIGH>;
+               mod-def0-gpio = <&gpio0 25 GPIO_ACTIVE_LOW>;
+               tx-disable-gpio = <&gpio1 14 GPIO_ACTIVE_HIGH>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               pinctrl-0 = <&cf_gtr_rear_button_pins &cf_gtr_front_button_pins>;
+               pinctrl-names = "default";
+
+               button_0 {
+                       label = "Rear Button";
+                       gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+                       linux,can-disable;
+                       linux,code = <BTN_0>;
+               };
+
+               button_1 {
+                       label = "Front Button";
+                       gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+                       linux,can-disable;
+                       linux,code = <BTN_1>;
+               };
+       };
+
+       gpio-leds {
+               compatible = "gpio-leds";
+
+               led1 {
+                       function = LED_FUNCTION_CPU;
+                       color = <LED_COLOR_ID_GREEN>;
+                       gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>;
+               };
+
+               led2 {
+                       function = LED_FUNCTION_HEARTBEAT;
+                       color = <LED_COLOR_ID_GREEN>;
+                       gpios = <&gpio1 20 GPIO_ACTIVE_HIGH>;
+               };
+       };
+};
+
+&bm {
+       status = "okay";
+};
+
+&bm_bppi {
+       status = "okay";
+};
+
+&eth0 {
+       /* ethernet@70000 */
+       pinctrl-0 = <&ge0_rgmii_pins>;
+       pinctrl-names = "default";
+       phy = <&phy_dedicated>;
+       phy-mode = "rgmii-id";
+       buffer-manager = <&bm>;
+       bm,pool-long = <0>;
+       bm,pool-short = <1>;
+       status = "okay";
+};
+
+&eth1 {
+       /* ethernet@30000 */
+       bm,pool-long = <2>;
+       bm,pool-short = <1>;
+       buffer-manager = <&bm>;
+       phys = <&comphy1 1>;
+       phy-mode = "2500base-x";
+       status = "okay";
+
+       fixed-link {
+               speed = <2500>;
+               full-duplex;
+       };
+};
+
+&eth2 {
+       /* ethernet@34000 */
+       bm,pool-long = <3>;
+       bm,pool-short = <1>;
+       buffer-manager = <&bm>;
+       managed = "in-band-status";
+       phys = <&comphy5 1>;
+       phy-mode = "sgmii";
+       sfp = <&sfp0>;
+       status = "okay";
+};
+
+&mdio {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mdio_pins>;
+       status = "okay";
+
+       phy_dedicated: ethernet-phy@0 {
+               /*
+                * Annoyingly, the marvell phy driver configures the LED
+                * register, rather than preserving reset-loaded setting.
+                * We undo that rubbish here.
+                */
+               marvell,reg-init = <3 16 0 0x1017>;
+               reg = <0>;
+       };
+};
+
+&uart0 {
+       pinctrl-0 = <&uart0_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&spi1 {
+       /*
+        * CS0: W25Q32 flash
+        */
+       pinctrl-0 = <&spi1_pins &cf_gtr_spi1_cs_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       spi-flash@0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "w25q32", "jedec,spi-nor";
+               reg = <0>; /* Chip select 0 */
+               spi-max-frequency = <3000000>;
+               status = "okay";
+       };
+};
+
+&i2c0 {
+       pinctrl-0 = <&i2c0_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       /* U26 temperature sensor placed near SoC */
+       temp1: nct75@4c {
+               compatible = "lm75";
+               reg = <0x4c>;
+       };
+
+       /* U27 temperature sensor placed near RTC battery */
+       temp2: nct75@4d {
+               compatible = "lm75";
+               reg = <0x4d>;
+       };
+
+       /* 2Kb eeprom */
+       eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+       };
+};
+
+&ahci0 {
+       status = "okay";
+};
+
+&ahci1 {
+       status = "okay";
+};
+
+&gpio0 {
+       pinctrl-0 = <&cf_gtr_fan_pwm>;
+       pinctrl-names = "default";
+
+       wifi-disable {
+               gpio-hog;
+               gpios = <30 GPIO_ACTIVE_LOW>, <31 GPIO_ACTIVE_LOW>;
+               output-low;
+               line-name = "wifi-disable";
+       };
+};
+
+&gpio1 {
+       pinctrl-0 = <&cf_gtr_isolation_pins &cf_gtr_poe_reset_pins>;
+       pinctrl-names = "default";
+
+       lte-disable {
+               gpio-hog;
+               gpios = <2 GPIO_ACTIVE_LOW>;
+               output-low;
+               line-name = "lte-disable";
+       };
+
+       /*
+        * This signal, when asserted, isolates Armada 38x sample at reset pins
+        * from control of external devices. Should be de-asserted after reset.
+        */
+       sar-isolation {
+               gpio-hog;
+               gpios = <15 GPIO_ACTIVE_LOW>;
+               output-low;
+               line-name = "sar-isolation";
+       };
+
+       poe-reset {
+               gpio-hog;
+               gpios = <16 GPIO_ACTIVE_LOW>;
+               output-low;
+               line-name = "poe-reset";
+       };
+};
index 0d81600..a0aa1d1 100644 (file)
 };
 
 &i2c0 {
-       clock-frequency = <400000>;
-       pinctrl-0 = <&i2c0_pins>;
-       pinctrl-names = "default";
-       status = "okay";
-
        /*
         * PCA9655 GPIO expander, up to 1MHz clock.
         *  0-CON3 CLKREQ#
                compatible = "microchip,mcp3021";
                reg = <0x4c>;
        };
+
+       eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
 };
 
 &i2c1 {
index 705adfa..fb49df2 100644 (file)
        soc {
                internal-regs {
                        i2c@11000 {
-                               clock-frequency = <400000>;
-                               pinctrl-0 = <&i2c0_pins>;
-                               pinctrl-names = "default";
-                               status = "okay";
-
                                /*
                                 * PCA9655 GPIO expander, up to 1MHz clock.
                                 *  0-Board Revision bit 0 #
index 3a7f9c1..363ac42 100644 (file)
        };
 };
 
+&i2c0 {
+       clock-frequency = <400000>;
+       pinctrl-0 = <&i2c0_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+};
+
 &pinctrl {
        microsom_phy_clk_pins: microsom-phy-clk-pins {
                marvell,pins = "mpp45";
index b1e10f0..322587b 100644 (file)
@@ -76,7 +76,6 @@
 
 &mac1 {
        status = "okay";
-       no-hw-checksum;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
 };
index aaa77a5..54e5085 100644 (file)
@@ -75,7 +75,6 @@
 
 &mac1 {
        status = "okay";
-       no-hw-checksum;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
 };
index 5293359..fe2e11c 100644 (file)
@@ -35,7 +35,6 @@
 &mac0 {
        status = "okay";
        use-ncsi;
-       no-hw-checksum;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
        clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>,
index 13f7aef..6232cd7 100644 (file)
        status = "okay";
 
        power-supply@68 {
-               compatible = "ibm,cffps2";
+               compatible = "ibm,cffps";
                reg = <0x68>;
        };
 
        power-supply@69 {
-               compatible = "ibm,cffps2";
+               compatible = "ibm,cffps";
                reg = <0x69>;
        };
 
        power-supply@6a {
-               compatible = "ibm,cffps2";
+               compatible = "ibm,cffps";
                reg = <0x6a>;
        };
 
        power-supply@6b {
-               compatible = "ibm,cffps2";
+               compatible = "ibm,cffps";
                reg = <0x6b>;
        };
 };
 &i2c8 {
        status = "okay";
 
-       ucd90320@b {
-               compatible = "ti,ucd90160";
-               reg = <0x0b>;
-       };
-
-       ucd90320@c {
-               compatible = "ti,ucd90160";
-               reg = <0x0c>;
-       };
-
        ucd90320@11 {
-               compatible = "ti,ucd90160";
+               compatible = "ti,ucd90320";
                reg = <0x11>;
        };
 
index c17bb7f..62a3ab4 100644 (file)
@@ -94,8 +94,6 @@
 
        gpio-keys-polled {
                compatible = "gpio-keys-polled";
-               #address-cells = <1>;
-               #size-cells = <0>;
                poll-interval = <1000>;
 
                fan0-presence {
index b8fdd2a..d56b5ed 100644 (file)
@@ -82,8 +82,6 @@
 
        gpio-keys-polled {
                compatible = "gpio-keys-polled";
-               #address-cells = <1>;
-               #size-cells = <0>;
                poll-interval = <1000>;
 
                scm0-presence {
index affd2c8..01074b6 100644 (file)
@@ -14,7 +14,7 @@
                bootargs = "console=ttyS4,115200 earlyprintk";
        };
 
-       memory {
+       memory@40000000 {
                reg = <0x40000000 0x20000000>;
        };
 
 
 &mac0 {
        status = "okay";
-
        use-ncsi;
-       no-hw-checksum;
-
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rmii1_default>;
 };
 &wdt2 {
        aspeed,alt-boot;
 };
+
+&sdmmc {
+       status = "okay";
+};
+
+&sdhci1 {
+       status = "okay";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sd2_default>;
+       cd-inverted;
+       disable-wp;
+};
index 569dad9..421aa60 100644 (file)
@@ -77,8 +77,6 @@
 
        gpio-keys-polled {
                compatible = "gpio-keys-polled";
-               #address-cells = <1>;
-               #size-cells = <0>;
                poll-interval = <1000>;
 
                fan0-presence {
index 46c0891..807a0fc 100644 (file)
                                compatible = "aspeed,ast2400-scu", "syscon", "simple-mfd";
                                reg = <0x1e6e2000 0x1a8>;
                                #address-cells = <1>;
-                               #size-cells = <0>;
+                               #size-cells = <1>;
+                               ranges = <0 0x1e6e2000 0x1000>;
                                #clock-cells = <1>;
                                #reset-cells = <1>;
 
-                               pinctrl: pinctrl {
-                                       compatible = "aspeed,ast2400-pinctrl";
-                               };
-
-                               p2a: p2a-control {
+                               p2a: p2a-control@2c {
+                                       reg = <0x2c 0x4>;
                                        compatible = "aspeed,ast2400-p2a-ctrl";
                                        status = "disabled";
                                };
+
+                               pinctrl: pinctrl@80 {
+                                       reg = <0x80 0x18>, <0xa0 0x10>;
+                                       compatible = "aspeed,ast2400-pinctrl";
+                               };
                        };
 
                        rng: hwrng@1e6e2078 {
 
                                        lpc_ctrl: lpc-ctrl@0 {
                                                compatible = "aspeed,ast2400-lpc-ctrl";
-                                               reg = <0x0 0x80>;
+                                               reg = <0x0 0x10>;
                                                clocks = <&syscon ASPEED_CLK_GATE_LCLK>;
                                                status = "disabled";
                                        };
 
-                                       lpc_snoop: lpc-snoop@0 {
+                                       lpc_snoop: lpc-snoop@10 {
                                                compatible = "aspeed,ast2400-lpc-snoop";
-                                               reg = <0x0 0x80>;
+                                               reg = <0x10 0x8>;
                                                interrupts = <8>;
                                                status = "disabled";
                                        };
index a259c63..ebec0fa 100644 (file)
                reg = <0x80000000 0>;
        };
 
-       edac: sdram@1e6e0000 {
-               compatible = "aspeed,ast2500-sdram-edac";
-               reg = <0x1e6e0000 0x174>;
-               interrupts = <0>;
-               status = "disabled";
-       };
-
        ahb {
                compatible = "simple-bus";
                #address-cells = <1>;
                        #size-cells = <1>;
                        ranges;
 
+                       edac: memory-controller@1e6e0000 {
+                               compatible = "aspeed,ast2500-sdram-edac";
+                               reg = <0x1e6e0000 0x174>;
+                               interrupts = <0>;
+                               status = "disabled";
+                       };
+
                        syscon: syscon@1e6e2000 {
                                compatible = "aspeed,ast2500-scu", "syscon", "simple-mfd";
                                reg = <0x1e6e2000 0x1a8>;
                                #address-cells = <1>;
-                               #size-cells = <0>;
+                               #size-cells = <1>;
+                               ranges = <0 0x1e6e2000 0x1000>;
                                #clock-cells = <1>;
                                #reset-cells = <1>;
 
-                               pinctrl: pinctrl {
-                                       compatible = "aspeed,ast2500-pinctrl";
-                                       aspeed,external-nodes = <&gfx &lhc>;
-
-                               };
-
-                               p2a: p2a-control {
+                               p2a: p2a-control@2c {
                                        compatible = "aspeed,ast2500-p2a-ctrl";
+                                       reg = <0x2c 0x4>;
                                        status = "disabled";
                                };
+
+                               pinctrl: pinctrl@80 {
+                                       compatible = "aspeed,ast2500-pinctrl";
+                                       reg = <0x80 0x18>, <0xa0 0x10>;
+                                       aspeed,external-nodes = <&gfx>, <&lhc>;
+                               };
                        };
 
                        rng: hwrng@1e6e2078 {
 
                                        lpc_ctrl: lpc-ctrl@0 {
                                                compatible = "aspeed,ast2500-lpc-ctrl";
-                                               reg = <0x0 0x80>;
+                                               reg = <0x0 0x10>;
                                                clocks = <&syscon ASPEED_CLK_GATE_LCLK>;
                                                status = "disabled";
                                        };
 
-                                       lpc_snoop: lpc-snoop@0 {
+                                       lpc_snoop: lpc-snoop@10 {
                                                compatible = "aspeed,ast2500-lpc-snoop";
-                                               reg = <0x0 0x80>;
+                                               reg = <0x10 0x8>;
                                                interrupts = <8>;
                                                status = "disabled";
                                        };
 
-                                       lhc: lhc@20 {
-                                               compatible = "aspeed,ast2500-lhc";
-                                               reg = <0x20 0x24 0x48 0x8>;
-                                       };
-
                                        lpc_reset: reset-controller@18 {
                                                compatible = "aspeed,ast2500-lpc-reset";
                                                reg = <0x18 0x4>;
                                                #reset-cells = <1>;
                                        };
 
+                                       lhc: lhc@20 {
+                                               compatible = "aspeed,ast2500-lhc";
+                                               reg = <0x20 0x24 0x48 0x8>;
+                                       };
+
+
                                        ibt: ibt@c0 {
                                                compatible = "aspeed,ast2500-ibt-bmc";
                                                reg = <0xc0 0x18>;
index b72afba..796976d 100644 (file)
                                status = "disabled";
                        };
 
-                       wdt4: watchdog@1e7850C0 {
+                       wdt4: watchdog@1e7850c0 {
                                compatible = "aspeed,ast2600-wdt";
                                reg = <0x1e7850C0 0x40>;
                                status = "disabled";
index 7a395ba..7468f10 100644 (file)
@@ -71,7 +71,6 @@
 
 &mac1 {
        status = "okay";
-       no-hw-checksum;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_rgmii2_default &pinctrl_mdio2_default>;
 };
index 90996ea..7d938cc 100644 (file)
                };
        };
 
-       ahb {
-               apb {
-                       tcb0: timer@fffa0000 {
-                               timer@0 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <0>, <1>;
-                               };
-
-                               timer@2 {
-                                       compatible = "atmel,tcb-timer";
-                                       reg = <2>;
-                               };
-                       };
-
-                       macb0: ethernet@fffc4000 {
-                               phy-mode = "mii";
-                               pinctrl-0 = <&pinctrl_macb_rmii
-                                            &pinctrl_macb_rmii_mii_alt>;
-                               status = "okay";
-                       };
-
-                       usart3: serial@fffd0000 {
-                               status = "okay";
-                       };
-
-                       dbgu: serial@fffff200 {
-                               status = "okay";
-                       };
-
-                       watchdog@fffffd40 {
-                               timeout-sec = <15>;
-                               atmel,max-heartbeat-sec = <16>;
-                               atmel,min-heartbeat-sec = <0>;
-                               status = "okay";
-                       };
-               };
-
-               usb0: ohci@500000 {
-                       num-ports = <1>;
-                       status = "okay";
-               };
-
-               ebi: ebi@10000000 {
-                       status = "okay";
-
-                       nand_controller: nand-controller {
-                               status = "okay";
-                               pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>;
-                               pinctrl-names = "default";
-
-                               nand@3 {
-                                       reg = <0x3 0x0 0x800000>;
-                                       rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>;
-                                       cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>;
-                                       nand-bus-width = <8>;
-                                       nand-ecc-mode = "soft";
-                                       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>;
                };
        };
 
-       i2c-gpio-0 {
-               status = "okay";
-
-               rtc: pcf8563@51 {
-                       compatible = "nxp,pcf8563";
-                       reg = <0x51>;
-               };
-       };
-
        pwm_leds {
                compatible = "pwm-leds";
 
                             &pinctrl_tcb1_tiob0>;
        };
 };
+
+&tcb0 {
+       timer@0 {
+               compatible = "atmel,tcb-timer";
+               reg = <0>, <1>;
+       };
+
+       timer@2 {
+               compatible = "atmel,tcb-timer";
+               reg = <2>;
+       };
+};
+
+&ebi {
+       status = "okay";
+};
+
+&nand_controller {
+       status = "okay";
+       pinctrl-0 = <&pinctrl_nand_cs &pinctrl_nand_rb>;
+       pinctrl-names = "default";
+
+       nand@3 {
+               reg = <0x3 0x0 0x800000>;
+               rb-gpios = <&pioC 13 GPIO_ACTIVE_HIGH>;
+               cs-gpios = <&pioC 14 GPIO_ACTIVE_HIGH>;
+               nand-bus-width = <8>;
+               nand-ecc-mode = "soft";
+               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>;
+                       };
+               };
+       };
+};
+
+&macb0 {
+       phy-mode = "mii";
+       pinctrl-0 = <&pinctrl_macb_rmii
+                    &pinctrl_macb_rmii_mii_alt>;
+       status = "okay";
+};
+
+&usart3 {
+       status = "okay";
+};
+
+&dbgu {
+       status = "okay";
+};
+
+&watchdog {
+       timeout-sec = <15>;
+       atmel,max-heartbeat-sec = <16>;
+       atmel,min-heartbeat-sec = <0>;
+       status = "okay";
+};
+
+&usb0 {
+       num-ports = <1>;
+       status = "okay";
+};
+
+&i2c_gpio0 {
+       status = "okay";
+
+       rtc: pcf8563@51 {
+               compatible = "nxp,pcf8563";
+               reg = <0x51>;
+       };
+};
diff --git a/arch/arm/boot/dts/at91-kizboxmini-base.dts b/arch/arm/boot/dts/at91-kizboxmini-base.dts
new file mode 100644 (file)
index 0000000..81c29ca
--- /dev/null
@@ -0,0 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * at91-kizboxmini-base.dts - Device Tree file for Overkiz Kizbox mini
+ * base board
+ *
+ * Copyright (C) 2015 Overkiz SAS
+ *   Author: Antoine Aubert <a.aubert@overkiz.com>
+ *           Kévin Raymond <k.raymond@overkiz.com>
+ */
+/dts-v1/;
+#include "at91-kizboxmini-common.dtsi"
+
+/ {
+       model = "Overkiz Kizbox Mini";
+       compatible = "overkiz,kizboxmini-base", "atmel,at91sam9g25",
+                    "atmel,at91sam9x5", "atmel,at91sam9";
+};
+
+&pinctrl_usart0 {
+       atmel,pins =
+               <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+                AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_NONE
+                AT91_PIOA 2 AT91_PERIPH_GPIO AT91_PINCTRL_MULTI_DRIVE>;
+};
similarity index 51%
rename from arch/arm/boot/dts/at91-kizboxmini.dts
rename to arch/arm/boot/dts/at91-kizboxmini-common.dtsi
index cb22f5f..fddf267 100644 (file)
@@ -1,17 +1,16 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
+// SPDX-License-Identifier: GPL-2.0
 /*
  * at91-kizboxmini.dts - Device Tree file for Overkiz Kizbox mini board
  *
- * Copyright (C) 2014 Gaël PORTAY <g.portay@overkiz.com>
+ * Copyright (C) 2014-2018 Overkiz SAS
+ *   Author: Antoine Aubert <a.aubert@overkiz.com>
+ *           Gaël Portay <g.portay@overkiz.com>
+ *           Kévin Raymond <k.raymond@overkiz.com>
+ *           Dorian Rocipon <d.rocipon@overkiz.com>
  */
-/dts-v1/;
 #include "at91sam9g25.dtsi"
-#include <dt-bindings/pwm/pwm.h>
 
 / {
-       model = "Overkiz Kizbox mini";
-       compatible = "overkiz,kizboxmini", "atmel,at91sam9g25", "atmel,at91sam9x5", "atmel,at91sam9";
-
        chosen {
                bootargs = "ubi.mtd=ubi";
                stdout-path = &dbgu;
        };
 
        clocks {
-               slow_xtal {
-                       clock-frequency = <32768>;
-               };
-
                main_xtal {
                        clock-frequency = <12000000>;
                };
-       };
 
-       ahb {
-               nand0: nand@40000000 {
-                       nand-bus-width = <8>;
-                       nand-ecc-mode = "hw";
-                       atmel,has-pmecc;
-                       atmel,pmecc-cap = <4>;
-                       atmel,pmecc-sector-size = <512>;
-                       nand-on-flash-bbt;
-                       status = "okay";
+               slow_xtal {
+                       clock-frequency = <32768>;
+               };
+
+               adc_op_clk {
+                       status = "disabled";
                };
        };
 
                };
        };
 
-       pwm_leds {
+       leds: pwm_leds {
                compatible = "pwm-leds";
 
-               green {
+               led_blue: pwm_blue {
+                       label = "pwm:blue:user";
+                       pwms = <&pwm0 2 10000000 0>;
+                       max-brightness = <255>;
+                       linux,default-trigger = "none";
+                       status = "disabled";
+               };
+
+               led_green: pwm_green {
                        label = "pwm:green:user";
                        pwms = <&pwm0 0 10000000 0>;
                        max-brightness = <255>;
                        linux,default-trigger = "default-on";
                };
 
-               red {
+               led_red: pwm_red {
                        label = "pwm:red:user";
                        pwms = <&pwm0 1 10000000 0>;
                        max-brightness = <255>;
        };
 };
 
-&dbgu {
+&usart0 {
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
        status = "okay";
 };
 
-&ebi {
-       pinctrl-0 = <&pinctrl_ebi_addr_nand
-                    &pinctrl_ebi_data_0_7>;
-       pinctrl-names = "default";
-       status = "okay";
-
-       nand-controller {
-               pinctrl-0 = <&pinctrl_nand_oe_we
-                            &pinctrl_nand_cs
-                            &pinctrl_nand_rb>;
-               pinctrl-names = "default";
-               status = "okay";
-
-               nand@3 {
-                       reg = <0x3 0x0 0x800000>;
-                       rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
-                       cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
-                       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>;
-                               };
-                       };
-               };
-       };
-};
-
 &macb0 {
        phy-mode = "rmii";
        status = "okay";
 &pwm0 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_pwm0_pwm0_1
-                    &pinctrl_pwm0_pwm1_1>;
+                    &pinctrl_pwm0_pwm1_1
+                    &pinctrl_pwm0_pwm2_1>;
        status = "okay";
 };
 
-&tcb0 {
-       timer@0 {
-               compatible = "atmel,tcb-timer";
-               reg = <0>;
-       };
+&dbgu {
+       status = "okay";
+};
 
-       timer@1 {
-               compatible = "atmel,tcb-timer";
-               reg = <1>;
-       };
+&watchdog {
+       status = "okay";
 };
 
-&usart0 {
+&adc0 {
+       status = "disabled";
+};
+
+&rtc {
+       status = "disabled";
+};
+
+&ebi {
+       pinctrl-0 = <&pinctrl_ebi_addr_nand
+                       &pinctrl_ebi_data_0_7>;
+       pinctrl-names = "default";
        status = "okay";
 };
 
+&nand_controller {
+       status = "okay";
+       pinctrl-0 = <&pinctrl_nand_oe_we
+                    &pinctrl_nand_cs
+                    &pinctrl_nand_rb>;
+       pinctrl-names = "default";
+
+       nand@3 {
+               reg = <0x3 0x0 0x800000>;
+               rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
+               cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
+               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>;
+                       };
+               };
+       };
+};
+
 &usb0 {
        num-ports = <1>;
        status = "okay";
        status = "okay";
 };
 
-&watchdog {
-       status = "okay";
-};
diff --git a/arch/arm/boot/dts/at91-kizboxmini-mb.dts b/arch/arm/boot/dts/at91-kizboxmini-mb.dts
new file mode 100644 (file)
index 0000000..c07d307
--- /dev/null
@@ -0,0 +1,26 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2015-2018 Overkiz SAS
+ *   Author: Mickael Gardet <m.gardet@overkiz.com>
+ *           Kévin Raymond <k.raymond@overkiz.com>
+ */
+/dts-v1/;
+#include "at91-kizboxmini-common.dtsi"
+
+/ {
+       model = "Overkiz Kizbox Mini Mother Board";
+       compatible = "overkiz,kizboxmini-mb", "atmel,at91sam9g25",
+                    "atmel,at91sam9x5", "atmel,at91sam9";
+};
+
+&usb0 {
+       num-ports = <2>;
+};
+
+&rtc {
+       status = "okay";
+};
+
+&led_blue {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/at91-kizboxmini-rd.dts b/arch/arm/boot/dts/at91-kizboxmini-rd.dts
new file mode 100644 (file)
index 0000000..ab50f4d
--- /dev/null
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2015-2018 Overkiz SAS
+ *   Author: Mickael Gardet <m.gardet@overkiz.com>
+ *           Kévin Raymond <k.raymond@overkiz.com>
+ */
+/dts-v1/;
+#include "at91-kizboxmini-common.dtsi"
+
+/ {
+       model = "Overkiz Kizbox Mini RailDIN";
+       compatible = "overkiz,kizboxmini-rd", "atmel,at91sam9g25",
+                    "atmel,at91sam9x5", "atmel,at91sam9";
+
+       clocks {
+               adc_op_clk {
+                       status = "okay";
+               };
+       };
+};
+
+&pinctrl {
+       adc0 {
+               pinctrl_adc0_ad5: adc0_ad5-0 {
+                       /* pull-up disable */
+                       atmel,pins = <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+       };
+};
+
+&usart0 {
+       status = "disabled";
+};
+
+&rtc {
+       status = "okay";
+};
+
+&led_blue {
+       status = "okay";
+};
+
+&adc0 {
+       atmel,adc-vref = <2500>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc0_ad5>;
+       atmel,adc-channels-used = <0x0020>;
+       status = "okay";
+};
index f245944..4f12347 100644 (file)
@@ -8,7 +8,6 @@
  */
 /dts-v1/;
 #include "at91-linea.dtsi"
-#include "sama5d3_lcd.dtsi"
 #include "at91-natte.dtsi"
 
 / {
diff --git a/arch/arm/boot/dts/at91-sam9x60ek.dts b/arch/arm/boot/dts/at91-sam9x60ek.dts
new file mode 100644 (file)
index 0000000..9f30132
--- /dev/null
@@ -0,0 +1,647 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sam9x60ek.dts - Device Tree file for Microchip SAM9X60-EK board
+ *
+ * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Sandeep Sheriker M <sandeepsheriker.mallikarjun@microchip.com>
+ */
+/dts-v1/;
+#include "sam9x60.dtsi"
+
+/ {
+       model = "Microchip SAM9X60-EK";
+       compatible = "microchip,sam9x60ek", "microchip,sam9x60", "atmel,at91sam9";
+
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               serial1 = &uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       clocks {
+               slow_xtal {
+                       clock-frequency = <32768>;
+               };
+
+               main_xtal {
+                       clock-frequency = <24000000>;
+               };
+       };
+
+       regulators: regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               vdd_1v8: fixed-regulator-vdd_1v8@0 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "VDD_1V8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+                       status = "okay";
+               };
+
+               vdd_1v5: fixed-regulator-vdd_1v5@1 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "VDD_1V5";
+                       regulator-min-microvolt = <1500000>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-always-on;
+                       status = "okay";
+               };
+
+               vdd1_3v3: fixed-regulator-vdd1_3v3@2 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "VDD1_3V3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+                       status = "okay";
+               };
+
+               vdd2_3v3: regulator-fixed-vdd2_3v3@3 {
+                       compatible = "regulator-fixed";
+                       regulator-name = "VDD2_3V3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+                       status = "okay";
+               };
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_key_gpio_default>;
+               status = "okay";
+
+               sw1 {
+                       label = "SW1";
+                       gpios = <&pioD 18 GPIO_ACTIVE_LOW>;
+                       linux,code=<0x104>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               status = "okay"; /* Conflict with pwm0. */
+
+               red {
+                       label = "red";
+                       gpios = <&pioB 11 GPIO_ACTIVE_HIGH>;
+               };
+
+               green {
+                       label = "green";
+                       gpios = <&pioB 12 GPIO_ACTIVE_HIGH>;
+               };
+
+               blue {
+                       label = "blue";
+                       gpios = <&pioB 13 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&adc {
+       vddana-supply = <&vdd1_3v3>;
+       vref-supply = <&vdd1_3v3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc_default &pinctrl_adtrg_default>;
+       status = "okay";
+};
+
+&can0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_can0_rx_tx>;
+       status = "disabled"; /* Conflict with dbgu. */
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_can1_rx_tx>;
+       status = "okay";
+};
+
+&classd {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_classd_default>;
+       atmel,pwm-type = "diff";
+       atmel,non-overlap-time = <10>;
+       status = "okay";
+};
+
+&dbgu {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_dbgu>;
+       status = "okay"; /* Conflict with can0. */
+};
+
+&ebi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ebi_addr_nand &pinctrl_ebi_data_0_7>;
+       status = "okay";
+
+       nand_controller: nand-controller {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_nand_oe_we &pinctrl_nand_cs &pinctrl_nand_rb>;
+               status = "okay";
+
+               nand@3 {
+                       reg = <0x3 0x0 0x800000>;
+                       rb-gpios = <&pioD 5 GPIO_ACTIVE_HIGH>;
+                       cs-gpios = <&pioD 4 GPIO_ACTIVE_HIGH>;
+                       nand-bus-width = <8>;
+                       nand-ecc-mode = "hw";
+                       nand-ecc-strength = <8>;
+                       nand-ecc-step-size = <512>;
+                       nand-on-flash-bbt;
+                       label = "atmel_nand";
+
+                       partitions {
+                               compatible = "fixed-partitions";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               at91bootstrap@0 {
+                                       label = "at91bootstrap";
+                                       reg = <0x0 0x40000>;
+                               };
+
+                               uboot@40000 {
+                                       label = "u-boot";
+                                       reg = <0x40000 0xc0000>;
+                               };
+
+                               ubootenvred@100000 {
+                                       label = "U-Boot Env Redundant";
+                                       reg = <0x100000 0x40000>;
+                               };
+
+                               ubootenv@140000 {
+                                       label = "U-Boot Env";
+                                       reg = <0x140000 0x40000>;
+                               };
+
+                               dtb@180000 {
+                                       label = "device tree";
+                                       reg = <0x180000 0x80000>;
+                               };
+
+                               kernel@200000 {
+                                       label = "kernel";
+                                       reg = <0x200000 0x600000>;
+                               };
+
+                               rootfs@800000 {
+                                       label = "rootfs";
+                                       reg = <0x800000 0x1f800000>;
+                               };
+                       };
+               };
+       };
+};
+
+&flx0 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+       status = "okay";
+
+       i2c0: i2c@600 {
+               compatible = "microchip,sam9x60-i2c";
+               reg = <0x600 0x200>;
+               interrupts = <5 IRQ_TYPE_LEVEL_HIGH 7>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_flx0_default>;
+               atmel,fifo-size = <16>;
+               i2c-analog-filter;
+               i2c-digital-filter;
+               i2c-digital-filter-width-ns = <35>;
+               status = "okay";
+
+               eeprom@53 {
+                       compatible = "atmel,24c32";
+                       reg = <0x53>;
+                       pagesize = <16>;
+                       size = <128>;
+                       status = "okay";
+               };
+       };
+};
+
+&flx4 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_SPI>;
+       status = "disabled";
+
+       spi0: spi@400 {
+               compatible = "microchip,sam9x60-spi", "atmel,at91rm9200-spi";
+               reg = <0x400 0x200>;
+               interrupts = <13 IRQ_TYPE_LEVEL_HIGH 7>;
+               clocks = <&pmc PMC_TYPE_PERIPHERAL 13>;
+               clock-names = "spi_clk";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_flx4_default>;
+               atmel,fifo-size = <16>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+       };
+};
+
+&flx5 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+       status = "okay";
+
+       uart1: serial@200 {
+               compatible = "microchip,sam9x60-usart", "atmel,at91sam9260-usart";
+               reg = <0x200 0x200>;
+               interrupts = <14 IRQ_TYPE_LEVEL_HIGH 7>;
+               dmas = <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                        AT91_XDMAC_DT_PERID(10))>,
+                      <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                        AT91_XDMAC_DT_PERID(11))>;
+               dma-names = "tx", "rx";
+               clocks = <&pmc PMC_TYPE_PERIPHERAL 14>;
+               clock-names = "usart";
+               pinctrl-0 = <&pinctrl_flx5_default>;
+               pinctrl-names = "default";
+               atmel,use-dma-rx;
+               atmel,use-dma-tx;
+               status = "okay";
+       };
+};
+
+&flx6 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>;
+       status = "okay";
+
+       i2c1: i2c@600 {
+               compatible = "microchip,sam9x60-i2c";
+               reg = <0x600 0x200>;
+               interrupts = <9 IRQ_TYPE_LEVEL_HIGH 7>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clocks = <&pmc PMC_TYPE_PERIPHERAL 9>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_flx6_default>;
+               atmel,fifo-size = <16>;
+               i2c-analog-filter;
+               i2c-digital-filter;
+               i2c-digital-filter-width-ns = <35>;
+               status = "okay";
+
+               gpio_exp: mcp23008@20 {
+                       compatible = "microchip,mcp23008";
+                       reg = <0x20>;
+               };
+       };
+};
+
+&i2s {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2s_default>;
+       #sound-dai-cells = <0>;
+       status = "disabled"; /* Conflict with QSPI. */
+};
+
+&macb0 {
+       phy-mode = "rmii";
+       #address-cells = <1>;
+       #size-cells = <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_macb0_rmii>;
+       status = "okay";
+
+       ethernet-phy@0 {
+               reg = <0x0>;
+       };
+};
+
+&pinctrl {
+       atmel,mux-mask = <
+                        /*     A       B       C       */
+                        0xFFFFFE7F 0xC0E0397F 0xEF00019D       /* pioA */
+                        0x03FFFFFF 0x02FC7E68 0x00780000       /* pioB */
+                        0xffffffff 0xF83FFFFF 0xB800F3FC       /* pioC */
+                        0x003FFFFF 0x003F8000 0x00000000       /* pioD */
+                        >;
+
+       adc {
+               pinctrl_adc_default: adc_default {
+                       atmel,pins = <AT91_PIOB 15 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_adtrg_default: adtrg_default {
+                       atmel,pins = <AT91_PIOB 18 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
+               };
+       };
+
+       dbgu {
+               pinctrl_dbgu: dbgu-0 {
+                       atmel,pins = <AT91_PIOA 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+                                     AT91_PIOA 10 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+               };
+       };
+
+       i2s {
+               pinctrl_i2s_default: i2s {
+                       atmel,pins =
+                               <AT91_PIOB 19 AT91_PERIPH_B AT91_PINCTRL_NONE           /* I2SCK */
+                                AT91_PIOB 20 AT91_PERIPH_B AT91_PINCTRL_NONE           /* I2SWS */
+                                AT91_PIOB 21 AT91_PERIPH_B AT91_PINCTRL_NONE           /* I2SDIN */
+                                AT91_PIOB 22 AT91_PERIPH_B AT91_PINCTRL_NONE           /* I2SDOUT */
+                                AT91_PIOB 23 AT91_PERIPH_B AT91_PINCTRL_NONE>;         /* I2SMCK */
+               };
+       };
+
+       qspi {
+               pinctrl_qspi: qspi {
+                       atmel,pins =
+                               <AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_SLEWRATE_DIS
+                                AT91_PIOB 20 AT91_PERIPH_A AT91_PINCTRL_SLEWRATE_DIS
+                                AT91_PIOB 21 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOB 22 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOB 23 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOB 24 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_SLEWRATE_DIS)>;
+               };
+       };
+
+       nand {
+               pinctrl_nand_oe_we: nand-oe-we-0 {
+                       atmel,pins =
+                               <AT91_PIOD 0 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 1 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)>;
+               };
+
+               pinctrl_nand_rb: nand-rb-0 {
+                       atmel,pins =
+                               <AT91_PIOD 5 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+               };
+
+               pinctrl_nand_cs: nand-cs-0 {
+                       atmel,pins =
+                               <AT91_PIOD 4 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_UP>;
+               };
+       };
+
+       ebi {
+               pinctrl_ebi_data_0_7: ebi-data-lsb-0 {
+                       atmel,pins =
+                               <AT91_PIOD 6 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 7 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 8 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 9 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 10 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 11 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 12 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 13 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)>;
+               };
+
+               pinctrl_ebi_data_0_15: ebi-data-msb-0 {
+                       atmel,pins =
+                               <AT91_PIOD 6 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 7 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 8 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 9 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 10 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 11 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 12 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 13 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 14 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 15 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 16 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 17 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 18 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 19 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 20 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOD 21 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_ebi_addr_nand: ebi-addr-0 {
+                       atmel,pins =
+                               <AT91_PIOD 2 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)
+                                AT91_PIOD 3 AT91_PERIPH_A (AT91_PINCTRL_NONE | AT91_PINCTRL_SLEWRATE_DIS)>;
+               };
+       };
+
+       flexcom {
+               pinctrl_flx0_default: flx0_twi {
+                       atmel,pins =
+                               <AT91_PIOA 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+                                AT91_PIOA 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+               };
+
+               pinctrl_flx4_default: flx4_spi {
+                       atmel,pins =
+                               <AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_flx5_default: flx_uart {
+                       atmel,pins =
+                               <AT91_PIOA 7 AT91_PERIPH_C AT91_PINCTRL_NONE
+                                AT91_PIOA 8 AT91_PERIPH_B AT91_PINCTRL_NONE
+                                AT91_PIOA 21 AT91_PERIPH_B AT91_PINCTRL_NONE
+                                AT91_PIOA 22 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_flx6_default: flx6_twi {
+                       atmel,pins =
+                               <AT91_PIOA 30 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
+                                AT91_PIOA 31 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
+               };
+       };
+
+       classd {
+               pinctrl_classd_default: classd {
+                       atmel,pins =
+                               <AT91_PIOA 24 AT91_PERIPH_C AT91_PINCTRL_PULL_UP
+                                AT91_PIOA 25 AT91_PERIPH_C AT91_PINCTRL_PULL_UP
+                                AT91_PIOA 26 AT91_PERIPH_C AT91_PINCTRL_PULL_UP
+                                AT91_PIOA 27 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>;
+               };
+       };
+
+       can0 {
+               pinctrl_can0_rx_tx: can0_rx_tx {
+                       atmel,pins =
+                               <AT91_PIOA 9 AT91_PERIPH_B AT91_PINCTRL_NONE    /* CANRX0 */
+                                AT91_PIOA 10 AT91_PERIPH_B AT91_PINCTRL_NONE   /* CANTX0 */
+                                AT91_PIOD 20 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_DOWN   /* Enable CAN0 mux */
+                                AT91_PIOD 21 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_DOWN>; /* Enable CAN Transceivers */
+               };
+       };
+
+       can1 {
+               pinctrl_can1_rx_tx: can1_rx_tx {
+                       atmel,pins =
+                               <AT91_PIOA 6 AT91_PERIPH_B AT91_PINCTRL_NONE    /* CANRX1 RXD1 */
+                                AT91_PIOA 5 AT91_PERIPH_B AT91_PINCTRL_NONE    /* CANTX1 TXD1 */
+                                AT91_PIOD 19 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_DOWN   /* Enable CAN1 mux */
+                                AT91_PIOD 21 AT91_PERIPH_GPIO AT91_PINCTRL_PULL_DOWN>; /* Enable CAN Transceivers */
+               };
+       };
+
+       macb0 {
+               pinctrl_macb0_rmii: macb0_rmii-0 {
+                       atmel,pins =
+                               <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB0 periph A */
+                                AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB1 periph A */
+                                AT91_PIOB 2 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB2 periph A */
+                                AT91_PIOB 3 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB3 periph A */
+                                AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB4 periph A */
+                                AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB5 periph A */
+                                AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB6 periph A */
+                                AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB7 periph A */
+                                AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_NONE    /* PB9 periph A */
+                                AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE>; /* PB10 periph A */
+               };
+       };
+
+       pwm0 {
+               pinctrl_pwm0_0: pwm0_0 {
+                       atmel,pins = <AT91_PIOB 11 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_pwm0_1: pwm0_1 {
+                       atmel,pins = <AT91_PIOB 12 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_pwm0_2: pwm0_2 {
+                       atmel,pins = <AT91_PIOB 13 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+               };
+
+               pinctrl_pwm0_3: pwm0_3 {
+                       atmel,pins = <AT91_PIOB 14 AT91_PERIPH_B AT91_PINCTRL_NONE>;
+               };
+       };
+
+       sdmmc0 {
+               pinctrl_sdmmc0_default: sdmmc0 {
+                       atmel,pins =
+                               <AT91_PIOA 17 AT91_PERIPH_A (AT91_PINCTRL_DRIVE_STRENGTH_HI)                            /* PA17 CK  periph A with pullup */
+                                AT91_PIOA 16 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI)     /* PA16 CMD periph A with pullup */
+                                AT91_PIOA 15 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI)     /* PA15 DAT0 periph A */
+                                AT91_PIOA 18 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI)     /* PA18 DAT1 periph A with pullup */
+                                AT91_PIOA 19 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI)     /* PA19 DAT2 periph A with pullup */
+                                AT91_PIOA 20 AT91_PERIPH_A (AT91_PINCTRL_PULL_UP | AT91_PINCTRL_DRIVE_STRENGTH_HI)>;   /* PA20 DAT3 periph A with pullup */
+               };
+       };
+
+       gpio_keys {
+               pinctrl_key_gpio_default: pinctrl_key_gpio {
+                       atmel,pins = <AT91_PIOD 18 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+       };
+}; /* pinctrl */
+
+&pmc {
+       atmel,osc-bypass;
+};
+
+&pwm0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_0 &pinctrl_pwm0_1 &pinctrl_pwm0_2 &pinctrl_pwm0_3>;
+       status = "disabled"; /* Conflict with leds. */
+};
+
+&sdmmc0 {
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sdmmc0_default>;
+       status = "okay";
+       cd-gpios = <&pioA 23 GPIO_ACTIVE_LOW>;
+       disable-wp;
+};
+
+&qspi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_qspi>;
+       status = "okay"; /* Conflict with i2s. */
+
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <80000000>;
+               m25p,fast-read;
+
+               at91bootstrap@0 {
+                       label = "qspi: at91bootstrap";
+                       reg = <0x0 0x40000>;
+               };
+
+               bootloader@40000 {
+                       label = "qspi: bootloader";
+                       reg = <0x40000 0xc0000>;
+               };
+
+               bootloaderenvred@100000 {
+                       label = "qspi: bootloader env redundant";
+                       reg = <0x100000 0x40000>;
+               };
+
+               bootloaderenv@140000 {
+                       label = "qspi: bootloader env";
+                       reg = <0x140000 0x40000>;
+               };
+
+               dtb@180000 {
+                       label = "qspi: device tree";
+                       reg = <0x180000 0x80000>;
+               };
+
+               kernel@200000 {
+                       label = "qspi: kernel";
+                       reg = <0x200000 0x600000>;
+               };
+       };
+};
+
+&shutdown_controller {
+       atmel,shdwc-debouncer = <976>;
+       status = "okay";
+
+       input@0 {
+               reg = <0>;
+       };
+};
+
+&tcb0 {
+       timer0: timer@0 {
+               compatible = "atmel,tcb-timer";
+               reg = <0>;
+       };
+
+       timer1: timer@1 {
+               compatible = "atmel,tcb-timer";
+               reg = <1>;
+       };
+};
+
+&usb1 {
+       num-ports = <3>;
+       atmel,vbus-gpio = <0
+                          &pioD 15 GPIO_ACTIVE_HIGH
+                          &pioD 16 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&usb2 {
+       status = "okay";
+};
index 7788d5d..6281590 100644 (file)
        };
 
        ahb {
+               sdmmc0: sdio-host@a0000000 {
+                       microchip,sdcal-inverted;
+               };
+
                apb {
                        qspi1: spi@f0024000 {
                                pinctrl-names = "default";
index fca5716..b0853bf 100644 (file)
                                        interrupts = <20 IRQ_TYPE_LEVEL_HIGH 7>;
                                        dmas = <0>, <0>;
                                        dma-names = "tx", "rx";
+                                       i2c-analog-filter;
+                                       i2c-digital-filter;
+                                       i2c-digital-filter-width-ns = <35>;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        clocks = <&pmc PMC_TYPE_PERIPHERAL 20>;
 
                        i2c1: i2c@fc028000 {
                                dmas = <0>, <0>;
+                               i2c-analog-filter;
+                               i2c-digital-filter;
+                               i2c-digital-filter-width-ns = <35>;
                                pinctrl-names = "default";
                                pinctrl-0 = <&pinctrl_i2c1_default>;
                                status = "okay";
diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi b/arch/arm/boot/dts/at91-sama5d27_wlsom1.dtsi
new file mode 100644 (file)
index 0000000..db3e223
--- /dev/null
@@ -0,0 +1,304 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sama5d27_wlsom1.dtsi - Device Tree file for SAMA5D27 WLSOM1
+ *
+ * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Nicolas Ferre <nicolas.ferre@microcihp.com>
+ * Author: Eugen Hristev <eugen.hristev@microcihp.com>
+ */
+#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>
+
+/ {
+       model = "Microchip SAMA5D27 WLSOM1";
+       compatible = "microchip,sama5d27-wlsom1", "atmel,sama5d27", "atmel,sama5d2", "atmel,sama5";
+
+       clocks {
+               slow_xtal {
+                       clock-frequency = <32768>;
+               };
+
+               main_xtal {
+                       clock-frequency = <24000000>;
+               };
+       };
+};
+
+&flx1 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+
+       uart6: serial@200 {
+               compatible = "atmel,at91sam9260-usart";
+               reg = <0x200 0x200>;
+               interrupts = <20 IRQ_TYPE_LEVEL_HIGH 7>;
+               dmas = <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                        AT91_XDMAC_DT_PERID(13))>,
+                      <&dma0
+                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                        AT91_XDMAC_DT_PERID(14))>;
+               dma-names = "tx", "rx";
+               clocks = <&pmc PMC_TYPE_PERIPHERAL 20>;
+               clock-names = "usart";
+               pinctrl-0 = <&pinctrl_flx1_default>;
+               pinctrl-names = "default";
+       };
+};
+
+&i2c0 {
+       pinctrl-0 = <&pinctrl_i2c0_default>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&i2c1 {
+       dmas = <0>, <0>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1_default>;
+       status = "okay";
+
+       mcp16502@5b {
+               compatible = "microchip,mcp16502";
+               reg = <0x5b>;
+               status = "okay";
+               lpm-gpios = <&pioBU 0 GPIO_ACTIVE_LOW>;
+
+               regulators {
+                       vdd_3v3: VDD_IO {
+                               regulator-name = "VDD_IO";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3700000>;
+                               regulator-initial-mode = <2>;
+                               regulator-allowed-modes = <2>, <4>;
+                               regulator-always-on;
+
+                               regulator-state-standby {
+                                       regulator-on-in-suspend;
+                                       regulator-mode = <4>;
+                               };
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-mode = <4>;
+                               };
+                       };
+
+                       vddio_ddr: VDD_DDR {
+                               regulator-name = "VDD_DDR";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-initial-mode = <2>;
+                               regulator-allowed-modes = <2>, <4>;
+                               regulator-always-on;
+
+                               regulator-state-standby {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1200000>;
+                                       regulator-changeable-in-suspend;
+                                       regulator-mode = <4>;
+                               };
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1200000>;
+                                       regulator-changeable-in-suspend;
+                                       regulator-mode = <4>;
+                               };
+                       };
+
+                       vdd_core: VDD_CORE {
+                               regulator-name = "VDD_CORE";
+                               regulator-min-microvolt = <600000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-initial-mode = <2>;
+                               regulator-allowed-modes = <2>, <4>;
+                               regulator-always-on;
+
+                               regulator-state-standby {
+                                       regulator-on-in-suspend;
+                                       regulator-mode = <4>;
+                               };
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-mode = <4>;
+                               };
+                       };
+
+                       vdd_ddr: VDD_OTHER {
+                               regulator-name = "VDD_OTHER";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-initial-mode = <2>;
+                               regulator-allowed-modes = <2>, <4>;
+                               regulator-always-on;
+
+                               regulator-state-standby {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                                       regulator-changeable-in-suspend;
+                                       regulator-mode = <4>;
+                               };
+
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <1800000>;
+                                       regulator-changeable-in-suspend;
+                                       regulator-mode = <4>;
+                               };
+                       };
+
+                       LDO1 {
+                               regulator-name = "LDO1";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3700000>;
+                               regulator-always-on;
+
+                               regulator-state-standby {
+                                       regulator-on-in-suspend;
+                               };
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       LDO2 {
+                               regulator-name = "LDO2";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <3700000>;
+                               regulator-always-on;
+
+                               regulator-state-standby {
+                                       regulator-on-in-suspend;
+                               };
+
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&macb0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_macb0_default>;
+       phy-mode = "rmii";
+
+       ethernet-phy@0 {
+               reg = <0x0>;
+               interrupt-parent = <&pioA>;
+               interrupts = <PIN_PB24 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_macb0_phy_irq>;
+       };
+};
+
+&pmc {
+       atmel,osc-bypass;
+};
+
+&qspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_qspi1_default>;
+       status = "disabled";
+
+       qspi1_flash: spi_flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <80000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <4>;
+               m25p,fast-read;
+               status = "disabled";
+
+               at91bootstrap@0 {
+                       label = "at91bootstrap";
+                       reg = <0x0 0x40000>;
+               };
+
+               bootloader@40000 {
+                       label = "bootloader";
+                       reg = <0x40000 0xc0000>;
+               };
+
+               bootloaderenvred@100000 {
+                       label = "bootloader env redundant";
+                       reg = <0x100000 0x40000>;
+               };
+
+               bootloaderenv@140000 {
+                       label = "bootloader env";
+                       reg = <0x140000 0x40000>;
+               };
+
+               dtb@180000 {
+                       label = "device tree";
+                       reg = <0x180000 0x80000>;
+               };
+
+               kernel@200000 {
+                       label = "kernel";
+                       reg = <0x200000 0x600000>;
+               };
+       };
+};
+
+&pioA {
+       pinctrl_flx1_default: flx1_usart_default {
+               pinmux = <PIN_PA24__FLEXCOM1_IO0>,
+                        <PIN_PA23__FLEXCOM1_IO1>,
+                        <PIN_PA25__FLEXCOM1_IO3>,
+                        <PIN_PA26__FLEXCOM1_IO4>;
+               bias-disable;
+       };
+
+       pinctrl_i2c0_default: i2c0_default {
+               pinmux = <PIN_PD21__TWD0>,
+                        <PIN_PD22__TWCK0>;
+               bias-disable;
+       };
+
+       pinctrl_i2c1_default: i2c1_default {
+               pinmux = <PIN_PD19__TWD1>,
+                        <PIN_PD20__TWCK1>;
+               bias-disable;
+       };
+
+       pinctrl_macb0_default: macb0_default {
+               pinmux = <PIN_PB14__GTXCK>,
+                        <PIN_PB15__GTXEN>,
+                        <PIN_PB16__GRXDV>,
+                        <PIN_PB17__GRXER>,
+                        <PIN_PB18__GRX0>,
+                        <PIN_PB19__GRX1>,
+                        <PIN_PB20__GTX0>,
+                        <PIN_PB21__GTX1>,
+                        <PIN_PB22__GMDC>,
+                        <PIN_PB23__GMDIO>;
+               bias-disable;
+       };
+
+       pinctrl_macb0_phy_irq: macb0_phy_irq {
+               pinmux = <PIN_PB24__GPIO>;
+               bias-disable;
+       };
+
+       pinctrl_qspi1_default: qspi1_default {
+               pinmux = <PIN_PB5__QSPI1_SCK>,
+                        <PIN_PB6__QSPI1_CS>,
+                        <PIN_PB7__QSPI1_IO0>,
+                        <PIN_PB8__QSPI1_IO1>,
+                        <PIN_PB9__QSPI1_IO2>,
+                        <PIN_PB10__QSPI1_IO3>;
+               bias-pull-up;
+       };
+};
+
diff --git a/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts b/arch/arm/boot/dts/at91-sama5d27_wlsom1_ek.dts
new file mode 100644 (file)
index 0000000..0b9fa29
--- /dev/null
@@ -0,0 +1,270 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * at91-sama5d27_wlsom1_ek.dts - Device Tree file for SAMA5D27 WLSOM1 EK
+ *
+ * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Nicolas Ferre <nicolas.ferre@microcihp.com>
+ */
+/dts-v1/;
+#include "at91-sama5d27_wlsom1.dtsi"
+
+/ {
+       model = "Microchip SAMA5D27 WLSOM1 EK";
+       compatible = "microchip,sama5d27-wlsom1-ek", "microchip,sama5d27-wlsom1", "atmel,sama5d27", "atmel,sama5d2", "atmel,sama5";
+
+       aliases {
+               serial0 = &uart0;       /* DBGU */
+               serial1 = &uart6;       /* BT */
+               serial2 = &uart5;       /* mikro BUS 2 */
+               serial3 = &uart3;       /* mikro BUS 1 */
+               i2c1    = &i2c1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       gpio_keys {
+               compatible = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_key_gpio_default>;
+               status = "okay";
+
+               sw4 {
+                       label = "USER BUTTON";
+                       gpios = <&pioA PIN_PB2 GPIO_ACTIVE_LOW>;
+                       linux,code = <0x104>;
+                       wakeup-source;
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_led_gpio_default>;
+               status = "okay";
+
+               red {
+                       label = "red";
+                       gpios = <&pioA PIN_PA6 GPIO_ACTIVE_HIGH>;
+               };
+
+               green {
+                       label = "green";
+                       gpios = <&pioA PIN_PA7 GPIO_ACTIVE_HIGH>;
+               };
+
+               blue {
+                       label = "blue";
+                       gpios = <&pioA PIN_PA8 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+};
+
+&adc {
+       vddana-supply = <&vdd_3v3>;
+       vref-supply = <&vdd_3v3>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_adc_default>;
+       status = "okay";
+};
+
+&flx0 {
+       atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>;
+       status = "okay";
+
+       uart5: serial@200 {
+               compatible = "atmel,at91sam9260-usart";
+               reg = <0x200 0x200>;
+               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-0 = <&pinctrl_flx0_default>;
+               pinctrl-names = "default";
+               atmel,use-dma-rx;
+               atmel,use-dma-tx;
+               status = "okay";
+       };
+};
+
+&flx1 {
+       status = "okay";
+
+       uart6: serial@200 {
+               atmel,use-dma-rx;
+               atmel,use-dma-tx;
+               status = "okay";
+       };
+};
+
+&macb0 {
+       status = "okay";
+};
+
+&pioA {
+       /*
+        * There is no real pinmux for ADC, if the pin
+        * is not requested by another peripheral then
+        * the muxing is done when channel is enabled.
+        * Requesting pins for ADC is GPIO is
+        * encouraged to prevent conflicts and to
+        * disable bias in order to be in the same
+        * state when the pin is not muxed to the adc.
+        */
+       pinctrl_adc_default: adc_default {
+               pinmux = <PIN_PD25__GPIO>,
+                        <PIN_PD26__GPIO>;
+               bias-disable;
+       };
+
+       pinctrl_flx0_default: flx0_usart_default {
+               pinmux = <PIN_PB28__FLEXCOM0_IO0>,
+                        <PIN_PB29__FLEXCOM0_IO1>;
+               bias-disable;
+       };
+
+       pinctrl_key_gpio_default: key_gpio_default {
+               pinmux = <PIN_PB2__GPIO>;
+               bias-pull-up;
+       };
+
+       pinctrl_led_gpio_default: led_gpio_default {
+               pinmux = <PIN_PA6__GPIO>,
+                        <PIN_PA7__GPIO>,
+                        <PIN_PA8__GPIO>;
+               bias-pull-down;
+       };
+
+       pinctrl_sdmmc0_default: sdmmc0_default {
+               cmd_data {
+                       pinmux = <PIN_PA1__SDMMC0_CMD>,
+                                <PIN_PA2__SDMMC0_DAT0>,
+                                <PIN_PA3__SDMMC0_DAT1>,
+                                <PIN_PA4__SDMMC0_DAT2>,
+                                <PIN_PA5__SDMMC0_DAT3>;
+                       bias-disable;
+               };
+
+               ck_cd_vddsel {
+                       pinmux = <PIN_PA0__SDMMC0_CK>,
+                                <PIN_PA11__SDMMC0_VDDSEL>,
+                                <PIN_PA12__SDMMC0_WP>,
+                                <PIN_PA13__SDMMC0_CD>;
+                       bias-disable;
+               };
+       };
+
+       pinctrl_uart0_default: uart0_default {
+               pinmux = <PIN_PB26__URXD0>,
+                        <PIN_PB27__UTXD0>;
+               bias-disable;
+       };
+
+       pinctrl_uart3_default: uart3_default {
+               pinmux = <PIN_PB11__URXD3>,
+                        <PIN_PB12__UTXD3>;
+               bias-disable;
+       };
+
+       pinctrl_pwm0_default: pwm0_default {
+               pinmux = <PIN_PA31__PWML0>,
+                        <PIN_PA30__PWMH0>;
+               bias-disable;
+       };
+
+       pinctrl_usb_default: usb_default {
+               pinmux = <PIN_PA10__GPIO>;
+               bias-disable;
+       };
+};
+
+&pwm0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm0_default>;
+       status = "okay";
+};
+
+&qspi1 {
+       status = "okay";
+
+       qspi1_flash: spi_flash@0 {
+               status = "okay";
+       };
+};
+
+&sdmmc0 {
+       bus-width = <4>;
+       mmc-ddr-3_3v;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_sdmmc0_default>;
+       status = "okay";
+};
+
+&shutdown_controller {
+       atmel,shdwc-debouncer = <976>;
+       atmel,wakeup-rtc-timer;
+
+       input@0 {
+               reg = <0>;
+               atmel,wakeup-type = "low";
+       };
+};
+
+&tcb0 {
+       timer0: timer@0 {
+               compatible = "atmel,tcb-timer";
+               reg = <0>;
+       };
+
+       timer1: timer@1 {
+               compatible = "atmel,tcb-timer";
+               reg = <1>;
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart0_default>;
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3_default>;
+       atmel,use-dma-rx;
+       atmel,use-dma-tx;
+       status = "okay";
+};
+
+&usb1 {
+       num-ports = <3>;
+       atmel,vbus-gpio = <0
+                          &pioA PIN_PA10 GPIO_ACTIVE_HIGH
+                          0
+                         >;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usb_default>;
+       status = "okay";
+};
+
+&usb2 {
+       phy_type = "hsic";
+       status = "okay";
+};
+
+&watchdog {
+       status = "okay";
+};
+
diff --git a/arch/arm/boot/dts/at91-smartkiz.dts b/arch/arm/boot/dts/at91-smartkiz.dts
new file mode 100644 (file)
index 0000000..106f23b
--- /dev/null
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017-2018 Overkiz SAS
+ *   Author: Mickael Gardet <m.gardet@overkiz.com>
+ *           Kévin Raymond <k.raymond@overkiz.com>
+ *           Dorian Rocipon <d.rocipon@overkiz.com>
+ */
+/dts-v1/;
+#include "at91-kizboxmini-common.dtsi"
+
+/ {
+       model = "Overkiz SmartKiz";
+       compatible = "overkiz,smartkiz", "atmel,at91sam9g25",
+                    "atmel,at91sam9x5", "atmel,at91sam9";
+
+       clocks {
+               adc_op_clk {
+                       status = "okay";
+               };
+       };
+
+       aliases {
+               serial5 = &uart0;
+       };
+
+       pio_keys {
+               hk_reset {
+                       label = "HK_RESET";
+                       gpios = <&pioC 13 GPIO_ACTIVE_HIGH>;
+               };
+
+               power_rf {
+                       label = "POWER_RF";
+                       gpios = <&pioA 20 GPIO_ACTIVE_HIGH>;
+               };
+
+               power_wifi {
+                       label = "POWER_WIFI";
+                       gpios = <&pioA 21 GPIO_ACTIVE_HIGH>;
+               };
+       };
+};
+
+&pinctrl {
+       i2c1 {
+               pinctrl_i2c1: i2c1-0 {
+                       atmel,pins =
+                               <AT91_PIOC 0 AT91_PERIPH_C AT91_PINCTRL_PULL_UP
+                               AT91_PIOC 1 AT91_PERIPH_C AT91_PINCTRL_PULL_UP>;
+               };
+       };
+
+       adc0 {
+               pinctrl_adc0_ad0: adc0_ad0-0 {
+                       /* pull-up disable */
+                       atmel,pins = <AT91_PIOB 11 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+               pinctrl_adc0_ad5: adc0_ad5-0 {
+                       /* pull-up disable */
+                       atmel,pins = <AT91_PIOB 16 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+               pinctrl_adc0_ad6: adc0_ad6-0 {
+                       /* pull-up disable */
+                       atmel,pins = <AT91_PIOB 17 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+               pinctrl_adc0_ad11: adc0_ad11-0 {
+                       /* pull-up disable */
+                       atmel,pins = <AT91_PIOB 10 AT91_PERIPH_GPIO AT91_PINCTRL_NONE>;
+               };
+       };
+};
+
+&i2c1 {
+       dmas = <0>, <0>;
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "disabled";
+};
+
+&macb0 {
+       status = "disabled";
+};
+
+&rtc {
+       status = "okay";
+};
+
+&leds {
+       blue {
+               status = "okay";
+       };
+};
+
+&adc0 {
+       atmel,adc-vref = <2500>;
+       pinctrl-names = "default";
+       pinctrl-0 = <
+               &pinctrl_adc0_ad0
+               &pinctrl_adc0_ad5
+               &pinctrl_adc0_ad6
+               &pinctrl_adc0_ad11
+       >;
+       atmel,adc-channels-used = <0x0861>;
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
index dee9c0c..6afbb48 100644 (file)
                                usart0 {
                                        pinctrl_usart0: usart0-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart1 {
                                        pinctrl_usart1: usart1-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart2 {
                                        pinctrl_usart2: usart2-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart3 {
                                        pinctrl_usart3: usart3-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 10 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                uart0 {
                                        pinctrl_uart0: uart0-0 {
                                                atmel,pins =
-                                                       <AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_NONE
+                                                       <AT91_PIOA 31 AT91_PERIPH_B AT91_PINCTRL_PULL_UP
                                                         AT91_PIOA 30 AT91_PERIPH_B AT91_PINCTRL_PULL_UP>;
                                        };
                                };
                                uart1 {
                                        pinctrl_uart1: uart1-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
                                };
                                status = "disabled";
                        };
 
-                       watchdog@fffffd40 {
+                       watchdog: watchdog@fffffd40 {
                                compatible = "atmel,at91sam9260-wdt";
                                reg = <0xfffffd40 0x10>;
                                interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
                };
        };
 
-       i2c-gpio-0 {
+       i2c_gpio0: i2c-gpio-0 {
                compatible = "i2c-gpio";
                gpios = <&pioA 23 GPIO_ACTIVE_HIGH /* sda */
                         &pioA 24 GPIO_ACTIVE_HIGH /* scl */
index dba025a..5ed3d74 100644 (file)
                                usart0 {
                                        pinctrl_usart0: usart0-0 {
                                                atmel,pins =
-                                                       <AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOC 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
                                                        <AT91_PIOC 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart1 {
                                        pinctrl_usart1: usart1-0 {
                                                atmel,pins =
-                                                       <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOC 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
                                                        <AT91_PIOC 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart2 {
                                        pinctrl_usart2: usart2-0 {
                                                atmel,pins =
-                                                       <AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOC 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
                                                        <AT91_PIOC 15 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
index 99678ab..5c990cf 100644 (file)
                                usart0 {
                                        pinctrl_usart0: usart0-0 {
                                                atmel,pins =
-                                                       <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOA 26 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOA 27 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart1 {
                                        pinctrl_usart1: usart1-0 {
                                                atmel,pins =
-                                                       <AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOD 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOD 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart2 {
                                        pinctrl_usart2: usart2-0 {
                                                atmel,pins =
-                                                       <AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOD 2 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOD 3 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
index 691c95e..fd17909 100644 (file)
                                usart0 {
                                        pinctrl_usart0: usart0-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 19 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 18 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart1 {
                                        pinctrl_usart1: usart1-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 4 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 5 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart2 {
                                        pinctrl_usart2: usart2-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart3 {
                                        pinctrl_usart3: usart3-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_NONE
+                                                       <AT91_PIOB 8 AT91_PERIPH_A AT91_PINCTRL_PULL_UP
                                                         AT91_PIOB 9 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
index 8643b71..ea024e4 100644 (file)
                                usart0 {
                                        pinctrl_usart0: usart0-0 {
                                                atmel,pins =
-                                                       <AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 6 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
                                                        <AT91_PIOA 7 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart1 {
                                        pinctrl_usart1: usart1-0 {
                                                atmel,pins =
-                                                       <AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 11 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
                                                        <AT91_PIOA 12 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart2 {
                                        pinctrl_usart2: usart2-0 {
                                                atmel,pins =
-                                                       <AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOA 13 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
                                                        <AT91_PIOA 14 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
                                usart3 {
                                        pinctrl_usart3: usart3-0 {
                                                atmel,pins =
-                                                       <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_NONE>,
+                                                       <AT91_PIOB 0 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>,
                                                        <AT91_PIOB 1 AT91_PERIPH_A AT91_PINCTRL_PULL_UP>;
                                        };
 
index 8eedd6e..d1e684d 100644 (file)
 
        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:
                };
 
                rng@7e104000 {
-                       interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>;
-
-                       /* RNG is incompatible with brcm,bcm2835-rng */
-                       status = "disabled";
+                       compatible = "brcm,bcm2711-rng200";
+                       reg = <0x7e104000 0x28>;
                };
 
                uart2: serial@7e201400 {
                #address-cells = <2>;
                #size-cells = <1>;
 
-               ranges = <0x0 0x7c000000  0x0 0xfc000000  0x03800000>;
+               ranges = <0x0 0x7c000000  0x0 0xfc000000  0x03800000>,
+                        <0x6 0x00000000  0x6 0x00000000  0x40000000>;
+
+               pcie0: pcie@7d500000 {
+                       compatible = "brcm,bcm2711-pcie";
+                       reg = <0x0 0x7d500000 0x9310>;
+                       device_type = "pci";
+                       #address-cells = <3>;
+                       #interrupt-cells = <1>;
+                       #size-cells = <2>;
+                       interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "pcie", "msi";
+                       interrupt-map-mask = <0x0 0x0 0x0 0x7>;
+                       interrupt-map = <0 0 0 1 &gicv2 GIC_SPI 143
+                                                       IRQ_TYPE_LEVEL_HIGH>;
+                       msi-controller;
+                       msi-parent = <&pcie0>;
+
+                       ranges = <0x02000000 0x0 0xf8000000 0x6 0x00000000
+                                 0x0 0x04000000>;
+                       /*
+                        * The wrapper around the PCIe block has a bug
+                        * preventing it from accessing beyond the first 3GB of
+                        * memory.
+                        */
+                       dma-ranges = <0x02000000 0x0 0x00000000 0x0 0x00000000
+                                     0x0 0xc0000000>;
+                       brcm,enable-ssc;
+               };
 
                genet: ethernet@7d580000 {
                        compatible = "brcm,bcm2711-genet-v5";
        };
 };
 
+&rmem {
+       #address-cells = <2>;
+};
+
+&cma {
+       /*
+        * 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).
+        */
+       alloc-ranges = <0x0 0x00000000 0x40000000>;
+};
+
 &i2c0 {
        compatible = "brcm,bcm2711-i2c", "brcm,bcm2835-i2c";
        interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
index fe1ab40..2b1d9d4 100644 (file)
                        system-power-controller;
                };
 
+               rng@7e104000 {
+                       compatible = "brcm,bcm2835-rng";
+                       reg = <0x7e104000 0x10>;
+                       interrupts = <2 29>;
+               };
+
                pixelvalve@7e206000 {
                        compatible = "brcm,bcm2835-pixelvalve0";
                        reg = <0x7e206000 0x100>;
index 8394916..e1abe8c 100644 (file)
                stdout-path = "serial0:115200n8";
        };
 
+       rmem: reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               cma: linux,cma {
+                       compatible = "shared-dma-pool";
+                       size = <0x4000000>; /* 64MB */
+                       reusable;
+                       linux,cma-default;
+               };
+       };
+
        thermal-zones {
                cpu_thermal: cpu-thermal {
                        polling-delay-passive = <0>;
                                <&dsi1 0>, <&dsi1 1>, <&dsi1 2>;
                };
 
-               rng@7e104000 {
-                       compatible = "brcm,bcm2835-rng";
-                       reg = <0x7e104000 0x10>;
-                       interrupts = <2 29>;
-               };
-
                mailbox: mailbox@7e00b880 {
                        compatible = "brcm,bcm2835-mbox";
                        reg = <0x7e00b880 0x40>;
index a2c9de3..536fb24 100644 (file)
                priority = <200>;
        };
 
-       /* Hardware I2C block cannot do more than 63 bytes per transfer,
-        * which would prevent reading from a SFP's EEPROM (256 byte).
-        */
-       i2c1: i2c {
-               compatible = "i2c-gpio";
-               sda-gpios = <&gpioa 5 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-               scl-gpios = <&gpioa 4 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
-       };
-
        sfp: sfp {
                compatible = "sff,sfp";
-               i2c-bus = <&i2c1>;
+               i2c-bus = <&i2c0>;
                mod-def0-gpios = <&gpioa 28 GPIO_ACTIVE_LOW>;
                los-gpios = <&gpioa 24 GPIO_ACTIVE_HIGH>;
                tx-fault-gpios = <&gpioa 30 GPIO_ACTIVE_HIGH>;
        };
 };
 
+&i2c0 {
+       status = "okay";
+};
+
 &amac0 {
        status = "okay";
 };
diff --git a/arch/arm/boot/dts/dm3725.dtsi b/arch/arm/boot/dts/dm3725.dtsi
new file mode 100644 (file)
index 0000000..d24e906
--- /dev/null
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2020 André Hentschel <nerv@dawncrow.de>
+ */
+
+#include "omap36xx.dtsi"
+
+&sgx_module {
+       status = "disabled";
+};
index 82eeba8..23244b5 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clk/ti-dra7-atl.h>
+#include <dt-bindings/clock/ti-dra7-atl.h>
 #include <dt-bindings/input/input.h>
 
 / {
index 7e7aa10..fc41883 100644 (file)
 
                target-module@56000 {                   /* 0x4a056000, ap 9 02.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "dma_system";
                        reg = <0x56000 0x4>,
                              <0x5602c 0x4>,
                              <0x56028 0x4>;
                        ranges = <0x0 0x56000 0x1000>;
 
                        sdma: dma-controller@0 {
-                               compatible = "ti,omap4430-sdma";
+                               compatible = "ti,omap4430-sdma", "ti,omap-sdma";
                                reg = <0x0 0x1000>;
                                interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
 
                target-module@80000 {                   /* 0x4a080000, ap 13 20.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "ocp2scp1";
                        reg = <0x80000 0x4>,
                              <0x80010 0x4>,
                              <0x80014 0x4>;
 
                target-module@90000 {                   /* 0x4a090000, ap 59 42.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "ocp2scp3";
                        reg = <0x90000 0x4>,
                              <0x90010 0x4>,
                              <0x90014 0x4>;
 
                target-module@d9000 {                   /* 0x4a0d9000, ap 17 72.0 */
                        compatible = "ti,sysc-omap4-sr", "ti,sysc";
-                       ti,hwmods = "smartreflex_mpu";
                        reg = <0xd9038 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
 
                target-module@dd000 {                   /* 0x4a0dd000, ap 19 18.0 */
                        compatible = "ti,sysc-omap4-sr", "ti,sysc";
-                       ti,hwmods = "smartreflex_core";
                        reg = <0xdd038 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
 
                target-module@f6000 {                   /* 0x4a0f6000, ap 25 78.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spinlock";
                        reg = <0xf6000 0x4>,
                              <0xf6010 0x4>,
                              <0xf6014 0x4>;
 
                target-module@3e000 {                   /* 0x4803e000, ap 11 56.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer9";
                        reg = <0x3e000 0x4>,
                              <0x3e010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@78000 {                   /* 0x48078000, ap 39 0a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "elm";
                        reg = <0x78000 0x4>,
                              <0x78010 0x4>,
                              <0x78014 0x4>;
 
                target-module@86000 {                   /* 0x48086000, ap 41 5e.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer10";
                        reg = <0x86000 0x4>,
                              <0x86010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@88000 {                   /* 0x48088000, ap 43 66.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer11";
                        reg = <0x88000 0x4>,
                              <0x88010 0x4>;
                        reg-names = "rev", "sysc";
                                 <0x00001000 0x000a5000 0x00001000>;
                };
 
+               des_target: target-module@a5000 {       /* 0x480a5000 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0xa5030 0x4>,
+                             <0xa5034 0x4>,
+                             <0xa5038 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): l4per_pwrdm, l4sec_clkdm */
+                       clocks = <&l4sec_clkctrl DRA7_L4SEC_DES_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0xa5000 0x00001000>;
+
+                       des: des@0 {
+                               compatible = "ti,omap4-des";
+                               reg = <0 0xa0>;
+                               interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&sdma_xbar 117>, <&sdma_xbar 116>;
+                               dma-names = "tx", "rx";
+                               clocks = <&l3_iclk_div>;
+                               clock-names = "fck";
+                       };
+               };
+
                target-module@a8000 {                   /* 0x480a8000, ap 59 1a.0 */
                        compatible = "ti,sysc";
                        status = "disabled";
 
                target-module@3e000 {                   /* 0x4843e000, ap 25 30.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss0";
                        reg = <0x3e000 0x4>,
                              <0x3e004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@40000 {                   /* 0x48440000, ap 27 38.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss1";
                        reg = <0x40000 0x4>,
                              <0x40004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@42000 {                   /* 0x48442000, ap 29 20.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "epwmss2";
                        reg = <0x42000 0x4>,
                              <0x42004 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@20000 {                   /* 0x48820000, ap 5 08.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer5";
                        reg = <0x20000 0x4>,
                              <0x20010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@22000 {                   /* 0x48822000, ap 7 24.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer6";
                        reg = <0x22000 0x4>,
                              <0x22010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@24000 {                   /* 0x48824000, ap 9 26.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer7";
                        reg = <0x24000 0x4>,
                              <0x24010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@26000 {                   /* 0x48826000, ap 11 0c.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer8";
                        reg = <0x26000 0x4>,
                              <0x26010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@28000 {                   /* 0x48828000, ap 13 16.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer13";
                        reg = <0x28000 0x4>,
                              <0x28010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@2a000 {                   /* 0x4882a000, ap 15 10.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer14";
                        reg = <0x2a000 0x4>,
                              <0x2a010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@2c000 {                   /* 0x4882c000, ap 17 02.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer15";
                        reg = <0x2c000 0x4>,
                              <0x2c010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@2e000 {                   /* 0x4882e000, ap 19 14.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer16";
                        reg = <0x2e000 0x4>,
                              <0x2e010 0x4>;
                        reg-names = "rev", "sysc";
                };
 
                target-module@170000 {                  /* 0x48970000, ap 21 0a.0 */
-                       compatible = "ti,sysc";
-                       status = "disabled";
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x170010 0x4>;
+                       reg-names = "sysc";
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       clocks = <&cam_clkctrl DRA7_CAM_VIP1_CLKCTRL 0>;
+                       clock-names = "fck";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x170000 0x10000>;
+                       status = "disabled";
                };
 
                target-module@190000 {                  /* 0x48990000, ap 23 2e.0 */
-                       compatible = "ti,sysc";
-                       status = "disabled";
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x190010 0x4>;
+                       reg-names = "sysc";
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       clocks = <&cam_clkctrl DRA7_CAM_VIP2_CLKCTRL 0>;
+                       clock-names = "fck";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x190000 0x10000>;
+                       status = "disabled";
                };
 
                target-module@1b0000 {                  /* 0x489b0000, ap 25 34.0 */
-                       compatible = "ti,sysc";
-                       status = "disabled";
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x1b0000 0x4>,
+                             <0x1b0010 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       clocks = <&cam_clkctrl DRA7_CAM_VIP3_CLKCTRL 0>;
+                       clock-names = "fck";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x1b0000 0x10000>;
+                       status = "disabled";
                };
 
-               target-module@1d0000 {                  /* 0x489d0000, ap 27 30.0 */
-                       compatible = "ti,sysc";
-                       status = "disabled";
+               target-module@1d0010 {                  /* 0x489d0000, ap 27 30.0 */
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x1d0010 0x4>;
+                       reg-names = "sysc";
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       clocks = <&vpe_clkctrl DRA7_VPE_VPE_CLKCTRL 0>;
+                       clock-names = "fck";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x1d0000 0x10000>;
+
+                       vpe: vpe@0 {
+                               compatible = "ti,dra7-vpe";
+                               reg = <0x0000 0x120>,
+                                     <0x0700 0x80>,
+                                     <0x5700 0x18>,
+                                     <0xd000 0x400>;
+                               reg-names = "vpe_top",
+                                           "sc",
+                                           "csc",
+                                           "vpdma";
+                               interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                       };
                };
        };
 };
 
                target-module@0 {                       /* 0x4ae20000, ap 19 08.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer12";
                        reg = <0x0 0x4>,
                              <0x10 0x4>;
                        reg-names = "rev", "sysc";
index 73e5011..d78b684 100644 (file)
                        ti,hwmods = "dmm";
                };
 
-               mmu0_dsp1: mmu@40d01000 {
-                       compatible = "ti,dra7-dsp-iommu";
-                       reg = <0x40d01000 0x100>;
-                       interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu0_dsp1";
-                       #iommu-cells = <0>;
-                       ti,syscon-mmuconfig = <&dsp1_system 0x0>;
-                       status = "disabled";
+               target-module@40d01000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x40d01000 0x4>,
+                             <0x40d01010 0x4>,
+                             <0x40d01014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       clocks = <&dsp1_clkctrl DRA7_DSP1_MMU0_DSP1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_dsp1 1>;
+                       reset-names = "rstctrl";
+                       ranges = <0x0 0x40d01000 0x1000>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+
+                       mmu0_dsp1: mmu@0 {
+                               compatible = "ti,dra7-dsp-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                               ti,syscon-mmuconfig = <&dsp1_system 0x0>;
+                       };
                };
 
-               mmu1_dsp1: mmu@40d02000 {
-                       compatible = "ti,dra7-dsp-iommu";
-                       reg = <0x40d02000 0x100>;
-                       interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu1_dsp1";
-                       #iommu-cells = <0>;
-                       ti,syscon-mmuconfig = <&dsp1_system 0x1>;
-                       status = "disabled";
+               target-module@40d02000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x40d02000 0x4>,
+                             <0x40d02010 0x4>,
+                             <0x40d02014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       clocks = <&dsp1_clkctrl DRA7_DSP1_MMU0_DSP1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_dsp1 1>;
+                       reset-names = "rstctrl";
+                       ranges = <0x0 0x40d02000 0x1000>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+
+                       mmu1_dsp1: mmu@0 {
+                               compatible = "ti,dra7-dsp-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                               ti,syscon-mmuconfig = <&dsp1_system 0x1>;
+                       };
                };
 
-               mmu_ipu1: mmu@58882000 {
-                       compatible = "ti,dra7-iommu";
-                       reg = <0x58882000 0x100>;
-                       interrupts = <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu_ipu1";
-                       #iommu-cells = <0>;
-                       ti,iommu-bus-err-back;
-                       status = "disabled";
+               target-module@58882000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x58882000 0x4>,
+                             <0x58882010 0x4>,
+                             <0x58882014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       clocks = <&ipu1_clkctrl DRA7_IPU1_MMU_IPU1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_ipu 2>;
+                       reset-names = "rstctrl";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x58882000 0x100>;
+
+                       mmu_ipu1: mmu@0 {
+                               compatible = "ti,dra7-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                               ti,iommu-bus-err-back;
+                       };
                };
 
-               mmu_ipu2: mmu@55082000 {
-                       compatible = "ti,dra7-iommu";
-                       reg = <0x55082000 0x100>;
-                       interrupts = <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu_ipu2";
-                       #iommu-cells = <0>;
-                       ti,iommu-bus-err-back;
-                       status = "disabled";
+               target-module@55082000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x55082000 0x4>,
+                             <0x55082010 0x4>,
+                             <0x55082014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       clocks = <&ipu2_clkctrl DRA7_IPU2_MMU_IPU2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_core 2>;
+                       reset-names = "rstctrl";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x55082000 0x100>;
+
+                       mmu_ipu2: mmu@0 {
+                               compatible = "ti,dra7-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                               ti,iommu-bus-err-back;
+                       };
                };
 
                abb_mpu: regulator-abb-mpu {
                        status = "disabled";
                };
 
+               target-module@56000000 {
+                       compatible = "ti,sysc-omap4", "ti,sysc";
+                       reg = <0x5600fe00 0x4>,
+                             <0x5600fe10 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       clocks = <&gpu_clkctrl DRA7_GPU_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x56000000 0x2000000>;
+               };
+
                crossbar_mpu: crossbar@4a002a48 {
                        compatible = "ti,irq-crossbar";
                        reg = <0x4a002a48 0x130>;
                        };
                };
 
-               aes1: aes@4b500000 {
-                       compatible = "ti,omap4-aes";
-                       ti,hwmods = "aes1";
-                       reg = <0x4b500000 0xa0>;
-                       interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&edma_xbar 111 0>, <&edma_xbar 110 0>;
-                       dma-names = "tx", "rx";
-                       clocks = <&l3_iclk_div>;
-                       clock-names = "fck";
-               };
-
-               aes2: aes@4b700000 {
-                       compatible = "ti,omap4-aes";
-                       ti,hwmods = "aes2";
-                       reg = <0x4b700000 0xa0>;
-                       interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&edma_xbar 114 0>, <&edma_xbar 113 0>;
-                       dma-names = "tx", "rx";
-                       clocks = <&l3_iclk_div>;
+               aes1_target: target-module@4b500000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x4b500080 0x4>,
+                             <0x4b500084 0x4>,
+                             <0x4b500088 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): per_pwrdm, l4sec_clkdm */
+                       clocks = <&l4sec_clkctrl DRA7_L4SEC_AES1_CLKCTRL 0>;
                        clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4b500000 0x1000>;
+
+                       aes1: aes@0 {
+                               compatible = "ti,omap4-aes";
+                               reg = <0 0xa0>;
+                               interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&edma_xbar 111 0>, <&edma_xbar 110 0>;
+                               dma-names = "tx", "rx";
+                               clocks = <&l3_iclk_div>;
+                               clock-names = "fck";
+                       };
                };
 
-               des: des@480a5000 {
-                       compatible = "ti,omap4-des";
-                       ti,hwmods = "des";
-                       reg = <0x480a5000 0xa0>;
-                       interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&sdma_xbar 117>, <&sdma_xbar 116>;
-                       dma-names = "tx", "rx";
-                       clocks = <&l3_iclk_div>;
+               aes2_target: target-module@4b700000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x4b700080 0x4>,
+                             <0x4b700084 0x4>,
+                             <0x4b700088 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): per_pwrdm, l4sec_clkdm */
+                       clocks = <&l4sec_clkctrl DRA7_L4SEC_AES2_CLKCTRL 0>;
                        clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4b700000 0x1000>;
+
+                       aes2: aes@0 {
+                               compatible = "ti,omap4-aes";
+                               reg = <0 0xa0>;
+                               interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&edma_xbar 114 0>, <&edma_xbar 113 0>;
+                               dma-names = "tx", "rx";
+                               clocks = <&l3_iclk_div>;
+                               clock-names = "fck";
+                       };
                };
 
-               sham: sham@53100000 {
-                       compatible = "ti,omap5-sham";
-                       ti,hwmods = "sham";
-                       reg = <0x4b101000 0x300>;
-                       interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&edma_xbar 119 0>;
-                       dma-names = "rx";
-                       clocks = <&l3_iclk_div>;
+               sham_target: target-module@4b101000 {
+                       compatible = "ti,sysc-omap3-sham", "ti,sysc";
+                       reg = <0x4b101100 0x4>,
+                             <0x4b101110 0x4>,
+                             <0x4b101114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): l4per_pwrdm, l4sec_clkdm */
+                       clocks = <&l4sec_clkctrl DRA7_L4SEC_SHAM_CLKCTRL 0>;
                        clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4b101000 0x1000>;
+
+                       sham: sham@0 {
+                               compatible = "ti,omap5-sham";
+                               reg = <0 0x300>;
+                               interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&edma_xbar 119 0>;
+                               dma-names = "rx";
+                               clocks = <&l3_iclk_div>;
+                               clock-names = "fck";
+                       };
                };
 
                opp_supply_mpu: opp-supply@4a003b20 {
index 8641a3d..01558a8 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "dra72x.dtsi"
 #include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/clk/ti-dra7-atl.h>
+#include <dt-bindings/clock/ti-dra7-atl.h>
 
 / {
        compatible = "ti,dra72-evm", "ti,dra722", "ti,dra72", "ti,dra7";
                gpio = <&gpio5 8 GPIO_ACTIVE_HIGH>;
                enable-active-high;
        };
+
+       clk_ov5640_fixed: clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24000000>;
+       };
 };
 
 &dra7_pmx_core {
                        line-name = "vin6_sel_s0";
                };
        };
+
+       ov5640@3c {
+               compatible = "ovti,ov5640";
+               reg = <0x3c>;
+
+               clocks = <&clk_ov5640_fixed>;
+               clock-names = "xclk";
+
+               port {
+                       csi2_cam0: endpoint {
+                               remote-endpoint = <&csi2_phy0>;
+                               clock-lanes = <0>;
+                               data-lanes = <1 2>;
+                       };
+               };
+       };
+
 };
 
 &uart1 {
 &pcie1_rc {
        status = "okay";
 };
+
+&csi2_0 {
+       csi2_phy0: endpoint {
+               remote-endpoint = <&csi2_cam0>;
+               clock-lanes = <0>;
+               data-lanes = <1 2>;
+       };
+};
index f576270..82b57a3 100644 (file)
        };
 };
 
+&l4_per2 {
+       target-module@5b000 {                   /* 0x4845b000, ap 59 46.0 */
+               compatible = "ti,sysc-omap4", "ti,sysc";
+               reg = <0x5b000 0x4>,
+                     <0x5b010 0x4>;
+               reg-names = "rev", "sysc";
+               ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                               <SYSC_IDLE_NO>;
+               ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                               <SYSC_IDLE_NO>;
+               clocks = <&cam_clkctrl DRA7_CAM_VIP2_CLKCTRL 0>;
+               clock-names = "fck";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x5b000 0x1000>;
+
+               cal: cal@0 {
+                       compatible = "ti,dra72-cal";
+                       reg = <0x0000 0x400>,
+                             <0x0800 0x40>,
+                             <0x0900 0x40>;
+                       reg-names = "cal_top",
+                                   "cal_rx_core0",
+                                   "cal_rx_core1";
+                       interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,camerrx-control = <&scm_conf 0xE94>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               csi2_0: port@0 {
+                                       reg = <0>;
+                               };
+                               csi2_1: port@1 {
+                                       reg = <1>;
+                               };
+                       };
+               };
+       };
+};
+
 &dss {
        reg = <0x58000000 0x80>,
              <0x58004054 0x4>,
index d1b5b76..c5abc43 100644 (file)
                        };
                };
 
-               mmu0_dsp2: mmu@41501000 {
-                       compatible = "ti,dra7-dsp-iommu";
-                       reg = <0x41501000 0x100>;
-                       interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu0_dsp2";
-                       #iommu-cells = <0>;
-                       ti,syscon-mmuconfig = <&dsp2_system 0x0>;
-                       status = "disabled";
+               target-module@41501000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x41501000 0x4>,
+                             <0x41501010 0x4>,
+                             <0x41501014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       clocks = <&dsp2_clkctrl DRA7_DSP2_MMU0_DSP2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_dsp2 1>;
+                       reset-names = "rstctrl";
+                       ranges = <0x0 0x41501000 0x1000>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+
+                       mmu0_dsp2: mmu@0 {
+                               compatible = "ti,dra7-dsp-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                               ti,syscon-mmuconfig = <&dsp2_system 0x0>;
+                       };
                };
 
-               mmu1_dsp2: mmu@41502000 {
-                       compatible = "ti,dra7-dsp-iommu";
-                       reg = <0x41502000 0x100>;
-                       interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu1_dsp2";
-                       #iommu-cells = <0>;
-                       ti,syscon-mmuconfig = <&dsp2_system 0x1>;
-                       status = "disabled";
+               target-module@41502000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x41502000 0x4>,
+                             <0x41502010 0x4>,
+                             <0x41502014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+
+                       clocks = <&dsp2_clkctrl DRA7_DSP2_MMU0_DSP2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_dsp2 1>;
+                       reset-names = "rstctrl";
+                       ranges = <0x0 0x41502000 0x1000>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+
+                       mmu1_dsp2: mmu@0 {
+                               compatible = "ti,dra7-dsp-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                               ti,syscon-mmuconfig = <&dsp2_system 0x1>;
+                       };
                };
        };
 };
index 1fb6f13..e958cb3 100644 (file)
        model = "TI DRA762 EVM";
        compatible = "ti,dra76-evm", "ti,dra762", "ti,dra7";
 
+       aliases {
+               display0 = &hdmi0;
+
+               sound0 = &sound0;
+               sound1 = &hdmi;
+       };
+
        memory@0 {
                device_type = "memory";
                reg = <0x0 0x80000000 0x0 0x80000000>;
                regulator-min-microvolt = <1800000>;
                regulator-max-microvolt = <1800000>;
        };
+
+       clk_ov5640_fixed: clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24000000>;
+       };
+
+       hdmi0: connector {
+               compatible = "hdmi-connector";
+               label = "hdmi";
+
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&tpd12s015_out>;
+                       };
+               };
+       };
+
+       tpd12s015: encoder {
+               compatible = "ti,tpd12s015";
+
+               gpios = <&gpio7 30 GPIO_ACTIVE_HIGH>,   /* gpio7_30, CT CP HPD */
+                       <&gpio7 31 GPIO_ACTIVE_HIGH>,   /* gpio7_31, LS OE */
+                       <&gpio7 12 GPIO_ACTIVE_HIGH>;   /* gpio7_12/sp1_cs2, HPD */
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tpd12s015_in: endpoint {
+                                       remote-endpoint = <&hdmi_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tpd12s015_out: endpoint {
+                                       remote-endpoint = <&hdmi_connector_in>;
+                               };
+                       };
+               };
+       };
 };
 
 &i2c1 {
        };
 };
 
+&i2c5 {
+       status = "okay";
+       clock-frequency = <400000>;
+
+       ov5640@3c {
+               compatible = "ovti,ov5640";
+               reg = <0x3c>;
+
+               clocks = <&clk_ov5640_fixed>;
+               clock-names = "xclk";
+
+               port {
+                       csi2_cam0: endpoint {
+                               remote-endpoint = <&csi2_phy0>;
+                               clock-lanes = <0>;
+                               data-lanes = <1 2>;
+                       };
+               };
+       };
+};
+
 &cpu0 {
        vdd-supply = <&buck10_reg>;
 };
        phy-supply = <&ldo3_reg>;
 };
 
+&dss {
+       status = "ok";
+       vdda_video-supply = <&ldo5_reg>;
+};
+
+&hdmi {
+       status = "ok";
+
+       vdda-supply = <&ldo1_reg>;
+
+       port {
+               hdmi_out: endpoint {
+                       remote-endpoint = <&tpd12s015_in>;
+               };
+       };
+};
+
 &qspi {
        spi-max-frequency = <96000000>;
        m25p80@0 {
                max-bitrate = <5000000>;
        };
 };
+
+&csi2_0 {
+       csi2_phy0: endpoint {
+               remote-endpoint = <&csi2_cam0>;
+               clock-lanes = <0>;
+               data-lanes = <1 2>;
+       };
+};
index cdcba3f..2f7539a 100644 (file)
 
 };
 
+&l4_per3 {
+       target-module@1b0000 {                  /* 0x489b0000, ap 25 34.0 */
+               compatible = "ti,sysc-omap4", "ti,sysc";
+               reg = <0x1b0000 0x4>,
+                     <0x1b0010 0x4>;
+               reg-names = "rev", "sysc";
+               ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                               <SYSC_IDLE_NO>;
+               ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                               <SYSC_IDLE_NO>;
+               clocks = <&cam_clkctrl DRA7_CAM_VIP3_CLKCTRL 0>;
+               clock-names = "fck";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x1b0000 0x10000>;
+
+               cal: cal@0 {
+                       compatible = "ti,dra76-cal";
+                       reg = <0x0000 0x400>,
+                             <0x0800 0x40>,
+                             <0x0900 0x40>;
+                       reg-names = "cal_top",
+                                   "cal_rx_core0",
+                                   "cal_rx_core1";
+                       interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                       ti,camerrx-control = <&scm_conf 0x6dc>;
+
+                       ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               csi2_0: port@0 {
+                                       reg = <0>;
+                               };
+                               csi2_1: port@1 {
+                                       reg = <1>;
+                               };
+                       };
+               };
+       };
+};
+
 /* MCAN interrupts are hard-wired to irqs 67, 68 */
 &crossbar_mpu {
        ti,irqs-skip = <10 67 68 133 139 140>;
index 93e1eb8..55cef4c 100644 (file)
 
        rtc_cm: rtc-cm@700 {
                compatible = "ti,omap4-cm";
-               reg = <0x700 0x100>;
+               reg = <0x700 0x60>;
                #address-cells = <1>;
                #size-cells = <1>;
-               ranges = <0 0x700 0x100>;
+               ranges = <0 0x700 0x60>;
 
                rtc_clkctrl: rtc-clkctrl@20 {
                        compatible = "ti,clkctrl";
                };
        };
 
+       vpe_cm: vpe-cm@760 {
+               compatible = "ti,omap4-cm";
+               reg = <0x760 0xc>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0x760 0xc>;
+
+               vpe_clkctrl: vpe-clkctrl@0 {
+                       compatible = "ti,clkctrl";
+                       reg = <0x0 0xc>;
+                       #clock-cells = <2>;
+               };
+       };
+
 };
 
 &cm_core {
                };
        };
 
+       cam_cm: cam-cm@1000 {
+               compatible = "ti,omap4-cm";
+               reg = <0x1000 0x100>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0x1000 0x100>;
+
+               cam_clkctrl: cam-clkctrl@20 {
+                       compatible = "ti,clkctrl";
+                       reg = <0x20 0x2c>;
+                       #clock-cells = <2>;
+               };
+       };
+
        dss_cm: dss-cm@1100 {
                compatible = "ti,omap4-cm";
                reg = <0x1100 0x100>;
                };
        };
 
+       gpu_cm: gpu-cm@1200 {
+               compatible = "ti,omap4-cm";
+               reg = <0x1200 0x100>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0x1200 0x100>;
+
+               gpu_clkctrl: gpu-clkctrl@20 {
+                       compatible = "ti,clkctrl";
+                       reg = <0x20 0x4>;
+                       #clock-cells = <2>;
+               };
+       };
+
        l3init_cm: l3init-cm@1300 {
                compatible = "ti,omap4-cm";
                reg = <0x1300 0x100>;
index 5a2c532..ce50c4d 100644 (file)
@@ -48,7 +48,8 @@
                };
        };
 
-       memory {
+       memory@80000000 {
+               device_type = "memory";
                reg = <0x80000000 0x20000000>;
        };
 
index b016b0b..044e5da 100644 (file)
                        #size-cells = <1>;
                        ranges = <0 0x02020000 0x40000>;
 
-                       smp-sysram@0 {
+                       smp-sram@0 {
                                compatible = "samsung,exynos4210-sysram";
                                reg = <0x0 0x1000>;
                        };
 
-                       smp-sysram@3f000 {
+                       smp-sram@3f000 {
                                compatible = "samsung,exynos4210-sysram-ns";
                                reg = <0x3f000 0x1000>;
                        };
index 09d3d54..a1bdf78 100644 (file)
 };
 
 &sysram {
-       smp-sysram@0 {
+       smp-sram@0 {
                status = "disabled";
        };
 
-       smp-sysram@5000 {
+       smp-sram@5000 {
                compatible = "samsung,exynos4210-sysram";
                reg = <0x5000 0x1000>;
        };
 
-       smp-sysram@1f000 {
+       smp-sram@1f000 {
                status = "disabled";
        };
 };
index 554819a..b446623 100644 (file)
                        #size-cells = <1>;
                        ranges = <0 0x02020000 0x20000>;
 
-                       smp-sysram@0 {
+                       smp-sram@0 {
                                compatible = "samsung,exynos4210-sysram";
                                reg = <0x0 0x1000>;
                        };
 
-                       smp-sysram@1f000 {
+                       smp-sram@1f000 {
                                compatible = "samsung,exynos4210-sysram-ns";
                                reg = <0x1f000 0x1000>;
                        };
index ce87d2f..31719c0 100644 (file)
        vdda-supply = <&ldo17_reg>;
        status = "okay";
 };
+
+&touchkey_reg {
+       gpio = <&gpm0 0 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
index 83be3a7..3023bc3 100644 (file)
@@ -13,6 +13,7 @@
 #include "exynos4412.dtsi"
 #include "exynos4412-ppmu-common.dtsi"
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/clock/maxim,max77686.h>
 #include <dt-bindings/pinctrl/samsung.h>
                enable-active-high;
        };
 
+       touchkey_reg: voltage-regulator-6 {
+               compatible = "regulator-fixed";
+               regulator-name = "LED_VDD_3.3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               enable-active-high;
+               status = "disabled";
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
                pinctrl-names = "default";
                };
        };
 
+       i2c-gpio-4 {
+               compatible = "i2c-gpio";
+               sda-gpios = <&gpl0 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               scl-gpios = <&gpl0 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>;
+               i2c-gpio,delay-us = <2>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               touchkey@20 {
+                       compatible = "cypress,midas-touchkey";
+                       reg = <0x20>;
+                       vdd-supply = <&touchkey_reg>;
+                       vcc-supply = <&ldo5_reg>;
+                       interrupt-parent = <&gpj0>;
+                       interrupts = <3 IRQ_TYPE_EDGE_FALLING>;
+                       linux,keycodes = <KEY_BACK KEY_MENU>;
+               };
+       };
+
        i2c-mhl {
                compatible = "i2c-gpio";
                gpios = <&gpf0 4 GPIO_ACTIVE_HIGH>, <&gpf0 6 GPIO_ACTIVE_HIGH>;
index fe2bfd7..98cd128 100644 (file)
@@ -73,3 +73,8 @@
        vdda-supply = <&cam_vdda_reg>;
        status = "okay";
 };
+
+&touchkey_reg {
+       gpio = <&gpm0 5 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
index ea55f37..9c39e82 100644 (file)
 
                intn-gpios = <&gpx3 0 GPIO_ACTIVE_HIGH>;
                connect-gpios = <&gpx3 4 GPIO_ACTIVE_HIGH>;
-               reset-gpios = <&gpx3 5 GPIO_ACTIVE_HIGH>;
+               reset-gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
                initial-mode = <1>;
        };
 
index 01f37b5..3a91de8 100644 (file)
                        clock-frequency = <24000000>;
                };
        };
+
+       panel {
+               compatible = "innolux,at070tn92";
+
+               port {
+                       panel_input: endpoint {
+                               remote-endpoint = <&lcdc_output>;
+                       };
+               };
+       };
+};
+
+&fimd {
+       pinctrl-0 = <&lcd_clk>, <&lcd_data24>;
+       pinctrl-names = "default";
+       #address-cells = <1>;
+       #size-cells = <0>;
+       status = "okay";
+
+       port@3 {
+               reg = <3>;
+               lcdc_output: endpoint {
+                       remote-endpoint = <&panel_input>;
+               };
+       };
 };
 
 &rtc {
index 5022aa5..4886894 100644 (file)
                        #size-cells = <1>;
                        ranges = <0 0x02020000 0x40000>;
 
-                       smp-sysram@0 {
+                       smp-sram@0 {
                                compatible = "samsung,exynos4210-sysram";
                                reg = <0x0 0x1000>;
                        };
 
-                       smp-sysram@2f000 {
+                       smp-sram@2f000 {
                                compatible = "samsung,exynos4210-sysram-ns";
                                reg = <0x2f000 0x1000>;
                        };
index 4801ca7..22eb951 100644 (file)
@@ -36,7 +36,7 @@
                ranges;
 
                chipid: chipid@10000000 {
-                       compatible = "samsung,exynos4210-chipid", "syscon";
+                       compatible = "samsung,exynos4210-chipid";
                        reg = <0x10000000 0x100>;
                };
 
index d6c85ef..f8ebc62 100644 (file)
@@ -15,7 +15,7 @@
 #include "exynos5250.dtsi"
 
 / {
-       model = "Insignal Arndale evaluation board based on EXYNOS5250";
+       model = "Insignal Arndale evaluation board based on Exynos5250";
        compatible = "insignal,arndale", "samsung,exynos5250", "samsung,exynos5";
 
        memory@40000000 {
                compatible = "smsc,usb3503a";
 
                reset-gpios = <&gpx3 5 GPIO_ACTIVE_LOW>;
-               connect-gpios = <&gpd1 7 GPIO_ACTIVE_LOW>;
+               connect-gpios = <&gpd1 7 GPIO_ACTIVE_HIGH>;
        };
 };
 
index 6dc9694..5c42df0 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG SMDK5250 board device tree source
+ * Samsung SMDK5250 board device tree source
  *
  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
@@ -12,7 +12,7 @@
 #include "exynos5250.dtsi"
 
 / {
-       model = "SAMSUNG SMDK5250 board based on EXYNOS5250";
+       model = "Samsung SMDK5250 board based on Exynos5250";
        compatible = "samsung,smdk5250", "samsung,exynos5250", "samsung,exynos5";
 
        aliases {
index e1f0215..b6135af 100644 (file)
@@ -1,16 +1,16 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG EXYNOS5250 SoC device tree source
+ * Samsung Exynos5250 SoC device tree source
  *
  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * SAMSUNG EXYNOS5250 SoC device nodes are listed in this file.
- * EXYNOS5250 based board files can include this file and provide
+ * Samsung Exynos5250 SoC device nodes are listed in this file.
+ * Exynos5250 based board files can include this file and provide
  * values for board specfic bindings.
  *
  * Note: This file does not include device nodes for all the controllers in
- * EXYNOS5250 SoC. As device tree coverage for EXYNOS5250 increases,
+ * Exynos5250 SoC. As device tree coverage for Exynos5250 increases,
  * additional nodes can be added to this file.
  */
 
                        #size-cells = <1>;
                        ranges = <0 0x02020000 0x30000>;
 
-                       smp-sysram@0 {
+                       smp-sram@0 {
                                compatible = "samsung,exynos4210-sysram";
                                reg = <0x0 0x1000>;
                        };
 
-                       smp-sysram@2f000 {
+                       smp-sram@2f000 {
                                compatible = "samsung,exynos4210-sysram-ns";
                                reg = <0x2f000 0x1000>;
                        };
index 36a2b77..0dc2ec1 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG XYREF5260 board device tree source
+ * Samsung XYREF5260 board device tree source
  *
  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
@@ -10,7 +10,7 @@
 #include "exynos5260.dtsi"
 
 / {
-       model = "SAMSUNG XYREF5260 board based on EXYNOS5260";
+       model = "Samsung XYREF5260 board based on Exynos5260";
        compatible = "samsung,xyref5260", "samsung,exynos5260", "samsung,exynos5";
 
        memory@20000000 {
index b0811db..154df70 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG EXYNOS5260 SoC device tree source
+ * Samsung Exynos5260 SoC device tree source
  *
  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
index e0db251..4f9297a 100644 (file)
 
                intn-gpios = <&gpx0 7 GPIO_ACTIVE_HIGH>;
                connect-gpios = <&gpx0 6 GPIO_ACTIVE_HIGH>;
-               reset-gpios = <&gpx1 4 GPIO_ACTIVE_HIGH>;
+               reset-gpios = <&gpx1 4 GPIO_ACTIVE_LOW>;
                initial-mode = <1>;
 
                clock-names = "refclk";
index dffa5e3..5282b5d 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG SMDK5410 board device tree source
+ * Samsung SMDK5410 board device tree source
  *
  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
@@ -10,7 +10,7 @@
 #include "exynos5410.dtsi"
 #include <dt-bindings/interrupt-controller/irq.h>
 / {
-       model = "Samsung SMDK5410 board based on EXYNOS5410";
+       model = "Samsung SMDK5410 board based on Exynos5410";
        compatible = "samsung,smdk5410", "samsung,exynos5410", "samsung,exynos5";
 
        memory@40000000 {
index a4b03d4..2eab80b 100644 (file)
@@ -1,12 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG EXYNOS5410 SoC device tree source
+ * Samsung Exynos5410 SoC device tree source
  *
  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * SAMSUNG EXYNOS5410 SoC device nodes are listed in this file.
- * EXYNOS5410 based board files can include this file and provide
+ * Samsung Exynos5410 SoC device nodes are listed in this file.
+ * Exynos5410 based board files can include this file and provide
  * values for board specfic bindings.
  */
 
index 592d7b4..ee28d30 100644 (file)
@@ -15,7 +15,7 @@
 #include <dt-bindings/clock/samsung,s2mps11.h>
 
 / {
-       model = "Insignal Arndale Octa evaluation board based on EXYNOS5420";
+       model = "Insignal Arndale Octa evaluation board based on Exynos5420";
        compatible = "insignal,arndale-octa", "samsung,exynos5420", "samsung,exynos5";
 
        memory@20000000 {
index 0ee6e92..58d1c54 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG EXYNOS5420 SoC cpu device tree source
+ * Samsung Exynos5420 SoC cpu device tree source
  *
  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
index 8240e51..e3f2afe 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG SMDK5420 board device tree source
+ * Samsung SMDK5420 board device tree source
  *
  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
@@ -12,7 +12,7 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
-       model = "Samsung SMDK5420 board based on EXYNOS5420";
+       model = "Samsung SMDK5420 board based on Exynos5420";
        compatible = "samsung,smdk5420", "samsung,exynos5420", "samsung,exynos5";
 
        memory@20000000 {
index d39907a..b672080 100644 (file)
@@ -1,12 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG EXYNOS5420 SoC device tree source
+ * Samsung Exynos5420 SoC device tree source
  *
  * Copyright (c) 2013 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * SAMSUNG EXYNOS5420 SoC device nodes are listed in this file.
- * EXYNOS5420 based board files can include this file and provide
+ * Samsung Exynos5420 SoC device nodes are listed in this file.
+ * Exynos5420 based board files can include this file and provide
  * values for board specfic bindings.
  */
 
 
                opp-1800000000 {
                        opp-hz = /bits/ 64 <1800000000>;
-                       opp-microvolt = <1250000>;
+                       opp-microvolt = <1250000 1250000 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-1700000000 {
                        opp-hz = /bits/ 64 <1700000000>;
-                       opp-microvolt = <1212500>;
+                       opp-microvolt = <1212500 1212500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-1600000000 {
                        opp-hz = /bits/ 64 <1600000000>;
-                       opp-microvolt = <1175000>;
+                       opp-microvolt = <1175000 1175000 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-1500000000 {
                        opp-hz = /bits/ 64 <1500000000>;
-                       opp-microvolt = <1137500>;
+                       opp-microvolt = <1137500 1137500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-1400000000 {
                        opp-hz = /bits/ 64 <1400000000>;
-                       opp-microvolt = <1112500>;
+                       opp-microvolt = <1112500 1112500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-1300000000 {
                        opp-hz = /bits/ 64 <1300000000>;
-                       opp-microvolt = <1062500>;
+                       opp-microvolt = <1062500 1062500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-1200000000 {
                        opp-hz = /bits/ 64 <1200000000>;
-                       opp-microvolt = <1037500>;
+                       opp-microvolt = <1037500 1037500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-1100000000 {
                        opp-hz = /bits/ 64 <1100000000>;
-                       opp-microvolt = <1012500>;
+                       opp-microvolt = <1012500 1012500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-1000000000 {
                        opp-hz = /bits/ 64 <1000000000>;
-                       opp-microvolt = < 987500>;
+                       opp-microvolt = < 987500 987500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-900000000 {
                        opp-hz = /bits/ 64 <900000000>;
-                       opp-microvolt = < 962500>;
+                       opp-microvolt = < 962500 962500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-800000000 {
                        opp-hz = /bits/ 64 <800000000>;
-                       opp-microvolt = < 937500>;
+                       opp-microvolt = < 937500 937500 1500000>;
                        clock-latency-ns = <140000>;
                };
                opp-700000000 {
                        opp-hz = /bits/ 64 <700000000>;
-                       opp-microvolt = < 912500>;
+                       opp-microvolt = < 912500 912500 1500000>;
                        clock-latency-ns = <140000>;
                };
        };
                        iommus = <&sysmmu_gscl1>;
                };
 
+               gpu: gpu@11800000 {
+                       compatible = "samsung,exynos5420-mali", "arm,mali-t628";
+                       reg = <0x11800000 0x5000>;
+                       interrupts = <GIC_SPI 219 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "job", "mmu", "gpu";
+
+                       clocks = <&clock CLK_G3D>;
+                       clock-names = "core";
+                       power-domains = <&g3d_pd>;
+                       operating-points-v2 = <&gpu_opp_table>;
+
+                       status = "disabled";
+                       #cooling-cells = <2>;
+
+                       gpu_opp_table: opp-table {
+                               compatible = "operating-points-v2";
+
+                               opp-177000000 {
+                                       opp-hz = /bits/ 64 <177000000>;
+                                       opp-microvolt = <812500>;
+                               };
+                               opp-266000000 {
+                                       opp-hz = /bits/ 64 <266000000>;
+                                       opp-microvolt = <862500>;
+                               };
+                               opp-350000000 {
+                                       opp-hz = /bits/ 64 <350000000>;
+                                       opp-microvolt = <912500>;
+                               };
+                               opp-420000000 {
+                                       opp-hz = /bits/ 64 <420000000>;
+                                       opp-microvolt = <962500>;
+                               };
+                               opp-480000000 {
+                                       opp-hz = /bits/ 64 <480000000>;
+                                       opp-microvolt = <1000000>;
+                               };
+                               opp-543000000 {
+                                       opp-hz = /bits/ 64 <543000000>;
+                                       opp-microvolt = <1037500>;
+                               };
+                               opp-600000000 {
+                                       opp-hz = /bits/ 64 <600000000>;
+                                       opp-microvolt = <1150000>;
+                               };
+                       };
+               };
+
                scaler_0: scaler@12800000 {
                        compatible = "samsung,exynos5420-scaler";
                        reg = <0x12800000 0x1294>;
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK400_WCORE>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_wcore_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK100_NOC>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_noc_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_PCLK200_FSYS>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_fsys_apb_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK200_FSYS>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_fsys_apb_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK200_FSYS2>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_fsys2_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK333>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_mfc_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK266>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_gen_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK66>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_peri_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK333_G2D>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_g2d_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK266_G2D>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_g2d_acp_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK300_JPEG>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_jpeg_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK166>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_jpeg_apb_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK300_DISP1>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_disp1_fimd_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK400_DISP1>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_disp1_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK300_GSCL>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_gscl_opp_table>;
                        status = "disabled";
                };
 
                        compatible = "samsung,exynos-bus";
                        clocks = <&clock CLK_DOUT_ACLK400_MSCL>;
                        clock-names = "bus";
-                       operating-points-v2 = <&bus_mscl_opp_table>;
                        status = "disabled";
                };
-
-               bus_wcore_opp_table: opp_table2 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <84000000>;
-                               opp-microvolt = <925000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <111000000>;
-                               opp-microvolt = <950000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <222000000>;
-                               opp-microvolt = <950000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <333000000>;
-                               opp-microvolt = <950000>;
-                       };
-                       opp04 {
-                               opp-hz = /bits/ 64 <400000000>;
-                               opp-microvolt = <987500>;
-                       };
-               };
-
-               bus_noc_opp_table: opp_table3 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <67000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <75000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <86000000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <100000000>;
-                       };
-               };
-
-               bus_fsys_apb_opp_table: opp_table4 {
-                       compatible = "operating-points-v2";
-                       opp-shared;
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <100000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <200000000>;
-                       };
-               };
-
-               bus_fsys2_opp_table: opp_table5 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <75000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <100000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <150000000>;
-                       };
-               };
-
-               bus_mfc_opp_table: opp_table6 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <96000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <111000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <167000000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <222000000>;
-                       };
-                       opp04 {
-                               opp-hz = /bits/ 64 <333000000>;
-                       };
-               };
-
-               bus_gen_opp_table: opp_table7 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <89000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <133000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <178000000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <267000000>;
-                       };
-               };
-
-               bus_peri_opp_table: opp_table8 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <67000000>;
-                       };
-               };
-
-               bus_g2d_opp_table: opp_table9 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <84000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <167000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <222000000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <300000000>;
-                       };
-                       opp04 {
-                               opp-hz = /bits/ 64 <333000000>;
-                       };
-               };
-
-               bus_g2d_acp_opp_table: opp_table10 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <67000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <133000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <178000000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <267000000>;
-                       };
-               };
-
-               bus_jpeg_opp_table: opp_table11 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <75000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <150000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <200000000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <300000000>;
-                       };
-               };
-
-               bus_jpeg_apb_opp_table: opp_table12 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <84000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <111000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <134000000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <167000000>;
-                       };
-               };
-
-               bus_disp1_fimd_opp_table: opp_table13 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <120000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <200000000>;
-                       };
-               };
-
-               bus_disp1_opp_table: opp_table14 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <120000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <200000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <300000000>;
-                       };
-               };
-
-               bus_gscl_opp_table: opp_table15 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <150000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <200000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <300000000>;
-                       };
-               };
-
-               bus_mscl_opp_table: opp_table16 {
-                       compatible = "operating-points-v2";
-
-                       opp00 {
-                               opp-hz = /bits/ 64 <84000000>;
-                       };
-                       opp01 {
-                               opp-hz = /bits/ 64 <167000000>;
-                       };
-                       opp02 {
-                               opp-hz = /bits/ 64 <222000000>;
-                       };
-                       opp03 {
-                               opp-hz = /bits/ 64 <333000000>;
-                       };
-                       opp04 {
-                               opp-hz = /bits/ 64 <400000000>;
-                       };
-               };
        };
 
        thermal-zones {
index e4a5857..1b8605c 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG EXYNOS5422 SoC cpu device tree source
+ * Samsung Exynos5422 SoC cpu device tree source
  *
  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
index 059fa32..5cf1aed 100644 (file)
                };
        };
 
-       dmc_opp_table: opp_table2 {
+       bus_wcore_opp_table: opp_table2 {
+               compatible = "operating-points-v2";
+
+               /* derived from 532MHz MPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <88700000>;
+                       opp-microvolt = <925000 925000 1400000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <133000000>;
+                       opp-microvolt = <950000 950000 1400000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <177400000>;
+                       opp-microvolt = <950000 950000 1400000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <266000000>;
+                       opp-microvolt = <950000 950000 1400000>;
+               };
+               opp04 {
+                       opp-hz = /bits/ 64 <532000000>;
+                       opp-microvolt = <1000000 1000000 1400000>;
+               };
+       };
+
+       bus_noc_opp_table: opp_table3 {
+               compatible = "operating-points-v2";
+
+               /* derived from 666MHz CPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <66600000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <74000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <83250000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <111000000>;
+               };
+       };
+
+       bus_fsys_apb_opp_table: opp_table4 {
+               compatible = "operating-points-v2";
+
+               /* derived from 666MHz CPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <111000000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <222000000>;
+               };
+       };
+
+       bus_fsys2_opp_table: opp_table5 {
+               compatible = "operating-points-v2";
+
+               /* derived from 600MHz DPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <75000000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <120000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <200000000>;
+               };
+       };
+
+       bus_mfc_opp_table: opp_table6 {
+               compatible = "operating-points-v2";
+
+               /* derived from 666MHz CPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <83250000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <111000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <166500000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <222000000>;
+               };
+               opp04 {
+                       opp-hz = /bits/ 64 <333000000>;
+               };
+       };
+
+       bus_gen_opp_table: opp_table7 {
+               compatible = "operating-points-v2";
+
+               /* derived from 532MHz MPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <88700000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <133000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <178000000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <266000000>;
+               };
+       };
+
+       bus_peri_opp_table: opp_table8 {
+               compatible = "operating-points-v2";
+
+               /* derived from 666MHz CPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <66600000>;
+               };
+       };
+
+       bus_g2d_opp_table: opp_table9 {
+               compatible = "operating-points-v2";
+
+               /* derived from 666MHz CPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <83250000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <111000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <166500000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <222000000>;
+               };
+               opp04 {
+                       opp-hz = /bits/ 64 <333000000>;
+               };
+       };
+
+       bus_g2d_acp_opp_table: opp_table10 {
+               compatible = "operating-points-v2";
+
+               /* derived from 532MHz MPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <66500000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <133000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <178000000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <266000000>;
+               };
+       };
+
+       bus_jpeg_opp_table: opp_table11 {
+               compatible = "operating-points-v2";
+
+               /* derived from 600MHz DPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <75000000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <150000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <200000000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <300000000>;
+               };
+       };
+
+       bus_jpeg_apb_opp_table: opp_table12 {
+               compatible = "operating-points-v2";
+
+               /* derived from 666MHz CPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <83250000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <111000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <133000000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <166500000>;
+               };
+       };
+
+       bus_disp1_fimd_opp_table: opp_table13 {
+               compatible = "operating-points-v2";
+
+               /* derived from 600MHz DPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <120000000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <200000000>;
+               };
+       };
+
+       bus_disp1_opp_table: opp_table14 {
+               compatible = "operating-points-v2";
+
+               /* derived from 600MHz DPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <120000000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <200000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <300000000>;
+               };
+       };
+
+       bus_gscl_opp_table: opp_table15 {
+               compatible = "operating-points-v2";
+
+               /* derived from 600MHz DPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <150000000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <200000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <300000000>;
+               };
+       };
+
+       bus_mscl_opp_table: opp_table16 {
+               compatible = "operating-points-v2";
+
+               /* derived from 666MHz CPLL */
+               opp00 {
+                       opp-hz = /bits/ 64 <84000000>;
+               };
+               opp01 {
+                       opp-hz = /bits/ 64 <167000000>;
+               };
+               opp02 {
+                       opp-hz = /bits/ 64 <222000000>;
+               };
+               opp03 {
+                       opp-hz = /bits/ 64 <333000000>;
+               };
+               opp04 {
+                       opp-hz = /bits/ 64 <666000000>;
+               };
+       };
+
+       dmc_opp_table: opp_table17 {
                compatible = "operating-points-v2";
 
                opp00 {
 };
 
 &bus_wcore {
+       operating-points-v2 = <&bus_wcore_opp_table>;
        devfreq-events = <&nocp_mem0_0>, <&nocp_mem0_1>,
                        <&nocp_mem1_0>, <&nocp_mem1_1>;
        vdd-supply = <&buck3_reg>;
 };
 
 &bus_noc {
+       operating-points-v2 = <&bus_noc_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_fsys_apb {
+       operating-points-v2 = <&bus_fsys_apb_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_fsys {
+       operating-points-v2 = <&bus_fsys2_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_fsys2 {
+       operating-points-v2 = <&bus_fsys2_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_mfc {
+       operating-points-v2 = <&bus_mfc_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_gen {
+       operating-points-v2 = <&bus_gen_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_peri {
+       operating-points-v2 = <&bus_peri_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_g2d {
+       operating-points-v2 = <&bus_g2d_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_g2d_acp {
+       operating-points-v2 = <&bus_g2d_acp_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_jpeg {
+       operating-points-v2 = <&bus_jpeg_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_jpeg_apb {
+       operating-points-v2 = <&bus_jpeg_apb_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_disp1_fimd {
+       operating-points-v2 = <&bus_disp1_fimd_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_disp1 {
+       operating-points-v2 = <&bus_disp1_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_gscl_scaler {
+       operating-points-v2 = <&bus_gscl_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
 
 &bus_mscl {
+       operating-points-v2 = <&bus_mscl_opp_table>;
        devfreq = <&bus_wcore>;
        status = "okay";
 };
                                regulator-max-microvolt = <1500000>;
                                regulator-always-on;
                                regulator-boot-on;
+                               regulator-coupled-with = <&buck3_reg>;
+                               regulator-coupled-max-spread = <300000>;
 
                                regulator-state-mem {
                                        regulator-off-in-suspend;
                                regulator-max-microvolt = <1400000>;
                                regulator-always-on;
                                regulator-boot-on;
+                               regulator-coupled-with = <&buck2_reg>;
+                               regulator-coupled-max-spread = <300000>;
 
                                regulator-state-mem {
                                        regulator-off-in-suspend;
                                regulator-name = "vdd_g3d";
                                regulator-min-microvolt = <800000>;
                                regulator-max-microvolt = <1400000>;
-                               regulator-always-on;
                                regulator-boot-on;
 
                                regulator-state-mem {
        vtmu-supply = <&ldo7_reg>;
 };
 
+&gpu {
+       mali-supply = <&buck4_reg>;
+       status = "okay";
+};
+
 &rtc {
        status = "okay";
        clocks = <&clock CLK_RTC>, <&s2mps11_osc S2MPS11_CLK_AP>;
index d271e75..f163206 100644 (file)
                                 */
                                map1 {
                                        trip = <&cpu0_alert1>;
-                                       cooling-device = <&cpu0 3 7>,
-                                                        <&cpu1 3 7>,
-                                                        <&cpu2 3 7>,
-                                                        <&cpu3 3 7>,
-                                                        <&cpu4 3 12>,
-                                                        <&cpu5 3 12>,
-                                                        <&cpu6 3 12>,
-                                                        <&cpu7 3 12>;
+                                       cooling-device = <&cpu0 3 8>,
+                                                        <&cpu1 3 8>,
+                                                        <&cpu2 3 8>,
+                                                        <&cpu3 3 8>,
+                                                        <&cpu4 3 14>,
+                                                        <&cpu5 3 14>,
+                                                        <&cpu6 3 14>,
+                                                        <&cpu7 3 14>;
                                };
                        };
                };
                                };
                                map1 {
                                        trip = <&cpu1_alert1>;
-                                       cooling-device = <&cpu0 3 7>,
-                                                        <&cpu1 3 7>,
-                                                        <&cpu2 3 7>,
-                                                        <&cpu3 3 7>,
-                                                        <&cpu4 3 12>,
-                                                        <&cpu5 3 12>,
-                                                        <&cpu6 3 12>,
-                                                        <&cpu7 3 12>;
+                                       cooling-device = <&cpu0 3 8>,
+                                                        <&cpu1 3 8>,
+                                                        <&cpu2 3 8>,
+                                                        <&cpu3 3 8>,
+                                                        <&cpu4 3 14>,
+                                                        <&cpu5 3 14>,
+                                                        <&cpu6 3 14>,
+                                                        <&cpu7 3 14>;
                                };
                        };
                };
                                };
                                map1 {
                                        trip = <&cpu2_alert1>;
-                                       cooling-device = <&cpu0 3 7>,
-                                                        <&cpu1 3 7>,
-                                                        <&cpu2 3 7>,
-                                                        <&cpu3 3 7>,
-                                                        <&cpu4 3 12>,
-                                                        <&cpu5 3 12>,
-                                                        <&cpu6 3 12>,
-                                                        <&cpu7 3 12>;
+                                       cooling-device = <&cpu0 3 8>,
+                                                        <&cpu1 3 8>,
+                                                        <&cpu2 3 8>,
+                                                        <&cpu3 3 8>,
+                                                        <&cpu4 3 14>,
+                                                        <&cpu5 3 14>,
+                                                        <&cpu6 3 14>,
+                                                        <&cpu7 3 14>;
                                };
                        };
                };
                                };
                                map1 {
                                        trip = <&cpu3_alert1>;
-                                       cooling-device = <&cpu0 3 7>,
-                                                        <&cpu1 3 7>,
-                                                        <&cpu2 3 7>,
-                                                        <&cpu3 3 7>,
-                                                        <&cpu4 3 12>,
-                                                        <&cpu5 3 12>,
-                                                        <&cpu6 3 12>,
-                                                        <&cpu7 3 12>;
+                                       cooling-device = <&cpu0 3 8>,
+                                                        <&cpu1 3 8>,
+                                                        <&cpu2 3 8>,
+                                                        <&cpu3 3 8>,
+                                                        <&cpu4 3 14>,
+                                                        <&cpu5 3 14>,
+                                                        <&cpu6 3 14>,
+                                                        <&cpu7 3 14>;
                                };
                        };
                };
index 8388720..1865a70 100644 (file)
                                /*
                                 * When reaching cpu0_alert3, reduce CPU
                                 * by 2 steps. On Exynos5422/5800 that would
-                                * be: 1600 MHz and 1100 MHz.
+                                * (usually) be: 1800 MHz and 1200 MHz.
                                 */
                                map3 {
                                        trip = <&cpu0_alert3>;
                                };
                                /*
                                 * When reaching cpu0_alert4, reduce CPU
-                                * further, down to 600 MHz (12 steps for big,
-                                * 7 steps for LITTLE).
+                                * further, down to 600 MHz (14 steps for big,
+                                * 8 steps for LITTLE).
                                 */
-                               map4 {
+                               cpu0_cooling_map4: map4 {
                                        trip = <&cpu0_alert4>;
-                                       cooling-device = <&cpu0 3 7>,
-                                                        <&cpu1 3 7>,
-                                                        <&cpu2 3 7>,
-                                                        <&cpu3 3 7>,
-                                                        <&cpu4 3 12>,
-                                                        <&cpu5 3 12>,
-                                                        <&cpu6 3 12>,
-                                                        <&cpu7 3 12>;
+                                       cooling-device = <&cpu0 3 8>,
+                                                        <&cpu1 3 8>,
+                                                        <&cpu2 3 8>,
+                                                        <&cpu3 3 8>,
+                                                        <&cpu4 3 14>,
+                                                        <&cpu5 3 14>,
+                                                        <&cpu6 3 14>,
+                                                        <&cpu7 3 14>;
                                };
                        };
                };
                                                         <&cpu6 0 2>,
                                                         <&cpu7 0 2>;
                                };
-                               map4 {
+                               cpu1_cooling_map4: map4 {
                                        trip = <&cpu1_alert4>;
-                                       cooling-device = <&cpu0 3 7>,
-                                                        <&cpu1 3 7>,
-                                                        <&cpu2 3 7>,
-                                                        <&cpu3 3 7>,
-                                                        <&cpu4 3 12>,
-                                                        <&cpu5 3 12>,
-                                                        <&cpu6 3 12>,
-                                                        <&cpu7 3 12>;
+                                       cooling-device = <&cpu0 3 8>,
+                                                        <&cpu1 3 8>,
+                                                        <&cpu2 3 8>,
+                                                        <&cpu3 3 8>,
+                                                        <&cpu4 3 14>,
+                                                        <&cpu5 3 14>,
+                                                        <&cpu6 3 14>,
+                                                        <&cpu7 3 14>;
                                };
                        };
                };
                                                         <&cpu6 0 2>,
                                                         <&cpu7 0 2>;
                                };
-                               map4 {
+                               cpu2_cooling_map4: map4 {
                                        trip = <&cpu2_alert4>;
-                                       cooling-device = <&cpu0 3 7>,
-                                                        <&cpu1 3 7>,
-                                                        <&cpu2 3 7>,
-                                                        <&cpu3 3 7>,
-                                                        <&cpu4 3 12>,
-                                                        <&cpu5 3 12>,
-                                                        <&cpu6 3 12>,
-                                                        <&cpu7 3 12>;
+                                       cooling-device = <&cpu0 3 8>,
+                                                        <&cpu1 3 8>,
+                                                        <&cpu2 3 8>,
+                                                        <&cpu3 3 8>,
+                                                        <&cpu4 3 14>,
+                                                        <&cpu5 3 14>,
+                                                        <&cpu6 3 14>,
+                                                        <&cpu7 3 14>;
                                };
                        };
                };
                                                         <&cpu6 0 2>,
                                                         <&cpu7 0 2>;
                                };
-                               map4 {
+                               cpu3_cooling_map4: map4 {
                                        trip = <&cpu3_alert4>;
-                                       cooling-device = <&cpu0 3 7>,
-                                                        <&cpu1 3 7>,
-                                                        <&cpu2 3 7>,
-                                                        <&cpu3 3 7>,
-                                                        <&cpu4 3 12>,
-                                                        <&cpu5 3 12>,
-                                                        <&cpu6 3 12>,
-                                                        <&cpu7 3 12>;
+                                       cooling-device = <&cpu0 3 8>,
+                                                        <&cpu1 3 8>,
+                                                        <&cpu2 3 8>,
+                                                        <&cpu3 3 8>,
+                                                        <&cpu4 3 14>,
+                                                        <&cpu5 3 14>,
+                                                        <&cpu6 3 14>,
+                                                        <&cpu7 3 14>;
                                };
                        };
                };
index a31ca2e..98feeca 100644 (file)
        samsung,asv-bin = <2>;
 };
 
+/*
+ * Odroid XU3-Lite board uses SoC revision with lower maximum frequencies
+ * than Odroid XU3/XU4 boards: 1.8 GHz for A15 cores & 1.3 GHz for A7 cores.
+ * Therefore we need to update OPPs tables and thermal maps accordingly.
+ */
+&cluster_a15_opp_table {
+       /delete-node/opp-2000000000;
+       /delete-node/opp-1900000000;
+};
+
+&cluster_a7_opp_table {
+       /delete-node/opp-1400000000;
+};
+
+&cpu0_cooling_map4 {
+       cooling-device = <&cpu0 3 7>,
+                        <&cpu1 3 7>,
+                        <&cpu2 3 7>,
+                        <&cpu3 3 7>,
+                        <&cpu4 3 12>,
+                        <&cpu5 3 12>,
+                        <&cpu6 3 12>,
+                        <&cpu7 3 12>;
+};
+
+&cpu1_cooling_map4 {
+       cooling-device = <&cpu0 3 7>,
+                        <&cpu1 3 7>,
+                        <&cpu2 3 7>,
+                        <&cpu3 3 7>,
+                        <&cpu4 3 12>,
+                        <&cpu5 3 12>,
+                        <&cpu6 3 12>,
+                        <&cpu7 3 12>;
+};
+
+&cpu2_cooling_map4 {
+       cooling-device = <&cpu0 3 7>,
+                        <&cpu1 3 7>,
+                        <&cpu2 3 7>,
+                        <&cpu3 3 7>,
+                        <&cpu4 3 12>,
+                        <&cpu5 3 12>,
+                        <&cpu6 3 12>,
+                        <&cpu7 3 12>;
+};
+
+&cpu3_cooling_map4 {
+       cooling-device = <&cpu0 3 7>,
+                        <&cpu1 3 7>,
+                        <&cpu2 3 7>,
+                        <&cpu3 3 7>,
+                        <&cpu4 3 12>,
+                        <&cpu5 3 12>,
+                        <&cpu6 3 12>,
+                        <&cpu7 3 12>;
+};
+
 &pwm {
        /*
         * PWM 0 -- fan
index f78dee8..8aa5117 100644 (file)
                        #size-cells = <1>;
                        ranges = <0 0x02020000 0x54000>;
 
-                       smp-sysram@0 {
+                       smp-sram@0 {
                                compatible = "samsung,exynos4210-sysram";
                                reg = <0x0 0x1000>;
                        };
 
-                       smp-sysram@53000 {
+                       smp-sram@53000 {
                                compatible = "samsung,exynos4210-sysram-ns";
                                reg = <0x53000 0x1000>;
                        };
index 60ca3d6..60ab0ef 100644 (file)
        assigned-clock-parents = <&clock CLK_MAU_EPLL>;
 };
 
+/*
+ * Peach Pi board uses SoC revision with lower maximum frequency for A7 cores
+ * (1.3 GHz instead of 1.4 GHz) than Odroid XU3/XU4 boards.  Thus we need to
+ * update A7 OPPs table accordingly.
+ */
+&cluster_a7_opp_table {
+       /delete-node/opp-1400000000;
+};
+
 &cpu0 {
        cpu-supply = <&buck2_reg>;
 };
                                regulator-always-on;
                                regulator-boot-on;
                                regulator-ramp-delay = <12500>;
+                               regulator-coupled-with = <&buck3_reg>;
+                               regulator-coupled-max-spread = <300000>;
                                regulator-state-mem {
                                        regulator-off-in-suspend;
                                };
                                regulator-always-on;
                                regulator-boot-on;
                                regulator-ramp-delay = <12500>;
+                               regulator-coupled-with = <&buck2_reg>;
+                               regulator-coupled-max-spread = <300000>;
                                regulator-state-mem {
                                        regulator-off-in-suspend;
                                };
index 16177d8..dfb99ab 100644 (file)
@@ -1,12 +1,12 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG EXYNOS5800 SoC device tree source
+ * Samsung Exynos5800 SoC device tree source
  *
  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * SAMSUNG EXYNOS5800 SoC device nodes are listed in this file.
- * EXYNOS5800 based board files can include this file and provide
+ * Samsung Exynos5800 SoC device nodes are listed in this file.
+ * Exynos5800 based board files can include this file and provide
  * values for board specfic bindings.
  */
 
 };
 
 &cluster_a15_opp_table {
+       opp-2000000000 {
+               opp-hz = /bits/ 64 <2000000000>;
+               opp-microvolt = <1312500>;
+               clock-latency-ns = <140000>;
+       };
+       opp-1900000000 {
+               opp-hz = /bits/ 64 <1900000000>;
+               opp-microvolt = <1262500>;
+               clock-latency-ns = <140000>;
+       };
+       opp-1800000000 {
+               opp-hz = /bits/ 64 <1800000000>;
+               opp-microvolt = <1237500>;
+               clock-latency-ns = <140000>;
+       };
        opp-1700000000 {
-               opp-microvolt = <1250000>;
+               opp-microvolt = <1250000 1250000 1500000>;
        };
        opp-1600000000 {
-               opp-microvolt = <1250000>;
+               opp-microvolt = <1250000 1250000 1500000>;
        };
        opp-1500000000 {
-               opp-microvolt = <1100000>;
+               opp-microvolt = <1100000 1100000 1500000>;
        };
        opp-1400000000 {
-               opp-microvolt = <1100000>;
+               opp-microvolt = <1100000 1100000 1500000>;
        };
        opp-1300000000 {
-               opp-microvolt = <1100000>;
+               opp-microvolt = <1100000 1100000 1500000>;
        };
        opp-1200000000 {
-               opp-microvolt = <1000000>;
+               opp-microvolt = <1000000 1000000 1500000>;
        };
        opp-1100000000 {
-               opp-microvolt = <1000000>;
+               opp-microvolt = <1000000 1000000 1500000>;
        };
        opp-1000000000 {
-               opp-microvolt = <1000000>;
+               opp-microvolt = <1000000 1000000 1500000>;
        };
        opp-900000000 {
-               opp-microvolt = <1000000>;
+               opp-microvolt = <1000000 1000000 1500000>;
        };
        opp-800000000 {
-               opp-microvolt = <900000>;
+               opp-microvolt = <900000 900000 1500000>;
        };
        opp-700000000 {
-               opp-microvolt = <900000>;
+               opp-microvolt = <900000 900000 1500000>;
        };
        opp-600000000 {
                opp-hz = /bits/ 64 <600000000>;
-               opp-microvolt = <900000>;
+               opp-microvolt = <900000 900000 1500000>;
                clock-latency-ns = <140000>;
        };
        opp-500000000 {
                opp-hz = /bits/ 64 <500000000>;
-               opp-microvolt = <900000>;
+               opp-microvolt = <900000 900000 1500000>;
                clock-latency-ns = <140000>;
        };
        opp-400000000 {
                opp-hz = /bits/ 64 <400000000>;
-               opp-microvolt = <900000>;
+               opp-microvolt = <900000 900000 1500000>;
                clock-latency-ns = <140000>;
        };
        opp-300000000 {
                opp-hz = /bits/ 64 <300000000>;
-               opp-microvolt = <900000>;
+               opp-microvolt = <900000 900000 1500000>;
                clock-latency-ns = <140000>;
        };
        opp-200000000 {
                opp-hz = /bits/ 64 <200000000>;
-               opp-microvolt = <900000>;
+               opp-microvolt = <900000 900000 1500000>;
                clock-latency-ns = <140000>;
        };
 };
 
 &cluster_a7_opp_table {
+       opp-1400000000 {
+               opp-hz = /bits/ 64 <1400000000>;
+               opp-microvolt = <1275000>;
+               clock-latency-ns = <140000>;
+       };
        opp-1300000000 {
                opp-microvolt = <1250000>;
        };
index 2abc42e..a0fa65b 100644 (file)
@@ -86,7 +86,7 @@
                        #address-cells = <1>;
                        #size-cells = <0>;
 
-                       fsi_occ0: occ {
+                       fsi_occ0: occ@1 {
                                compatible = "ibm,p9-occ";
                        };
                };
                        #address-cells = <1>;
                        #size-cells = <0>;
 
-                       fsi_occ1: occ {
+                       fsi_occ1: occ@2 {
                                compatible = "ibm,p9-occ";
                        };
                };
index 0fde90d..3f38c2e 100644 (file)
 };
 
 &usbhost1 {
-       phy_type = "serial";
-       dr_mode = "host";
        status = "okay";
 };
 
index 05cccd1..fb66884 100644 (file)
 };
 
 &usbhost1 {
-       phy_type = "serial";
-       dr_mode = "host";
        status = "okay";
 };
 
index 9a097ef..40b95a2 100644 (file)
                                clock-names = "ipg", "ahb", "per";
                                fsl,usbmisc = <&usbmisc 1>;
                                fsl,usbphy = <&usbphy1>;
+                               maximum-speed = "full-speed";
+                               phy_type = "serial";
+                               dr_mode = "host";
                                status = "disabled";
                        };
 
index ed6a3ce..552196d 100644 (file)
 
        display1: disp1 {
                compatible = "fsl,imx-parallel-display";
+               #address-cells = <1>;
+               #size-cells = <0>;
                interface-pix-fmt = "rgb24";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_ipu_disp1>;
-               display-timings {
-                       native-mode = <&timing0>;
-                       timing0: dvi {
-                               clock-frequency = <65000000>;
-                               hactive = <1024>;
-                               vactive = <768>;
-                               hback-porch = <220>;
-                               hfront-porch = <40>;
-                               vback-porch = <21>;
-                               vfront-porch = <7>;
-                               hsync-len = <60>;
-                               vsync-len = <10>;
-                       };
-               };
 
-               port {
+               port@0 {
+               reg = <0>;
+
                        display0_in: endpoint {
                                remote-endpoint = <&ipu_di0_disp1>;
                        };
                };
+
+               port@1 {
+                       reg = <1>;
+
+                       parallel_display_out: endpoint {
+                               remote-endpoint = <&tfp410_in>;
+                       };
+               };
        };
 
        display2: disp2 {
                };
        };
 
+       dvi-connector {
+               compatible = "dvi-connector";
+               digital;
+
+               port {
+                       dvi_connector_in: endpoint {
+                               remote-endpoint = <&tfp410_out>;
+                       };
+               };
+       };
+
+       dvi-encoder {
+               compatible = "ti,tfp410";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+
+                               tfp410_in: endpoint {
+                                       remote-endpoint = <&parallel_display_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+
+                               tfp410_out: endpoint {
+                                       remote-endpoint = <&dvi_connector_in>;
+                               };
+                       };
+               };
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
                pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/imx6dl-gw5907.dts b/arch/arm/boot/dts/imx6dl-gw5907.dts
new file mode 100644 (file)
index 0000000..3fa2822
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw5907.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite/Solo GW5907";
+       compatible = "gw,imx6dl-gw5907", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw5910.dts b/arch/arm/boot/dts/imx6dl-gw5910.dts
new file mode 100644 (file)
index 0000000..0d5e7e5
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw5910.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite/Solo GW5910";
+       compatible = "gw,imx6dl-gw5910", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw5912.dts b/arch/arm/boot/dts/imx6dl-gw5912.dts
new file mode 100644 (file)
index 0000000..5260e01
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+/dts-v1/;
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw5912.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite/Solo GW5912";
+       compatible = "gw,imx6dl-gw5912", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6dl-gw5913.dts b/arch/arm/boot/dts/imx6dl-gw5913.dts
new file mode 100644 (file)
index 0000000..b74e533
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-gw5913.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 DualLite/Solo GW5913";
+       compatible = "gw,imx6dl-gw5913", "gw,ventana", "fsl,imx6dl";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw5907.dts b/arch/arm/boot/dts/imx6q-gw5907.dts
new file mode 100644 (file)
index 0000000..b25526e
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-gw5907.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Dual/Quad GW5907";
+       compatible = "gw,imx6q-gw5907", "gw,ventana", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw5910.dts b/arch/arm/boot/dts/imx6q-gw5910.dts
new file mode 100644 (file)
index 0000000..6aafa2f
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-gw5910.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Dual/Quad GW5910";
+       compatible = "gw,imx6q-gw5910", "gw,ventana", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw5912.dts b/arch/arm/boot/dts/imx6q-gw5912.dts
new file mode 100644 (file)
index 0000000..4dcbd94
--- /dev/null
@@ -0,0 +1,13 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+/dts-v1/;
+#include "imx6q.dtsi"
+#include "imx6qdl-gw5912.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Dual/Quad GW5912";
+       compatible = "gw,imx6q-gw5912", "gw,ventana", "fsl,imx6q";
+};
diff --git a/arch/arm/boot/dts/imx6q-gw5913.dts b/arch/arm/boot/dts/imx6q-gw5913.dts
new file mode 100644 (file)
index 0000000..6f511f1
--- /dev/null
@@ -0,0 +1,14 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-gw5913.dtsi"
+
+/ {
+       model = "Gateworks Ventana i.MX6 Dual/Quad GW5913";
+       compatible = "gw,imx6q-gw5913", "gw,ventana", "fsl,imx6q";
+};
index d96ae54..7a3d1d3 100644 (file)
        status = "okay";
 };
 
+&i2c1 {
+       touchscreen@26 {
+               compatible = "ilitek,ili2117";
+               reg = <0x26>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_touchscreen>;
+               interrupts-extended = <&gpio1 6 IRQ_TYPE_EDGE_RISING>;
+       };
+};
+
 &ldb {
        status = "okay";
 
index ff1287e..1b5bc6b 100644 (file)
 
 &hdmi {
        pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_hdmi_ddc>;
+       pinctrl-0 = <&pinctrl_hdmi_ddc &pinctrl_hdmi_cec>;
        status = "disabled";
 };
 
diff --git a/arch/arm/boot/dts/imx6qdl-gw5907.dtsi b/arch/arm/boot/dts/imx6qdl-gw5907.dtsi
new file mode 100644 (file)
index 0000000..0bdebdd
--- /dev/null
@@ -0,0 +1,399 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               led0 = &led0;
+               led1 = &led1;
+               nand = &gpmi;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+       };
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+                       default-state = "off";
+               };
+       };
+
+       memory@10000000 {
+               device_type = "memory";
+               reg = <0x10000000 0x20000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pps>;
+               gpios = <&gpio1 26 GPIO_ACTIVE_HIGH>;
+               status = "okay";
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_5p0v: regulator-5p0v {
+               compatible = "regulator-fixed";
+               regulator-name = "5P0V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       reg_usb_otg_vbus: regulator-usb-otg-vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_otg_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               gpio = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii-id";
+       phy-reset-gpios = <&gpio1 30 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&hdmi {
+       ddc-i2c-bus = <&i2c3>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       gpio@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       rtc@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       gpio@20 {
+               compatible = "nxp,pca9555";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       adc@48 {
+               compatible = "ti,ads1015";
+               reg = <0x48>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               channel@4 {
+                       reg = <4>;
+                       ti,gain = <0>;
+                       ti,datarate = <5>;
+               };
+
+               channel@5 {
+                       reg = <5>;
+                       ti,gain = <0>;
+                       ti,datarate = <5>;
+               };
+
+               channel@6 {
+                       reg = <6>;
+                       ti,gain = <0>;
+                       ti,datarate = <5>;
+               };
+       };
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pcie>;
+       reset-gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
+&pwm4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm4>; /* MX6_DIO3 */
+       status = "disabled";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_otg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+};
+
+&iomuxc {
+       pinctrl_enet: enetgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b0b0
+                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b0b0
+                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b0b0
+                       MX6QDL_PAD_RGMII_TXC__RGMII_TXC         0x1b0b0
+                       MX6QDL_PAD_RGMII_TD0__RGMII_TD0         0x1b0b0
+                       MX6QDL_PAD_RGMII_TD1__RGMII_TD1         0x1b0b0
+                       MX6QDL_PAD_RGMII_TD2__RGMII_TD2         0x1b0b0
+                       MX6QDL_PAD_RGMII_TD3__RGMII_TD3         0x1b0b0
+                       MX6QDL_PAD_RGMII_TX_CTL__RGMII_TX_CTL   0x1b0b0
+                       MX6QDL_PAD_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       MX6QDL_PAD_ENET_TXD0__GPIO1_IO30        0x1b0b0
+               >;
+       };
+
+       pinctrl_gpio_leds: gpioledsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL0__GPIO4_IO06         0x1b0b0
+                       MX6QDL_PAD_KEY_ROW0__GPIO4_IO07         0x1b0b0
+               >;
+       };
+
+       pinctrl_gpmi_nand: gpminandgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                       MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                       MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                       MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                       MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                       MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                       MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                       MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                       MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                       MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                       MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                       MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                       MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                       MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                       MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                       MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x0001b0b0
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                       MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+                       MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x1b0b0
+                       MX6QDL_PAD_GPIO_19__GPIO4_IO05          0x1b0b0
+               >;
+       };
+
+       pinctrl_pcie: pciegrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_0__GPIO1_IO00           0x1b0b0
+               >;
+       };
+
+       pinctrl_pps: ppsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_RXD1__GPIO1_IO26        0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm2: pwm2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm3: pwm3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT1__PWM3_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm4: pwm4grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_CMD__PWM4_OUT            0x1b0b1
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D24__UART3_TX_DATA       0x1b0b1
+                       MX6QDL_PAD_EIM_D25__UART3_RX_DATA       0x1b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg: usbotggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+                       MX6QDL_PAD_EIM_D22__GPIO3_IO22          0x1b0b0
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT8__WDOG1_B          0x1b0b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw5910.dtsi b/arch/arm/boot/dts/imx6qdl-gw5910.dtsi
new file mode 100644 (file)
index 0000000..be1af74
--- /dev/null
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+       };
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       memory@10000000 {
+               device_type = "memory";
+               reg = <0x10000000 0x20000000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pps>;
+               gpios = <&gpio4 16 GPIO_ACTIVE_HIGH>;
+               status = "okay";
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_5p0v: regulator-5p0v {
+               compatible = "regulator-fixed";
+               regulator-name = "5P0V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       reg_wl: regulator-wl {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_wl>;
+               compatible = "regulator-fixed";
+               regulator-name = "wl";
+               gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+               startup-delay-us = <100>;
+               enable-active-high;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_bt: regulator-bt {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_bt>;
+               compatible = "regulator-fixed";
+               regulator-name = "bt";
+               gpio = <&gpio1 2 GPIO_ACTIVE_HIGH>;
+               startup-delay-us = <100>;
+               enable-active-high;
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+};
+
+
+&ecspi3 {
+       cs-gpios = <&gpio4 24 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi3>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       gpio@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       rtc@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accel@19 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_accel>;
+               compatible = "st,lis2de12";
+               reg = <0x19>;
+               st,drdy-int-pin = <1>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <13 0>;
+               interrupt-names = "INT1";
+       };
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pcie>;
+       reset-gpio = <&gpio3 20 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
+/* off-board RS232 */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+/* serial console */
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+/* Sterling-LWB Bluetooth */
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart4>;
+       uart-has-rtscts;
+       status = "okay";
+};
+
+/* GPS */
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_5p0v>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+/* Sterling-LWB SDIO WiFi */
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       vmmc-supply = <&reg_3p3v>;
+       non-removable;
+       bus-width = <4>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+       cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_3p3v>;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+};
+
+&iomuxc {
+       pinctrl_accel: accelmuxgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_18__GPIO7_IO13          0x1b0b1
+               >;
+       };
+
+       pinctrl_ecspi3: escpi3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT0__ECSPI3_SCLK      0x100b1
+                       MX6QDL_PAD_DISP0_DAT1__ECSPI3_MOSI      0x100b1
+                       MX6QDL_PAD_DISP0_DAT2__ECSPI3_MISO      0x100b1
+                       MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24       0x100b1
+               >;
+       };
+
+       pinctrl_enet: enetgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b030
+                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b030
+                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b030
+                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b030
+                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b030
+                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b030
+                       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_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       MX6QDL_PAD_ENET_TXD0__GPIO1_IO30        0x1b0b0
+               >;
+       };
+
+       pinctrl_gpio_leds: gpioledsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL0__GPIO4_IO06  0x1b0b0
+                       MX6QDL_PAD_KEY_ROW0__GPIO4_IO07  0x1b0b0
+                       MX6QDL_PAD_KEY_ROW4__GPIO4_IO15  0x1b0b0
+               >;
+       };
+
+       pinctrl_gpmi_nand: gpminandgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                       MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                       MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                       MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                       MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                       MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                       MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                       MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                       MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                       MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                       MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                       MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                       MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                       MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                       MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                       MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x0001b0b0
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                       MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+               >;
+       };
+
+       pinctrl_pcie: pciegrp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D20__GPIO3_IO20          0x1b0b0
+               >;
+       };
+
+       pinctrl_pps: ppsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_DI0_DISP_CLK__GPIO4_IO16     0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm2: pwm2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm3: pwm3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT1__PWM3_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_reg_bt: regbtgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x1b0b1
+               >;
+       };
+
+       pinctrl_reg_wl: regwlgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_5__GPIO1_IO05           0x1b0b1
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA    0x1b0b1
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart4: uart4grp {
+               fsl,pins = <
+                       MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA    0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT16__UART4_RTS_B      0x1b0b1
+                       MX6QDL_PAD_CSI0_DAT17__UART4_CTS_B      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg: usbotggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x13059
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD2_CMD__SD2_CMD             0x17059
+                       MX6QDL_PAD_SD2_CLK__SD2_CLK             0x10059
+                       MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x17059
+                       MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
+                       MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
+                       MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x17059 /* CD */
+                       MX6QDL_PAD_NANDF_CS1__SD3_VSELECT       0x17059
+               >;
+       };
+
+       pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x170b9
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x170b9
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x170b9
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x170b9
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x170b9
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x170b9
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x170b9 /* CD */
+                       MX6QDL_PAD_NANDF_CS1__SD3_VSELECT       0x170b9
+               >;
+       };
+
+       pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x170f9
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x100f9
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x170f9
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x170f9
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x170f9
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x170f9
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x170f9 /* CD */
+                       MX6QDL_PAD_NANDF_CS1__SD3_VSELECT       0x170f9
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT8__WDOG1_B          0x1b0b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw5912.dtsi b/arch/arm/boot/dts/imx6qdl-gw5912.dtsi
new file mode 100644 (file)
index 0000000..8c57fd2
--- /dev/null
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               led0 = &led0;
+               led1 = &led1;
+               led2 = &led2;
+               nand = &gpmi;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+       };
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+                       default-state = "off";
+               };
+
+               led2: user3 {
+                       label = "user3";
+                       gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; /* MX6_LOCLED# */
+                       default-state = "off";
+               };
+       };
+
+       memory@10000000 {
+               device_type = "memory";
+               reg = <0x10000000 0x40000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pps>;
+               gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_usb_vbus: regulator-5p0v {
+               compatible = "regulator-fixed";
+               regulator-name = "usb_vbus";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "okay";
+};
+
+&ecspi2 {
+       cs-gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi2>;
+       status = "okay";
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       gpio@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       rtc@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+
+       accel@19 {
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_accel>;
+               compatible = "st,lis2de12";
+               reg = <0x19>;
+               st,drdy-int-pin = <1>;
+               interrupt-parent = <&gpio7>;
+               interrupts = <13 0>;
+               interrupt-names = "INT1";
+       };
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pcie>;
+       reset-gpio = <&gpio1 29 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>; /* MX6_DIO0 */
+       status = "disabled";
+};
+
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
+&pwm4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm4>; /* MX6_DIO3 */
+       status = "disabled";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       rts-gpios = <&gpio7 12 GPIO_ACTIVE_HIGH>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usb_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       dr_mode = "host";
+       status = "okay";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usb_vbus>;
+       status = "okay";
+};
+
+&usdhc3 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc3>;
+       pinctrl-1 = <&pinctrl_usdhc3_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc3_200mhz>;
+       cd-gpios = <&gpio7 0 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_3p3v>;
+       no-1-8-v; /* firmware will remove if board revision supports */
+       status = "okay";
+};
+
+&wdog1 {
+       status = "disabled";
+};
+
+&wdog2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_accel: accelmuxgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_18__GPIO7_IO13          0x1b0b1
+               >;
+       };
+
+       pinctrl_enet: enetgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b030
+                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b030
+                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b030
+                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b030
+                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b030
+                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b030
+                       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_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+               >;
+       };
+
+       pinctrl_ecspi2: escpi2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_CS0__ECSPI2_SCLK 0x100b1
+                       MX6QDL_PAD_EIM_CS1__ECSPI2_MOSI 0x100b1
+                       MX6QDL_PAD_EIM_OE__ECSPI2_MISO  0x100b1
+                       MX6QDL_PAD_EIM_RW__GPIO2_IO26   0x100b1
+               >;
+       };
+
+       pinctrl_flexcan1: flexcan1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_ROW2__FLEXCAN1_RX        0x1b0b1
+                       MX6QDL_PAD_KEY_COL2__FLEXCAN1_TX        0x1b0b1
+                       MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x4001b0b0
+               >;
+       };
+
+       pinctrl_gpio_leds: gpioledsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL0__GPIO4_IO06         0x1b0b0
+                       MX6QDL_PAD_KEY_ROW0__GPIO4_IO07         0x1b0b0
+                       MX6QDL_PAD_KEY_ROW4__GPIO4_IO15         0x1b0b0
+               >;
+       };
+
+       pinctrl_gpmi_nand: gpminandgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                       MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                       MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                       MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                       MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                       MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                       MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                       MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                       MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                       MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                       MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                       MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                       MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                       MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                       MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                       MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x0001b0b0
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                       MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+               >;
+       };
+
+       pinctrl_pcie: pciegrp {
+               fsl,pins = <
+                       MX6QDL_PAD_ENET_TX_EN__GPIO1_IO28       0x1b0b0
+                       MX6QDL_PAD_ENET_TXD1__GPIO1_IO29        0x1b0b0
+               >;
+       };
+
+       pinctrl_pps: ppsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_5__GPIO1_IO05           0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm1: pwm1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_9__PWM1_OUT             0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm2: pwm2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm3: pwm3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT1__PWM3_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm4: pwm4grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT2__PWM4_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       MX6QDL_PAD_GPIO_17__GPIO7_IO12          0x4001b0b1
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD4_DAT3__GPIO2_IO11         0x4001b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg: usbotggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x13059
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x17059
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x10059
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x17059
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x17059 /* CD */
+                       MX6QDL_PAD_NANDF_CS1__SD3_VSELECT       0x17059
+               >;
+       };
+
+       pinctrl_usdhc3_100mhz: usdhc3grp100mhz {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x170b9
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x100b9
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x170b9
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x170b9
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x170b9
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x170b9
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x170b9 /* CD */
+                       MX6QDL_PAD_NANDF_CS1__SD3_VSELECT       0x170b9
+               >;
+       };
+
+       pinctrl_usdhc3_200mhz: usdhc3grp200mhz {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_CMD__SD3_CMD             0x170f9
+                       MX6QDL_PAD_SD3_CLK__SD3_CLK             0x100f9
+                       MX6QDL_PAD_SD3_DAT0__SD3_DATA0          0x170f9
+                       MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x170f9
+                       MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x170f9
+                       MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x170f9
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x170f9 /* CD */
+                       MX6QDL_PAD_NANDF_CS1__SD3_VSELECT       0x170f9
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT3__WDOG2_B            0x1b0b0
+               >;
+       };
+};
diff --git a/arch/arm/boot/dts/imx6qdl-gw5913.dtsi b/arch/arm/boot/dts/imx6qdl-gw5913.dtsi
new file mode 100644 (file)
index 0000000..635c203
--- /dev/null
@@ -0,0 +1,348 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 Gateworks Corporation
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       /* these are used by bootloader for disabling nodes */
+       aliases {
+               led0 = &led0;
+               led1 = &led1;
+               nand = &gpmi;
+               usb0 = &usbh1;
+               usb1 = &usbotg;
+       };
+
+       chosen {
+               stdout-path = &uart2;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               led0: user1 {
+                       label = "user1";
+                       gpios = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDG */
+                       default-state = "on";
+                       linux,default-trigger = "heartbeat";
+               };
+
+               led1: user2 {
+                       label = "user2";
+                       gpios = <&gpio4 7 GPIO_ACTIVE_HIGH>; /* MX6_PANLEDR */
+                       default-state = "off";
+               };
+       };
+
+       memory@10000000 {
+               device_type = "memory";
+               reg = <0x10000000 0x20000000>;
+       };
+
+       pps {
+               compatible = "pps-gpio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pps>;
+               gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>;
+               status = "okay";
+       };
+
+       reg_3p3v: regulator-3p3v {
+               compatible = "regulator-fixed";
+               regulator-name = "3P3V";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_5p0v: regulator-5p0v {
+               compatible = "regulator-fixed";
+               regulator-name = "5P0V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       phy-mode = "rgmii-id";
+       status = "okay";
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       status = "okay";
+};
+
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       gpio@23 {
+               compatible = "nxp,pca9555";
+               reg = <0x23>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       eeprom@50 {
+               compatible = "atmel,24c02";
+               reg = <0x50>;
+               pagesize = <16>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c02";
+               reg = <0x51>;
+               pagesize = <16>;
+       };
+
+       eeprom@52 {
+               compatible = "atmel,24c02";
+               reg = <0x52>;
+               pagesize = <16>;
+       };
+
+       eeprom@53 {
+               compatible = "atmel,24c02";
+               reg = <0x53>;
+               pagesize = <16>;
+       };
+
+       rtc@68 {
+               compatible = "dallas,ds1672";
+               reg = <0x68>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+};
+
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+};
+
+&pcie {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pcie>;
+       reset-gpio = <&gpio1 0 GPIO_ACTIVE_LOW>;
+       status = "okay";
+};
+
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>; /* MX6_DIO1 */
+       status = "disabled";
+};
+
+&pwm3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm3>; /* MX6_DIO2 */
+       status = "disabled";
+};
+
+&pwm4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm4>; /* MX6_DIO3 */
+       status = "disabled";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       status = "okay";
+};
+
+&uart5 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart5>;
+       status = "okay";
+};
+
+&usbotg {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       disable-over-current;
+       status = "okay";
+};
+
+&usbh1 {
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+};
+
+&iomuxc {
+       pinctrl_enet: enetgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_RGMII_RXC__RGMII_RXC         0x1b030
+                       MX6QDL_PAD_RGMII_RD0__RGMII_RD0         0x1b030
+                       MX6QDL_PAD_RGMII_RD1__RGMII_RD1         0x1b030
+                       MX6QDL_PAD_RGMII_RD2__RGMII_RD2         0x1b030
+                       MX6QDL_PAD_RGMII_RD3__RGMII_RD3         0x1b030
+                       MX6QDL_PAD_RGMII_RX_CTL__RGMII_RX_CTL   0x1b030
+                       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_ENET_REF_CLK__ENET_TX_CLK    0x1b0b0
+                       MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                       MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                       MX6QDL_PAD_GPIO_16__ENET_REF_CLK        0x4001b0a8
+                       MX6QDL_PAD_ENET_TXD0__GPIO1_IO30        0x1b0b0
+               >;
+       };
+
+       pinctrl_gpio_leds: gpioledsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL0__GPIO4_IO06         0x1b0b0
+                       MX6QDL_PAD_KEY_ROW0__GPIO4_IO07         0x1b0b0
+               >;
+       };
+
+       pinctrl_gpmi_nand: gpminandgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_NANDF_CLE__NAND_CLE          0xb0b1
+                       MX6QDL_PAD_NANDF_ALE__NAND_ALE          0xb0b1
+                       MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0xb0b1
+                       MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0xb000
+                       MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0xb0b1
+                       MX6QDL_PAD_SD4_CMD__NAND_RE_B           0xb0b1
+                       MX6QDL_PAD_SD4_CLK__NAND_WE_B           0xb0b1
+                       MX6QDL_PAD_NANDF_D0__NAND_DATA00        0xb0b1
+                       MX6QDL_PAD_NANDF_D1__NAND_DATA01        0xb0b1
+                       MX6QDL_PAD_NANDF_D2__NAND_DATA02        0xb0b1
+                       MX6QDL_PAD_NANDF_D3__NAND_DATA03        0xb0b1
+                       MX6QDL_PAD_NANDF_D4__NAND_DATA04        0xb0b1
+                       MX6QDL_PAD_NANDF_D5__NAND_DATA05        0xb0b1
+                       MX6QDL_PAD_NANDF_D6__NAND_DATA06        0xb0b1
+                       MX6QDL_PAD_NANDF_D7__NAND_DATA07        0xb0b1
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D21__I2C1_SCL            0x4001b8b1
+                       MX6QDL_PAD_EIM_D28__I2C1_SDA            0x4001b8b1
+                       MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x0001b0b0
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL3__I2C2_SCL           0x4001b8b1
+                       MX6QDL_PAD_KEY_ROW3__I2C2_SDA           0x4001b8b1
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                       MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+               >;
+       };
+
+       pinctrl_pcie: pciegrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_0__GPIO1_IO00           0x1b0b0
+               >;
+       };
+
+       pinctrl_pps: ppsgrp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_DAT5__GPIO7_IO00         0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm2: pwm2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT2__PWM2_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm3: pwm3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_DAT1__PWM3_OUT           0x1b0b1
+               >;
+       };
+
+       pinctrl_pwm4: pwm4grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD1_CMD__PWM4_OUT            0x1b0b1
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D24__UART3_TX_DATA       0x1b0b1
+                       MX6QDL_PAD_EIM_D25__UART3_RX_DATA       0x1b0b1
+               >;
+       };
+
+       pinctrl_uart5: uart5grp {
+               fsl,pins = <
+                       MX6QDL_PAD_KEY_COL1__UART5_TX_DATA      0x1b0b1
+                       MX6QDL_PAD_KEY_ROW1__UART5_RX_DATA      0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg: usbotggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_GPIO_1__USB_OTG_ID           0x17059
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_DISP0_DAT8__WDOG1_B          0x1b0b0
+               >;
+       };
+};
index d91d46b..0fd7f2e 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
        clocks = <&clks IMX6QDL_CLK_ENET>,
                 <&clks IMX6QDL_CLK_ENET>,
                 <&clks IMX6QDL_CLK_ENET_REF>;
-       phy-mode = "rmii";
        status = "okay";
 };
index 7814f1e..756f3a9 100644 (file)
 &fec {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_enet>;
-       phy-reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
        clocks = <&clks IMX6QDL_CLK_ENET>, <&clks IMX6QDL_CLK_ENET>, <&rmii_clk>;
        phy-mode = "rmii";
+       phy-handle = <&eth_phy>;
        status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               eth_phy: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+                       reset-gpios = <&gpio7 12 GPIO_ACTIVE_LOW>;
+                       reset-assert-us = <4000>;
+                       reset-deassert-us = <4000>;
+               };
+       };
 };
 
 &gpmi {
index 6486df3..978dc1c 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/regulator/dlg,da9063-regulator.h>
 
 / {
        aliases {
                        compatible = "dlg,da9062-rtc";
                };
 
+               da9062_onkey: onkey {
+                       compatible = "dlg,da9062-onkey";
+               };
+
                watchdog {
                        compatible = "dlg,da9062-watchdog";
                };
                                regulator-name = "vdd_arm";
                                regulator-min-microvolt = <730000>;
                                regulator-max-microvolt = <1380000>;
+                               regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
                                regulator-always-on;
                        };
 
                                regulator-name = "vdd_soc";
                                regulator-min-microvolt = <730000>;
                                regulator-max-microvolt = <1380000>;
+                               regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
                                regulator-always-on;
                        };
 
                                regulator-name = "vdd_ddr3";
                                regulator-min-microvolt = <1500000>;
                                regulator-max-microvolt = <1500000>;
+                               regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
                                regulator-always-on;
                        };
 
                                regulator-name = "vdd_eth";
                                regulator-min-microvolt = <1200000>;
                                regulator-max-microvolt = <1200000>;
+                               regulator-initial-mode = <DA9063_BUCK_MODE_SYNC>;
                                regulator-always-on;
                        };
 
index a2a4f33..0075637 100644 (file)
                regulator-always-on;
        };
 
-       reg_5p0v_user_usb: regulator-5p0v-user-usb {
-               compatible = "regulator-fixed";
-               pinctrl-names = "default";
-               pinctrl-0 = <&pinctrl_reg_user_usb>;
-               vin-supply = <&reg_5p0v_main>;
-               regulator-name = "5V_USER_USB";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               gpio = <&gpio3 22 GPIO_ACTIVE_LOW>;
-               startup-delay-us = <1000>;
-       };
-
        reg_3p3v_pmic: regulator-3p3v-pmic {
                compatible = "regulator-fixed";
                vin-supply = <&reg_12p0v>;
        };
 };
 
+&gpio3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpio3_hog>;
+
+       usb-emulation {
+               gpio-hog;
+               gpios = <19 GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "usb-emulation";
+       };
+
+       usb-mode1 {
+               gpio-hog;
+               gpios = <20 GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "usb-mode1";
+       };
+
+       usb-pwr {
+               gpio-hog;
+               gpios = <22 GPIO_ACTIVE_LOW>;
+               output-high;
+               line-name = "usb-pwr-ctrl-en-n";
+       };
+
+       usb-mode2 {
+               gpio-hog;
+               gpios = <23 GPIO_ACTIVE_HIGH>;
+               output-high;
+               line-name = "usb-mode2";
+       };
+};
+
 &i2c1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_i2c1>;
                status = "disabled";
        };
 
+       reg_5p0v_user_usb: charger@32 {
+               compatible = "microchip,ucs1002";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ucs1002_pins>;
+               reg = <0x32>;
+               interrupts-extended = <&gpio5 2 IRQ_TYPE_EDGE_BOTH>,
+                                     <&gpio3 21 IRQ_TYPE_EDGE_BOTH>;
+               interrupt-names = "a_det", "alert";
+       };
+
        hpa1: amp@60 {
                compatible = "ti,tpa6130a2";
                pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc2>;
        bus-width = <4>;
        cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
-       wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
+       disable-wp;
        vmmc-supply = <&reg_3p3v_sd>;
        vqmmc-supply = <&reg_3p3v>;
        no-1-8-v;
        pinctrl-0 = <&pinctrl_usdhc3>;
        bus-width = <4>;
        cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
-       wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
+       disable-wp;
        vmmc-supply = <&reg_3p3v_sd>;
        vqmmc-supply = <&reg_3p3v>;
        no-1-8-v;
 &usbh1 {
        vbus-supply = <&reg_5p0v_main>;
        disable-over-current;
+       maximum-speed = "full-speed";
        status = "okay";
 };
 
                >;
        };
 
+       pinctrl_gpio3_hog: gpio3hoggrp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_D19__GPIO3_IO19          0x1b0b0
+                       MX6QDL_PAD_EIM_D20__GPIO3_IO20          0x1b0b0
+                       MX6QDL_PAD_EIM_D22__GPIO3_IO22          0x1b0b0
+                       MX6QDL_PAD_EIM_D23__GPIO3_IO23          0x1b0b0
+               >;
+       };
+
        pinctrl_i2c1: i2c1grp {
                fsl,pins = <
                        MX6QDL_PAD_CSI0_DAT8__I2C1_SDA          0x4001b8b1
                >;
        };
 
-       pinctrl_reg_user_usb: usbotggrp {
-               fsl,pins = <
-                       MX6QDL_PAD_EIM_D22__GPIO3_IO22          0x40000038
-               >;
-       };
-
        pinctrl_rmii_phy_irq: phygrp {
                fsl,pins = <
                        MX6QDL_PAD_EIM_D30__GPIO3_IO30          0x40010000
                >;
        };
 
+       pinctrl_ucs1002_pins: ucs1002grp {
+               fsl,pins = <
+                       MX6QDL_PAD_EIM_A25__GPIO5_IO02          0x1b0b0
+                       MX6QDL_PAD_EIM_D21__GPIO3_IO21          0x1b0b0
+               >;
+       };
+
        pinctrl_usdhc2: usdhc2grp {
                fsl,pins = <
                        MX6QDL_PAD_SD2_CMD__SD2_CMD             0x10059
                        MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x17059
                        MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x17059
                        MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x17059
-                       MX6QDL_PAD_NANDF_D3__GPIO2_IO03         0x40010040
                        MX6QDL_PAD_NANDF_D2__GPIO2_IO02         0x40010040
                >;
        };
                        MX6QDL_PAD_SD3_DAT1__SD3_DATA1          0x17059
                        MX6QDL_PAD_SD3_DAT2__SD3_DATA2          0x17059
                        MX6QDL_PAD_SD3_DAT3__SD3_DATA3          0x17059
-                       MX6QDL_PAD_NANDF_D1__GPIO2_IO01         0x40010040
                        MX6QDL_PAD_NANDF_D0__GPIO2_IO00         0x40010040
 
                >;
diff --git a/arch/arm/boot/dts/imx6sl-tolino-shine3.dts b/arch/arm/boot/dts/imx6sl-tolino-shine3.dts
new file mode 100644 (file)
index 0000000..27143ea
--- /dev/null
@@ -0,0 +1,322 @@
+// SPDX-License-Identifier: (GPL-2.0)
+/*
+ * Device tree for the Tolino Shine 3 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 Toline Shine 3 ebook reader it is a i.MX6SL
+ *
+ * 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 "imx6sl.dtsi"
+#include "e60k02.dtsi"
+
+/ {
+       model = "Tolino Shine 3";
+       compatible = "kobo,tolino-shine3", "fsl,imx6sl";
+};
+
+&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 = <
+                       MX6SL_PAD_SD1_DAT1__GPIO5_IO08  0x17059 /* PWR_SW */
+                       MX6SL_PAD_SD1_DAT4__GPIO5_IO12  0x17059 /* HALL_EN */
+               >;
+       };
+
+       pinctrl_hog: hoggrp {
+               fsl,pins = <
+                       MX6SL_PAD_LCD_DAT0__GPIO2_IO20  0x79
+                       MX6SL_PAD_LCD_DAT1__GPIO2_IO21  0x79
+                       MX6SL_PAD_LCD_DAT2__GPIO2_IO22  0x79
+                       MX6SL_PAD_LCD_DAT3__GPIO2_IO23  0x79
+                       MX6SL_PAD_LCD_DAT4__GPIO2_IO24  0x79
+                       MX6SL_PAD_LCD_DAT5__GPIO2_IO25  0x79
+                       MX6SL_PAD_LCD_DAT6__GPIO2_IO26  0x79
+                       MX6SL_PAD_LCD_DAT7__GPIO2_IO27  0x79
+                       MX6SL_PAD_LCD_DAT8__GPIO2_IO28  0x79
+                       MX6SL_PAD_LCD_DAT9__GPIO2_IO29  0x79
+                       MX6SL_PAD_LCD_DAT10__GPIO2_IO30 0x79
+                       MX6SL_PAD_LCD_DAT11__GPIO2_IO31 0x79
+                       MX6SL_PAD_LCD_DAT12__GPIO3_IO00 0x79
+                       MX6SL_PAD_LCD_DAT13__GPIO3_IO01 0x79
+                       MX6SL_PAD_LCD_DAT14__GPIO3_IO02 0x79
+                       MX6SL_PAD_LCD_DAT15__GPIO3_IO03 0x79
+                       MX6SL_PAD_LCD_DAT16__GPIO3_IO04 0x79
+                       MX6SL_PAD_LCD_DAT17__GPIO3_IO05 0x79
+                       MX6SL_PAD_LCD_DAT18__GPIO3_IO06 0x79
+                       MX6SL_PAD_LCD_DAT19__GPIO3_IO07 0x79
+                       MX6SL_PAD_LCD_DAT20__GPIO3_IO08 0x79
+                       MX6SL_PAD_LCD_DAT21__GPIO3_IO09 0x79
+                       MX6SL_PAD_LCD_DAT22__GPIO3_IO10 0x79
+                       MX6SL_PAD_LCD_DAT23__GPIO3_IO11 0x79
+                       MX6SL_PAD_LCD_CLK__GPIO2_IO15           0x79
+                       MX6SL_PAD_LCD_ENABLE__GPIO2_IO16        0x79
+                       MX6SL_PAD_LCD_HSYNC__GPIO2_IO17 0x79
+                       MX6SL_PAD_LCD_VSYNC__GPIO2_IO18 0x79
+                       MX6SL_PAD_LCD_RESET__GPIO2_IO19 0x79
+                       MX6SL_PAD_KEY_COL3__GPIO3_IO30          0x79
+                       MX6SL_PAD_KEY_ROW7__GPIO4_IO07          0x79
+                       MX6SL_PAD_ECSPI2_MOSI__GPIO4_IO13       0x79
+                       MX6SL_PAD_KEY_COL5__GPIO4_IO02          0x79
+                       MX6SL_PAD_KEY_ROW6__GPIO4_IO05          0x79
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX6SL_PAD_I2C1_SCL__I2C1_SCL     0x4001f8b1
+                       MX6SL_PAD_I2C1_SDA__I2C1_SDA     0x4001f8b1
+               >;
+       };
+
+       pinctrl_i2c1_sleep: i2c1grp-sleep {
+               fsl,pins = <
+                       MX6SL_PAD_I2C1_SCL__I2C1_SCL     0x400108b1
+                       MX6SL_PAD_I2C1_SDA__I2C1_SDA     0x400108b1
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX6SL_PAD_I2C2_SCL__I2C2_SCL     0x4001f8b1
+                       MX6SL_PAD_I2C2_SDA__I2C2_SDA     0x4001f8b1
+               >;
+       };
+
+       pinctrl_i2c2_sleep: i2c2grp-sleep {
+               fsl,pins = <
+                       MX6SL_PAD_I2C2_SCL__I2C2_SCL     0x400108b1
+                       MX6SL_PAD_I2C2_SDA__I2C2_SDA     0x400108b1
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX6SL_PAD_REF_CLK_24M__I2C3_SCL  0x4001f8b1
+                       MX6SL_PAD_REF_CLK_32K__I2C3_SDA  0x4001f8b1
+               >;
+       };
+
+       pinctrl_led: ledgrp {
+               fsl,pins = <
+                       MX6SL_PAD_SD1_DAT6__GPIO5_IO07 0x17059
+               >;
+       };
+
+       pinctrl_lm3630a_bl_gpio: lm3630a-bl-gpiogrp {
+               fsl,pins = <
+                       MX6SL_PAD_EPDC_PWRCTRL3__GPIO2_IO10             0x10059 /* HWEN */
+               >;
+       };
+
+       pinctrl_ricoh_gpio: ricoh_gpiogrp {
+               fsl,pins = <
+                       MX6SL_PAD_SD1_CLK__GPIO5_IO15                  0x1b8b1 /* ricoh619 chg */
+                       MX6SL_PAD_SD1_DAT0__GPIO5_IO11        0x1b8b1 /* ricoh619 irq */
+                       MX6SL_PAD_KEY_COL2__GPIO3_IO28                         0x1b8b1 /* ricoh619 bat_low_int */
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX6SL_PAD_UART1_TXD__UART1_TX_DATA 0x1b0b1
+                       MX6SL_PAD_UART1_RXD__UART1_TX_DATA 0x1b0b1
+               >;
+       };
+
+       pinctrl_usbotg1: usbotg1grp {
+               fsl,pins = <
+                       MX6SL_PAD_EPDC_PWRCOM__USB_OTG1_ID 0x17059
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX6SL_PAD_SD2_CMD__SD2_CMD              0x17059
+                       MX6SL_PAD_SD2_CLK__SD2_CLK              0x13059
+                       MX6SL_PAD_SD2_DAT0__SD2_DATA0           0x17059
+                       MX6SL_PAD_SD2_DAT1__SD2_DATA1           0x17059
+                       MX6SL_PAD_SD2_DAT2__SD2_DATA2           0x17059
+                       MX6SL_PAD_SD2_DAT3__SD2_DATA3           0x17059
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp-100mhz {
+               fsl,pins = <
+                       MX6SL_PAD_SD2_CMD__SD2_CMD              0x170b9
+                       MX6SL_PAD_SD2_CLK__SD2_CLK              0x130b9
+                       MX6SL_PAD_SD2_DAT0__SD2_DATA0           0x170b9
+                       MX6SL_PAD_SD2_DAT1__SD2_DATA1           0x170b9
+                       MX6SL_PAD_SD2_DAT2__SD2_DATA2           0x170b9
+                       MX6SL_PAD_SD2_DAT3__SD2_DATA3           0x170b9
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp-200mhz {
+               fsl,pins = <
+                       MX6SL_PAD_SD2_CMD__SD2_CMD              0x170f9
+                       MX6SL_PAD_SD2_CLK__SD2_CLK              0x130f9
+                       MX6SL_PAD_SD2_DAT0__SD2_DATA0           0x170f9
+                       MX6SL_PAD_SD2_DAT1__SD2_DATA1           0x170f9
+                       MX6SL_PAD_SD2_DAT2__SD2_DATA2           0x170f9
+                       MX6SL_PAD_SD2_DAT3__SD2_DATA3           0x170f9
+               >;
+       };
+
+       pinctrl_usdhc2_sleep: usdhc2grp-sleep {
+               fsl,pins = <
+                       MX6SL_PAD_SD2_CMD__GPIO5_IO04           0x100f9
+                       MX6SL_PAD_SD2_CLK__GPIO5_IO05           0x100f9
+                       MX6SL_PAD_SD2_DAT0__GPIO5_IO01          0x100f9
+                       MX6SL_PAD_SD2_DAT1__GPIO4_IO30          0x100f9
+                       MX6SL_PAD_SD2_DAT2__GPIO5_IO03          0x100f9
+                       MX6SL_PAD_SD2_DAT3__GPIO4_IO28          0x100f9
+               >;
+       };
+
+       pinctrl_usdhc3: usdhc3grp {
+               fsl,pins = <
+                       MX6SL_PAD_SD3_CMD__SD3_CMD      0x11059
+                       MX6SL_PAD_SD3_CLK__SD3_CLK      0x11059
+                       MX6SL_PAD_SD3_DAT0__SD3_DATA0   0x11059
+                       MX6SL_PAD_SD3_DAT1__SD3_DATA1   0x11059
+                       MX6SL_PAD_SD3_DAT2__SD3_DATA2   0x11059
+                       MX6SL_PAD_SD3_DAT3__SD3_DATA3   0x11059
+               >;
+       };
+
+       pinctrl_usdhc3_100mhz: usdhc3grp-100mhz {
+               fsl,pins = <
+                       MX6SL_PAD_SD3_CMD__SD3_CMD      0x170b9
+                       MX6SL_PAD_SD3_CLK__SD3_CLK      0x170b9
+                       MX6SL_PAD_SD3_DAT0__SD3_DATA0   0x170b9
+                       MX6SL_PAD_SD3_DAT1__SD3_DATA1   0x170b9
+                       MX6SL_PAD_SD3_DAT2__SD3_DATA2   0x170b9
+                       MX6SL_PAD_SD3_DAT3__SD3_DATA3   0x170b9
+               >;
+       };
+
+       pinctrl_usdhc3_200mhz: usdhc3grp-200mhz {
+               fsl,pins = <
+                       MX6SL_PAD_SD3_CMD__SD3_CMD      0x170f9
+                       MX6SL_PAD_SD3_CLK__SD3_CLK      0x170f9
+                       MX6SL_PAD_SD3_DAT0__SD3_DATA0   0x170f9
+                       MX6SL_PAD_SD3_DAT1__SD3_DATA1   0x170f9
+                       MX6SL_PAD_SD3_DAT2__SD3_DATA2   0x170f9
+                       MX6SL_PAD_SD3_DAT3__SD3_DATA3   0x170f9
+               >;
+       };
+
+       pinctrl_usdhc3_sleep: usdhc3grp-sleep {
+               fsl,pins = <
+                       MX6SL_PAD_SD3_CMD__GPIO5_IO21   0x100c1
+                       MX6SL_PAD_SD3_CLK__GPIO5_IO18   0x100c1
+                       MX6SL_PAD_SD3_DAT0__GPIO5_IO19  0x100c1
+                       MX6SL_PAD_SD3_DAT1__GPIO5_IO20  0x100c1
+                       MX6SL_PAD_SD3_DAT2__GPIO5_IO16  0x100c1
+                       MX6SL_PAD_SD3_DAT3__GPIO5_IO17  0x100c1
+               >;
+       };
+
+       pinctrl_wifi_power: wifi-powergrp {
+               fsl,pins = <
+                       MX6SL_PAD_SD2_DAT6__GPIO4_IO29  0x10059 /* WIFI_3V3_ON */
+               >;
+       };
+
+       pinctrl_wifi_reset: wifi-resetgrp {
+               fsl,pins = <
+                       MX6SL_PAD_SD2_DAT7__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>;
+};
+
+&reg_vdd1p1 {
+       vin-supply = <&dcdc2_reg>;
+};
+
+&reg_vdd2p5 {
+       vin-supply = <&dcdc2_reg>;
+};
+
+&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 85aa8bb..a1bc5bb 100644 (file)
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx6q.bin";
                        };
 
+                       pxp: pxp@20f0000 {
+                               compatible = "fsl,imx6sll-pxp", "fsl,imx6ull-pxp";
+                               reg = <0x20f0000 0x4000>;
+                               interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+                                       <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clks IMX6SLL_CLK_PXP>;
+                               clock-names = "axi";
+                       };
+
                        lcdif: lcd-controller@20f8000 {
                                compatible = "fsl,imx6sll-lcdif", "fsl,imx28-lcdif";
                                reg = <0x020f8000 0x4000>;
index 91a7548..dce5dcf 100644 (file)
@@ -6,6 +6,7 @@
 
 / {
        model = "Freescale i.MX6 SoloX SDB RevA Board";
+       compatible = "fsl,imx6sx-sdb-reva", "fsl,imx6sx";
 };
 
 &i2c1 {
index 2121445..265bf41 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_usdhc2>;
        no-1-8-v;
+       broken-cd;
        keep-power-in-suspend;
        wakeup-source;
        status = "okay";
index 6d850d9..9145c53 100644 (file)
 &iomuxc {
        pinctrl_can_int: canint-grp {
                fsl,pins = <
-                       MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04    0X14 /* SODIMM 73 */
+                       MX6UL_PAD_ENET1_TX_DATA1__GPIO2_IO04    0x13010 /* SODIMM 73 */
                >;
        };
 
 
        pinctrl_ecspi1_cs: ecspi1-cs-grp {
                fsl,pins = <
-                       MX6UL_PAD_LCD_DATA21__GPIO3_IO26        0x000a0
+                       MX6UL_PAD_LCD_DATA21__GPIO3_IO26        0x70a0  /* SODIMM 86 */
                >;
        };
 
        pinctrl_ecspi1: ecspi1-grp {
                fsl,pins = <
-                       MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK       0x000a0
-                       MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI       0x000a0
-                       MX6UL_PAD_LCD_DATA23__ECSPI1_MISO       0x100a0
+                       MX6UL_PAD_LCD_DATA20__ECSPI1_SCLK       0x000a0 /* SODIMM 88 */
+                       MX6UL_PAD_LCD_DATA22__ECSPI1_MOSI       0x000a0 /* SODIMM 92 */
+                       MX6UL_PAD_LCD_DATA23__ECSPI1_MISO       0x100a0 /* SODIMM 90 */
                >;
        };
 
 
        pinctrl_gpio_bl_on: gpio-bl-on-grp {
                fsl,pins = <
-                       MX6UL_PAD_JTAG_TMS__GPIO1_IO11          0x000a0
+                       MX6UL_PAD_JTAG_TMS__GPIO1_IO11          0x30a0  /* SODIMM 71 */
                >;
        };
 
        pinctrl_gpio1: gpio1-grp {
                fsl,pins = <
-                       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 */
-                       MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24     0x14 /* SODIMM 135 */
-                       MX6UL_PAD_UART3_CTS_B__GPIO1_IO26       0x14 /* SODIMM 100 */
-                       MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15       0x14 /* SODIMM 102 */
-                       MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07       0x14 /* SODIMM 104 */
-                       MX6UL_PAD_UART3_RTS_B__GPIO1_IO27       0x14 /* SODIMM 186 */
+                       MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25     0x10b0 /* SODIMM 77 */
+                       MX6UL_PAD_JTAG_TCK__GPIO1_IO14          0x70a0 /* SODIMM 99 */
+                       MX6UL_PAD_NAND_CE1_B__GPIO4_IO14        0x10b0 /* SODIMM 133 */
+                       MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24     0x10b0 /* SODIMM 135 */
+                       MX6UL_PAD_UART3_CTS_B__GPIO1_IO26       0x10b0 /* SODIMM 100 */
+                       MX6UL_PAD_JTAG_TRST_B__GPIO1_IO15       0x70a0 /* SODIMM 102 */
+                       MX6UL_PAD_ENET1_RX_ER__GPIO2_IO07       0x10b0 /* SODIMM 104 */
+                       MX6UL_PAD_UART3_RTS_B__GPIO1_IO27       0x10b0 /* SODIMM 186 */
                >;
        };
 
        pinctrl_gpio2: gpio2-grp { /* Camera */
                fsl,pins = <
-                       MX6UL_PAD_CSI_DATA04__GPIO4_IO25        0x74 /* SODIMM 69 */
-                       MX6UL_PAD_CSI_MCLK__GPIO4_IO17          0x14 /* SODIMM 75 */
-                       MX6UL_PAD_CSI_DATA06__GPIO4_IO27        0x14 /* SODIMM 85 */
-                       MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18        0x14 /* SODIMM 96 */
-                       MX6UL_PAD_CSI_DATA05__GPIO4_IO26        0x14 /* SODIMM 98 */
+                       MX6UL_PAD_CSI_DATA04__GPIO4_IO25        0x10b0 /* SODIMM 69 */
+                       MX6UL_PAD_CSI_MCLK__GPIO4_IO17          0x10b0 /* SODIMM 75 */
+                       MX6UL_PAD_CSI_DATA06__GPIO4_IO27        0x10b0 /* SODIMM 85 */
+                       MX6UL_PAD_CSI_PIXCLK__GPIO4_IO18        0x10b0 /* SODIMM 96 */
+                       MX6UL_PAD_CSI_DATA05__GPIO4_IO26        0x10b0 /* SODIMM 98 */
                >;
        };
 
        pinctrl_gpio3: gpio3-grp { /* CAN2 */
                fsl,pins = <
-                       MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02       0x14 /* SODIMM 178 */
-                       MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03    0x14 /* SODIMM 188 */
+                       MX6UL_PAD_ENET1_RX_EN__GPIO2_IO02       0x10b0 /* SODIMM 178 */
+                       MX6UL_PAD_ENET1_TX_DATA0__GPIO2_IO03    0x10b0 /* SODIMM 188 */
                >;
        };
 
        pinctrl_gpio4: gpio4-grp {
                fsl,pins = <
-                       MX6UL_PAD_CSI_DATA07__GPIO4_IO28        0x74 /* SODIMM 65 */
+                       MX6UL_PAD_CSI_DATA07__GPIO4_IO28        0x10b0 /* SODIMM 65 */
                >;
        };
 
        pinctrl_gpio5: gpio5-grp { /* ATMEL MXT TOUCH */
                fsl,pins = <
-                       MX6UL_PAD_JTAG_MOD__GPIO1_IO10          0x74 /* SODIMM 106 */
+                       MX6UL_PAD_JTAG_MOD__GPIO1_IO10          0xb0a0 /* SODIMM 106 */
                >;
        };
 
        pinctrl_gpio6: gpio6-grp { /* Wifi pins */
                fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO03__GPIO1_IO03        0x14 /* SODIMM 89 */
-                       MX6UL_PAD_CSI_DATA02__GPIO4_IO23        0x14 /* SODIMM 79 */
-                       MX6UL_PAD_CSI_VSYNC__GPIO4_IO19         0x14 /* SODIMM 81 */
-                       MX6UL_PAD_CSI_DATA03__GPIO4_IO24        0x14 /* SODIMM 97 */
-                       MX6UL_PAD_CSI_DATA00__GPIO4_IO21        0x14 /* SODIMM 101 */
-                       MX6UL_PAD_CSI_DATA01__GPIO4_IO22        0x14 /* SODIMM 103 */
-                       MX6UL_PAD_CSI_HSYNC__GPIO4_IO20         0x14 /* SODIMM 94 */
+                       MX6UL_PAD_GPIO1_IO03__GPIO1_IO03        0x10b0 /* SODIMM 89 */
+                       MX6UL_PAD_CSI_DATA02__GPIO4_IO23        0x10b0 /* SODIMM 79 */
+                       MX6UL_PAD_CSI_VSYNC__GPIO4_IO19         0x10b0 /* SODIMM 81 */
+                       MX6UL_PAD_CSI_DATA03__GPIO4_IO24        0x10b0 /* SODIMM 97 */
+                       MX6UL_PAD_CSI_DATA00__GPIO4_IO21        0x10b0 /* SODIMM 101 */
+                       MX6UL_PAD_CSI_DATA01__GPIO4_IO22        0x10b0 /* SODIMM 103 */
+                       MX6UL_PAD_CSI_HSYNC__GPIO4_IO20         0x10b0 /* SODIMM 94 */
                >;
        };
 
        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 */
+                       MX6UL_PAD_ENET1_RX_DATA0__GPIO2_IO00    0xb0b0/* SODIMM 55 */
+                       MX6UL_PAD_ENET1_RX_DATA1__GPIO2_IO01    0xb0b0 /* SODIMM 63 */
                >;
        };
 
 
        pinctrl_i2c1: i2c1-grp {
                fsl,pins = <
-                       MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0
-                       MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0
+                       MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0    /* SODIMM 196 */
+                       MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0    /* SODIMM 194 */
                >;
        };
 
        pinctrl_i2c1_gpio: i2c1-gpio-grp {
                fsl,pins = <
-                       MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x4001b8b0
-                       MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x4001b8b0
+                       MX6UL_PAD_UART4_TX_DATA__GPIO1_IO28 0x4001b8b0  /* SODIMM 196 */
+                       MX6UL_PAD_UART4_RX_DATA__GPIO1_IO29 0x4001b8b0  /* SODIMM 194 */
                >;
        };
 
 
        pinctrl_lcdif_dat: lcdif-dat-grp {
                fsl,pins = <
-                       MX6UL_PAD_LCD_DATA00__LCDIF_DATA00  0x00079
-                       MX6UL_PAD_LCD_DATA01__LCDIF_DATA01  0x00079
-                       MX6UL_PAD_LCD_DATA02__LCDIF_DATA02  0x00079
-                       MX6UL_PAD_LCD_DATA03__LCDIF_DATA03  0x00079
-                       MX6UL_PAD_LCD_DATA04__LCDIF_DATA04  0x00079
-                       MX6UL_PAD_LCD_DATA05__LCDIF_DATA05  0x00079
-                       MX6UL_PAD_LCD_DATA06__LCDIF_DATA06  0x00079
-                       MX6UL_PAD_LCD_DATA07__LCDIF_DATA07  0x00079
-                       MX6UL_PAD_LCD_DATA08__LCDIF_DATA08  0x00079
-                       MX6UL_PAD_LCD_DATA09__LCDIF_DATA09  0x00079
-                       MX6UL_PAD_LCD_DATA10__LCDIF_DATA10  0x00079
-                       MX6UL_PAD_LCD_DATA11__LCDIF_DATA11  0x00079
-                       MX6UL_PAD_LCD_DATA12__LCDIF_DATA12  0x00079
-                       MX6UL_PAD_LCD_DATA13__LCDIF_DATA13  0x00079
-                       MX6UL_PAD_LCD_DATA14__LCDIF_DATA14  0x00079
-                       MX6UL_PAD_LCD_DATA15__LCDIF_DATA15  0x00079
-                       MX6UL_PAD_LCD_DATA16__LCDIF_DATA16  0x00079
-                       MX6UL_PAD_LCD_DATA17__LCDIF_DATA17  0x00079
+                       MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x00079      /* SODIMM 76 */
+                       MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x00079      /* SODIMM 70 */
+                       MX6UL_PAD_LCD_DATA02__LCDIF_DATA02 0x00079      /* SODIMM 60 */
+                       MX6UL_PAD_LCD_DATA03__LCDIF_DATA03 0x00079      /* SODIMM 58 */
+                       MX6UL_PAD_LCD_DATA04__LCDIF_DATA04 0x00079      /* SODIMM 78 */
+                       MX6UL_PAD_LCD_DATA05__LCDIF_DATA05 0x00079      /* SODIMM 72 */
+                       MX6UL_PAD_LCD_DATA06__LCDIF_DATA06 0x00079      /* SODIMM 80 */
+                       MX6UL_PAD_LCD_DATA07__LCDIF_DATA07 0x00079      /* SODIMM 46 */
+                       MX6UL_PAD_LCD_DATA08__LCDIF_DATA08 0x00079      /* SODIMM 62 */
+                       MX6UL_PAD_LCD_DATA09__LCDIF_DATA09 0x00079      /* SODIMM 48 */
+                       MX6UL_PAD_LCD_DATA10__LCDIF_DATA10 0x00079      /* SODIMM 74 */
+                       MX6UL_PAD_LCD_DATA11__LCDIF_DATA11 0x00079      /* SODIMM 50 */
+                       MX6UL_PAD_LCD_DATA12__LCDIF_DATA12 0x00079      /* SODIMM 52 */
+                       MX6UL_PAD_LCD_DATA13__LCDIF_DATA13 0x00079      /* SODIMM 54 */
+                       MX6UL_PAD_LCD_DATA14__LCDIF_DATA14 0x00079      /* SODIMM 66 */
+                       MX6UL_PAD_LCD_DATA15__LCDIF_DATA15 0x00079      /* SODIMM 64 */
+                       MX6UL_PAD_LCD_DATA16__LCDIF_DATA16 0x00079      /* SODIMM 57 */
+                       MX6UL_PAD_LCD_DATA17__LCDIF_DATA17 0x00079      /* SODIMM 61 */
                >;
        };
 
        pinctrl_lcdif_ctrl: lcdif-ctrl-grp {
                fsl,pins = <
-                       MX6UL_PAD_LCD_CLK__LCDIF_CLK        0x00079
-                       MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x00079
-                       MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x00079
-                       MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x00079
+                       MX6UL_PAD_LCD_CLK__LCDIF_CLK        0x00079     /* SODIMM 56 */
+                       MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE  0x00079     /* SODIMM 44 */
+                       MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC    0x00079     /* SODIMM 68 */
+                       MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC    0x00079     /* SODIMM 82 */
                >;
        };
 
        pinctrl_pwm4: pwm4-grp {
                fsl,pins = <
-                       MX6UL_PAD_NAND_WP_B__PWM4_OUT   0x00079
+                       MX6UL_PAD_NAND_WP_B__PWM4_OUT   0x00079         /* SODIMM 59 */
                >;
        };
 
        pinctrl_pwm5: pwm5-grp {
                fsl,pins = <
-                       MX6UL_PAD_NAND_DQS__PWM5_OUT    0x00079
+                       MX6UL_PAD_NAND_DQS__PWM5_OUT    0x00079         /* SODIMM 28 */
                >;
        };
 
        pinctrl_pwm6: pwm6-grp {
                fsl,pins = <
-                       MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00079
+                       MX6UL_PAD_ENET1_TX_EN__PWM6_OUT 0x00079         /* SODIMM 30 */
                >;
        };
 
        pinctrl_pwm7: pwm7-grp {
                fsl,pins = <
-                       MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT        0x00079
+                       MX6UL_PAD_ENET1_TX_CLK__PWM7_OUT        0x00079 /* SODIMM 67 */
                >;
        };
 
        pinctrl_uart1: uart1-grp {
                fsl,pins = <
-                       MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX   0x1b0b1
-                       MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX   0x1b0b1
-                       MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS    0x1b0b1
-                       MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS    0x1b0b1
+                       MX6UL_PAD_UART1_TX_DATA__UART1_DTE_RX   0x1b0b1 /* SODIMM 33 */
+                       MX6UL_PAD_UART1_RX_DATA__UART1_DTE_TX   0x1b0b1 /* SODIMM 35 */
+                       MX6UL_PAD_UART1_RTS_B__UART1_DTE_CTS    0x1b0b1 /* SODIMM 27 */
+                       MX6UL_PAD_UART1_CTS_B__UART1_DTE_RTS    0x1b0b1 /* SODIMM 25 */
                >;
        };
 
        pinctrl_uart1_ctrl1: uart1-ctrl1-grp { /* Additional DTR, DCD */
                fsl,pins = <
-                       MX6UL_PAD_JTAG_TDI__GPIO1_IO13          0x1b0b1 /* DCD */
-                       MX6UL_PAD_LCD_DATA18__GPIO3_IO23        0x1b0b1 /* DSR */
-                       MX6UL_PAD_JTAG_TDO__GPIO1_IO12          0x1b0b1 /* DTR */
-                       MX6UL_PAD_LCD_DATA19__GPIO3_IO24        0x1b0b1 /* RI */
+                       MX6UL_PAD_JTAG_TDI__GPIO1_IO13          0x70a0 /* SODIMM 31 */
+                       MX6UL_PAD_LCD_DATA18__GPIO3_IO23        0x10b0 /* SODIMM 29 */
+                       MX6UL_PAD_JTAG_TDO__GPIO1_IO12          0x90b1 /* SODIMM 23 */
+                       MX6UL_PAD_LCD_DATA19__GPIO3_IO24        0x10b0 /* SODIMM 37 */
                >;
        };
 
        pinctrl_uart2: uart2-grp {
                fsl,pins = <
-                       MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX   0x1b0b1
-                       MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX   0x1b0b1
-                       MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS    0x1b0b1
-                       MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS    0x1b0b1
+                       MX6UL_PAD_UART2_TX_DATA__UART2_DTE_RX   0x1b0b1 /* SODIMM 36 */
+                       MX6UL_PAD_UART2_RX_DATA__UART2_DTE_TX   0x1b0b1 /* SODIMM 38 */
+                       MX6UL_PAD_UART2_CTS_B__UART2_DTE_RTS    0x1b0b1 /* SODIMM 32 */
+                       MX6UL_PAD_UART2_RTS_B__UART2_DTE_CTS    0x1b0b1 /* SODIMM 34 */
                >;
        };
        pinctrl_uart5: uart5-grp {
                fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX      0x1b0b1
-                       MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX      0x1b0b1
+                       MX6UL_PAD_GPIO1_IO04__UART5_DTE_RX      0x1b0b1 /* SODIMM 19 */
+                       MX6UL_PAD_GPIO1_IO05__UART5_DTE_TX      0x1b0b1 /* SODIMM 21 */
                >;
        };
 
        pinctrl_usbh_reg: gpio-usbh-reg {
                fsl,pins = <
-                       MX6UL_PAD_GPIO1_IO02__GPIO1_IO02        0x1b0b1 /* SODIMM 129 USBH PEN */
+                       MX6UL_PAD_GPIO1_IO02__GPIO1_IO02        0x10b0 /* SODIMM 129 */
                >;
        };
 
        pinctrl_usdhc1: usdhc1-grp {
                fsl,pins = <
-                       MX6UL_PAD_SD1_CLK__USDHC1_CLK           0x17059
-                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           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_SD1_CLK__USDHC1_CLK           0x17059 /* SODIMM 47 */
+                       MX6UL_PAD_SD1_CMD__USDHC1_CMD           0x10059 /* SODIMM 190 */
+                       MX6UL_PAD_SD1_DATA0__USDHC1_DATA0       0x17059 /* SODIMM 192 */
+                       MX6UL_PAD_SD1_DATA1__USDHC1_DATA1       0x17059 /* SODIMM 49 */
+                       MX6UL_PAD_SD1_DATA2__USDHC1_DATA2       0x17059 /* SODIMM 51 */
+                       MX6UL_PAD_SD1_DATA3__USDHC1_DATA3       0x17059 /* SODIMM 53 */
                >;
        };
 
                        MX6UL_PAD_CSI_HSYNC__USDHC2_CMD         0x17059
                        MX6UL_PAD_CSI_VSYNC__USDHC2_CLK         0x17059
 
-                       MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT    0x14
+                       MX6UL_PAD_GPIO1_IO03__OSC32K_32K_OUT    0x10
                >;
        };
 
 &iomuxc_snvs {
        pinctrl_snvs_gpio1: snvs-gpio1-grp {
                fsl,pins = <
-                       MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06     0x14 /* SODIMM 93 */
-                       MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03     0x14 /* SODIMM 95 */
-                       MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10       0x74 /* SODIMM 105 */
-                       MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05     0x14 /* SODIMM 131 USBH OC */
-                       MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08     0x74 /* SODIMM 138 */
+                       MX6ULL_PAD_SNVS_TAMPER6__GPIO5_IO06     0x110a0 /* SODIMM 93 */
+                       MX6ULL_PAD_SNVS_TAMPER3__GPIO5_IO03     0x110a0 /* SODIMM 95 */
+                       MX6ULL_PAD_BOOT_MODE0__GPIO5_IO10       0x1b0a0 /* SODIMM 105 */
+                       MX6ULL_PAD_SNVS_TAMPER5__GPIO5_IO05     0x0b0a0 /* SODIMM 131 */
+                       MX6ULL_PAD_SNVS_TAMPER8__GPIO5_IO08     0x110a0 /* SODIMM 138 */
                >;
        };
 
        pinctrl_snvs_gpio2: snvs-gpio2-grp { /* ATMEL MXT TOUCH */
                fsl,pins = <
-                       MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04     0x74 /* SODIMM 107 */
+                       MX6ULL_PAD_SNVS_TAMPER4__GPIO5_IO04     0xb0a0  /* SODIMM 107 */
                >;
        };
 
        pinctrl_snvs_gpio3: snvs-gpio3-grp { /* Wifi pins */
                fsl,pins = <
-                       MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11       0x14 /* SODIMM 127 */
+                       MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11       0x130a0 /* SODIMM 127 */
                >;
        };
 
 
        pinctrl_snvs_gpiokeys: snvs-gpiokeys-grp {
                fsl,pins = <
-                       MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01     0x130b0
+                       MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01     0x130a0 /* SODIMM 45 */
                >;
        };
 
        pinctrl_snvs_usdhc1_cd: snvs-usdhc1-cd-grp {
                fsl,pins = <
-                       MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00     0x1b0b0 /* CD */
+                       MX6ULL_PAD_SNVS_TAMPER0__GPIO5_IO00     0x1b0a0 /* SODIMM 43 */
                >;
        };
 
 
        pinctrl_snvs_wifi_pdn: snvs-wifi-pdn-grp {
                fsl,pins = <
-                       MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11       0x14
+                       MX6ULL_PAD_BOOT_MODE1__GPIO5_IO11       0x130a0
                >;
        };
 };
index 6f50ebf..e57da0d 100644 (file)
@@ -7,12 +7,42 @@
 #include "imx7d.dtsi"
 
 / {
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm4 0 50000 0>;
+               brightness-levels = <0 36 72 108 144 180 216 255>;
+               default-brightness-level = <6>;
+       };
+
        /* Will be filled by the bootloader */
        memory@80000000 {
                device_type = "memory";
                reg = <0x80000000 0>;
        };
 
+       panel {
+               compatible = "vxt,vl050-8048nt-c01";
+               backlight = <&backlight>;
+               power-supply = <&reg_lcd_3v3>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&display_out>;
+                       };
+               };
+       };
+
+       reg_lcd_3v3: regulator-lcd-3v3 {
+               compatible = "regulator-fixed";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_lcdreg_on>;
+               regulator-name = "lcd-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               gpio = <&gpio1 6 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+        };
+
        reg_wlreg_on: regulator-wlreg_on {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
        };
 };
 
+&lcdif {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lcdif>;
+       status = "okay";
+
+       port {
+               display_out: endpoint {
+                       remote-endpoint = <&panel_in>;
+               };
+       };
+};
+
 &sai1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_sai1>;
 };
 
 &pwm4 { /* Backlight */
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm4>;
        status = "okay";
 };
 
                >;
        };
 
+       pinctrl_lcdif: lcdifgrp {
+               fsl,pins = <
+                       MX7D_PAD_LCD_DATA00__LCD_DATA0          0x79
+                       MX7D_PAD_LCD_DATA01__LCD_DATA1          0x79
+                       MX7D_PAD_LCD_DATA02__LCD_DATA2          0x79
+                       MX7D_PAD_LCD_DATA03__LCD_DATA3          0x79
+                       MX7D_PAD_LCD_DATA04__LCD_DATA4          0x79
+                       MX7D_PAD_LCD_DATA05__LCD_DATA5          0x79
+                       MX7D_PAD_LCD_DATA06__LCD_DATA6          0x79
+                       MX7D_PAD_LCD_DATA07__LCD_DATA7          0x79
+                       MX7D_PAD_LCD_DATA08__LCD_DATA8          0x79
+                       MX7D_PAD_LCD_DATA09__LCD_DATA9          0x79
+                       MX7D_PAD_LCD_DATA10__LCD_DATA10         0x79
+                       MX7D_PAD_LCD_DATA11__LCD_DATA11         0x79
+                       MX7D_PAD_LCD_DATA12__LCD_DATA12         0x79
+                       MX7D_PAD_LCD_DATA13__LCD_DATA13         0x79
+                       MX7D_PAD_LCD_DATA14__LCD_DATA14         0x79
+                       MX7D_PAD_LCD_DATA15__LCD_DATA15         0x79
+                       MX7D_PAD_LCD_DATA16__LCD_DATA16         0x79
+                       MX7D_PAD_LCD_DATA17__LCD_DATA17         0x79
+                       MX7D_PAD_LCD_DATA18__LCD_DATA18         0x79
+                       MX7D_PAD_LCD_DATA19__LCD_DATA19         0x79
+                       MX7D_PAD_LCD_DATA20__LCD_DATA20         0x79
+                       MX7D_PAD_LCD_DATA21__LCD_DATA21         0x79
+                       MX7D_PAD_LCD_DATA22__LCD_DATA22         0x79
+                       MX7D_PAD_LCD_DATA23__LCD_DATA23         0x79
+                       MX7D_PAD_LCD_CLK__LCD_CLK               0x79
+                       MX7D_PAD_LCD_ENABLE__LCD_ENABLE         0x78
+                       MX7D_PAD_LCD_VSYNC__LCD_VSYNC           0x78
+                       MX7D_PAD_LCD_HSYNC__LCD_HSYNC           0x78
+                       MX7D_PAD_LCD_RESET__GPIO3_IO4           0x14
+               >;
+       };
+
        pinctrl_pwm1: pwm1 {
                fsl,pins = <
                        MX7D_PAD_GPIO1_IO08__PWM1_OUT   0x7f
                >;
        };
 
+       pinctrl_pwm4: pwm4grp{
+               fsl,pins = <
+                       MX7D_PAD_GPIO1_IO11__PWM4_OUT   0x7f
+               >;
+       };
+
        pinctrl_reg_wlreg_on: regregongrp {
                fsl,pins = <
                        MX7D_PAD_ECSPI1_SCLK__GPIO4_IO16        0x59
                >;
        };
 
+       pinctrl_reg_lcdreg_on: reglcdongrp {
+       fsl,pins = <
+                       MX7D_PAD_LPSR_GPIO1_IO06__GPIO1_IO6     0x59
+               >;
+       };
+
        pinctrl_wdog: wdoggrp {
                fsl,pins = <
                        MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B  0x74
index 7ce9d8c..cabdaa6 100644 (file)
@@ -7,6 +7,9 @@
 #include "imx7d-sdb.dts"
 
 / {
+       model = "Freescale i.MX7 SabreSD RevA Board";
+       compatible = "fsl,imx7d-sdb-reva", "fsl,imx7d";
+
        reg_usb_otg2_vbus: regulator-usb-otg2-vbus {
                pinctrl-0 = <&pinctrl_usb_otg2_vbus_reg_reva>;
                gpio = <&gpio4 7 GPIO_ACTIVE_HIGH>;
index d8acd7c..92f6d0c 100644 (file)
@@ -12,7 +12,7 @@
                        clock-frequency = <996000000>;
                        operating-points-v2 = <&cpu0_opp_table>;
                        #cooling-cells = <2>;
-                       nvmem-cells = <&cpu_speed_grade>;
+                       nvmem-cells = <&fuse_grade>;
                        nvmem-cell-names = "speed_grade";
                };
 
index 1b812f4..568d7a9 100644 (file)
                interrupt-parent = <&gpc>;
                interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
                fsl,tempmon = <&anatop>;
-               nvmem-cells = <&tempmon_calib>,
-                       <&tempmon_temp_grade>;
+               nvmem-cells = <&tempmon_calib>, <&fuse_grade>;
                nvmem-cell-names = "calib", "temp_grade";
                clocks = <&clks IMX7D_PLL_SYS_MAIN_CLK>;
        };
                                        reg = <0x3c 0x4>;
                                };
 
-                               tempmon_temp_grade: temp-grade@10 {
-                                       reg = <0x10 0x4>;
-                               };
-
-                               cpu_speed_grade: speed-grade@10 {
+                               fuse_grade: fuse-grade@10 {
                                        reg = <0x10 0x4>;
                                };
                        };
                                                reg = <1>;
                                                power-supply = <&reg_1p0d>;
                                        };
+
+                                       pgc_hsic_phy: power-domain@2 {
+                                               #power-domain-cells = <0>;
+                                               reg = <2>;
+                                               power-supply = <&reg_1p2>;
+                                       };
                                };
                        };
                };
                                compatible = "fsl,imx7d-usb", "fsl,imx27-usb";
                                reg = <0x30b30000 0x200>;
                                interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                               power-domains = <&pgc_hsic_phy>;
                                clocks = <&clks IMX7D_USB_CTRL_CLK>;
                                fsl,usbphy = <&usbphynop3>;
                                fsl,usbmisc = <&usbmisc3 0>;
diff --git a/arch/arm/boot/dts/imx7ulp-com.dts b/arch/arm/boot/dts/imx7ulp-com.dts
new file mode 100644 (file)
index 0000000..d76fea3
--- /dev/null
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2019 NXP
+
+/dts-v1/;
+
+#include "imx7ulp.dtsi"
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "Embedded Artists i.MX7ULP COM";
+       compatible = "ea,imx7ulp-com", "fsl,imx7ulp";
+
+       chosen {
+               stdout-path = &lpuart4;
+       };
+
+       memory@60000000 {
+               device_type = "memory";
+               reg = <0x60000000 0x4000000>;
+       };
+};
+
+&lpuart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_lpuart4>;
+       status = "okay";
+};
+
+&usbotg1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg1_id>;
+       srp-disable;
+       hnp-disable;
+       adp-disable;
+       status = "okay";
+};
+
+&usdhc0 {
+       assigned-clocks = <&pcc2 IMX7ULP_CLK_USDHC0>;
+       assigned-clock-parents = <&scg1 IMX7ULP_CLK_APLL_PFD1>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc0>;
+       non-removable;
+       bus-width = <8>;
+       no-1-8-v;
+       status = "okay";
+};
+
+&iomuxc1 {
+       pinctrl_lpuart4: lpuart4grp {
+               fsl,pins = <
+                       IMX7ULP_PAD_PTC3__LPUART4_RX    0x3
+                       IMX7ULP_PAD_PTC2__LPUART4_TX    0x3
+               >;
+       };
+
+       pinctrl_usbotg1_id: otg1idgrp {
+               fsl,pins = <
+                       IMX7ULP_PAD_PTC13__USB0_ID      0x10003
+               >;
+       };
+
+       pinctrl_usdhc0: usdhc0grp {
+               fsl,pins = <
+                       IMX7ULP_PAD_PTD1__SDHC0_CMD     0x43
+                       IMX7ULP_PAD_PTD2__SDHC0_CLK     0x10042
+                       IMX7ULP_PAD_PTD3__SDHC0_D7      0x43
+                       IMX7ULP_PAD_PTD4__SDHC0_D6      0x43
+                       IMX7ULP_PAD_PTD5__SDHC0_D5      0x43
+                       IMX7ULP_PAD_PTD6__SDHC0_D4      0x43
+                       IMX7ULP_PAD_PTD7__SDHC0_D3      0x43
+                       IMX7ULP_PAD_PTD8__SDHC0_D2      0x43
+                       IMX7ULP_PAD_PTD9__SDHC0_D1      0x43
+                       IMX7ULP_PAD_PTD10__SDHC0_D0     0x43
+                       IMX7ULP_PAD_PTD11__SDHC0_DQS    0x42
+               >;
+       };
+};
index ae75a1d..ebbe151 100644 (file)
                clock-frequency = <26000000>;
        };
 
+       lcd_backlight: backlight {
+               compatible = "pwm-backlight";
+
+               pwms = <&pwm3 0 5000000 0>;
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <7>;
+               enable-gpios = <&gpio5 14 GPIO_ACTIVE_HIGH>;
+       };
+
+       lvds-receiver {
+               compatible = "ti,ds90cf384a", "lvds-decoder";
+               powerdown-gpios = <&gpio7 25 GPIO_ACTIVE_LOW>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               lvds_receiver_in: endpoint {
+                                       remote-endpoint = <&lvds0_out>;
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               lvds_receiver_out: endpoint {
+                                       remote-endpoint = <&panel_in>;
+                               };
+                       };
+               };
+       };
+
+       panel {
+               compatible = "edt,etm0700g0dh6";
+               backlight = <&lcd_backlight>;
+
+               port {
+                       panel_in: endpoint {
+                               remote-endpoint = <&lvds_receiver_out>;
+                       };
+               };
+       };
+
        reg_1p5v: 1p5v {
                compatible = "regulator-fixed";
                regulator-name = "1P5V";
 
                gpios = <&gpio2 30 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 };
 
        status = "okay";
 };
 
+&du {
+       status = "okay";
+};
+
+&gpio2 {
+       touch-interrupt {
+               gpio-hog;
+               gpios = <12 GPIO_ACTIVE_LOW>;
+               input;
+       };
+};
+
 &hsusb {
        status = "okay";
        pinctrl-0 = <&usb0_pins>;
                VDDIO-supply = <&reg_3p3v>;
                VDDD-supply = <&reg_1p5v>;
        };
+
+       touch: touchpanel@38 {
+               compatible = "edt,edt-ft5406";
+               reg = <0x38>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
+       };
+};
+
+&lvds0 {
+       status = "okay";
+
+       ports {
+               port@1 {
+                       lvds0_out: endpoint {
+                               remote-endpoint = <&lvds_receiver_in>;
+                       };
+               };
+       };
 };
 
 &pci0 {
                function = "i2c2";
        };
 
+       pwm3_pins: pwm3 {
+               groups = "pwm3";
+               function = "pwm3";
+       };
+
        scif0_pins: scif0 {
                groups = "scif0_data_d";
                function = "scif0";
        };
 };
 
+&pwm3 {
+       pinctrl-0 = <&pwm3_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
 &rcar_sound {
        pinctrl-0 = <&sound_pins>;
        pinctrl-names = "default";
index 0e99df2..ede2e0c 100644 (file)
@@ -39,7 +39,6 @@
 &du {
        pinctrl-0 = <&du_pins>;
        pinctrl-names = "default";
-       status = "okay";
 
        ports {
                port@0 {
index 5b76890..9d8f0c2 100644 (file)
        /* AR8031 */
        sgmii_phy1: ethernet-phy@1 {
                reg = <0x1>;
+               /* SGMII1_PHY_INT_B: connected to IRQ2, active low */
+               interrupts-extended = <&extirq 2 IRQ_TYPE_LEVEL_LOW>;
        };
 
        /* AR8031 */
        sgmii_phy2: ethernet-phy@2 {
                reg = <0x2>;
+               /* SGMII2_PHY_INT_B: connected to IRQ2, active low */
+               interrupts-extended = <&extirq 2 IRQ_TYPE_LEVEL_LOW>;
        };
 
        /* BCM5464 quad PHY */
index 2f6977a..0855b1f 100644 (file)
                        compatible = "fsl,ls1021a-scfg", "syscon";
                        reg = <0x0 0x1570000 0x0 0x10000>;
                        big-endian;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x0 0x1570000 0x10000>;
+
+                       extirq: interrupt-controller@1ac {
+                               compatible = "fsl,ls1021a-extirq";
+                               #interrupt-cells = <2>;
+                               #address-cells = <0>;
+                               interrupt-controller;
+                               reg = <0x1ac 4>;
+                               interrupt-map =
+                                       <0 0 &gic GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>,
+                                       <1 0 &gic GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>,
+                                       <2 0 &gic GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>,
+                                       <3 0 &gic GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
+                                       <4 0 &gic GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+                                       <5 0 &gic GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-map-mask = <0xffffffff 0x0>;
+                       };
                };
 
                crypto: crypto@1700000 {
index c4447f6..5d19830 100644 (file)
                        };
                };
        };
+
+       xtal: xtal-clk {
+               compatible = "fixed-clock";
+               clock-frequency = <24000000>;
+               clock-output-names = "xtal";
+               #clock-cells = <0>;
+       };
 }; /* end of / */
index 2d31b7c..4716030 100644 (file)
                ranges = <0x0 0xd0000000 0x40000>;
        };
 
-       xtal: xtal-clk {
-               compatible = "fixed-clock";
-               clock-frequency = <24000000>;
-               clock-output-names = "xtal";
-               #clock-cells = <0>;
-       };
-
        clk81: clk@0 {
                #clock-cells = <0>;
                compatible = "fixed-clock";
index 3c534cd..eedb925 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright 2014 Carlo Caione <carlo@caione.org>
  */
 
+#include <dt-bindings/clock/meson8-ddr-clkc.h>
 #include <dt-bindings/clock/meson8b-clkc.h>
 #include <dt-bindings/gpio/meson8-gpio.h>
 #include <dt-bindings/reset/amlogic,meson8b-clkc-reset.h>
        gpu_opp_table: gpu-opp-table {
                compatible = "operating-points-v2";
 
-               opp-182150000 {
-                       opp-hz = /bits/ 64 <182150000>;
+               opp-182142857 {
+                       opp-hz = /bits/ 64 <182142857>;
                        opp-microvolt = <1150000>;
                };
                opp-318750000 {
                #size-cells = <1>;
                ranges = <0x0 0xc8000000 0x8000>;
 
+               ddr_clkc: clock-controller@400 {
+                       compatible = "amlogic,meson8-ddr-clkc";
+                       reg = <0x400 0x20>;
+                       clocks = <&xtal>;
+                       clock-names = "xtal";
+                       #clock-cells = <1>;
+               };
+
                dmcbus: bus@6000 {
                        compatible = "simple-bus";
                        reg = <0x6000 0x400>;
 &hhi {
        clkc: clock-controller {
                compatible = "amlogic,meson8-clkc";
+               clocks = <&xtal>, <&ddr_clkc DDR_CLKID_DDR_PLL>;
+               clock-names = "xtal", "ddr_pll";
                #clock-cells = <1>;
                #reset-cells = <1>;
        };
 
 &saradc {
        compatible = "amlogic,meson8-saradc", "amlogic,meson-saradc";
-       clocks = <&clkc CLKID_XTAL>,
-               <&clkc CLKID_SAR_ADC>;
+       clocks = <&xtal>, <&clkc CLKID_SAR_ADC>;
        clock-names = "clkin", "core";
        amlogic,hhi-sysctrl = <&hhi>;
        nvmem-cells = <&temperature_calib>;
 };
 
 &timer_abcde {
-       clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_CLK81>;
+       clocks = <&xtal>, <&clkc CLKID_CLK81>;
        clock-names = "xtal", "pclk";
 };
 
 &uart_AO {
        compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
-       clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_XTAL>, <&clkc CLKID_CLK81>;
+       clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_CLK81>;
        clock-names = "baud", "xtal", "pclk";
 };
 
 &uart_A {
        compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
-       clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_XTAL>, <&clkc CLKID_UART0>;
+       clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART0>;
        clock-names = "baud", "xtal", "pclk";
 };
 
 &uart_B {
        compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
-       clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_XTAL>, <&clkc CLKID_UART1>;
+       clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART1>;
        clock-names = "baud", "xtal", "pclk";
 };
 
 &uart_C {
        compatible = "amlogic,meson8-uart", "amlogic,meson-uart";
-       clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_XTAL>, <&clkc CLKID_UART2>;
+       clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART2>;
        clock-names = "baud", "xtal", "pclk";
 };
 
index bed1dfe..163a200 100644 (file)
        status = "okay";
        pinctrl-0 = <&pwm_c1_pins>, <&pwm_d_pins>;
        pinctrl-names = "default";
-       clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_XTAL>;
+       clocks = <&xtal>, <&xtal>;
        clock-names = "clkin0", "clkin1";
 };
 
index 6e39ad5..33037ef 100644 (file)
        status = "okay";
        pinctrl-0 = <&pwm_c1_pins>, <&pwm_d_pins>;
        pinctrl-names = "default";
-       clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_XTAL>;
+       clocks = <&xtal>, <&xtal>;
        clock-names = "clkin0", "clkin1";
 };
 
index a24eccc..a2a4780 100644 (file)
        status = "okay";
        pinctrl-0 = <&pwm_c1_pins>, <&pwm_d_pins>;
        pinctrl-names = "default";
-       clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_XTAL>;
+       clocks = <&xtal>, <&xtal>;
        clock-names = "clkin0", "clkin1";
 };
 
index 099bf8e..e34b039 100644 (file)
@@ -4,6 +4,7 @@
  * Author: Carlo Caione <carlo@endlessm.com>
  */
 
+#include <dt-bindings/clock/meson8-ddr-clkc.h>
 #include <dt-bindings/clock/meson8b-clkc.h>
 #include <dt-bindings/gpio/meson8b-gpio.h>
 #include <dt-bindings/reset/amlogic,meson8b-reset.h>
                        opp-hz = /bits/ 64 <255000000>;
                        opp-microvolt = <1100000>;
                };
-               opp-364300000 {
-                       opp-hz = /bits/ 64 <364300000>;
+               opp-364285714 {
+                       opp-hz = /bits/ 64 <364285714>;
                        opp-microvolt = <1100000>;
                };
                opp-425000000 {
                #size-cells = <1>;
                ranges = <0x0 0xc8000000 0x8000>;
 
+               ddr_clkc: clock-controller@400 {
+                       compatible = "amlogic,meson8b-ddr-clkc";
+                       reg = <0x400 0x20>;
+                       clocks = <&xtal>;
+                       clock-names = "xtal";
+                       #clock-cells = <1>;
+               };
+
                dmcbus: bus@6000 {
                        compatible = "simple-bus";
                        reg = <0x6000 0x400>;
 
 &hhi {
        clkc: clock-controller {
-               compatible = "amlogic,meson8-clkc";
+               compatible = "amlogic,meson8b-clkc";
+               clocks = <&xtal>, <&ddr_clkc DDR_CLKID_DDR_PLL>;
+               clock-names = "xtal", "ddr_pll";
                #clock-cells = <1>;
                #reset-cells = <1>;
        };
 
 &saradc {
        compatible = "amlogic,meson8b-saradc", "amlogic,meson-saradc";
-       clocks = <&clkc CLKID_XTAL>,
-               <&clkc CLKID_SAR_ADC>;
+       clocks = <&xtal>, <&clkc CLKID_SAR_ADC>;
        clock-names = "clkin", "core";
        amlogic,hhi-sysctrl = <&hhi>;
        nvmem-cells = <&temperature_calib>;
 };
 
 &timer_abcde {
-       clocks = <&clkc CLKID_XTAL>, <&clkc CLKID_CLK81>;
+       clocks = <&xtal>, <&clkc CLKID_CLK81>;
        clock-names = "xtal", "pclk";
 };
 
 &uart_AO {
        compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
-       clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_XTAL>, <&clkc CLKID_CLK81>;
+       clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_CLK81>;
        clock-names = "baud", "xtal", "pclk";
 };
 
 &uart_A {
        compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
-       clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_XTAL>, <&clkc CLKID_UART0>;
+       clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART0>;
        clock-names = "baud", "xtal", "pclk";
 };
 
 &uart_B {
        compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
-       clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_XTAL>, <&clkc CLKID_UART1>;
+       clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART1>;
        clock-names = "baud", "xtal", "pclk";
 };
 
 &uart_C {
        compatible = "amlogic,meson8b-uart", "amlogic,meson-uart";
-       clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_XTAL>, <&clkc CLKID_UART2>;
+       clocks = <&clkc CLKID_CLK81>, <&xtal>, <&clkc CLKID_UART2>;
        clock-names = "baud", "xtal", "pclk";
 };
 
index c1947b5..15449c7 100644 (file)
        status = "okay";
 };
 
+&hsic0 {
+       status = "okay";
+
+       usb1@1 {
+               compatible = "usb424,2640";
+               reg = <0x01>;
+               #address-cells = <0x01>;
+               #size-cells = <0x00>;
+
+               mass-storage@1 {
+                       compatible = "usb424,4040";
+                       reg = <0x01>;
+                       status = "disabled";
+               };
+       };
+};
+
+&hsic_phy0 {
+       status = "okay";
+       reset-gpios = <&gpio 63 GPIO_ACTIVE_HIGH>;
+};
+
 &mmc3 {
        status = "okay";
        max-frequency = <50000000>;
index 6f48082..59a108e 100644 (file)
                                status = "disabled";
                        };
 
+                       hsic_phy0: hsic-phy@f0001800 {
+                               compatible = "marvell,mmp3-hsic-phy",
+                                            "usb-nop-xceiv";
+                               reg = <0xf0001800 0x40>;
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       hsic0: hsic@f0001000 {
+                               compatible = "marvell,pxau2o-ehci";
+                               reg = <0xf0001000 0x200>;
+                               interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_USBHSIC0>;
+                               clock-names = "USBCLK";
+                               phys = <&hsic_phy0>;
+                               phy-names = "usb";
+                               phy_type = "hsic";
+                               #address-cells = <0x01>;
+                               #size-cells = <0x00>;
+                               status = "disabled";
+                       };
+
+                       hsic_phy1: hsic-phy@f0002800 {
+                               compatible = "marvell,mmp3-hsic-phy",
+                                            "usb-nop-xceiv";
+                               reg = <0xf0002800 0x40>;
+                               #phy-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       hsic1: hsic@f0002000 {
+                               compatible = "marvell,pxau2o-ehci";
+                               reg = <0xf0002000 0x200>;
+                               interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&soc_clocks MMP2_CLK_USBHSIC1>;
+                               clock-names = "USBCLK";
+                               phys = <&hsic_phy1>;
+                               phy-names = "usb";
+                               phy_type = "hsic";
+                               #address-cells = <0x01>;
+                               #size-cells = <0x00>;
+                               status = "disabled";
+                       };
+
                        mmc1: mmc@d4280000 {
                                compatible = "mrvl,pxav3-mmc";
                                reg = <0xd4280000 0x120>;
index 936ad01..e39eee6 100644 (file)
                        compatible = "motorola,cpcap-battery";
                        interrupts-extended = <
                                &cpcap 6 0 &cpcap 5 0 &cpcap 3 0
-                               &cpcap 20 0 &cpcap 54 0
+                               &cpcap 20 0 &cpcap 54 0 &cpcap 57 0
                        >;
                        interrupt-names =
                                "eol", "lowbph", "lowbpl",
-                               "chrgcurr1", "battdetb";
+                               "chrgcurr1", "battdetb",
+                               "cccal";
                        io-channels = <&cpcap_adc 0 &cpcap_adc 1
                                       &cpcap_adc 5 &cpcap_adc 6>;
                        io-channel-names = "battdetb", "battp",
index da6b107..8566550 100644 (file)
        };
 };
 
+/* Battery NVRAM on 1-wire handled by w1_ds250x driver */
+&hdqw1w {
+       pinctrl-0 = <&hdq_pins>;
+       pinctrl-names = "default";
+       ti,mode = "1w";
+};
+
 &i2c1 {
        tmp105@48 {
                compatible = "ti,tmp105";
                >;
        };
 
+       hdq_pins: pinmux_hdq_pins {
+               pinctrl-single,pins = <
+               /* 0x4a100120 hdq_sio.hdq_sio aa27 */
+               OMAP4_IOPAD(0x120, PIN_INPUT | MUX_MODE0)
+               >;
+       };
+
        /* hdmi_cec.hdmi_cec, hdmi_scl.hdmi_scl, hdmi_sda.hdmi_sda */
        dss_hdmi_pins: pinmux_dss_hdmi_pins {
                pinctrl-single,pins = <
        };
 };
 
+/* RNG is used by secure mode and not accessible */
+&rng_target {
+       status = "disabled";
+};
+
 /* Configure pwm clock source for timers 8 & 9 */
 &timer8 {
        assigned-clocks = <&abe_clkctrl OMAP4_TIMER8_CLKCTRL 24>;
index 000bf16..0e453fe 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>
                        reg = <0x480FE000 0x1000>;
                };
 
-               sdma: dma-controller@48056000 {
-                       compatible = "ti,omap2430-sdma", "ti,omap2420-sdma";
-                       ti,hwmods = "dma";
-                       reg = <0x48056000 0x1000>;
-                       interrupts = <12>,
-                                    <13>,
-                                    <14>,
-                                    <15>;
-                       #dma-cells = <1>;
-                       dma-channels = <32>;
-                       dma-requests = <64>;
+               target-module@48056000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x48056000 0x4>,
+                             <0x4805602c 0x4>,
+                             <0x48056028 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       clocks = <&core_l3_ck>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x48056000 0x1000>;
+
+                       sdma: dma-controller@0 {
+                               compatible = "ti,omap2420-sdma", "ti,omap-sdma";
+                               reg = <0 0x1000>;
+                               interrupts = <12>,
+                                            <13>,
+                                            <14>,
+                                            <15>;
+                               #dma-cells = <1>;
+                               dma-channels = <32>;
+                               dma-requests = <64>;
+                       };
                };
 
                i2c1: i2c@48070000 {
index 7f57af2..15ef759 100644 (file)
        };
 };
 
+&sdma {
+       compatible = "ti,omap2430-sdma", "ti,omap-sdma";
+};
+
 &i2c1 {
        compatible = "ti,omap2430-i2c";
 };
diff --git a/arch/arm/boot/dts/omap3-echo.dts b/arch/arm/boot/dts/omap3-echo.dts
new file mode 100644 (file)
index 0000000..93ffedd
--- /dev/null
@@ -0,0 +1,461 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 André Hentschel <nerv@dawncrow.de>
+ */
+/dts-v1/;
+
+#include "dm3725.dtsi"
+
+#include <dt-bindings/input/input.h>
+
+/ {
+       model = "Amazon Echo (first generation)";
+       compatible = "amazon,omap3-echo", "ti,omap3630", "ti,omap3";
+
+       cpus {
+               cpu@0 {
+                       cpu0-supply = <&vdd1_reg>;
+               };
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x80000000 0xc600000>; /* 198 MB */
+       };
+
+       vcc5v: fixedregulator0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vcc3v3: fixedregulator1 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       vcc1v8: fixedregulator2 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc1v8";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               reset-gpios = <&gpio1 21 GPIO_ACTIVE_LOW>;
+               post-power-on-delay-ms = <40>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&button_pins>;
+
+               mute-button {
+                       label = "mute";
+                       linux,code = <KEY_MUTE>;
+                       gpios = <&gpio3 6 GPIO_ACTIVE_LOW>;     /* GPIO_70 */
+                       wakeup-source;
+               };
+
+               help-button {
+                       label = "help";
+                       linux,code = <KEY_HELP>;
+                       gpios = <&gpio3 8 GPIO_ACTIVE_LOW>;     /* GPIO_72 */
+                       wakeup-source;
+               };
+       };
+
+       rotary: rotary-encoder {
+               compatible = "rotary-encoder";
+               gpios = <
+                       &gpio3  5 GPIO_ACTIVE_HIGH /* GPIO_69 */
+                       &gpio3 12 GPIO_ACTIVE_HIGH /* GPIO_76 */
+               >;
+               linux,axis = <REL_X>;
+               rotary-encoder,relative-axis;
+       };
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+
+       tps: tps@2d {
+               reg = <0x2d>;
+       };
+};
+
+&i2c2 {
+       clock-frequency = <400000>;
+
+       lp5523A: lp5523A@32 {
+               compatible = "national,lp5523";
+               label = "q1";
+               reg = <0x32>;
+               clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */
+               enable-gpio = <&gpio4 13 GPIO_ACTIVE_HIGH>; /* GPIO_109 */
+
+               chan0 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan1 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan2 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan3 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan4 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan5 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan6 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan7 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan8 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+       };
+
+       lp5523B: lp5523B@33 {
+               compatible = "national,lp5523";
+               label = "q3";
+               reg = <0x33>;
+               clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */
+
+               chan0 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan1 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan2 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan3 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan4 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan5 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan6 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan7 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan8 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+       };
+
+       lp5523C: lp5523C@34 {
+               compatible = "national,lp5523";
+               label = "q4";
+               reg = <0x34>;
+               clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */
+
+               chan0 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan1 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan2 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan3 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan4 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan5 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan6 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan7 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan8 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+       };
+
+       lp5523D: lp552D@35 {
+               compatible = "national,lp5523";
+               label = "q2";
+               reg = <0x35>;
+               clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */
+
+               chan0 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan1 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan2 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan3 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan4 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan5 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan6 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan7 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+               chan8 {
+                       led-cur = /bits/ 8 <12>;
+                       max-cur = /bits/ 8 <15>;
+               };
+       };
+};
+
+#include "tps65910.dtsi"
+
+&omap3_pmx_core {
+       tps_pins: pinmux_tps_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x21e0, PIN_INPUT_PULLUP | PIN_OFF_INPUT_PULLUP | PIN_OFF_OUTPUT_LOW | PIN_OFF_WAKEUPENABLE | MUX_MODE0) /* sys_nirq.sys_nirq */
+               >;
+       };
+
+       button_pins: pinmux_button_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x20dc, PIN_INPUT | MUX_MODE4)        /* dss_data0.gpio_70 */
+                       OMAP3_CORE1_IOPAD(0x20e0, PIN_INPUT | MUX_MODE4)        /* dss_data2.gpio_72 */
+               >;
+       };
+
+       mmc1_pins: pinmux_mmc1_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2144, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_clk.sdmmc1_clk */
+                       OMAP3_CORE1_IOPAD(0x2146, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_cmd.sdmmc1_cmd */
+                       OMAP3_CORE1_IOPAD(0x2148, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat0.sdmmc1_dat0 */
+                       OMAP3_CORE1_IOPAD(0x214a, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat1.sdmmc1_dat1 */
+                       OMAP3_CORE1_IOPAD(0x214c, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat2.sdmmc1_dat2 */
+                       OMAP3_CORE1_IOPAD(0x214e, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc1_dat3.sdmmc1_dat3 */
+               >;
+       };
+
+       mmc2_pins: pinmux_mmc2_pins {
+               pinctrl-single,pins = <
+                       OMAP3_CORE1_IOPAD(0x2158, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_clk.sdmmc2_clk */
+                       OMAP3_CORE1_IOPAD(0x215a, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_cmd.sdmmc2_cmd */
+                       OMAP3_CORE1_IOPAD(0x215c, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat0.sdmmc2_dat0 */
+                       OMAP3_CORE1_IOPAD(0x215e, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat1.sdmmc2_dat1 */
+                       OMAP3_CORE1_IOPAD(0x2160, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat2.sdmmc2_dat2 */
+                       OMAP3_CORE1_IOPAD(0x2162, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat3.sdmmc2_dat3 */
+                       OMAP3_CORE1_IOPAD(0x2164, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat4.sdmmc2_dat4 */
+                       OMAP3_CORE1_IOPAD(0x2166, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat5.sdmmc2_dat5 */
+                       OMAP3_CORE1_IOPAD(0x2168, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat6.sdmmc2_dat6 */
+                       OMAP3_CORE1_IOPAD(0x216a, PIN_INPUT_PULLUP | MUX_MODE0)         /* sdmmc2_dat7.sdmmc2_dat7 */
+               >;
+       };
+};
+
+&omap3_pmx_core2 {
+       mmc3_pins: pinmux_mmc3_pins {
+               pinctrl-single,pins = <
+                       OMAP3630_CORE2_IOPAD(0x25d8, PIN_INPUT_PULLUP | MUX_MODE2)      /* etk_clk.sdmmc3_clk */
+                       OMAP3630_CORE2_IOPAD(0x25da, PIN_INPUT_PULLUP | MUX_MODE2)      /* etk_ctl.sdmmc3_cmd */
+                       OMAP3630_CORE2_IOPAD(0x25e2, PIN_INPUT_PULLUP | MUX_MODE2)      /* etk_d3.sdmmc3_dat3 */
+                       OMAP3630_CORE2_IOPAD(0x25e4, PIN_INPUT_PULLUP | MUX_MODE2)      /* etk_d4.sdmmc3_dat0 */
+                       OMAP3630_CORE2_IOPAD(0x25e6, PIN_INPUT_PULLUP | MUX_MODE2)      /* etk_d5.sdmmc3_dat1 */
+                       OMAP3630_CORE2_IOPAD(0x25e8, PIN_INPUT_PULLUP | MUX_MODE2)      /* etk_d6.sdmmc3_dat2 */
+               >;
+       };
+};
+
+&mmc1 {
+       status = "okay";
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc1_pins>;
+       vmmc-supply = <&vmmc_reg>;
+};
+
+&mmc2 {
+       status = "okay";
+       bus-width = <8>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_pins>;
+       vmmc-supply = <&vmmc_reg>;
+};
+
+&mmc3 {
+       status = "okay";
+       bus-width = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc3_pins>;
+       non-removable;
+       disable-wp;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       vmmc-supply = <&vcc3v3>;
+       vqmmc-supply = <&vcc1v8>;
+};
+
+&tps {
+       pinctrl-names = "default";
+       pinctrl-0 = <&tps_pins>;
+
+       interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+       interrupt-parent = <&intc>;
+
+       ti,en-ck32k-xtal;
+       ti,system-power-controller;
+
+       vcc1-supply = <&vcc5v>;
+       vcc2-supply = <&vcc5v>;
+       vcc3-supply = <&vcc5v>;
+       vcc4-supply = <&vcc5v>;
+       vcc5-supply = <&vcc5v>;
+       vcc6-supply = <&vcc5v>;
+       vcc7-supply = <&vcc5v>;
+       vccio-supply = <&vcc5v>;
+
+       regulators {
+
+               vio_reg: regulator@1 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               vdd1_reg: regulator@2 {
+                       regulator-name = "vdd_mpu";
+                       regulator-min-microvolt = <600000>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+
+               vdd2_reg: regulator@3 {
+                       regulator-name = "vdd_dsp";
+                       regulator-min-microvolt = <600000>;
+                       regulator-max-microvolt = <1500000>;
+                       regulator-always-on;
+               };
+
+               vdd3_reg: regulator@4 {
+                       regulator-name = "vdd_core";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       regulator-always-on;
+               };
+
+               vdig1_reg: regulator@5 {
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <2700000>;
+                       regulator-always-on;
+               };
+
+               vdig2_reg: regulator@6 {
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+
+               vpll_reg: regulator@7 {
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               vdac_reg: regulator@8 {
+                       regulator-min-microvolt = <1100000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vaux1_reg: regulator@9 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2850000>;
+                       regulator-always-on;
+               };
+
+               vaux2_reg: regulator@10 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vaux33_reg: regulator@11 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               vmmc_reg: regulator@12 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <3000000>;
+                       regulator-always-on;
+               };
+       };
+};
index a638e05..c3c6d7d 100644 (file)
        regulator-always-on;
 };
 
+/* First two dma channels are reserved on secure omap3 */
+&sdma {
+       dma-channel-mask = <0xfffffffc>;
+};
+
 &twl {
        twl_audio: audio {
                compatible = "ti,twl4030-audio";
index 5698a3e..634ea16 100644 (file)
                        reg = <0x48200000 0x1000>;
                };
 
-               sdma: dma-controller@48056000 {
-                       compatible = "ti,omap3630-sdma", "ti,omap3430-sdma";
-                       reg = <0x48056000 0x1000>;
-                       interrupts = <12>,
-                                    <13>,
-                                    <14>,
-                                    <15>;
-                       #dma-cells = <1>;
-                       dma-channels = <32>;
-                       dma-requests = <96>;
-                       ti,hwmods = "dma";
+               target-module@48056000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x48056000 0x4>,
+                             <0x4805602c 0x4>,
+                             <0x48056028 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_EMUFREE |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-midle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (V, P, C): core, core_pwrdm, core_l3_clkdm */
+                       clocks = <&core_l3_ick>;
+                       clock-names = "ick";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x48056000 0x1000>;
+
+                       sdma: dma-controller@0 {
+                               compatible = "ti,omap3430-sdma", "ti,omap-sdma";
+                               reg = <0x0 0x1000>;
+                               interrupts = <12>,
+                                            <13>,
+                                            <14>,
+                                            <15>;
+                               #dma-cells = <1>;
+                               dma-channels = <32>;
+                               dma-requests = <96>;
+                       };
                };
 
                gpio1: gpio@48310000 {
index c618cb2..71f3c8f 100644 (file)
        };
 };
 
+&sdma {
+       compatible = "ti,omap3630-sdma", "ti,omap-sdma";
+};
+
 /* OMAP3630 needs dss_96m_fck for VENC */
 &venc {
        clocks = <&dss_tv_fck>, <&dss_96m_fck>;
index 6c892fc..a6feb20 100644 (file)
 
                target-module@2e000 {                   /* 0x4012e000, ap 12 0c.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "dmic";
                        reg = <0x2e000 0x4>,
                              <0x2e010 0x4>;
                        reg-names = "rev", "sysc";
 
                mcpdm_module: target-module@32000 {     /* 0x40132000, ap 16 10.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcpdm";
                        reg = <0x32000 0x4>,
                              <0x32010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@38000 {                   /* 0x40138000, ap 18 12.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer5";
                        reg = <0x38000 0x4>,
                              <0x38010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3a000 {                   /* 0x4013a000, ap 20 14.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer6";
                        reg = <0x3a000 0x4>,
                              <0x3a010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3c000 {                   /* 0x4013c000, ap 22 16.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer7";
                        reg = <0x3c000 0x4>,
                              <0x3c010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3e000 {                   /* 0x4013e000, ap 24 18.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer8";
                        reg = <0x3e000 0x4>,
                              <0x3e010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@f1000 {                   /* 0x401f1000, ap 32 20.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "aess";
                        reg = <0xf1000 0x4>,
                              <0xf1010 0x4>;
                        reg-names = "rev", "sysc";
index 83f803b..459fd70 100644 (file)
 
                target-module@56000 {                   /* 0x4a056000, ap 7 0a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "dma_system";
                        reg = <0x56000 0x4>,
                              <0x5602c 0x4>,
                              <0x56028 0x4>;
                        ranges = <0x0 0x56000 0x1000>;
 
                        sdma: dma-controller@0 {
-                               compatible = "ti,omap4430-sdma";
+                               compatible = "ti,omap4430-sdma", "ti,omap-sdma";
                                reg = <0x0 0x1000>;
                                interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
 
                target-module@58000 {                   /* 0x4a058000, ap 10 0e.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "hsi";
                        reg = <0x58000 0x4>,
                              <0x58010 0x4>,
                              <0x58014 0x4>;
 
                target-module@66000 {                   /* 0x4a066000, ap 25 26.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mmu_dsp";
                        reg = <0x66000 0x4>,
                              <0x66010 0x4>,
                              <0x66014 0x4>;
                        /* Domains (V, P, C): iva, tesla_pwrdm, tesla_clkdm */
                        clocks = <&tesla_clkctrl OMAP4_DSP_CLKCTRL 0>;
                        clock-names = "fck";
+                       resets = <&prm_tesla 1>;
+                       reset-names = "rstctrl";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x66000 0x1000>;
 
-                       /* mmu_dsp cannot be moved before reset driver */
-                       status = "disabled";
+                       mmu_dsp: mmu@0 {
+                               compatible = "ti,omap4-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                       };
                };
        };
 
 
                target-module@2d000 {                   /* 0x4a0ad000, ap 88 0c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "ocp2scp_usb_phy";
                        reg = <0x2d000 0x4>,
                              <0x2d010 0x4>,
                              <0x2d014 0x4>;
 
                target-module@59000 {                   /* 0x4a0d9000, ap 13 1a.0 */
                        compatible = "ti,sysc-omap4-sr", "ti,sysc";
-                       ti,hwmods = "smartreflex_mpu";
                        reg = <0x59038 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
 
                target-module@5b000 {                   /* 0x4a0db000, ap 15 08.0 */
                        compatible = "ti,sysc-omap4-sr", "ti,sysc";
-                       ti,hwmods = "smartreflex_iva";
                        reg = <0x5b038 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
 
                target-module@5d000 {                   /* 0x4a0dd000, ap 17 22.0 */
                        compatible = "ti,sysc-omap4-sr", "ti,sysc";
-                       ti,hwmods = "smartreflex_core";
                        reg = <0x5d038 0x4>;
                        reg-names = "sysc";
                        ti,sysc-mask = <SYSC_OMAP3_SR_ENAWAKEUP>;
 
                target-module@76000 {                   /* 0x4a0f6000, ap 29 3a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spinlock";
                        reg = <0x76000 0x4>,
                              <0x76010 0x4>,
                              <0x76014 0x4>;
 
                target-module@a000 {                    /* 0x4a10a000, ap 65 50.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "fdif";
                        reg = <0xa000 0x4>,
                              <0xa010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@c000 {                    /* 0x4a31c000, ap 11 20.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "kbd";
                        reg = <0xc000 0x4>,
                              <0xc010 0x4>,
                              <0xc014 0x4>;
 
                target-module@32000 {                   /* 0x48032000, ap 5 02.0 */
                        compatible = "ti,sysc-omap2-timer", "ti,sysc";
-                       ti,hwmods = "timer2";
                        reg = <0x32000 0x4>,
                              <0x32010 0x4>,
                              <0x32014 0x4>;
 
                target-module@34000 {                   /* 0x48034000, ap 7 04.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer3";
                        reg = <0x34000 0x4>,
                              <0x34010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@36000 {                   /* 0x48036000, ap 9 0e.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer4";
                        reg = <0x36000 0x4>,
                              <0x36010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3e000 {                   /* 0x4803e000, ap 11 08.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer9";
                        reg = <0x3e000 0x4>,
                              <0x3e010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@76000 {                   /* 0x48076000, ap 39 38.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "slimbus2";
                        reg = <0x76000 0x4>,
                              <0x76010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@78000 {                   /* 0x48078000, ap 41 1a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "elm";
                        reg = <0x78000 0x4>,
                              <0x78010 0x4>,
                              <0x78014 0x4>;
 
                target-module@86000 {                   /* 0x48086000, ap 43 24.0 */
                        compatible = "ti,sysc-omap2-timer", "ti,sysc";
-                       ti,hwmods = "timer10";
                        reg = <0x86000 0x4>,
                              <0x86010 0x4>,
                              <0x86014 0x4>;
 
                target-module@88000 {                   /* 0x48088000, ap 45 2e.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer11";
                        reg = <0x88000 0x4>,
                              <0x88010 0x4>;
                        reg-names = "rev", "sysc";
                        };
                };
 
-               target-module@90000 {                   /* 0x48090000, ap 57 2a.0 */
-                       compatible = "ti,sysc";
-                       status = "disabled";
+               rng_target: target-module@90000 {       /* 0x48090000, ap 57 2a.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x91fe0 0x4>,
+                             <0x91fe4 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>;
+                       /* Domains (P, C): l4per_pwrdm, l4_secure_clkdm */
+                       clocks = <&l4_secure_clkctrl OMAP4_RNG_CLKCTRL 0>;
+                       clock-names = "fck";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x90000 0x2000>;
+
+                       rng: rng@0 {
+                               compatible = "ti,omap4-rng";
+                               reg = <0x0 0x2000>;
+                               interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+                       };
                };
 
                target-module@96000 {                   /* 0x48096000, ap 37 26.0 */
                                 <0x00001000 0x000a5000 0x00001000>;
                };
 
+               des_target: target-module@a5000 {       /* 0x480a5000 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0xa5030 0x4>,
+                             <0xa5034 0x4>,
+                             <0xa5038 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): l4per_pwrdm, l4_secure_clkdm */
+                       clocks = <&l4_secure_clkctrl OMAP4_DES3DES_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0xa5000 0x00001000>;
+
+                       des: des@0 {
+                               compatible = "ti,omap4-des";
+                               reg = <0 0xa0>;
+                               interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&sdma 117>, <&sdma 116>;
+                               dma-names = "tx", "rx";
+                       };
+               };
+
                target-module@a8000 {                   /* 0x480a8000, ap 61 3e.0 */
                        compatible = "ti,sysc";
                        status = "disabled";
index 2de8a6b..9a87440 100644 (file)
                        #gpio-cells = <2>;
                };
 
-               mmu_dsp: mmu@4a066000 {
-                       compatible = "ti,omap4-iommu";
-                       reg = <0x4a066000 0x100>;
-                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu_dsp";
-                       #iommu-cells = <0>;
-               };
-
                target-module@52000000 {
                        compatible = "ti,sysc-omap4", "ti,sysc";
                        ti,hwmods = "iss";
                        /* No child device binding, driver in staging */
                };
 
-               mmu_ipu: mmu@55082000 {
-                       compatible = "ti,omap4-iommu";
-                       reg = <0x55082000 0x100>;
-                       interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu_ipu";
-                       #iommu-cells = <0>;
-                       ti,iommu-bus-err-back;
+               target-module@55082000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x55082000 0x4>,
+                             <0x55082010 0x4>,
+                             <0x55082014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       clocks = <&ducati_clkctrl OMAP4_IPU_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_core 2>;
+                       reset-names = "rstctrl";
+                       ranges = <0x0 0x55082000 0x100>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
+
+                       mmu_ipu: mmu@0 {
+                               compatible = "ti,omap4-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                               ti,iommu-bus-err-back;
+                       };
                };
+
                target-module@4012c000 {
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "slimbus1";
                        reg = <0x4012c000 0x4>,
                              <0x4012c010 0x4>;
                        reg-names = "rev", "sysc";
                        hw-caps-temp-alert;
                };
 
-               aes1: aes@4b501000 {
-                       compatible = "ti,omap4-aes";
-                       ti,hwmods = "aes1";
-                       reg = <0x4b501000 0xa0>;
-                       interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&sdma 111>, <&sdma 110>;
-                       dma-names = "tx", "rx";
-               };
-
-               aes2: aes@4b701000 {
-                       compatible = "ti,omap4-aes";
-                       ti,hwmods = "aes2";
-                       reg = <0x4b701000 0xa0>;
-                       interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&sdma 114>, <&sdma 113>;
-                       dma-names = "tx", "rx";
+               aes1_target: target-module@4b501000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x4b501080 0x4>,
+                             <0x4b501084 0x4>,
+                             <0x4b501088 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): l4per_pwrdm, l4_secure_clkdm */
+                       clocks = <&l4_secure_clkctrl OMAP4_AES1_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4b501000 0x1000>;
+
+                       aes1: aes@0 {
+                               compatible = "ti,omap4-aes";
+                               reg = <0 0xa0>;
+                               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&sdma 111>, <&sdma 110>;
+                               dma-names = "tx", "rx";
+                       };
                };
 
-               des: des@480a5000 {
-                       compatible = "ti,omap4-des";
-                       ti,hwmods = "des";
-                       reg = <0x480a5000 0xa0>;
-                       interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&sdma 117>, <&sdma 116>;
-                       dma-names = "tx", "rx";
+               aes2_target: target-module@4b701000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x4b701080 0x4>,
+                             <0x4b701084 0x4>,
+                             <0x4b701088 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>,
+                                       <SYSC_IDLE_SMART_WKUP>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): l4per_pwrdm, l4_secure_clkdm */
+                       clocks = <&l4_secure_clkctrl OMAP4_AES2_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4b701000 0x1000>;
+
+                       aes2: aes@0 {
+                               compatible = "ti,omap4-aes";
+                               reg = <0 0xa0>;
+                               interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&sdma 114>, <&sdma 113>;
+                               dma-names = "tx", "rx";
+                       };
                };
 
-               sham: sham@4b100000 {
-                       compatible = "ti,omap4-sham";
-                       ti,hwmods = "sham";
-                       reg = <0x4b100000 0x300>;
-                       interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas = <&sdma 119>;
-                       dma-names = "rx";
+               sham_target: target-module@4b100000 {
+                       compatible = "ti,sysc-omap3-sham", "ti,sysc";
+                       reg = <0x4b100100 0x4>,
+                             <0x4b100110 0x4>,
+                             <0x4b100114 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-mask = <(SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,syss-mask = <1>;
+                       /* Domains (P, C): l4per_pwrdm, l4_secure_clkdm */
+                       clocks = <&l4_secure_clkctrl OMAP4_SHA2MD5_CLKCTRL 0>;
+                       clock-names = "fck";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0x0 0x4b100000 0x1000>;
+
+                       sham: sham@0 {
+                               compatible = "ti,omap4-sham";
+                               reg = <0 0x300>;
+                               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
+                               dmas = <&sdma 119>;
+                               dma-names = "rx";
+                       };
                };
 
                abb_mpu: regulator-abb-mpu {
index e9d9c84..5328685 100644 (file)
                #size-cells = <1>;
                ranges = <0 0x1400 0x200>;
 
-               l4_per_clkctrl: clk@20 {
-                       compatible = "ti,clkctrl";
+               l4_per_clkctrl: clock@20 {
+                       compatible = "ti,clkctrl-l4-per", "ti,clkctrl";
                        reg = <0x20 0x144>;
                        #clock-cells = <2>;
                };
-       };
 
+               l4_secure_clkctrl: clock@1a0 {
+                       compatible = "ti,clkctrl-l4-secure", "ti,clkctrl";
+                       reg = <0x1a0 0x3c>;
+                       #clock-cells = <2>;
+               };
+       };
 };
 
 &prm {
index 23aa907..4ec7909 100644 (file)
 
                target-module@2e000 {                   /* 0x4012e000, ap 12 0c.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "dmic";
                        reg = <0x2e000 0x4>,
                              <0x2e010 0x4>;
                        reg-names = "rev", "sysc";
 
                mcpdm_module: target-module@32000 {     /* 0x40132000, ap 16 10.0 */
                        compatible = "ti,sysc-omap4", "ti,sysc";
-                       ti,hwmods = "mcpdm";
                        reg = <0x32000 0x4>,
                              <0x32010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@38000 {                   /* 0x40138000, ap 18 12.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer5";
                        reg = <0x38000 0x4>,
                              <0x38010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3a000 {                   /* 0x4013a000, ap 20 14.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer6";
                        reg = <0x3a000 0x4>,
                              <0x3a010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3c000 {                   /* 0x4013c000, ap 22 16.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer7";
                        reg = <0x3c000 0x4>,
                              <0x3c010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3e000 {                   /* 0x4013e000, ap 24 18.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer8";
                        reg = <0x3e000 0x4>,
                              <0x3e010 0x4>;
                        reg-names = "rev", "sysc";
index 25aacf1..f68740a 100644 (file)
 
                target-module@56000 {                   /* 0x4a056000, ap 7 02.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "dma_system";
                        reg = <0x56000 0x4>,
                              <0x5602c 0x4>,
                              <0x56028 0x4>;
                        ranges = <0x0 0x56000 0x1000>;
 
                        sdma: dma-controller@0 {
-                               compatible = "ti,omap4430-sdma";
+                               compatible = "ti,omap4430-sdma", "ti,omap-sdma";
                                reg = <0x0 0x1000>;
                                interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
                                             <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
 
                target-module@66000 {                   /* 0x4a066000, ap 23 0a.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "mmu_dsp";
                        reg = <0x66000 0x4>,
                              <0x66010 0x4>,
                              <0x66014 0x4>;
                        /* Domains (V, P, C): mm, dsp_pwrdm, dsp_clkdm */
                        clocks = <&dsp_clkctrl OMAP5_MMU_DSP_CLKCTRL 0>;
                        clock-names = "fck";
+                       resets = <&prm_dsp 1>;
+                       reset-names = "rstctrl";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x66000 0x1000>;
 
-                       /* mmu_dsp cannot be moved before reset driver */
-                       status = "disabled";
+                       mmu_dsp: mmu@0 {
+                               compatible = "ti,omap4-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                       };
                };
 
                target-module@70000 {                   /* 0x4a070000, ap 79 2e.0 */
 
                target-module@0 {                       /* 0x4a080000, ap 83 28.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "ocp2scp1";
                        reg = <0x0 0x4>,
                              <0x10 0x4>,
                              <0x14 0x4>;
 
                target-module@10000 {                   /* 0x4a090000, ap 89 36.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "ocp2scp3";
                        reg = <0x10000 0x4>,
                              <0x10010 0x4>,
                              <0x10014 0x4>;
 
                target-module@76000 {                   /* 0x4a0f6000, ap 27 0c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "spinlock";
                        reg = <0x76000 0x4>,
                              <0x76010 0x4>,
                              <0x76014 0x4>;
 
                target-module@32000 {                   /* 0x48032000, ap 5 3e.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer2";
                        reg = <0x32000 0x4>,
                              <0x32010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@34000 {                   /* 0x48034000, ap 7 46.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer3";
                        reg = <0x34000 0x4>,
                              <0x34010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@36000 {                   /* 0x48036000, ap 9 4e.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer4";
                        reg = <0x36000 0x4>,
                              <0x36010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@3e000 {                   /* 0x4803e000, ap 11 56.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer9";
                        reg = <0x3e000 0x4>,
                              <0x3e010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@86000 {                   /* 0x48086000, ap 41 5e.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer10";
                        reg = <0x86000 0x4>,
                              <0x86010 0x4>;
                        reg-names = "rev", "sysc";
 
                target-module@88000 {                   /* 0x48088000, ap 43 66.0 */
                        compatible = "ti,sysc-omap4-timer", "ti,sysc";
-                       ti,hwmods = "timer11";
                        reg = <0x88000 0x4>,
                              <0x88010 0x4>;
                        reg-names = "rev", "sysc";
                        };
                };
 
-               target-module@90000 {                   /* 0x48090000, ap 55 1a.0 */
-                       compatible = "ti,sysc";
-                       status = "disabled";
+               rng_target: target-module@90000 {       /* 0x48090000, ap 55 1a.0 */
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x91fe0 0x4>,
+                             <0x91fe4 0x4>;
+                       reg-names = "rev", "sysc";
+                       ti,sysc-mask = <(SYSC_OMAP2_AUTOIDLE)>;
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>;
+                       /* Domains (P, C): l4per_pwrdm, l4sec_clkdm */
+                       clocks = <&l4sec_clkctrl OMAP5_RNG_CLKCTRL 0>;
+                       clock-names = "fck";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x0 0x90000 0x2000>;
+
+                       rng: rng@0 {
+                               compatible = "ti,omap4-rng";
+                               reg = <0x0 0x2000>;
+                               interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
+                       };
                };
 
                target-module@98000 {                   /* 0x48098000, ap 47 08.0 */
 
                target-module@c000 {                    /* 0x4ae1c000, ap 11 1c.0 */
                        compatible = "ti,sysc-omap2", "ti,sysc";
-                       ti,hwmods = "kbd";
                        reg = <0xc000 0x4>,
                              <0xc010 0x4>;
                        reg-names = "rev", "sysc";
index 1f6ad1d..d0ecf54 100644 (file)
                        #gpio-cells = <2>;
                };
 
-               mmu_dsp: mmu@4a066000 {
-                       compatible = "ti,omap4-iommu";
-                       reg = <0x4a066000 0x100>;
-                       interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu_dsp";
-                       #iommu-cells = <0>;
-               };
+               target-module@55082000 {
+                       compatible = "ti,sysc-omap2", "ti,sysc";
+                       reg = <0x55082000 0x4>,
+                             <0x55082010 0x4>,
+                             <0x55082014 0x4>;
+                       reg-names = "rev", "sysc", "syss";
+                       ti,sysc-sidle = <SYSC_IDLE_FORCE>,
+                                       <SYSC_IDLE_NO>,
+                                       <SYSC_IDLE_SMART>;
+                       ti,sysc-mask = <(SYSC_OMAP2_CLOCKACTIVITY |
+                                        SYSC_OMAP2_SOFTRESET |
+                                        SYSC_OMAP2_AUTOIDLE)>;
+                       clocks = <&ipu_clkctrl OMAP5_MMU_IPU_CLKCTRL 0>;
+                       clock-names = "fck";
+                       resets = <&prm_core 2>;
+                       reset-names = "rstctrl";
+                       ranges = <0x0 0x55082000 0x100>;
+                       #size-cells = <1>;
+                       #address-cells = <1>;
 
-               mmu_ipu: mmu@55082000 {
-                       compatible = "ti,omap4-iommu";
-                       reg = <0x55082000 0x100>;
-                       interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
-                       ti,hwmods = "mmu_ipu";
-                       #iommu-cells = <0>;
-                       ti,iommu-bus-err-back;
+                       mmu_ipu: mmu@0 {
+                               compatible = "ti,omap4-iommu";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                               #iommu-cells = <0>;
+                               ti,iommu-bus-err-back;
+                       };
                };
 
                dmm@4e000000 {
index 4791834..42f2c44 100644 (file)
                #size-cells = <1>;
                ranges = <0 0x1000 0x200>;
 
-               l4per_clkctrl: clk@20 {
-                       compatible = "ti,clkctrl";
+               l4per_clkctrl: clock@20 {
+                       compatible = "ti,clkctrl-l4per", "ti,clkctrl";
                        reg = <0x20 0x15c>;
                        #clock-cells = <2>;
                };
+
+               l4sec_clkctrl: clock@1a0 {
+                       compatible = "ti,clkctrl-l4sec", "ti,clkctrl";
+                       reg = <0x1a0 0x3c>;
+                       #clock-cells = <2>;
+               };
        };
 
        dss_cm: dss_cm@1400 {
index 0a0fb14..fa1852e 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 
+#include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/qcom,gcc-apq8084.h>
 #include <dt-bindings/gpio/gpio.h>
 
 
        cpu-pmu {
                compatible = "qcom,krait-pmu";
-               interrupts = <1 7 0xf04>;
+               interrupts = <GIC_PPI 7 0xf04>;
        };
 
        clocks {
 
        timer {
                compatible = "arm,armv7-timer";
-               interrupts = <1 2 0xf08>,
-                            <1 3 0xf08>,
-                            <1 4 0xf08>,
-                            <1 1 0xf08>;
+               interrupts = <GIC_PPI 2 0xf08>,
+                            <GIC_PPI 3 0xf08>,
+                            <GIC_PPI 4 0xf08>,
+                            <GIC_PPI 1 0xf08>;
                clock-frequency = <19200000>;
        };
 
 
                tsens: thermal-sensor@fc4a8000 {
                        compatible = "qcom,msm8974-tsens";
-                       reg = <0xfc4a8000 0x2000>;
+                       reg = <0xfc4a9000 0x1000>, /* TM */
+                             <0xfc4a8000 0x1000>; /* SROT */
                        nvmem-cells = <&tsens_calib>, <&tsens_backup>;
                        nvmem-cell-names = "calib", "calib_backup";
+                       #qcom,sensors = <11>;
                        #thermal-sensor-cells = <1>;
                };
-
                timer@f9020000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
 
                        frame@f9021000 {
                                frame-number = <0>;
-                               interrupts = <0 8 0x4>,
-                                            <0 7 0x4>;
+                               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9021000 0x1000>,
                                      <0xf9022000 0x1000>;
                        };
 
                        frame@f9023000 {
                                frame-number = <1>;
-                               interrupts = <0 9 0x4>;
+                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9023000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9024000 {
                                frame-number = <2>;
-                               interrupts = <0 10 0x4>;
+                               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9024000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9025000 {
                                frame-number = <3>;
-                               interrupts = <0 11 0x4>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9025000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9026000 {
                                frame-number = <4>;
-                               interrupts = <0 12 0x4>;
+                               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9026000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9027000 {
                                frame-number = <5>;
-                               interrupts = <0 13 0x4>;
+                               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9027000 0x1000>;
                                status = "disabled";
                        };
 
                        frame@f9028000 {
                                frame-number = <6>;
-                               interrupts = <0 14 0x4>;
+                               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
                                reg = <0xf9028000 0x1000>;
                                status = "disabled";
                        };
                        #gpio-cells = <2>;
                        interrupt-controller;
                        #interrupt-cells = <2>;
-                       interrupts = <0 208 0>;
+                       interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                blsp2_uart2: serial@f995e000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        reg = <0xf995e000 0x1000>;
-                       interrupts = <0 114 0x0>;
+                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>, <&gcc GCC_BLSP2_AHB_CLK>;
                        clock-names = "core", "iface";
                        status = "disabled";
                        compatible = "qcom,apq8084-sdhci", "qcom,sdhci-msm-v4";
                        reg = <0xf9824900 0x11c>, <0xf9824000 0x800>;
                        reg-names = "hc_mem", "core_mem";
-                       interrupts = <0 123 0>, <0 138 0>;
+                       interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "hc_irq", "pwr_irq";
                        clocks = <&gcc GCC_SDCC1_APPS_CLK>,
                                 <&gcc GCC_SDCC1_AHB_CLK>,
                        compatible = "qcom,apq8084-sdhci", "qcom,sdhci-msm-v4";
                        reg = <0xf98a4900 0x11c>, <0xf98a4000 0x800>;
                        reg-names = "hc_mem", "core_mem";
-                       interrupts = <0 125 0>, <0 221 0>;
+                       interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "hc_irq", "pwr_irq";
                        clocks = <&gcc GCC_SDCC2_APPS_CLK>,
                                 <&gcc GCC_SDCC2_AHB_CLK>,
                              <0xfc4cb000 0x1000>,
                              <0xfc4ca000 0x1000>;
                        interrupt-names = "periph_irq";
-                       interrupts = <0 190 0>;
+                       interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
                        qcom,ee = <0>;
                        qcom,channel = <0>;
                        #address-cells = <2>;
                compatible = "qcom,smd";
 
                rpm {
-                       interrupts = <0 168 1>;
+                       interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
                        qcom,ipc = <&apcs 8 0>;
                        qcom,smd-edge = <15>;
 
index 8ef26da..71bb25a 100644 (file)
                L2: l2-cache {
                        compatible = "cache";
                        cache-level = <2>;
+                       qcom,saw = <&saw_l2>;
                };
        };
 
                        regulator;
                };
 
+               saw_l2: regulator@b012000 {
+                       compatible = "qcom,saw2";
+                       reg = <0xb012000 0x1000>;
+                       regulator;
+               };
+
                blsp1_uart1: serial@78af000 {
                        compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
                        reg = <0x78af000 0x200>;
index 2616039..d2d4877 100644 (file)
                status = "ok";
        };
 
+       remoteproc@fb21b000 {
+               status = "ok";
+
+               vddmx-supply = <&pm8841_s1>;
+               vddcx-supply = <&pm8841_s2>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&wcnss_pin_a>;
+
+               smd-edge {
+                       qcom,remote-pid = <4>;
+                       label = "pronto";
+
+                       wcnss {
+                               status = "ok";
+                       };
+               };
+       };
+
        pinctrl@fd510000 {
                sdhc1_pin_a: sdhc1-pin-active {
                        clk {
                                bias-pull-up;
                        };
                };
+
+               wcnss_pin_a: wcnss-pin-active {
+                       wlan {
+                               pins =  "gpio36", "gpio37", "gpio38", "gpio39", "gpio40";
+                               function = "wlan";
+
+                               drive-strength = <6>;
+                               bias-pull-down;
+                       };
+
+                       bt {
+                               pins = "gpio35", "gpio43", "gpio44";
+                               function = "bt";
+
+                               drive-strength = <2>;
+                               bias-pull-down;
+                       };
+
+                       fm {
+                               pins = "gpio41", "gpio42";
+                               function = "fm";
+
+                               drive-strength = <2>;
+                               bias-pull-down;
+                       };
+               };
        };
 
        sdhci@f9824900 {
index 9a84eb0..4b161b8 100644 (file)
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /dts-v1/;
 
+#include <dt-bindings/interconnect/qcom,msm8974.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/qcom,gcc-msm8974.h>
 #include <dt-bindings/clock/qcom,mmcc-msm8974.h>
                #size-cells = <1>;
                ranges;
 
-               mpss@8000000 {
+               mpss_region: mpss@8000000 {
                        reg = <0x08000000 0x5100000>;
                        no-map;
                };
 
-               mba@d100000 {
+               mba_region: mba@d100000 {
                        reg = <0x0d100000 0x100000>;
                        no-map;
                };
 
-               reserved@d200000 {
+               wcnss_region: wcnss@d200000 {
                        reg = <0x0d200000 0xa00000>;
                        no-map;
                };
                };
 
                rmtfs@fd80000 {
+                       compatible = "qcom,rmtfs-mem";
                        reg = <0x0fd80000 0x180000>;
                        no-map;
+
+                       qcom,client-id = <1>;
                };
        };
 
 
                qcom,smem-states = <&adsp_smp2p_out 0>;
                qcom,smem-state-names = "stop";
+
+               smd-edge {
+                       interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+
+                       qcom,ipc = <&apcs 8 8>;
+                       qcom,smd-edge = <1>;
+
+                       label = "lpass";
+               };
        };
 
        smem {
                        clock-names = "core";
                };
 
+               remoteproc@fc880000 {
+                       compatible = "qcom,msm8974-mss-pil";
+                       reg = <0xfc880000 0x100>, <0xfc820000 0x020>;
+                       reg-names = "qdsp6", "rmb";
+
+                       interrupts-extended = <&intc GIC_SPI 24 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+
+                       clocks = <&gcc GCC_MSS_Q6_BIMC_AXI_CLK>,
+                                <&gcc GCC_MSS_CFG_AHB_CLK>,
+                                <&gcc GCC_BOOT_ROM_AHB_CLK>,
+                                <&xo_board>;
+                       clock-names = "iface", "bus", "mem", "xo";
+
+                       resets = <&gcc GCC_MSS_RESTART>;
+                       reset-names = "mss_restart";
+
+                       cx-supply = <&pm8841_s2>;
+                       mss-supply = <&pm8841_s3>;
+                       mx-supply = <&pm8841_s1>;
+                       pll-supply = <&pm8941_l12>;
+
+                       qcom,halt-regs = <&tcsr_mutex_block 0x1180 0x1200 0x1280>;
+
+                       qcom,smem-states = <&modem_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       mba {
+                               memory-region = <&mba_region>;
+                       };
+
+                       mpss {
+                               memory-region = <&mpss_region>;
+                       };
+
+                       smd-edge {
+                               interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
+
+                               qcom,ipc = <&apcs 8 12>;
+                               qcom,smd-edge = <0>;
+
+                               label = "modem";
+                       };
+               };
+
+               pronto: remoteproc@fb21b000 {
+                       compatible = "qcom,pronto-v2-pil", "qcom,pronto";
+                       reg = <0xfb204000 0x2000>, <0xfb202000 0x1000>, <0xfb21b000 0x3000>;
+                       reg-names = "ccu", "dxe", "pmu";
+
+                       memory-region = <&wcnss_region>;
+
+                       interrupts-extended = <&intc GIC_SPI 149 IRQ_TYPE_EDGE_RISING>,
+                                             <&wcnss_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&wcnss_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&wcnss_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&wcnss_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready", "handover", "stop-ack";
+
+                       vddpx-supply = <&pm8941_s3>;
+
+                       qcom,smem-states = <&wcnss_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       status = "disabled";
+
+                       iris {
+                               compatible = "qcom,wcn3680";
+
+                               clocks = <&rpmcc RPM_SMD_CXO_A2>;
+                               clock-names = "xo";
+
+                               vddxo-supply = <&pm8941_l6>;
+                               vddrfa-supply = <&pm8941_l11>;
+                               vddpa-supply = <&pm8941_l19>;
+                               vdddig-supply = <&pm8941_s3>;
+                       };
+
+                       smd-edge {
+                               interrupts = <GIC_SPI 142 IRQ_TYPE_EDGE_RISING>;
+
+                               qcom,ipc = <&apcs 8 17>;
+                               qcom,smd-edge = <6>;
+
+                               wcnss {
+                                       compatible = "qcom,wcnss";
+                                       qcom,smd-channels = "WCNSS_CTRL";
+                                       status = "disabled";
+
+                                       qcom,mmio = <&pronto>;
+
+                                       bt {
+                                               compatible = "qcom,wcnss-bt";
+                                       };
+
+                                       wifi {
+                                               compatible = "qcom,wcnss-wlan";
+
+                                               interrupts = <GIC_SPI 145 IRQ_TYPE_EDGE_RISING>,
+                                                            <GIC_SPI 146 IRQ_TYPE_EDGE_RISING>;
+                                               interrupt-names = "tx", "rx";
+
+                                               qcom,smem-states = <&apps_smsm 10>, <&apps_smsm 9>;
+                                               qcom,smem-state-names = "tx-enable", "tx-rings-empty";
+                                       };
+                               };
+                       };
+               };
+
                msmgpio: pinctrl@fd510000 {
                        compatible = "qcom,msm8974-pinctrl";
                        reg = <0xfd510000 0x4000>;
                        };
                };
 
+               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>;
+                       };
+               };
+
+               bimc: interconnect@fc380000 {
+                       reg = <0xfc380000 0x6a000>;
+                       compatible = "qcom,msm8974-bimc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&rpmcc RPM_SMD_BIMC_CLK>,
+                                <&rpmcc RPM_SMD_BIMC_A_CLK>;
+               };
+
+               snoc: interconnect@fc460000 {
+                       reg = <0xfc460000 0x4000>;
+                       compatible = "qcom,msm8974-snoc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&rpmcc RPM_SMD_SNOC_CLK>,
+                                <&rpmcc RPM_SMD_SNOC_A_CLK>;
+               };
+
+               pnoc: interconnect@fc468000 {
+                       reg = <0xfc468000 0x4000>;
+                       compatible = "qcom,msm8974-pnoc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&rpmcc RPM_SMD_PNOC_CLK>,
+                                <&rpmcc RPM_SMD_PNOC_A_CLK>;
+               };
+
+               ocmemnoc: interconnect@fc470000 {
+                       reg = <0xfc470000 0x4000>;
+                       compatible = "qcom,msm8974-ocmemnoc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&rpmcc RPM_SMD_OCMEMGX_CLK>,
+                                <&rpmcc RPM_SMD_OCMEMGX_A_CLK>;
+               };
+
+               mmssnoc: interconnect@fc478000 {
+                       reg = <0xfc478000 0x4000>;
+                       compatible = "qcom,msm8974-mmssnoc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&mmcc MMSS_S0_AXI_CLK>,
+                                <&mmcc MMSS_S0_AXI_CLK>;
+               };
+
+               cnoc: interconnect@fc480000 {
+                       reg = <0xfc480000 0x4000>;
+                       compatible = "qcom,msm8974-cnoc";
+                       #interconnect-cells = <1>;
+                       clock-names = "bus", "bus_a";
+                       clocks = <&rpmcc RPM_SMD_CNOC_CLK>,
+                                <&rpmcc RPM_SMD_CNOC_A_CLK>;
+               };
+
                mdss: mdss@fd900000 {
                        status = "disabled";
 
                                              "core",
                                              "vsync";
 
+                               interconnects = <&mmssnoc MNOC_MAS_MDP_PORT0 &bimc BIMC_SLV_EBI_CH0>;
+                               interconnect-names = "mdp0-mem";
+
                                ports {
                                        #address-cells = <1>;
                                        #size-cells = <0>;
        smd {
                compatible = "qcom,smd";
 
-               adsp {
-                       interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
-
-                       qcom,ipc = <&apcs 8 8>;
-                       qcom,smd-edge = <1>;
-               };
-
-               modem {
-                       interrupts = <GIC_SPI 25 IRQ_TYPE_EDGE_RISING>;
-
-                       qcom,ipc = <&apcs 8 12>;
-                       qcom,smd-edge = <0>;
-               };
-
                rpm {
                        interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
                        qcom,ipc = <&apcs 8 0>;
index d03dcd9..75b2796 100644 (file)
                mmcif: mmc@e804c800 {
                        compatible = "renesas,mmcif-r7s72100", "renesas,sh-mmcif";
                        reg = <0xe804c800 0x80>;
-                       interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 269 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 267 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&mstp8_clks R7S72100_CLK_MMCIF>;
                        power-domains = <&cpg_clocks>;
                        reg-io-width = <4>;
                sdhi0: sd@e804e000 {
                        compatible = "renesas,sdhi-r7s72100";
                        reg = <0xe804e000 0x100>;
-                       interrupts = <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 270 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 271 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>;
 
                        clocks = <&mstp12_clks R7S72100_CLK_SDHI00>,
                                 <&mstp12_clks R7S72100_CLK_SDHI01>;
                sdhi1: sd@e804e800 {
                        compatible = "renesas,sdhi-r7s72100";
                        reg = <0xe804e800 0x100>;
-                       interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 273 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 274 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 275 IRQ_TYPE_LEVEL_HIGH>;
 
                        clocks = <&mstp12_clks R7S72100_CLK_SDHI10>,
                                 <&mstp12_clks R7S72100_CLK_SDHI11>;
index dd865f3..a5cd312 100644 (file)
                dma0: dma-controller@e6700020 {
                        compatible = "renesas,shdma-r8a73a4";
                        reg = <0 0xe6700020 0 0x89e0>;
-                       interrupts = <GIC_SPI 220 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
-                                       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>;
+                       interrupts = <GIC_SPI 220 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>,
+                                    <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>;
                        interrupt-names = "error",
                                        "ch0", "ch1", "ch2", "ch3",
                                        "ch4", "ch5", "ch6", "ch7",
index 758360a..d960c27 100644 (file)
@@ -60,8 +60,7 @@
 
                enable-gpio = <&pfc 74 GPIO_ACTIVE_HIGH>;
                gpios = <&pfc 17 GPIO_ACTIVE_HIGH>;
-               states = <3300000 0
-                         1800000 1>;
+               states = <3300000 0>, <1800000 1>;
 
                enable-active-high;
        };
index 12ffe73..ebc1ff6 100644 (file)
                        <0xe6900020 1>,
                        <0xe6900040 1>,
                        <0xe6900060 1>;
-               interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
                power-domains = <&pd_a4s>;
        };
                        <0xe6900024 1>,
                        <0xe6900044 1>,
                        <0xe6900064 1>;
-               interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
                power-domains = <&pd_a4s>;
        };
                        <0xe6900028 1>,
                        <0xe6900048 1>,
                        <0xe6900068 1>;
-               interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
                power-domains = <&pd_a4s>;
        };
                        <0xe690002c 1>,
                        <0xe690004c 1>,
                        <0xe690006c 1>;
-               interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp2_clks R8A7740_CLK_INTCA>;
                power-domains = <&pd_a4s>;
        };
                #size-cells = <0>;
                compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic";
                reg = <0xfff20000 0x425>;
-               interrupts = <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>;
+               interrupts = <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>;
                clocks = <&mstp1_clks R8A7740_CLK_IIC0>;
                power-domains = <&pd_a4r>;
                status = "disabled";
                #size-cells = <0>;
                compatible = "renesas,iic-r8a7740", "renesas,rmobile-iic";
                reg = <0xe6c20000 0x425>;
-               interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7740_CLK_IIC1>;
                power-domains = <&pd_a3sp>;
                status = "disabled";
        mmcif0: mmc@e6bd0000 {
                compatible = "renesas,mmcif-r8a7740", "renesas,sh-mmcif";
                reg = <0xe6bd0000 0x100>;
-               interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7740_CLK_MMC>;
                power-domains = <&pd_a3sp>;
                status = "disabled";
        sdhi0: sd@e6850000 {
                compatible = "renesas,sdhi-r8a7740";
                reg = <0xe6850000 0x100>;
-               interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7740_CLK_SDHI0>;
                power-domains = <&pd_a3sp>;
                cap-sd-highspeed;
        sdhi1: sd@e6860000 {
                compatible = "renesas,sdhi-r8a7740";
                reg = <0xe6860000 0x100>;
-               interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks R8A7740_CLK_SDHI1>;
                power-domains = <&pd_a3sp>;
                cap-sd-highspeed;
        sdhi2: sd@e6870000 {
                compatible = "renesas,sdhi-r8a7740";
                reg = <0xe6870000 0x100>;
-               interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp4_clks R8A7740_CLK_SDHI2>;
                power-domains = <&pd_a3sp>;
                cap-sd-highspeed;
index de981d6..1cd19a5 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                icram2: sram@e6300000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe6300000 0 0x40000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe6300000 0x40000>;
                };
 
                /* The memory map in the User's Manual maps the cores to
                        compatible = "renesas,r8a7743-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>;
+                       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 R8A7743_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7743-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>;
+                       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 R8A7743_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a7743",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7743",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7743",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec700000 0 0x10000>;
-                       interrupts = <GIC_SPI 346 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>;
+                       interrupts = <GIC_SPI 346 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7743",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec720000 0 0x10000>;
-                       interrupts = <GIC_SPI 347 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
-                                     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>;
+                       interrupts = <GIC_SPI 347 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>,
+                                    <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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x800 0 0 0 0>;
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x10800 0 0 0 0>;
                        #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>;
+                       ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
+                                <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
+                                <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
+                                <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
                        /* Map all possible DDR as inbound ranges */
-                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
-                                     0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>,
+                                    <0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
                        interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
index fa74a26..1c82dd0 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                icram2: sram@e6300000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe6300000 0 0x40000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe6300000 0x40000>;
                };
 
                /* The memory map in the User's Manual maps the cores to
                        compatible = "renesas,r8a7744-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>;
+                       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 R8A7744_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7744-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>;
+                       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 R8A7744_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a7744",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7744",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7744",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec700000 0 0x10000>;
-                       interrupts = <GIC_SPI 346 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>;
+                       interrupts = <GIC_SPI 346 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7744",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec720000 0 0x10000>;
-                       interrupts = <GIC_SPI 347 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
-                                     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>;
+                       interrupts = <GIC_SPI 347 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>,
+                                    <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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x800 0 0 0 0>;
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x10800 0 0 0 0>;
                        #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>;
+                       ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
+                                <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
+                                <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
+                                <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
                        /* Map all possible DDR as inbound ranges */
-                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
-                                     0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>,
+                                    <0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
                        interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
index ce6603b..58d369a 100644 (file)
@@ -76,8 +76,7 @@
 
                gpios = <&gpio0 20 GPIO_ACTIVE_LOW>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 };
 
index c53f7ff..3f88a7e 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                icram2: sram@e6300000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe6300000 0 0x40000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe6300000 0x40000>;
                };
                i2c0: i2c@e6508000 {
                        #address-cells = <1>;
                        compatible = "renesas,r8a7745-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>;
+                       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 R8A7745_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7745-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>;
+                       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 R8A7745_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a7745",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7745",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7745",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec700000 0 0x10000>;
-                       interrupts = <GIC_SPI 346 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>;
+                       interrupts = <GIC_SPI 346 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x800 0 0 0 0>;
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x10800 0 0 0 0>;
index 450efe9..8ac61b5 100644 (file)
@@ -65,8 +65,7 @@
 
                gpios = <&gpio2 24 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 };
 
index 51806c7..6efcef1 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                icram2: sram@e6300000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe6300000 0 0x20000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe6300000 0x20000>;
                };
 
                i2c0: i2c@e6508000 {
                        compatible = "renesas,r8a77470-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>;
+                       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 R8A77470_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a77470-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>;
+                       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 R8A77470_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a77470-usb-dmac",
                                     "renesas,usb-dmac";
                        reg = <0 0xe65a8000 0 0x100>;
-                       interrupts = <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 293 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "ch0", "ch1";
                        clocks = <&cpg CPG_MOD 326>;
                        power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a77470-usb-dmac",
                                     "renesas,usb-dmac";
                        reg = <0 0xe65b8000 0 0x100>;
-                       interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 292 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "ch0", "ch1";
                        clocks = <&cpg CPG_MOD 327>;
                        power-domains = <&sysc R8A77470_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a77470",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a77470",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
index 10d996d..593c6df 100644 (file)
                        <0xfe780024 4>,
                        <0xfe780044 4>,
                        <0xfe780064 4>;
-               interrupts =   <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH
-                               GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH
-                               GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH
-                               GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                sense-bitfield-width = <2>;
        };
 
                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>;
                };
 
                /* Fixed ratio clocks */
index c755f0b..d2240b8 100644 (file)
@@ -48,8 +48,7 @@
 
                gpios = <&gpio3 20 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        ethernet@18000000 {
index ebf5b7c..beb9885 100644 (file)
                      <0xf0000100 0x100>;
        };
 
+       timer@f0000200 {
+               compatible = "arm,cortex-a9-global-timer";
+               reg = <0xf0000200 0x100>;
+               interrupts = <GIC_PPI 11
+                       (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_EDGE_RISING)>;
+               clocks = <&cpg_clocks R8A7779_CLK_ZS>;
+       };
+
        timer@f0000600 {
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0xf0000600 0x20>;
                        <0xfe780044 4>,
                        <0xfe780064 4>,
                        <0xfe780000 4>;
-               interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
                sense-bitfield-width = <2>;
        };
 
index 6ec2cf7..097fd93 100644 (file)
 
                gpios = <&gpio5 29 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi2: regulator-vcc-sdhi2 {
 
                gpios = <&gpio5 30 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        audio_clock: audio_clock {
index 5a27477..334ba19 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                        compatible = "renesas,r8a7790-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>;
+                       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 R8A7790_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7790-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>;
+                       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 R8A7790_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a7790",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7790",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7790",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec700000 0 0x10000>;
-                       interrupts = <GIC_SPI 346 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>;
+                       interrupts = <GIC_SPI 346 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7790",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec720000 0 0x10000>;
-                       interrupts = <GIC_SPI 347 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
-                                     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>;
+                       interrupts = <GIC_SPI 347 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>,
+                                    <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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x800 0 0 0 0>;
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee0a0000 0 0xee0a0000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>;
                };
 
                pci2: pci@ee0d0000 {
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x20800 0 0 0 0>;
                        #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>;
+                       ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
+                                <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
+                                <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
+                                <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
                        /* Map all possible DDR as inbound ranges */
-                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
-                                     0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>;
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>,
+                                    <0x43000000 1 0x80000000 1 0x80000000 0 0x80000000>;
                        interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
index af6bd8f..2b096d5 100644 (file)
 
                gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi1: regulator-vcc-sdhi1 {
 
                gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi2: regulator-vcc-sdhi2 {
 
                gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        audio_clock: audio_clock {
index d6cf16a..f9ece7a 100644 (file)
@@ -63,8 +63,7 @@
 
                gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi2: regulator-vcc-sdhi2 {
@@ -85,8 +84,7 @@
 
                gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        hdmi-out {
index 6f87550..59a55e8 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                        compatible = "renesas,r8a7791-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>;
+                       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 R8A7791_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7791-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>;
+                       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 R8A7791_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a7791",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7791",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7791",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec700000 0 0x10000>;
-                       interrupts = <GIC_SPI 346 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>;
+                       interrupts = <GIC_SPI 346 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7791",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec720000 0 0x10000>;
-                       interrupts = <GIC_SPI 347 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
-                                     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>;
+                       interrupts = <GIC_SPI 347 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>,
+                                    <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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x800 0 0 0 0>;
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x10800 0 0 0 0>;
                        #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>;
+                       ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x00100000>,
+                                <0x02000000 0 0xfe200000 0 0xfe200000 0 0x00200000>,
+                                <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>,
+                                <0x42000000 0 0x38000000 0 0x38000000 0 0x08000000>;
                        /* Map all possible DDR as inbound ranges */
-                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000
-                                     0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
+                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 0 0x80000000>,
+                                    <0x43000000 2 0x00000000 2 0x00000000 1 0x00000000>;
                        interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
index c4ea2d6..39af16c 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                        compatible = "renesas,dmac-r8a7792",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7792",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
index 48fbeb6..22ca7cd 100644 (file)
 
                gpios = <&gpio2 12 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi1: regulator-vcc-sdhi1 {
 
                gpios = <&gpio2 13 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi2: regulator-vcc-sdhi2 {
 
                gpios = <&gpio2 26 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        audio_clock: audio_clock {
index bf05110..eef035c 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                        compatible = "renesas,dmac-r8a7793",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7793",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7793",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec700000 0 0x10000>;
-                       interrupts = <GIC_SPI 346 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>;
+                       interrupts = <GIC_SPI 346 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7793",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec720000 0 0x10000>;
-                       interrupts = <GIC_SPI 347 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
-                                     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>;
+                       interrupts = <GIC_SPI 347 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>,
+                                    <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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
index 1d22fcd..f79fce7 100644 (file)
@@ -60,8 +60,7 @@
 
                gpios = <&gpio2 29 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi1: regulator-vcc-sdhi1 {
@@ -84,8 +83,7 @@
 
                gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        lbsc {
index b3177ae..2c16ad8 100644 (file)
 
                gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vga-encoder {
index 8d797d3..05ef79c 100644 (file)
                icram0: sram@e63a0000 {
                        compatible = "mmio-sram";
                        reg = <0 0xe63a0000 0 0x12000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0 0xe63a0000 0x12000>;
                };
 
                icram1: sram@e63c0000 {
                        compatible = "renesas,dmac-r8a7794",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6700000 0 0x20000>;
-                       interrupts = <GIC_SPI 197 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>;
+                       interrupts = <GIC_SPI 197 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7794",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe6720000 0 0x20000>;
-                       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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a7794",
                                     "renesas,rcar-dmac";
                        reg = <0 0xec700000 0 0x10000>;
-                       interrupts = <GIC_SPI 346 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>;
+                       interrupts = <GIC_SPI 346 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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3", "ch4",
                                          "ch5", "ch6", "ch7", "ch8", "ch9",
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee080000 0 0xee080000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x800 0 0 0 0>;
                        #size-cells = <2>;
                        #interrupt-cells = <1>;
                        ranges = <0x02000000 0 0xee0c0000 0 0xee0c0000 0 0x00010000>;
-                       interrupt-map-mask = <0xff00 0 0 0x7>;
-                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH
-                                        0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-map-mask = <0xf800 0 0 0x7>;
+                       interrupt-map = <0x0000 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x0800 0 0 1 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                       <0x1000 0 0 2 &gic GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
 
                        usb@1,0 {
                                reg = <0x10800 0 0 0 0>;
index c70182c..cf36e25 100644 (file)
                status = "disabled";
        };
 
-       sdmmc: dwmmc@10214000 {
+       sdmmc: mmc@10214000 {
                compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x10214000 0x4000>;
                clock-frequency = <37500000>;
                status = "disabled";
        };
 
-       sdio: dwmmc@10218000 {
+       sdio: mmc@10218000 {
                compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x10218000 0x4000>;
                max-frequency = <37500000>;
                status = "disabled";
        };
 
-       emmc: dwmmc@1021c000 {
+       emmc: mmc@1021c000 {
                compatible = "rockchip,rk3036-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x1021c000 0x4000>;
                interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
index c8b62bb..ad1afd4 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&sd1_clk>, <&sd1_cmd>, <&sd1_bus4>;
        vmmcq-supply = <&vccio_wl>;
+       #address-cells = <1>;
+       #size-cells = <0>;
        status = "okay";
 
        brcmf: wifi@1 {
+               reg = <1>;
                compatible = "brcm,bcm4329-fmac";
                interrupt-parent = <&gpio3>;
                interrupts = <RK_PD2 GPIO_ACTIVE_HIGH>;
index 340ed6c..4e90efd 100644 (file)
                };
        };
 
-       sdmmc: dwmmc@30000000 {
+       sdmmc: mmc@30000000 {
                compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x30000000 0x4000>;
                interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       sdio: dwmmc@30010000 {
+       sdio: mmc@30010000 {
                compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x30010000 0x4000>;
                interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       emmc: dwmmc@30020000 {
+       emmc: mmc@30020000 {
                compatible = "rockchip,rk3228-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x30020000 0x4000>;
                interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
index 2afd686..018802d 100644 (file)
@@ -97,7 +97,7 @@
        };
 
        panel: panel {
-               compatible = "lg,lp079qx1-sp0v", "simple-panel";
+               compatible = "lg,lp079qx1-sp0v";
                backlight = <&backlight>;
                enable-gpios = <&gpio7 RK_PA4 GPIO_ACTIVE_HIGH>;
                pinctrl-0 = <&lcd_cs>;
index 0aeef23..312582c 100644 (file)
        cpu0-supply = <&vdd_cpu>;
 };
 
+&cpu_opp_table {
+       opp-1704000000 {
+               opp-hz = /bits/ 64 <1704000000>;
+               opp-microvolt = <1350000>;
+       };
+       opp-1800000000 {
+               opp-hz = /bits/ 64 <1800000000>;
+               opp-microvolt = <1400000>;
+       };
+};
+
 &gmac {
        assigned-clocks = <&cru SCLK_MAC>;
        assigned-clock-parents = <&ext_gmac>;
                                regulator-always-on;
                                regulator-boot-on;
                                regulator-min-microvolt = <750000>;
-                               regulator-max-microvolt = <1350000>;
+                               regulator-max-microvolt = <1400000>;
                                regulator-name = "vdd_arm";
                                regulator-ramp-delay = <6000>;
                                regulator-state-mem {
index 406146c..aa33d09 100644 (file)
@@ -7,6 +7,7 @@
 
 /dts-v1/;
 #include "rk3288-veyron.dtsi"
+#include "rk3288-veyron-broadcom-bluetooth.dtsi"
 
 / {
        model = "Google Brain";
 };
 
 &pinctrl {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+       >;
+
        hdmi {
                vcc50_hdmi_en: vcc50-hdmi-en {
                        rockchip,pins = <7 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm/boot/dts/rk3288-veyron-broadcom-bluetooth.dtsi b/arch/arm/boot/dts/rk3288-veyron-broadcom-bluetooth.dtsi
new file mode 100644 (file)
index 0000000..a10d25a
--- /dev/null
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Google Veyron (and derivatives) fragment for the Broadcom 43450 bluetooth
+ * chip.
+ *
+ * Copyright 2019 Google, Inc
+ */
+
+&uart0 {
+       bluetooth {
+               pinctrl-names = "default";
+               pinctrl-0 = <&bt_host_wake_l>, <&bt_enable_l>,
+                           <&bt_dev_wake>;
+
+               compatible = "brcm,bcm43540-bt";
+               host-wakeup-gpios       = <&gpio4 RK_PD7 GPIO_ACTIVE_HIGH>;
+               shutdown-gpios          = <&gpio4 RK_PD5 GPIO_ACTIVE_HIGH>;
+               device-wakeup-gpios     = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
+               max-speed               = <3000000>;
+               brcm,bt-pcm-int-params  = [01 02 00 01 01];
+       };
+};
index ffb60f8..05112c2 100644 (file)
 };
 
 &pinctrl {
-       pinctrl-0 = <
-               /* Common for sleep and wake, but no owners */
-               &ddr0_retention
-               &ddrio_pwroff
-               &global_pwroff
-
-               /* Wake only */
-               &suspend_l_wake
-               &bt_dev_wake_awake
-       >;
-       pinctrl-1 = <
-               /* Common for sleep and wake, but no owners */
-               &ddr0_retention
-               &ddrio_pwroff
-               &global_pwroff
-
-               /* Sleep only */
-               &suspend_l_sleep
-               &bt_dev_wake_sleep
-       >;
-
        buttons {
                ap_lid_int_l: ap-lid-int-l {
                        rockchip,pins = <0 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>;
index 300a7e3..32c0f10 100644 (file)
@@ -54,7 +54,7 @@
        };
 
        panel: panel {
-               compatible = "innolux,n116bge", "simple-panel";
+               compatible = "innolux,n116bge";
                status = "okay";
                power-supply = <&panel_regulator>;
                backlight = <&backlight>;
index 9a0f550..309b122 100644 (file)
@@ -18,8 +18,6 @@
                     "google,veyron-fievel-rev0", "google,veyron-fievel",
                     "google,veyron", "rockchip,rk3288";
 
-       /delete-node/ bt-activity;
-
        vccsys: vccsys {
                compatible = "regulator-fixed";
                regulator-name = "vccsys";
                          "PHY_PMEB",
 
                          "PHY_INT",
-                         "REC_MODE_L",
+                         /*
+                          * RECOVERY_SW_L is Chrome OS ABI.  Schematics call
+                          * it REC_MODE_L.
+                          */
+                         "RECOVERY_SW_L",
                          "OTP_OUT",
                          "",
                          "USB_OTG_POWER_EN",
                          "PWR_LED1",
                          "TPM_INT_H",
                          "SPK_ON",
-                         "FW_WP_AP",
+                         /*
+                          * AP_FLASH_WP_L is Chrome OS ABI.  Schematics call
+                          * it FW_WP_AP.
+                          */
+                         "AP_FLASH_WP_L",
                          "",
 
                          "CPU_NMI",
index a4966e5..171ba61 100644 (file)
 };
 
 &pinctrl {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Wake only */
+               &suspend_l_wake
+               &bt_dev_wake_awake
+       >;
+       pinctrl-1 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Sleep only */
+               &suspend_l_sleep
+               &bt_dev_wake_sleep
+       >;
+
        buck-5v {
                drv_5v: drv-5v {
                        rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
index a6ee44f..66f00d2 100644 (file)
 };
 
 &pinctrl {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Wake only */
+               &suspend_l_wake
+               &bt_dev_wake_awake
+       >;
+       pinctrl-1 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Sleep only */
+               &suspend_l_sleep
+               &bt_dev_wake_sleep
+       >;
+
        buck-5v {
                drv_5v: drv-5v {
                        rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
index 06a6a95..ffd1121 100644 (file)
@@ -7,6 +7,7 @@
 
 /dts-v1/;
 #include "rk3288-veyron.dtsi"
+#include "rk3288-veyron-broadcom-bluetooth.dtsi"
 
 / {
        model = "Google Mickey";
 };
 
 &pinctrl {
+       pinctrl-names = "default";
+       pinctrl-0 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+       >;
+
        hdmi {
                power_hdmi_on: power-hdmi-on {
                        rockchip,pins = <7 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
index c833716..383fad1 100644 (file)
@@ -7,6 +7,7 @@
 
 /dts-v1/;
 #include "rk3288-veyron-chromebook.dtsi"
+#include "rk3288-veyron-broadcom-bluetooth.dtsi"
 
 / {
        model = "Google Minnie";
@@ -70,7 +71,7 @@
 };
 
 &panel {
-       compatible = "auo,b101ean01", "simple-panel";
+       compatible = "auo,b101ean01";
 
        /delete-node/ panel-timing;
 
 };
 
 &pinctrl {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Wake only */
+               &suspend_l_wake
+       >;
+       pinctrl-1 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Sleep only */
+               &suspend_l_sleep
+       >;
+
        buck-5v {
                drv_5v: drv-5v {
                        rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
index f420499..71e6629 100644 (file)
 };
 
 &pinctrl {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Wake only */
+               &suspend_l_wake
+               &bt_dev_wake_awake
+       >;
+       pinctrl-1 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Sleep only */
+               &suspend_l_sleep
+               &bt_dev_wake_sleep
+       >;
+
        /delete-node/ lcd;
 
        backlight {
index 2f2989b..e354c61 100644 (file)
@@ -7,6 +7,7 @@
 
 /dts-v1/;
 #include "rk3288-veyron-chromebook.dtsi"
+#include "rk3288-veyron-broadcom-bluetooth.dtsi"
 #include "cros-ec-sbs.dtsi"
 
 / {
 };
 
 &pinctrl {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Wake only */
+               &suspend_l_wake
+       >;
+       pinctrl-1 = <
+               /* Common for sleep and wake, but no owners */
+               &ddr0_retention
+               &ddrio_pwroff
+               &global_pwroff
+
+               /* Sleep only */
+               &suspend_l_sleep
+       >;
+
        buck-5v {
                drv_5v: drv-5v {
                        rockchip,pins = <7 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>;
index bebb230..069f0c2 100644 (file)
@@ -53,7 +53,7 @@
 };
 
 &panel {
-       compatible = "auo,b101ean01", "simple-panel";
+       compatible = "auo,b101ean01";
 
        /delete-node/ panel-timing;
 
index 7525e3d..54a6838 100644 (file)
                reg = <0x0 0x0 0x0 0x80000000>;
        };
 
-       bt_activity: bt-activity {
-               compatible = "gpio-keys";
-               pinctrl-names = "default";
-               pinctrl-0 = <&bt_host_wake>;
-
-               /*
-                * HACK: until we have an LPM driver, we'll use an
-                * ugly GPIO key to allow Bluetooth to wake from S3.
-                * This is expected to only be used by BT modules that
-                * use UART for comms.  For BT modules that talk over
-                * SDIO we should use a wakeup mechanism related to SDIO.
-                *
-                * Use KEY_RESERVED here since that will work as a wakeup but
-                * doesn't get reported to higher levels (so doesn't confuse
-                * Chrome).
-                */
-               bt-wake {
-                       label = "BT Wakeup";
-                       gpios = <&gpio4 RK_PD7 GPIO_ACTIVE_HIGH>;
-                       linux,code = <KEY_RESERVED>;
-                       wakeup-source;
-               };
-
-       };
 
        power_button: power-button {
                compatible = "gpio-keys";
                clocks = <&rk808 RK808_CLKOUT1>;
                clock-names = "ext_clock";
                pinctrl-names = "default";
-               pinctrl-0 = <&bt_enable_l>, <&wifi_enable_h>;
+               pinctrl-0 = <&wifi_enable_h>;
 
                /*
-                * Depending on the actual card populated GPIO4 D4 and D5
+                * Depending on the actual card populated GPIO4 D4
                 * correspond to one of these signals on the module:
                 *
                 * D4:
                 * - SDIO_RESET_L_WL_REG_ON
                 * - PDN (power down when low)
-                *
-                * D5:
-                * - BT_I2S_WS_BT_RFDISABLE_L
-                * - No connect
                 */
-               reset-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_LOW>,
-                             <&gpio4 RK_PD5 GPIO_ACTIVE_LOW>;
+               reset-gpios = <&gpio4 RK_PD4 GPIO_ACTIVE_LOW>;
        };
 
        vcc_5v: vcc-5v {
 };
 
 &pinctrl {
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <
-               /* Common for sleep and wake, but no owners */
-               &ddr0_retention
-               &ddrio_pwroff
-               &global_pwroff
-
-               /* Wake only */
-               &bt_dev_wake_awake
-       >;
-       pinctrl-1 = <
-               /* Common for sleep and wake, but no owners */
-               &ddr0_retention
-               &ddrio_pwroff
-               &global_pwroff
-
-               /* Sleep only */
-               &bt_dev_wake_sleep
-       >;
-
        pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
                bias-disable;
                drive-strength = <8>;
                bt_dev_wake_awake: bt-dev-wake-awake {
                        rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_output_high>;
                };
+
+               bt_dev_wake: bt-dev-wake {
+                       rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
        };
 
        tpm {
index 415c75f..9beb662 100644 (file)
                ports = <&vopl_out>, <&vopb_out>;
        };
 
-       sdmmc: dwmmc@ff0c0000 {
+       sdmmc: mmc@ff0c0000 {
                compatible = "rockchip,rk3288-dw-mshc";
                max-frequency = <150000000>;
                clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
                status = "disabled";
        };
 
-       sdio0: dwmmc@ff0d0000 {
+       sdio0: mmc@ff0d0000 {
                compatible = "rockchip,rk3288-dw-mshc";
                max-frequency = <150000000>;
                clocks = <&cru HCLK_SDIO0>, <&cru SCLK_SDIO0>,
                status = "disabled";
        };
 
-       sdio1: dwmmc@ff0e0000 {
+       sdio1: mmc@ff0e0000 {
                compatible = "rockchip,rk3288-dw-mshc";
                max-frequency = <150000000>;
                clocks = <&cru HCLK_SDIO1>, <&cru SCLK_SDIO1>,
                status = "disabled";
        };
 
-       emmc: dwmmc@ff0f0000 {
+       emmc: mmc@ff0f0000 {
                compatible = "rockchip,rk3288-dw-mshc";
                max-frequency = <150000000>;
                clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
index 97307a4..241f43e 100644 (file)
                status = "disabled";
        };
 
-       mmc0: dwmmc@10214000 {
+       mmc0: mmc@10214000 {
                compatible = "rockchip,rk2928-dw-mshc";
                reg = <0x10214000 0x1000>;
                interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       mmc1: dwmmc@10218000 {
+       mmc1: mmc@10218000 {
                compatible = "rockchip,rk2928-dw-mshc";
                reg = <0x10218000 0x1000>;
                interrupts = <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       emmc: dwmmc@1021c000 {
+       emmc: mmc@1021c000 {
                compatible = "rockchip,rk2928-dw-mshc";
                reg = <0x1021c000 0x1000>;
                interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi b/arch/arm/boot/dts/rockchip-radxa-dalang-carrier.dtsi
new file mode 100644 (file)
index 0000000..df3712a
--- /dev/null
@@ -0,0 +1,81 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2019 Radxa Limited
+ * Copyright (c) 2019 Amarula Solutions(India)
+ */
+
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+};
+
+&gmac {
+       status = "okay";
+};
+
+&i2c1 {
+       status = "okay";
+       i2c-scl-rising-time-ns = <140>;
+       i2c-scl-falling-time-ns = <30>;
+};
+
+&i2c2 {
+       status = "okay";
+       clock-frequency = <400000>;
+
+       hym8563: hym8563@51 {
+               compatible = "haoyu,hym8563";
+               reg = <0x51>;
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "hym8563";
+               pinctrl-names = "default";
+               pinctrl-0 = <&hym8563_int>;
+               interrupt-parent = <&gpio4>;
+               interrupts = <30 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-mmc-highspeed;
+       cap-sd-highspeed;
+       cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>;
+       disable-wp;
+       vqmmc-supply = <&vccio_sd>;
+       max-frequency = <150000000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdmmc_clk &sdmmc_cmd &sdmmc_cd &sdmmc_bus4>;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts>;
+       status = "okay";
+};
+
+&uart2 {
+       status = "okay";
+};
+
+&pinctrl {
+       hym8563 {
+               hym8563_int: hym8563-int {
+                       rockchip,pins =
+                               <4 RK_PD6 0 &pcfg_pull_up>;
+               };
+       };
+};
index 5876690..1fd06e7 100644 (file)
                #reset-cells = <1>;
        };
 
-       emmc: dwmmc@30110000 {
+       emmc: mmc@30110000 {
                compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x30110000 0x4000>;
                interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       sdio: dwmmc@30120000 {
+       sdio: mmc@30120000 {
                compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x30120000 0x4000>;
                interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       sdmmc: dwmmc@30130000 {
+       sdmmc: mmc@30130000 {
                compatible = "rockchip,rv1108-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x30130000 0x4000>;
                interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
index cb371bf..811bfde 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG SMDK2416 board device tree source
+ * Samsung SMDK2416 board device tree source
  *
  * Copyright (c) 2013 Heiko Stuebner <heiko@sntech.de>
  */
index 3bf6c45..96267f5 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Copyright (c) 2013 Tomasz Figa <tomasz.figa@gmail.com>
  *
- * Device tree source file for SAMSUNG SMDK6410 board which is based on
+ * Device tree source file for Samsung SMDK6410 board which is based on
  * Samsung's S3C6410 SoC.
  */
 
@@ -16,7 +16,7 @@
 #include "s3c6410.dtsi"
 
 / {
-       model = "SAMSUNG SMDK6410 board based on S3C6410";
+       model = "Samsung SMDK6410 board based on S3C6410";
        compatible = "samsung,mini6410", "samsung,s3c6410";
 
        memory@50000000 {
diff --git a/arch/arm/boot/dts/sam9x60.dtsi b/arch/arm/boot/dts/sam9x60.dtsi
new file mode 100644 (file)
index 0000000..326b393
--- /dev/null
@@ -0,0 +1,691 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * sam9x60.dtsi - Device Tree Include file for Microchip SAM9X60 SoC
+ *
+ * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Sandeep Sheriker M <sandeepsheriker.mallikarjun@microchip.com>
+ */
+
+#include <dt-bindings/dma/at91.h>
+#include <dt-bindings/pinctrl/at91.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/clock/at91.h>
+#include <dt-bindings/mfd/atmel-flexcom.h>
+
+/ {
+       #address-cells = <1>;
+       #size-cells = <1>;
+       model = "Microchip SAM9X60 SoC";
+       compatible = "microchip,sam9x60";
+       interrupt-parent = <&aic>;
+
+       aliases {
+               serial0 = &dbgu;
+               gpio0 = &pioA;
+               gpio1 = &pioB;
+               gpio2 = &pioC;
+               gpio3 = &pioD;
+               tcb0 = &tcb0;
+               tcb1 = &tcb1;
+       };
+
+       cpus {
+               #address-cells = <0>;
+               #size-cells = <0>;
+
+               cpu {
+                       compatible = "arm,arm926ej-s";
+                       device_type = "cpu";
+               };
+       };
+
+       memory {
+               device_type = "memory";
+               reg = <0x20000000 0x10000000>;
+       };
+
+       clocks {
+               slow_xtal: slow_xtal {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+               };
+
+               main_xtal: main_xtal {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+               };
+       };
+
+       sram: sram@300000 {
+               compatible = "mmio-sram";
+               reg = <0x00300000 0x100000>;
+       };
+
+       ahb {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               usb1: ohci@600000 {
+                       compatible = "atmel,at91rm9200-ohci", "usb-ohci";
+                       reg = <0x00600000 0x100000>;
+                       interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
+                       clocks = <&pmc PMC_TYPE_PERIPHERAL 22>, <&pmc PMC_TYPE_PERIPHERAL 22>, <&pmc PMC_TYPE_SYSTEM 6>;
+                       clock-names = "ohci_clk", "hclk", "uhpck";
+                       status = "disabled";
+               };
+
+               usb2: ehci@700000 {
+                       compatible = "atmel,at91sam9g45-ehci", "usb-ehci";
+                       reg = <0x00700000 0x100000>;
+                       interrupts = <22 IRQ_TYPE_LEVEL_HIGH 2>;
+                       clocks = <&pmc PMC_TYPE_CORE PMC_UTMI>, <&pmc PMC_TYPE_PERIPHERAL 22>;
+                       clock-names = "usb_clk", "ehci_clk";
+                       assigned-clocks = <&pmc PMC_TYPE_CORE PMC_UTMI>;
+                       assigned-clock-rates = <480000000>;
+                       status = "disabled";
+               };
+
+               ebi: ebi@10000000 {
+                       compatible = "microchip,sam9x60-ebi";
+                       #address-cells = <2>;
+                       #size-cells = <1>;
+                       atmel,smc = <&smc>;
+                       microchip,sfr = <&sfr>;
+                       reg = <0x10000000 0x60000000>;
+                       ranges = <0x0 0x0 0x10000000 0x10000000
+                                 0x1 0x0 0x20000000 0x10000000
+                                 0x2 0x0 0x30000000 0x10000000
+                                 0x3 0x0 0x40000000 0x10000000
+                                 0x4 0x0 0x50000000 0x10000000
+                                 0x5 0x0 0x60000000 0x10000000>;
+                       clocks = <&pmc PMC_TYPE_CORE PMC_MCK>;
+                       status = "disabled";
+
+                       nand_controller: nand-controller {
+                               compatible = "microchip,sam9x60-nand-controller";
+                               ecc-engine = <&pmecc>;
+                               #address-cells = <2>;
+                               #size-cells = <1>;
+                               ranges;
+                               status = "disabled";
+                       };
+               };
+
+               sdmmc0: sdio-host@80000000 {
+                       compatible = "microchip,sam9x60-sdhci";
+                       reg = <0x80000000 0x300>;
+                       interrupts = <12 IRQ_TYPE_LEVEL_HIGH 0>;
+                       clocks = <&pmc PMC_TYPE_PERIPHERAL 12>, <&pmc PMC_TYPE_GCK 12>;
+                       clock-names = "hclock", "multclk";
+                       assigned-clocks = <&pmc PMC_TYPE_GCK 12>;
+                       assigned-clock-rates = <100000000>;
+                       status = "disabled";
+               };
+
+               sdmmc1: sdio-host@90000000 {
+                       compatible = "microchip,sam9x60-sdhci";
+                       reg = <0x90000000 0x300>;
+                       interrupts = <26 IRQ_TYPE_LEVEL_HIGH 0>;
+                       clocks = <&pmc PMC_TYPE_PERIPHERAL 26>, <&pmc PMC_TYPE_GCK 26>;
+                       clock-names = "hclock", "multclk";
+                       assigned-clocks = <&pmc PMC_TYPE_GCK 26>;
+                       assigned-clock-rates = <100000000>;
+                       status = "disabled";
+               };
+
+               apb {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+
+                       flx4: flexcom@f0000000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf0000000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 13>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf0000000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx5: flexcom@f0004000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf0004000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 14>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf0004000 0x800>;
+                               status = "disabled";
+                       };
+
+                       dma0: dma-controller@f0008000 {
+                               compatible = "microchip,sam9x60-dma", "atmel,sama5d4-dma";
+                               reg = <0xf0008000 0x1000>;
+                               interrupts = <20 IRQ_TYPE_LEVEL_HIGH 0>;
+                               #dma-cells = <1>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 20>;
+                               clock-names = "dma_clk";
+                       };
+
+                       ssc: ssc@f0010000 {
+                               compatible = "atmel,at91sam9g45-ssc";
+                               reg = <0xf0010000 0x4000>;
+                               interrupts = <28 IRQ_TYPE_LEVEL_HIGH 5>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(38))>,
+                                      <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(39))>;
+                               dma-names = "tx", "rx";
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 28>;
+                               clock-names = "pclk";
+                               status = "disabled";
+                       };
+
+                       qspi: spi@f0014000 {
+                               compatible = "microchip,sam9x60-qspi";
+                               reg = <0xf0014000 0x100>, <0x70000000 0x10000000>;
+                               reg-names = "qspi_base", "qspi_mmap";
+                               interrupts = <35 IRQ_TYPE_LEVEL_HIGH 7>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(26))>,
+                                      <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(27))>;
+                               dma-names = "tx", "rx";
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 35>, <&pmc PMC_TYPE_SYSTEM 19>;
+                               clock-names = "pclk", "qspick";
+                               atmel,pmc = <&pmc>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       i2s: i2s@f001c000 {
+                               compatible = "microchip,sam9x60-i2smcc";
+                               reg = <0xf001c000 0x100>;
+                               interrupts = <34 IRQ_TYPE_LEVEL_HIGH 7>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(36))>,
+                                      <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(37))>;
+                               dma-names = "tx", "rx";
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 34>, <&pmc PMC_TYPE_GCK 34>;
+                               clock-names = "pclk", "gclk";
+                               status = "disabled";
+                       };
+
+                       flx11: flexcom@f0020000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf0020000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 32>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf0020000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx12: flexcom@f0024000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf0024000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 33>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf0024000 0x800>;
+                               status = "disabled";
+                       };
+
+                       pit64b: timer@f0028000 {
+                               compatible = "microchip,sam9x60-pit64b";
+                               reg = <0xf0028000 0x100>;
+                               interrupts = <37 IRQ_TYPE_LEVEL_HIGH 7>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 37>, <&pmc PMC_TYPE_GCK 37>;
+                               clock-names = "pclk", "gclk";
+                       };
+
+                       sha: sha@f002c000 {
+                               compatible = "atmel,at91sam9g46-sha";
+                               reg = <0xf002c000 0x100>;
+                               interrupts = <41 IRQ_TYPE_LEVEL_HIGH 0>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(34))>;
+                               dma-names = "tx";
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 41>;
+                               clock-names = "sha_clk";
+                               status = "okay";
+                       };
+
+                       trng: trng@f0030000 {
+                               compatible = "microchip,sam9x60-trng";
+                               reg = <0xf0030000 0x100>;
+                               interrupts = <38 IRQ_TYPE_LEVEL_HIGH 0>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 38>;
+                               status = "okay";
+                       };
+
+                       aes: aes@f0034000 {
+                               compatible = "atmel,at91sam9g46-aes";
+                               reg = <0xf0034000 0x100>;
+                               interrupts = <39 IRQ_TYPE_LEVEL_HIGH 0>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(32))>,
+                                      <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(33))>;
+                               dma-names = "tx", "rx";
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 39>;
+                               clock-names = "aes_clk";
+                               status = "okay";
+                       };
+
+                       tdes: tdes@f0038000 {
+                               compatible = "atmel,at91sam9g46-tdes";
+                               reg = <0xf0038000 0x100>;
+                               interrupts = <40 IRQ_TYPE_LEVEL_HIGH 0>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(31))>,
+                                      <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(30))>;
+                               dma-names = "tx", "rx";
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 40>;
+                               clock-names = "tdes_clk";
+                               status = "okay";
+                       };
+
+                       classd: classd@f003c000 {
+                               compatible = "atmel,sama5d2-classd";
+                               reg = <0xf003c000 0x100>;
+                               interrupts = <42 IRQ_TYPE_LEVEL_HIGH 7>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(35))>;
+                               dma-names = "tx";
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 42>, <&pmc PMC_TYPE_GCK 42>;
+                               clock-names = "pclk", "gclk";
+                               status = "disabled";
+                       };
+
+                       can0: can@f8000000 {
+                               compatible = "microchip,sam9x60-can", "atmel,at91sam9x5-can";
+                               reg = <0xf8000000 0x300>;
+                               interrupts = <29 IRQ_TYPE_LEVEL_HIGH 3>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 29>;
+                               clock-names = "can_clk";
+                               status = "disabled";
+                       };
+
+                       can1: can@f8004000 {
+                               compatible = "microchip,sam9x60-can", "atmel,at91sam9x5-can";
+                               reg = <0xf8004000 0x300>;
+                               interrupts = <30 IRQ_TYPE_LEVEL_HIGH 3>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 30>;
+                               clock-names = "can_clk";
+                               status = "disabled";
+                       };
+
+                       tcb0: timer@f8008000 {
+                               compatible = "microchip,sam9x60-tcb", "atmel,at91sam9x5-tcb", "simple-mfd", "syscon";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0xf8008000 0x100>;
+                               interrupts = <17 IRQ_TYPE_LEVEL_HIGH 0>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 17>, <&clk32k 0>;
+                               clock-names = "t0_clk", "slow_clk";
+                       };
+
+                       tcb1: timer@f800c000 {
+                               compatible = "microchip,sam9x60-tcb", "atmel,at91sam9x5-tcb", "simple-mfd", "syscon";
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               reg = <0xf800c000 0x100>;
+                               interrupts = <45 IRQ_TYPE_LEVEL_HIGH 0>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 45>, <&clk32k 0>;
+                               clock-names = "t0_clk", "slow_clk";
+                       };
+
+                       flx6: flexcom@f8010000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf8010000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 9>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf8010000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx7: flexcom@f8014000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf8014000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 10>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf8014000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx8: flexcom@f8018000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf8018000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 11>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf8018000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx0: flexcom@f801c000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf801c000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 5>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf801c000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx1: flexcom@f8020000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf8020000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 6>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf8020000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx2: flexcom@f8024000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf8024000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 7>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf8024000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx3: flexcom@f8028000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf8028000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 8>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf8028000 0x800>;
+                               status = "disabled";
+                       };
+
+                       macb0: ethernet@f802c000 {
+                               compatible = "cdns,sam9x60-macb", "cdns,macb";
+                               reg = <0xf802c000 0x1000>;
+                               interrupts = <24 IRQ_TYPE_LEVEL_HIGH 3>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 24>, <&pmc PMC_TYPE_PERIPHERAL 24>;
+                               clock-names = "hclk", "pclk";
+                               status = "disabled";
+                       };
+
+                       macb1: ethernet@f8030000 {
+                               compatible = "cdns,sam9x60-macb", "cdns,macb";
+                               reg = <0xf8030000 0x1000>;
+                               interrupts = <27 IRQ_TYPE_LEVEL_HIGH 3>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 27>, <&pmc PMC_TYPE_PERIPHERAL 27>;
+                               clock-names = "hclk", "pclk";
+                               status = "disabled";
+                       };
+
+                       pwm0: pwm@f8034000 {
+                               compatible = "microchip,sam9x60-pwm";
+                               reg = <0xf8034000 0x300>;
+                               interrupts = <18 IRQ_TYPE_LEVEL_HIGH 4>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 18>;
+                               #pwm-cells = <3>;
+                               status="disabled";
+                       };
+
+                       hlcdc: hlcdc@f8038000 {
+                               compatible = "microchip,sam9x60-hlcdc";
+                               reg = <0xf8038000 0x4000>;
+                               interrupts = <25 IRQ_TYPE_LEVEL_HIGH 0>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 25>, <&pmc PMC_TYPE_GCK 25>, <&clk32k 1>;
+                               clock-names = "periph_clk","sys_clk", "slow_clk";
+                               assigned-clocks = <&pmc PMC_TYPE_GCK 25>;
+                               assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_MCK>;
+                               status = "disabled";
+
+                               hlcdc-display-controller {
+                                       compatible = "atmel,hlcdc-display-controller";
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+
+                                       port@0 {
+                                               #address-cells = <1>;
+                                               #size-cells = <0>;
+                                               reg = <0>;
+                                       };
+                               };
+
+                               hlcdc_pwm: hlcdc-pwm {
+                                       compatible = "atmel,hlcdc-pwm";
+                                       #pwm-cells = <3>;
+                               };
+                       };
+
+                       flx9: flexcom@f8040000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf8040000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 15>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf8040000 0x800>;
+                               status = "disabled";
+                       };
+
+                       flx10: flexcom@f8044000 {
+                               compatible = "atmel,sama5d2-flexcom";
+                               reg = <0xf8044000 0x200>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 16>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               ranges = <0x0 0xf8044000 0x800>;
+                               status = "disabled";
+                       };
+
+                       isi: isi@f8048000 {
+                               compatible = "microchip,sam9x60-isi", "atmel,at91sam9g45-isi";
+                               reg = <0xf8048000 0x100>;
+                               interrupts = <43 IRQ_TYPE_LEVEL_HIGH 5>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 43>;
+                               clock-names = "isi_clk";
+                               status = "disabled";
+                               port {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                               };
+                       };
+
+                       adc: adc@f804c000 {
+                               compatible = "microchip,sam9x60-adc", "atmel,sama5d2-adc";
+                               reg = <0xf804c000 0x100>;
+                               interrupts = <19 IRQ_TYPE_LEVEL_HIGH 7>;
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 19>;
+                               clock-names = "adc_clk";
+                               dmas = <&dma0 (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) | AT91_XDMAC_DT_PERID(40))>;
+                               dma-names = "rx";
+                               atmel,min-sample-rate-hz = <200000>;
+                               atmel,max-sample-rate-hz = <20000000>;
+                               atmel,startup-time-ms = <4>;
+                               atmel,trigger-edge-type = <IRQ_TYPE_EDGE_RISING>;
+                               #io-channel-cells = <1>;
+                               status = "disabled";
+                       };
+
+                       sfr: sfr@f8050000 {
+                               compatible = "microchip,sam9x60-sfr", "syscon";
+                               reg = <0xf8050000 0x100>;
+                       };
+
+                       matrix: matrix@ffffde00 {
+                               compatible = "microchip,sam9x60-matrix", "atmel,at91sam9x5-matrix", "syscon";
+                               reg = <0xffffde00 0x200>;
+                       };
+
+                       pmecc: ecc-engine@ffffe000 {
+                               compatible = "microchip,sam9x60-pmecc", "atmel,at91sam9g45-pmecc";
+                               reg = <0xffffe000 0x300>,
+                                     <0xffffe600 0x100>;
+                       };
+
+                       mpddrc: mpddrc@ffffe800 {
+                               compatible = "microchip,sam9x60-ddramc", "atmel,sama5d3-ddramc";
+                               reg = <0xffffe800 0x200>;
+                               clocks = <&pmc PMC_TYPE_SYSTEM 2>, <&pmc PMC_TYPE_CORE PMC_MCK>;
+                               clock-names = "ddrck", "mpddr";
+                       };
+
+                       smc: smc@ffffea00 {
+                               compatible = "microchip,sam9x60-smc", "atmel,at91sam9260-smc", "syscon";
+                               reg = <0xffffea00 0x100>;
+                       };
+
+                       aic: interrupt-controller@fffff100 {
+                               compatible = "microchip,sam9x60-aic";
+                               #interrupt-cells = <3>;
+                               interrupt-controller;
+                               reg = <0xfffff100 0x100>;
+                               atmel,external-irqs = <31>;
+                       };
+
+                       dbgu: serial@fffff200 {
+                               compatible = "microchip,sam9x60-dbgu", "microchip,sam9x60-usart", "atmel,at91sam9260-dbgu", "atmel,at91sam9260-usart";
+                               reg = <0xfffff200 0x200>;
+                               interrupts = <47 IRQ_TYPE_LEVEL_HIGH 7>;
+                               dmas = <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(28))>,
+                                      <&dma0
+                                       (AT91_XDMAC_DT_MEM_IF(0) | AT91_XDMAC_DT_PER_IF(1) |
+                                        AT91_XDMAC_DT_PERID(29))>;
+                               dma-names = "tx", "rx";
+                               clocks = <&pmc PMC_TYPE_PERIPHERAL 47>;
+                               clock-names = "usart";
+                               status = "disabled";
+                       };
+
+                       pinctrl: pinctrl@fffff400 {
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               compatible = "microchip,sam9x60-pinctrl", "atmel,at91sam9x5-pinctrl", "atmel,at91rm9200-pinctrl", "simple-bus";
+                               ranges = <0xfffff400 0xfffff400 0x800>;
+
+                               pioA: gpio@fffff400 {
+                                       compatible = "microchip,sam9x60-gpio", "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff400 0x200>;
+                                       interrupts = <2 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pmc PMC_TYPE_PERIPHERAL 2>;
+                               };
+
+                               pioB: gpio@fffff600 {
+                                       compatible = "microchip,sam9x60-gpio", "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff600 0x200>;
+                                       interrupts = <3 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       #gpio-lines = <26>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pmc PMC_TYPE_PERIPHERAL 3>;
+                               };
+
+                               pioC: gpio@fffff800 {
+                                       compatible = "microchip,sam9x60-gpio", "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+                                       reg = <0xfffff800 0x200>;
+                                       interrupts = <4 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pmc PMC_TYPE_PERIPHERAL 4>;
+                               };
+
+                               pioD: gpio@fffffa00 {
+                                       compatible = "microchip,sam9x60-gpio", "atmel,at91sam9x5-gpio", "atmel,at91rm9200-gpio";
+                                       reg = <0xfffffa00 0x200>;
+                                       interrupts = <44 IRQ_TYPE_LEVEL_HIGH 1>;
+                                       #gpio-cells = <2>;
+                                       gpio-controller;
+                                       #gpio-lines = <22>;
+                                       interrupt-controller;
+                                       #interrupt-cells = <2>;
+                                       clocks = <&pmc PMC_TYPE_PERIPHERAL 44>;
+                               };
+                       };
+
+                       pmc: pmc@fffffc00 {
+                               compatible = "microchip,sam9x60-pmc", "syscon";
+                               reg = <0xfffffc00 0x200>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               #clock-cells = <2>;
+                               clocks = <&clk32k 1>, <&clk32k 0>, <&main_xtal>;
+                               clock-names = "td_slck", "md_slck", "main_xtal";
+                       };
+
+                       reset_controller: rstc@fffffe00 {
+                               compatible = "microchip,sam9x60-rstc";
+                               reg = <0xfffffe00 0x10>;
+                               clocks = <&clk32k 0>;
+                       };
+
+                       shutdown_controller: shdwc@fffffe10 {
+                               compatible = "microchip,sam9x60-shdwc";
+                               reg = <0xfffffe10 0x10>;
+                               clocks = <&clk32k 0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               atmel,wakeup-rtc-timer;
+                               atmel,wakeup-rtt-timer;
+                               status = "disabled";
+                       };
+
+                       pit: timer@fffffe40 {
+                               compatible = "atmel,at91sam9260-pit";
+                               reg = <0xfffffe40 0x10>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               clocks = <&pmc PMC_TYPE_CORE PMC_MCK>;
+                       };
+
+                       clk32k: sckc@fffffe50 {
+                               compatible = "microchip,sam9x60-sckc";
+                               reg = <0xfffffe50 0x4>;
+                               clocks = <&slow_xtal>;
+                               #clock-cells = <1>;
+                       };
+
+                       gpbr: syscon@fffffe60 {
+                               compatible = "microchip,sam9x60-gpbr", "atmel,at91sam9260-gpbr", "syscon";
+                               reg = <0xfffffe60 0x10>;
+                       };
+
+                       rtc: rtc@fffffea8 {
+                               compatible = "microchip,sam9x60-rtc", "atmel,at91sam9x5-rtc";
+                               reg = <0xfffffea8 0x100>;
+                               interrupts = <1 IRQ_TYPE_LEVEL_HIGH 7>;
+                               clocks = <&clk32k 0>;
+                       };
+               };
+       };
+};
index 5652048..2012b74 100644 (file)
                        interrupts = <31 IRQ_TYPE_LEVEL_HIGH 0>;
                        clocks = <&pmc PMC_TYPE_PERIPHERAL 31>, <&pmc PMC_TYPE_GCK 31>, <&pmc PMC_TYPE_CORE PMC_MAIN>;
                        clock-names = "hclock", "multclk", "baseclk";
+                       assigned-clocks = <&pmc PMC_TYPE_GCK 31>;
+                       assigned-clock-rates = <480000000>;
                        status = "disabled";
                };
 
                        interrupts = <32 IRQ_TYPE_LEVEL_HIGH 0>;
                        clocks = <&pmc PMC_TYPE_PERIPHERAL 32>, <&pmc PMC_TYPE_GCK 32>, <&pmc PMC_TYPE_CORE PMC_MAIN>;
                        clock-names = "hclock", "multclk", "baseclk";
+                       assigned-clocks = <&pmc PMC_TYPE_GCK 32>;
+                       assigned-clock-rates = <480000000>;
                        status = "disabled";
                };
 
                                interrupts = <38 IRQ_TYPE_LEVEL_HIGH 7>;
                                #pwm-cells = <3>;
                                clocks = <&pmc PMC_TYPE_PERIPHERAL 38>;
+                               status = "disabled";
                        };
 
                        sfr: sfr@f8030000 {
                                clocks = <&pmc PMC_TYPE_PERIPHERAL 18>;
                        };
 
-                       secumod@fc040000 {
+                       pioBU: secumod@fc040000 {
                                compatible = "atmel,sama5d2-secumod", "syscon";
                                reg = <0xfc040000 0x100>;
+
+                               gpio-controller;
+                               #gpio-cells = <2>;
                        };
 
                        tdes@fc044000 {
index f770aac..203d40b 100644 (file)
                                        usart0_clk: usart0_clk {
                                                #clock-cells = <0>;
                                                reg = <12>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        usart1_clk: usart1_clk {
                                                #clock-cells = <0>;
                                                reg = <13>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        usart2_clk: usart2_clk {
                                                #clock-cells = <0>;
                                                reg = <14>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        usart3_clk: usart3_clk {
                                                #clock-cells = <0>;
                                                reg = <15>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        uart0_clk: uart0_clk {
                                                #clock-cells = <0>;
                                                reg = <16>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        twi0_clk: twi0_clk {
                                                reg = <18>;
                                                #clock-cells = <0>;
-                                               atmel,clk-output-range = <0 16625000>;
+                                               atmel,clk-output-range = <0 41500000>;
                                        };
 
                                        twi1_clk: twi1_clk {
                                                #clock-cells = <0>;
                                                reg = <19>;
-                                               atmel,clk-output-range = <0 16625000>;
+                                               atmel,clk-output-range = <0 41500000>;
                                        };
 
                                        twi2_clk: twi2_clk {
                                                #clock-cells = <0>;
                                                reg = <20>;
-                                               atmel,clk-output-range = <0 16625000>;
+                                               atmel,clk-output-range = <0 41500000>;
                                        };
 
                                        mci0_clk: mci0_clk {
                                        spi0_clk: spi0_clk {
                                                #clock-cells = <0>;
                                                reg = <24>;
-                                               atmel,clk-output-range = <0 133000000>;
+                                               atmel,clk-output-range = <0 166000000>;
                                        };
 
                                        spi1_clk: spi1_clk {
                                                #clock-cells = <0>;
                                                reg = <25>;
-                                               atmel,clk-output-range = <0 133000000>;
+                                               atmel,clk-output-range = <0 166000000>;
                                        };
 
                                        tcb0_clk: tcb0_clk {
                                                #clock-cells = <0>;
                                                reg = <26>;
-                                               atmel,clk-output-range = <0 133000000>;
+                                               atmel,clk-output-range = <0 166000000>;
                                        };
 
                                        pwm_clk: pwm_clk {
                                        adc_clk: adc_clk {
                                                #clock-cells = <0>;
                                                reg = <29>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        dma0_clk: dma0_clk {
                                        ssc0_clk: ssc0_clk {
                                                #clock-cells = <0>;
                                                reg = <38>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        ssc1_clk: ssc1_clk {
                                                #clock-cells = <0>;
                                                reg = <39>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        sha_clk: sha_clk {
index cf06a01..2470dd3 100644 (file)
                                        can0_clk: can0_clk {
                                                #clock-cells = <0>;
                                                reg = <40>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        can1_clk: can1_clk {
                                                #clock-cells = <0>;
                                                reg = <41>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
                                };
                        };
index 1584035..215802b 100644 (file)
@@ -22,6 +22,7 @@
                                        tcb1_clk: tcb1_clk {
                                                #clock-cells = <0>;
                                                reg = <27>;
+                                               atmel,clk-output-range = <0 166000000>;
                                        };
                                };
                        };
index 4316bdb..cb62adb 100644 (file)
                                        uart0_clk: uart0_clk {
                                                #clock-cells = <0>;
                                                reg = <16>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
 
                                        uart1_clk: uart1_clk {
                                                #clock-cells = <0>;
                                                reg = <17>;
-                                               atmel,clk-output-range = <0 66000000>;
+                                               atmel,clk-output-range = <0 83000000>;
                                        };
                                };
                        };
index 3383699..c134154 100644 (file)
                };
        };
 
+       timer@f0000200 {
+               compatible = "arm,cortex-a9-global-timer";
+               reg = <0xf0000200 0x100>;
+               interrupts = <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>;
+               clocks = <&periph_clk>;
+       };
+
        timer@f0000600 {
                compatible = "arm,cortex-a9-twd-timer";
                reg = <0xf0000600 0x20>;
                interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_EDGE_RISING)>;
-               clocks = <&twd_clk>;
+               clocks = <&periph_clk>;
        };
 
        gic: interrupt-controller@f0001000 {
                        <0xe6900020 1>,
                        <0xe6900040 1>,
                        <0xe6900060 1>;
-               interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp5_clks SH73A0_CLK_INTCA0>;
                power-domains = <&pd_a4s>;
                control-parent;
                        <0xe6900024 1>,
                        <0xe6900044 1>,
                        <0xe6900064 1>;
-               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI  9 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp5_clks SH73A0_CLK_INTCA0>;
                power-domains = <&pd_a4s>;
                control-parent;
                        <0xe6900028 1>,
                        <0xe6900048 1>,
                        <0xe6900068 1>;
-               interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp5_clks SH73A0_CLK_INTCA0>;
                power-domains = <&pd_a4s>;
                control-parent;
                        <0xe690002c 1>,
                        <0xe690004c 1>,
                        <0xe690006c 1>;
-               interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp5_clks SH73A0_CLK_INTCA0>;
                power-domains = <&pd_a4s>;
                control-parent;
                #size-cells = <0>;
                compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6820000 0x425>;
-               interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp1_clks SH73A0_CLK_IIC0>;
                power-domains = <&pd_a3sp>;
                status = "disabled";
                #size-cells = <0>;
                compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6822000 0x425>;
-               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks SH73A0_CLK_IIC1>;
                power-domains = <&pd_a3sp>;
                status = "disabled";
                #size-cells = <0>;
                compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6824000 0x425>;
-               interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp0_clks SH73A0_CLK_IIC2>;
                power-domains = <&pd_a3sp>;
                status = "disabled";
                #size-cells = <0>;
                compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6826000 0x425>;
-               interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp4_clks SH73A0_CLK_IIC3>;
                power-domains = <&pd_a3sp>;
                status = "disabled";
                #size-cells = <0>;
                compatible = "renesas,iic-sh73a0", "renesas,rmobile-iic";
                reg = <0xe6828000 0x425>;
-               interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp4_clks SH73A0_CLK_IIC4>;
                power-domains = <&pd_c5>;
                status = "disabled";
        mmcif: mmc@e6bd0000 {
                compatible = "renesas,mmcif-sh73a0", "renesas,sh-mmcif";
                reg = <0xe6bd0000 0x100>;
-               interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks SH73A0_CLK_MMCIF0>;
                power-domains = <&pd_a3sp>;
                reg-io-width = <4>;
        sdhi0: sd@ee100000 {
                compatible = "renesas,sdhi-sh73a0";
                reg = <0xee100000 0x100>;
-               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks SH73A0_CLK_SDHI0>;
                power-domains = <&pd_a3sp>;
                cap-sd-highspeed;
        sdhi1: sd@ee120000 {
                compatible = "renesas,sdhi-sh73a0";
                reg = <0xee120000 0x100>;
-               interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks SH73A0_CLK_SDHI1>;
                power-domains = <&pd_a3sp>;
                disable-wp;
        sdhi2: sd@ee140000 {
                compatible = "renesas,sdhi-sh73a0";
                reg = <0xee140000 0x100>;
-               interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH
-                             GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+               interrupts = <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&mstp3_clks SH73A0_CLK_SDHI2>;
                power-domains = <&pd_a3sp>;
                disable-wp;
                extal2_clk: extal2 {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
+                       /* This value must be overridden by the board. */
+                       clock-frequency = <0>;
                };
                extcki_clk: extcki {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
+                       /* This value can be overridden by the board. */
+                       clock-frequency = <0>;
                };
                fsiack_clk: fsiack {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
+                       /* This value can be overridden by the board. */
                        clock-frequency = <0>;
                };
                fsibck_clk: fsibck {
                        compatible = "fixed-clock";
                        #clock-cells = <0>;
+                       /* This value can be overridden by the board. */
                        clock-frequency = <0>;
                };
 
                        clock-div = <13>;
                        clock-mult = <1>;
                };
-               twd_clk: twd {
+               periph_clk: periph {
                        compatible = "fixed-factor-clock";
                        clocks = <&cpg_clocks SH73A0_CLK_Z>;
                        #clock-cells = <0>;
index 55fff4d..14d4d86 100644 (file)
@@ -6,6 +6,20 @@
 #include <dt-bindings/clock/ste-ab8500.h>
 
 / {
+       /* Essential housekeeping hardware monitors */
+       iio-hwmon {
+               compatible = "iio-hwmon";
+               io-channels = <&gpadc 0x02>, /* Battery temperature */
+                           <&gpadc 0x03>, /* Main charger voltage */
+                           <&gpadc 0x08>, /* Main battery voltage */
+                           <&gpadc 0x09>, /* VBUS */
+                           <&gpadc 0x0a>, /* Main charger current */
+                           <&gpadc 0x0b>, /* USB charger current */
+                           <&gpadc 0x0c>, /* Backup battery voltage */
+                           <&gpadc 0x0d>, /* Die temperature */
+                           <&gpadc 0x12>; /* Crystal temperature */
+       };
+
        soc {
                prcmu@80157000 {
                        ab8500 {
                                        interrupt-names = "60S", "ALARM";
                                };
 
-                               ab8500-gpadc {
+                               gpadc: ab8500-gpadc {
                                        compatible = "stericsson,ab8500-gpadc";
                                        interrupts = <32 IRQ_TYPE_LEVEL_HIGH
                                                      39 IRQ_TYPE_LEVEL_HIGH>;
                                        interrupt-names = "HW_CONV_END", "SW_CONV_END";
                                        vddadc-supply = <&ab8500_ldo_tvout_reg>;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       #io-channel-cells = <1>;
+
+                                       /* GPADC channels */
+                                       bat_ctrl: channel@01 {
+                                               reg = <0x01>;
+                                       };
+                                       btemp_ball: channel@02 {
+                                               reg = <0x02>;
+                                       };
+                                       main_charger_v: channel@03 {
+                                               reg = <0x03>;
+                                       };
+                                       acc_detect1: channel@04 {
+                                               reg = <0x04>;
+                                       };
+                                       acc_detect2: channel@05 {
+                                               reg = <0x05>;
+                                       };
+                                       adc_aux1: channel@06 {
+                                               reg = <0x06>;
+                                       };
+                                       adc_aux2: channel@07 {
+                                               reg = <0x07>;
+                                       };
+                                       main_batt_v: channel@08 {
+                                               reg = <0x08>;
+                                       };
+                                       vbus_v: channel@09 {
+                                               reg = <0x09>;
+                                       };
+                                       main_charger_c: channel@0a {
+                                               reg = <0x0a>;
+                                       };
+                                       usb_charger_c: channel@0b {
+                                               reg = <0x0b>;
+                                       };
+                                       bk_bat_v: channel@0c {
+                                               reg = <0x0c>;
+                                       };
+                                       die_temp: channel@0d {
+                                               reg = <0x0d>;
+                                       };
+                                       usb_id: channel@0e {
+                                               reg = <0x0e>;
+                                       };
+                                       xtal_temp: channel@12 {
+                                               reg = <0x12>;
+                                       };
+                                       vbat_true_meas: channel@13 {
+                                               reg = <0x13>;
+                                       };
+                                       bat_ctrl_and_ibat: channel@1c {
+                                               reg = <0x1c>;
+                                       };
+                                       vbat_meas_and_ibat: channel@1d {
+                                               reg = <0x1d>;
+                                       };
+                                       vbat_true_meas_and_ibat: channel@1e {
+                                               reg = <0x1e>;
+                                       };
+                                       bat_temp_and_ibat: channel@1f {
+                                               reg = <0x1f>;
+                                       };
+                               };
+
+                               ab8500_temp {
+                                       compatible = "stericsson,abx500-temp";
+                                       io-channels = <&gpadc 0x06>,
+                                                     <&gpadc 0x07>;
+                                       io-channel-name = "aux1", "aux2";
                                };
 
                                ab8500_battery: ab8500_battery {
                                ab8500_fg {
                                        compatible = "stericsson,ab8500-fg";
                                        battery    = <&ab8500_battery>;
+                                       io-channels = <&gpadc 0x08>;
+                                       io-channel-name = "main_bat_v";
                                };
 
                                ab8500_btemp {
                                        compatible = "stericsson,ab8500-btemp";
                                        battery    = <&ab8500_battery>;
+                                       io-channels = <&gpadc 0x02>,
+                                                     <&gpadc 0x01>;
+                                       io-channel-name = "btemp_ball",
+                                                       "bat_ctrl";
                                };
 
                                ab8500_charger {
                                        compatible      = "stericsson,ab8500-charger";
                                        battery         = <&ab8500_battery>;
                                        vddadc-supply   = <&ab8500_ldo_tvout_reg>;
+                                       io-channels = <&gpadc 0x03>,
+                                                     <&gpadc 0x0a>,
+                                                     <&gpadc 0x09>,
+                                                     <&gpadc 0x0b>;
+                                       io-channel-name = "main_charger_v",
+                                                       "main_charger_c",
+                                                       "vbus_v",
+                                                       "usb_charger_c";
                                };
 
                                ab8500_chargalg {
diff --git a/arch/arm/boot/dts/ste-ab8505.dtsi b/arch/arm/boot/dts/ste-ab8505.dtsi
new file mode 100644 (file)
index 0000000..c72aa25
--- /dev/null
@@ -0,0 +1,275 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2012 Linaro Ltd
+ */
+
+#include <dt-bindings/clock/ste-ab8500.h>
+
+/ {
+       /* Essential housekeeping hardware monitors */
+       iio-hwmon {
+               compatible = "iio-hwmon";
+               io-channels = <&gpadc 0x02>, /* Battery temperature */
+                             <&gpadc 0x08>, /* Main battery voltage */
+                             <&gpadc 0x09>, /* VBUS */
+                             <&gpadc 0x0b>, /* Charger current */
+                             <&gpadc 0x0c>; /* Backup battery voltage */
+       };
+
+       soc {
+               prcmu@80157000 {
+                       ab8505 {
+                               compatible = "stericsson,ab8505";
+                               interrupt-parent = <&intc>;
+                               interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+
+                               ab8500_clock: clock-controller {
+                                       compatible = "stericsson,ab8500-clk";
+                                       #clock-cells = <1>;
+                               };
+
+                               ab8505_gpio: ab8505-gpio {
+                                       compatible = "stericsson,ab8505-gpio";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                               };
+
+                               ab8500-rtc {
+                                       compatible = "stericsson,ab8500-rtc";
+                                       interrupts = <17 IRQ_TYPE_LEVEL_HIGH
+                                                     18 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names = "60S", "ALARM";
+                               };
+
+                               gpadc: ab8500-gpadc {
+                                       compatible = "stericsson,ab8500-gpadc";
+                                       interrupts = <32 IRQ_TYPE_LEVEL_HIGH
+                                                     39 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names = "HW_CONV_END", "SW_CONV_END";
+                                       vddadc-supply = <&ab8500_ldo_adc_reg>;
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
+                                       #io-channel-cells = <1>;
+
+                                       /* GPADC channels */
+                                       bat_ctrl: channel@01 {
+                                               reg = <0x01>;
+                                       };
+                                       btemp_ball: channel@02 {
+                                               reg = <0x02>;
+                                       };
+                                       acc_detect1: channel@04 {
+                                               reg = <0x04>;
+                                       };
+                                       acc_detect2: channel@05 {
+                                               reg = <0x05>;
+                                       };
+                                       adc_aux1: channel@06 {
+                                               reg = <0x06>;
+                                       };
+                                       adc_aux2: channel@07 {
+                                               reg = <0x07>;
+                                       };
+                                       main_batt_v: channel@08 {
+                                               reg = <0x08>;
+                                       };
+                                       vbus_v: channel@09 {
+                                               reg = <0x09>;
+                                       };
+                                       charger_c: channel@0b {
+                                               reg = <0x0b>;
+                                       };
+                                       bk_bat_v: channel@0c {
+                                               reg = <0x0c>;
+                                       };
+                                       usb_id: channel@0e {
+                                               reg = <0x0e>;
+                                       };
+                               };
+
+                               ab8500_battery: ab8500_battery {
+                                       status = "disabled";
+                                       thermistor-on-batctrl;
+                               };
+
+                               ab8500_fg {
+                                       status = "disabled";
+                                       compatible = "stericsson,ab8500-fg";
+                                       battery = <&ab8500_battery>;
+                                       io-channels = <&gpadc 0x08>;
+                                       io-channel-name = "main_bat_v";
+                               };
+
+                               ab8500_btemp {
+                                       status = "disabled";
+                                       compatible = "stericsson,ab8500-btemp";
+                                       battery = <&ab8500_battery>;
+                                       io-channels = <&gpadc 0x02>,
+                                                     <&gpadc 0x01>;
+                                       io-channel-name = "btemp_ball",
+                                                         "bat_ctrl";
+                               };
+
+                               ab8500_charger {
+                                       status = "disabled";
+                                       compatible = "stericsson,ab8500-charger";
+                                       battery = <&ab8500_battery>;
+                                       vddadc-supply = <&ab8500_ldo_adc_reg>;
+                                       io-channels = <&gpadc 0x09>,
+                                                     <&gpadc 0x0b>;
+                                       io-channel-name = "vbus_v",
+                                                         "usb_charger_c";
+                               };
+
+                               ab8500_chargalg {
+                                       status = "disabled";
+                                       compatible = "stericsson,ab8500-chargalg";
+                                       battery = <&ab8500_battery>;
+                               };
+
+                               ab8500_usb: ab8500_usb {
+                                       compatible = "stericsson,ab8500-usb";
+                                       interrupts = < 90 IRQ_TYPE_LEVEL_HIGH
+                                                      96 IRQ_TYPE_LEVEL_HIGH
+                                                      14 IRQ_TYPE_LEVEL_HIGH
+                                                      15 IRQ_TYPE_LEVEL_HIGH
+                                                      79 IRQ_TYPE_LEVEL_HIGH
+                                                      74 IRQ_TYPE_LEVEL_HIGH
+                                                      75 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names = "ID_WAKEUP_R",
+                                                         "ID_WAKEUP_F",
+                                                         "VBUS_DET_F",
+                                                         "VBUS_DET_R",
+                                                         "USB_LINK_STATUS",
+                                                         "USB_ADP_PROBE_PLUG",
+                                                         "USB_ADP_PROBE_UNPLUG";
+                                       vddulpivio18-supply = <&ab8500_ldo_intcore_reg>;
+                                       v-ape-supply = <&db8500_vape_reg>;
+                                       musb_1v8-supply = <&db8500_vsmps2_reg>;
+                                       clocks = <&prcmu_clk PRCMU_SYSCLK>;
+                                       clock-names = "sysclk";
+                               };
+
+                               ab8500-ponkey {
+                                       compatible = "stericsson,ab8500-poweron-key";
+                                       interrupts = <6 IRQ_TYPE_LEVEL_HIGH
+                                                     7 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names = "ONKEY_DBF", "ONKEY_DBR";
+                               };
+
+                               ab8500-sysctrl {
+                                       compatible = "stericsson,ab8500-sysctrl";
+                               };
+
+                               ab8500-pwm {
+                                       compatible = "stericsson,ab8500-pwm";
+                                       clocks = <&ab8500_clock AB8500_SYSCLK_INT>;
+                                       clock-names = "intclk";
+                               };
+
+                               ab8500-debugfs {
+                                       compatible = "stericsson,ab8500-debug";
+                               };
+
+                               codec: ab8500-codec {
+                                       compatible = "stericsson,ab8500-codec";
+
+                                       V-AUD-supply = <&ab8500_ldo_audio_reg>;
+                                       V-AMIC1-supply = <&ab8500_ldo_anamic1_reg>;
+                                       V-AMIC2-supply = <&ab8500_ldo_anamic2_reg>;
+
+                                       clocks = <&ab8500_clock AB8500_SYSCLK_AUDIO>;
+                                       clock-names = "audioclk";
+
+                                       stericsson,earpeice-cmv = <950>; /* Units in mV. */
+                               };
+
+                               ab8505-regulators {
+                                       compatible = "stericsson,ab8505-regulator";
+
+                                       ab8500_ldo_aux1_reg: ab8500_ldo_aux1 {
+                                               regulator-min-microvolt = <2800000>;
+                                               regulator-max-microvolt = <3300000>;
+                                       };
+
+                                       ab8500_ldo_aux2_reg: ab8500_ldo_aux2 {
+                                               regulator-min-microvolt = <1100000>;
+                                               regulator-max-microvolt = <3300000>;
+                                       };
+
+                                       ab8500_ldo_aux3_reg: ab8500_ldo_aux3 {
+                                               regulator-min-microvolt = <1100000>;
+                                               regulator-max-microvolt = <3300000>;
+                                       };
+
+                                       ab8500_ldo_aux4_reg: ab8500_ldo_aux4 {
+                                               regulator-min-microvolt = <1100000>;
+                                               regulator-max-microvolt = <3300000>;
+                                       };
+
+                                       ab8500_ldo_aux5_reg: ab8500_ldo_aux5 {
+                                               regulator-min-microvolt = <1050000>;
+                                               regulator-max-microvolt = <2790000>;
+                                       };
+
+                                       ab8500_ldo_aux6_reg: ab8500_ldo_aux6 {
+                                               regulator-min-microvolt = <1050000>;
+                                               regulator-max-microvolt = <2790000>;
+                                       };
+
+                                       // supply for v-intcore12; VINTCORE12 LDO
+                                       ab8500_ldo_intcore_reg: ab8500_ldo_intcore {
+                                               regulator-min-microvolt = <1250000>;
+                                               regulator-max-microvolt = <1350000>;
+                                       };
+
+                                       // supply for gpadc; ADC LDO
+                                       ab8500_ldo_adc_reg: ab8500_ldo_adc {
+                                       };
+
+                                       // supply for ab8500-vaudio; VAUDIO LDO
+                                       ab8500_ldo_audio_reg: ab8500_ldo_audio {
+                                       };
+
+                                       // supply for v-anamic1 VAMIC1 LDO
+                                       ab8500_ldo_anamic1_reg: ab8500_ldo_anamic1 {
+                                       };
+
+                                       // supply for v-amic2; VAMIC2 LDO; reuse constants for AMIC1
+                                       ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 {
+                                       };
+
+                                       // supply for v-aux8; VAUX8 LDO
+                                       ab8500_ldo_aux8_reg: ab8500_ldo_aux8 {
+                                       };
+
+                                       // supply for U8500 CSI/DSI; VANA LDO
+                                       ab8500_ldo_ana_reg: ab8500_ldo_ana {
+                                       };
+                               };
+                       };
+               };
+
+               sound {
+                       stericsson,audio-codec = <&codec>;
+                       clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>;
+                       clock-names = "sysclk", "ulpclk", "intclk";
+               };
+
+               mcde@a0350000 {
+                       vana-supply = <&ab8500_ldo_ana_reg>;
+
+                       dsi@a0351000 {
+                               vana-supply = <&ab8500_ldo_ana_reg>;
+                       };
+                       dsi@a0352000 {
+                               vana-supply = <&ab8500_ldo_ana_reg>;
+                       };
+                       dsi@a0353000 {
+                               vana-supply = <&ab8500_ldo_ana_reg>;
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-db8500.dtsi b/arch/arm/boot/dts/ste-db8500.dtsi
new file mode 100644 (file)
index 0000000..d309fad
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "ste-dbx5x0.dtsi"
+
+/ {
+       cpus {
+               cpu@300 {
+                       /* cpufreq controls */
+                       operating-points = <998400 0
+                                           800000 0
+                                           400000 0
+                                           200000 0>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-db8520.dtsi b/arch/arm/boot/dts/ste-db8520.dtsi
new file mode 100644 (file)
index 0000000..48bd872
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "ste-dbx5x0.dtsi"
+
+/ {
+       cpus {
+               cpu@300 {
+                       /* cpufreq controls */
+                       operating-points = <1152000 0
+                                           800000 0
+                                           400000 0
+                                           200000 0>;
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-dbx5x0-pinctrl.dtsi b/arch/arm/boot/dts/ste-dbx5x0-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..7bf7a2d
--- /dev/null
@@ -0,0 +1,632 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright 2013 Linaro Ltd.
+ */
+
+#include "ste-nomadik-pinctrl.dtsi"
+
+&pinctrl {
+       /* Settings for all UART default and sleep states */
+       uart0 {
+               u0_a_1_default: u0_a_1_default {
+                       default_mux {
+                               function = "u0";
+                               groups = "u0_a_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
+                               ste,config = <&in_pu>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
+                               ste,config = <&out_hi>;
+                       };
+               };
+
+               u0_a_1_sleep: u0_a_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins = "GPIO1_AJ3"; /* RTS */
+                               ste,config = <&slpm_out_hi_wkup_pdis>;
+                       };
+                       sleep_cfg3 {
+                               pins = "GPIO3_AH3"; /* TXD */
+                               ste,config = <&slpm_out_wkup_pdis>;
+                       };
+               };
+       };
+
+       uart1 {
+               u1rxtx_a_1_default: u1rxtx_a_1_default {
+                       default_mux {
+                               function = "u1";
+                               groups = "u1rxtx_a_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO4_AH6"; /* RXD */
+                               ste,config = <&in_pu>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO5_AG6"; /* TXD */
+                               ste,config = <&out_hi>;
+                       };
+               };
+
+               u1rxtx_a_1_sleep: u1rxtx_a_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO4_AH6"; /* RXD */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins = "GPIO5_AG6"; /* TXD */
+                               ste,config = <&slpm_out_wkup_pdis>;
+                       };
+               };
+
+               u1ctsrts_a_1_default: u1ctsrts_a_1_default {
+                       default_mux {
+                               function = "u1";
+                               groups = "u1ctsrts_a_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO6_AF6"; /* CTS */
+                               ste,config = <&in_pu>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO7_AG5"; /* RTS */
+                               ste,config = <&out_hi>;
+                       };
+               };
+
+               u1ctsrts_a_1_sleep: u1ctsrts_a_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO6_AF6"; /* CTS */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins = "GPIO7_AG5"; /* RTS */
+                               ste,config = <&slpm_out_hi_wkup_pdis>;
+                       };
+               };
+       };
+
+       uart2 {
+               u2rxtx_c_1_default: u2rxtx_c_1_default {
+                       default_mux {
+                               function = "u2";
+                               groups = "u2rxtx_c_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO29_W2"; /* RXD */
+                               ste,config = <&in_pu>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO30_W3"; /* TXD */
+                               ste,config = <&out_hi>;
+                       };
+               };
+
+               u2rxtx_c_1_sleep: u2rxtx_c_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO29_W2"; /* RXD */
+                               ste,config = <&in_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins = "GPIO30_W3"; /* TXD */
+                               ste,config = <&out_wkup_pdis>;
+                       };
+               };
+       };
+
+       /* Settings for all I2C default and sleep states */
+       i2c0 {
+               i2c0_a_1_default: i2c0_a_1_default {
+                       default_mux {
+                               function = "i2c0";
+                               groups = "i2c0_a_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
+                               ste,config = <&in_nopull>;
+                       };
+               };
+
+               i2c0_a_1_sleep: i2c0_a_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+               };
+       };
+
+       i2c1 {
+               i2c1_b_2_default: i2c1_b_2_default {
+                       default_mux {
+                               function = "i2c1";
+                               groups = "i2c1_b_2";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
+                               ste,config = <&in_nopull>;
+                       };
+               };
+
+               i2c1_b_2_sleep: i2c1_b_2_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+               };
+       };
+
+       i2c2 {
+               i2c2_b_2_default: i2c2_b_2_default {
+                       default_mux {
+                               function = "i2c2";
+                               groups = "i2c2_b_2";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
+                               ste,config = <&in_nopull>;
+                       };
+               };
+
+               i2c2_b_2_sleep: i2c2_b_2_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+               };
+       };
+
+       i2c3 {
+               i2c3_c_2_default: i2c3_c_2_default {
+                       default_mux {
+                               function = "i2c3";
+                               groups = "i2c3_c_2";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
+                               ste,config = <&in_nopull>;
+                       };
+               };
+
+               i2c3_c_2_sleep: i2c3_c_2_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+               };
+       };
+
+       /*
+        * Activating I2C4 will conflict with UART1 about the same pins so do not
+        * enable I2C4 and UART1 at the same time.
+        */
+       i2c4 {
+               i2c4_b_1_default: i2c4_b_1_default {
+                       default_mux {
+                               function = "i2c4";
+                               groups = "i2c4_b_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
+                               ste,config = <&in_nopull>;
+                       };
+               };
+
+               i2c4_b_1_sleep: i2c4_b_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+               };
+       };
+
+       /* Settings for all MMC/SD/SDIO default and sleep states */
+       sdi0 {
+               /* This is the external SD card slot, 4 bits wide */
+               mc0_a_1_default: mc0_a_1_default {
+                       default_mux {
+                               function = "mc0";
+                               groups = "mc0_a_1";
+                       };
+                       default_cfg1 {
+                               pins =
+                               "GPIO18_AC2", /* CMDDIR */
+                               "GPIO19_AC1", /* DAT0DIR */
+                               "GPIO20_AB4"; /* DAT2DIR */
+                               ste,config = <&out_hi>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO22_AA3"; /* FBCLK */
+                               ste,config = <&in_nopull>;
+                       };
+                       default_cfg3 {
+                               pins = "GPIO23_AA4"; /* CLK */
+                               ste,config = <&out_lo>;
+                       };
+                       default_cfg4 {
+                               pins =
+                               "GPIO24_AB2", /* CMD */
+                               "GPIO25_Y4", /* DAT0 */
+                               "GPIO26_Y2", /* DAT1 */
+                               "GPIO27_AA2", /* DAT2 */
+                               "GPIO28_AA1"; /* DAT3 */
+                               ste,config = <&in_pu>;
+                       };
+               };
+
+               mc0_a_1_sleep: mc0_a_1_sleep {
+                       sleep_cfg1 {
+                               pins =
+                               "GPIO18_AC2", /* CMDDIR */
+                               "GPIO19_AC1", /* DAT0DIR */
+                               "GPIO20_AB4"; /* DAT2DIR */
+                               ste,config = <&slpm_out_hi_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins =
+                               "GPIO22_AA3", /* FBCLK */
+                               "GPIO24_AB2", /* CMD */
+                               "GPIO25_Y4", /* DAT0 */
+                               "GPIO26_Y2", /* DAT1 */
+                               "GPIO27_AA2", /* DAT2 */
+                               "GPIO28_AA1"; /* DAT3 */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+                       sleep_cfg3 {
+                               pins = "GPIO23_AA4"; /* CLK */
+                               ste,config = <&slpm_out_lo_wkup_pdis>;
+                       };
+               };
+
+               mc0_a_2_default: mc0_a_2_default {
+                       default_mux {
+                               function = "mc0";
+                               groups = "mc0_a_2";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO22_AA3"; /* FBCLK */
+                               ste,config = <&in_nopull>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO23_AA4"; /* CLK */
+                               ste,config = <&out_lo>;
+                       };
+                       default_cfg3 {
+                               pins =
+                               "GPIO24_AB2", /* CMD */
+                               "GPIO25_Y4", /* DAT0 */
+                               "GPIO26_Y2", /* DAT1 */
+                               "GPIO27_AA2", /* DAT2 */
+                               "GPIO28_AA1"; /* DAT3 */
+                               ste,config = <&in_pu>;
+                       };
+               };
+
+               mc0_a_2_sleep: mc0_a_2_sleep {
+                       sleep_cfg1 {
+                               pins =
+                               "GPIO22_AA3", /* FBCLK */
+                               "GPIO24_AB2", /* CMD */
+                               "GPIO25_Y4", /* DAT0 */
+                               "GPIO26_Y2", /* DAT1 */
+                               "GPIO27_AA2", /* DAT2 */
+                               "GPIO28_AA1"; /* DAT3 */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins = "GPIO23_AA4"; /* CLK */
+                               ste,config = <&slpm_out_lo_wkup_pdis>;
+                       };
+               };
+       };
+
+       sdi1 {
+               /* This is the WLAN SDIO 4 bits wide */
+               mc1_a_1_default: mc1_a_1_default {
+                       default_mux {
+                               function = "mc1";
+                               groups = "mc1_a_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO208_AH16"; /* CLK */
+                               ste,config = <&out_lo>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO209_AG15"; /* FBCLK */
+                               ste,config = <&in_nopull>;
+                       };
+                       default_cfg3 {
+                               pins =
+                               "GPIO210_AJ15", /* CMD */
+                               "GPIO211_AG14", /* DAT0 */
+                               "GPIO212_AF13", /* DAT1 */
+                               "GPIO213_AG13", /* DAT2 */
+                               "GPIO214_AH15"; /* DAT3 */
+                               ste,config = <&in_pu>;
+                       };
+               };
+
+               mc1_a_1_sleep: mc1_a_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO208_AH16"; /* CLK */
+                               ste,config = <&slpm_out_lo_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins =
+                               "GPIO209_AG15", /* FBCLK */
+                               "GPIO210_AJ15", /* CMD */
+                               "GPIO211_AG14", /* DAT0 */
+                               "GPIO212_AF13", /* DAT1 */
+                               "GPIO213_AG13", /* DAT2 */
+                               "GPIO214_AH15"; /* DAT3 */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+               };
+
+               mc1_a_2_default: mc1_a_2_default {
+                       default_mux {
+                               function = "mc1";
+                               groups = "mc1_a_2";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO208_AH16"; /* CLK */
+                               ste,config = <&out_lo>;
+                       };
+                       default_cfg2 {
+                               pins =
+                               "GPIO210_AJ15", /* CMD */
+                               "GPIO211_AG14", /* DAT0 */
+                               "GPIO212_AF13", /* DAT1 */
+                               "GPIO213_AG13", /* DAT2 */
+                               "GPIO214_AH15"; /* DAT3 */
+                               ste,config = <&in_pu>;
+                       };
+               };
+
+               mc1_a_2_sleep: mc1_a_2_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO208_AH16"; /* CLK */
+                               ste,config = <&slpm_out_lo_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins =
+                               "GPIO210_AJ15", /* CMD */
+                               "GPIO211_AG14", /* DAT0 */
+                               "GPIO212_AF13", /* DAT1 */
+                               "GPIO213_AG13", /* DAT2 */
+                               "GPIO214_AH15"; /* DAT3 */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+               };
+       };
+
+       sdi2 {
+               /* This is the eMMC 8 bits wide, usually PoP eMMC */
+               mc2_a_1_default: mc2_a_1_default {
+                       default_mux {
+                               function = "mc2";
+                               groups = "mc2_a_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO128_A5"; /* CLK */
+                               ste,config = <&out_lo>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO130_C8"; /* FBCLK */
+                               ste,config = <&in_nopull>;
+                       };
+                       default_cfg3 {
+                               pins =
+                               "GPIO129_B4", /* CMD */
+                               "GPIO131_A12", /* DAT0 */
+                               "GPIO132_C10", /* DAT1 */
+                               "GPIO133_B10", /* DAT2 */
+                               "GPIO134_B9", /* DAT3 */
+                               "GPIO135_A9", /* DAT4 */
+                               "GPIO136_C7", /* DAT5 */
+                               "GPIO137_A7", /* DAT6 */
+                               "GPIO138_C5"; /* DAT7 */
+                               ste,config = <&in_pu>;
+                       };
+               };
+
+               mc2_a_1_sleep: mc2_a_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO128_A5"; /* CLK */
+                               ste,config = <&out_lo_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins =
+                               "GPIO130_C8", /* FBCLK */
+                               "GPIO129_B4"; /* CMD */
+                               ste,config = <&in_wkup_pdis_en>;
+                       };
+                       sleep_cfg3 {
+                               pins =
+                               "GPIO131_A12", /* DAT0 */
+                               "GPIO132_C10", /* DAT1 */
+                               "GPIO133_B10", /* DAT2 */
+                               "GPIO134_B9", /* DAT3 */
+                               "GPIO135_A9", /* DAT4 */
+                               "GPIO136_C7", /* DAT5 */
+                               "GPIO137_A7", /* DAT6 */
+                               "GPIO138_C5"; /* DAT7 */
+                               ste,config = <&in_wkup_pdis>;
+                       };
+               };
+       };
+
+       sdi4 {
+               /* This is the eMMC 8 bits wide, usually PCB-mounted eMMC */
+               mc4_a_1_default: mc4_a_1_default {
+                       default_mux {
+                               function = "mc4";
+                               groups = "mc4_a_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO203_AE23"; /* CLK */
+                               ste,config = <&out_lo>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO202_AF25"; /* FBCLK */
+                               ste,config = <&in_nopull>;
+                       };
+                       default_cfg3 {
+                               pins =
+                               "GPIO201_AF24", /* CMD */
+                               "GPIO200_AH26", /* DAT0 */
+                               "GPIO199_AH23", /* DAT1 */
+                               "GPIO198_AG25", /* DAT2 */
+                               "GPIO197_AH24", /* DAT3 */
+                               "GPIO207_AJ23", /* DAT4 */
+                               "GPIO206_AG24", /* DAT5 */
+                               "GPIO205_AG23", /* DAT6 */
+                               "GPIO204_AF23"; /* DAT7 */
+                               ste,config = <&in_pu>;
+                       };
+               };
+
+               mc4_a_1_sleep: mc4_a_1_sleep {
+                       sleep_cfg1 {
+                               pins = "GPIO203_AE23"; /* CLK */
+                               ste,config = <&out_lo_wkup_pdis>;
+                       };
+                       sleep_cfg2 {
+                               pins =
+                               "GPIO202_AF25", /* FBCLK */
+                               "GPIO201_AF24", /* CMD */
+                               "GPIO200_AH26", /* DAT0 */
+                               "GPIO199_AH23", /* DAT1 */
+                               "GPIO198_AG25", /* DAT2 */
+                               "GPIO197_AH24", /* DAT3 */
+                               "GPIO207_AJ23", /* DAT4 */
+                               "GPIO206_AG24", /* DAT5 */
+                               "GPIO205_AG23", /* DAT6 */
+                               "GPIO204_AF23"; /* DAT7 */
+                               ste,config = <&slpm_in_wkup_pdis>;
+                       };
+               };
+       };
+
+       /*
+        * Multi-rate serial ports (MSPs) - MSP3 output is internal and
+        * cannot be muxed onto any pins.
+        */
+       msp0 {
+               msp0txrxtfstck_a_1_default: msp0txrxtfstck_a_1_default {
+                       default_msp0_mux {
+                               function = "msp0";
+                               groups = "msp0txrx_a_1", "msp0tfstck_a_1";
+                       };
+                       default_msp0_cfg {
+                               pins =
+                               "GPIO12_AC4", /* TXD */
+                               "GPIO15_AC3", /* RXD */
+                               "GPIO13_AF3", /* TFS */
+                               "GPIO14_AE3"; /* TCK */
+                               ste,config = <&in_nopull>;
+                       };
+               };
+       };
+
+       msp1 {
+               msp1txrx_a_1_default: msp1txrx_a_1_default {
+                       default_mux {
+                               function = "msp1";
+                               groups = "msp1txrx_a_1", "msp1_a_1";
+                       };
+                       default_cfg1 {
+                               pins = "GPIO33_AF2";
+                               ste,config = <&out_lo>;
+                       };
+                       default_cfg2 {
+                               pins =
+                               "GPIO34_AE1",
+                               "GPIO35_AE2",
+                               "GPIO36_AG2";
+                               ste,config = <&in_nopull>;
+                       };
+               };
+       };
+
+       msp2 {
+               msp2_a_1_default: msp2_a_1_default {
+                       /* MSP2 usually used for HDMI audio */
+                       default_mux {
+                               function = "msp2";
+                               groups = "msp2_a_1";
+                       };
+                       default_cfg1 {
+                               pins =
+                               "GPIO193_AH27", /* TXD */
+                               "GPIO194_AF27", /* TCK */
+                               "GPIO195_AG28"; /* TFS */
+                               ste,config = <&in_pd>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO196_AG26"; /* RXD */
+                               ste,config = <&out_lo>;
+                       };
+               };
+       };
+
+       musb {
+               usb_a_1_default: usb_a_1_default {
+                       default_mux {
+                               function = "usb";
+                               groups = "usb_a_1";
+                       };
+                       default_cfg1 {
+                               pins =
+                               "GPIO256_AF28", /* NXT */
+                               "GPIO258_AD29", /* XCLK */
+                               "GPIO259_AC29", /* DIR */
+                               "GPIO260_AD28", /* DAT7 */
+                               "GPIO261_AD26", /* DAT6 */
+                               "GPIO262_AE26", /* DAT5 */
+                               "GPIO263_AG29", /* DAT4 */
+                               "GPIO264_AE27", /* DAT3 */
+                               "GPIO265_AD27", /* DAT2 */
+                               "GPIO266_AC28", /* DAT1 */
+                               "GPIO267_AC27"; /* DAT0 */
+                               ste,config = <&in_nopull>;
+                       };
+                       default_cfg2 {
+                               pins = "GPIO257_AE29"; /* STP */
+                               ste,config = <&out_hi>;
+                       };
+               };
+
+               usb_a_1_sleep: usb_a_1_sleep {
+                       sleep_cfg1 {
+                               pins =
+                               "GPIO256_AF28", /* NXT */
+                               "GPIO258_AD29", /* XCLK */
+                               "GPIO259_AC29"; /* DIR */
+                               ste,config = <&slpm_wkup_pdis_en>;
+                       };
+                       sleep_cfg2 {
+                               pins = "GPIO257_AE29"; /* STP */
+                               ste,config = <&slpm_out_hi_wkup_pdis>;
+                       };
+                       sleep_cfg3 {
+                               pins =
+                               "GPIO260_AD28", /* DAT7 */
+                               "GPIO261_AD26", /* DAT6 */
+                               "GPIO262_AE26", /* DAT5 */
+                               "GPIO263_AG29", /* DAT4 */
+                               "GPIO264_AE27", /* DAT3 */
+                               "GPIO265_AD27", /* DAT2 */
+                               "GPIO266_AC28", /* DAT1 */
+                               "GPIO267_AC27"; /* DAT0 */
+                               ste,config = <&slpm_in_wkup_pdis_en>;
+                       };
+               };
+       };
+};
index bda454d..6671f74 100644 (file)
        #address-cells = <1>;
        #size-cells = <1>;
 
+       /* This stablilizes the device enumeration */
+       aliases {
+               i2c0 = &i2c0;
+               i2c1 = &i2c1;
+               i2c2 = &i2c2;
+               i2c3 = &i2c3;
+               i2c4 = &i2c4;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi2 = &spi2;
+               spi3 = &spi3;
+               serial0 = &serial0;
+               serial1 = &serial1;
+               serial2 = &serial2;
+       };
+
        chosen {
        };
 
                        device_type = "cpu";
                        compatible = "arm,cortex-a9";
                        reg = <0x300>;
-                       /* cpufreq controls */
-                       operating-points = <998400 0
-                                           800000 0
-                                           400000 0
-                                           200000 0>;
                        clocks = <&prcmu_clk PRCMU_ARMSS>;
                        clock-names = "cpu";
                        clock-latency = <20000>;
        soc {
                #address-cells = <1>;
                #size-cells = <1>;
-               compatible = "stericsson,db8500";
+               compatible = "stericsson,db8500", "simple-bus";
                interrupt-parent = <&intc>;
                ranges;
 
                };
 
                rtc@80154000 {
-                       compatible = "arm,rtc-pl031", "arm,primecell";
+                       compatible = "arm,pl031", "arm,primecell";
                        reg = <0x80154000 0x1000>;
                        interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
 
                        };
                };
 
-               i2c@80004000 {
+               i2c0: i2c@80004000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x80004000 0x1000>;
                        interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&prcc_kclk 3 3>, <&prcc_pclk 3 3>;
                        clock-names = "i2cclk", "apb_pclk";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               i2c@80122000 {
+               i2c1: i2c@80122000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x80122000 0x1000>;
                        interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&prcc_kclk 1 2>, <&prcc_pclk 1 2>;
                        clock-names = "i2cclk", "apb_pclk";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               i2c@80128000 {
+               i2c2: i2c@80128000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x80128000 0x1000>;
                        interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&prcc_kclk 1 6>, <&prcc_pclk 1 6>;
                        clock-names = "i2cclk", "apb_pclk";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               i2c@80110000 {
+               i2c3: i2c@80110000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x80110000 0x1000>;
                        interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&prcc_kclk 2 0>, <&prcc_pclk 2 0>;
                        clock-names = "i2cclk", "apb_pclk";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               i2c@8012a000 {
+               i2c4: i2c@8012a000 {
                        compatible = "stericsson,db8500-i2c", "st,nomadik-i2c", "arm,primecell";
                        reg = <0x8012a000 0x1000>;
                        interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&prcc_kclk 1 9>, <&prcc_pclk 1 10>;
                        clock-names = "i2cclk", "apb_pclk";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               spi@80002000 {
+               ssp0: spi@80002000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x80002000 0x1000>;
                        interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
                               <&dma 8 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               spi@80003000 {
+               ssp1: spi@80003000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x80003000 0x1000>;
                        interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
                               <&dma 9 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               spi@8011a000 {
+               spi0: spi@8011a000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x8011a000 0x1000>;
                        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                               <&dma 0 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               spi@80112000 {
+               spi1: spi@80112000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x80112000 0x1000>;
                        interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
                               <&dma 35 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               spi@80111000 {
+               spi2: spi@80111000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x80111000 0x1000>;
                        interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
                               <&dma 33 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               spi@80129000 {
+               spi3: spi@80129000 {
                        compatible = "arm,pl022", "arm,primecell";
                        reg = <0x80129000 0x1000>;
                        interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
                               <&dma 40 0 0x0>; /* Logical - MemToDev */
                        dma-names = "rx", "tx";
                        power-domains = <&pm_domains DOMAIN_VAPE>;
+
+                       status = "disabled";
                };
 
-               ux500_serial0: uart@80120000 {
+               serial0: uart@80120000 {
                        compatible = "arm,pl011", "arm,primecell";
                        reg = <0x80120000 0x1000>;
                        interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
 
-               ux500_serial1: uart@80121000 {
+               serial1: uart@80121000 {
                        compatible = "arm,pl011", "arm,primecell";
                        reg = <0x80121000 0x1000>;
                        interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
                        status = "disabled";
                };
 
-               ux500_serial2: uart@80007000 {
+               serial2: uart@80007000 {
                        compatible = "arm,pl011", "arm,primecell";
                        reg = <0x80007000 0x1000>;
                        interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/ste-href-ab8505.dtsi b/arch/arm/boot/dts/ste-href-ab8505.dtsi
deleted file mode 100644 (file)
index 95cf38a..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/*
- * Copyright 2014 Linaro Ltd.
- */
-
-/ {
-       soc {
-               prcmu@80157000 {
-                       ab8505 {
-                               ab8505-gpio {
-                                       /* Hog a few default settings */
-                                       pinctrl-names = "default";
-                                       pinctrl-0 = <&gpio2_default_mode>,
-                                                   <&gpio10_default_mode>,
-                                                   <&gpio11_default_mode>,
-                                                   <&gpio13_default_mode>,
-                                                   <&gpio34_default_mode>,
-                                                   <&gpio50_default_mode>,
-                                                   <&pwm_default_mode>,
-                                                   <&adi2_default_mode>,
-                                                   <&modsclsda_default_mode>,
-                                                   <&resethw_default_mode>,
-                                                   <&service_default_mode>;
-
-                                       /*
-                                        * Pins 2, 10, 11, 13, 34 and 50
-                                        * are muxed in as GPIO, and configured as INPUT PULL DOWN
-                                        */
-                                       gpio2 {
-                                               gpio2_default_mode: gpio2_default {
-                                                       default_mux {
-                                                               function = "gpio";
-                                                               groups = "gpio2_a_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO2_R5";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       gpio10 {
-                                               gpio10_default_mode: gpio10_default {
-                                                       default_mux {
-                                                               function = "gpio";
-                                                               groups = "gpio10_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO10_B16";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       gpio11 {
-                                               gpio11_default_mode: gpio11_default {
-                                                       default_mux {
-                                                               function = "gpio";
-                                                               groups = "gpio11_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO11_B17";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       gpio13 {
-                                               gpio13_default_mode: gpio13_default {
-                                                       default_mux {
-                                                               function = "gpio";
-                                                               groups = "gpio13_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO13_D17";
-                                                               input-enable;
-                                                               bias-disable;
-                                                       };
-                                               };
-                                       };
-                                       gpio34 {
-                                               gpio34_default_mode: gpio34_default {
-                                                       default_mux {
-                                                               function = "gpio";
-                                                               groups = "gpio34_a_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO34_H14";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       gpio50 {
-                                               gpio50_default_mode: gpio50_default {
-                                                       default_mux {
-                                                               function = "gpio";
-                                                               groups = "gpio50_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO50_L4";
-                                                               input-enable;
-                                                               bias-disable;
-                                                       };
-                                               };
-                                       };
-                                       /* This sets up the PWM pin 14 */
-                                       pwm {
-                                               pwm_default_mode: pwm_default {
-                                                       default_mux {
-                                                               function = "pwmout";
-                                                               groups = "pwmout1_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO14_C16";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       /* This sets up audio interface 2 */
-                                       adi2 {
-                                               adi2_default_mode: adi2_default {
-                                                       default_mux {
-                                                               function = "adi2";
-                                                               groups = "adi2_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO17_P2",
-                                                                        "GPIO18_N3",
-                                                                        "GPIO19_T1",
-                                                                        "GPIO20_P3";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       /* Modem I2C setup (SCL and SDA pins) */
-                                       modsclsda {
-                                               modsclsda_default_mode: modsclsda_default {
-                                                       default_mux {
-                                                               function = "modsclsda";
-                                                               groups = "modsclsda_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO40_J15",
-                                                                       "GPIO41_J14";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       resethw {
-                                               resethw_default_mode: resethw_default {
-                                                       default_mux {
-                                                               function = "resethw";
-                                                               groups = "resethw_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO52_D16";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       service {
-                                               service_default_mode: service_default {
-                                                       default_mux {
-                                                               function = "service";
-                                                               groups = "service_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO53_D15";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       /*
-                                        * Clock output pins associated with regulators.
-                                        */
-                                       sysclkreq2 {
-                                               sysclkreq2_default_mode: sysclkreq2_default {
-                                                       default_mux {
-                                                               function = "sysclkreq";
-                                                               groups = "sysclkreq2_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO1_N4";
-                                                               input-enable;
-                                                               bias-disable;
-                                                       };
-                                               };
-                                               sysclkreq2_sleep_mode: sysclkreq2_sleep {
-                                                       default_mux {
-                                                               function = "gpio";
-                                                               groups = "gpio1_a_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO1_N4";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                                       sysclkreq4 {
-                                               sysclkreq4_default_mode: sysclkreq4_default {
-                                                       default_mux {
-                                                               function = "sysclkreq";
-                                                               groups = "sysclkreq4_d_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO3_P5";
-                                                               input-enable;
-                                                               bias-disable;
-                                                       };
-                                               };
-                                               sysclkreq4_sleep_mode: sysclkreq4_sleep {
-                                                       default_mux {
-                                                               function = "gpio";
-                                                               groups = "gpio3_a_1";
-                                                       };
-                                                       default_cfg {
-                                                               pins = "GPIO3_P5";
-                                                               input-enable;
-                                                               bias-pull-down;
-                                                       };
-                                               };
-                                       };
-                               };
-                       };
-               };
-       };
-};
index 2c382d2..434fa6b 100644 (file)
  * Copyright 2013 Linaro Ltd.
  */
 
-#include "ste-nomadik-pinctrl.dtsi"
+#include "ste-dbx5x0-pinctrl.dtsi"
 
 / {
        soc {
                pinctrl {
-                       /* Settings for all UART default and sleep states */
-                       uart0 {
-                               uart0_default_mode: uart0_default {
-                                       default_mux {
-                                               function = "u0";
-                                               groups = "u0_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
-                                               ste,config = <&in_pu>;
-                                       };
-
-                                       default_cfg2 {
-                                               pins = "GPIO1_AJ3", "GPIO3_AH3"; /* RTS+TXD */
-                                               ste,config = <&out_hi>;
-                                       };
-                               };
-
-                               uart0_sleep_mode: uart0_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO0_AJ5", "GPIO2_AH4"; /* CTS+RXD */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-
-                                       sleep_cfg2 {
-                                               pins = "GPIO1_AJ3"; /* RTS */
-                                               ste,config = <&slpm_out_hi_wkup_pdis>;
-                                       };
-
-                                       sleep_cfg3 {
-                                               pins = "GPIO3_AH3"; /* TXD */
-                                               ste,config = <&slpm_out_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       uart1 {
-                               uart1_default_mode: uart1_default {
-                                       default_mux {
-                                               function = "u1";
-                                               groups = "u1rxtx_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO4_AH6"; /* RXD */
-                                               ste,config = <&in_pu>;
-                                       };
-
-                                       default_cfg2 {
-                                               pins = "GPIO5_AG6"; /* TXD */
-                                               ste,config = <&out_hi>;
-                                       };
-                               };
-
-                               uart1_sleep_mode: uart1_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO4_AH6"; /* RXD */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-
-                                       sleep_cfg2 {
-                                               pins = "GPIO5_AG6"; /* TXD */
-                                               ste,config = <&slpm_out_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       uart2 {
-                               uart2_default_mode: uart2_default {
-                                       default_mux {
-                                               function = "u2";
-                                               groups = "u2rxtx_c_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO29_W2"; /* RXD */
-                                               ste,config = <&in_pu>;
-                                       };
-
-                                       default_cfg2 {
-                                               pins = "GPIO30_W3"; /* TXD */
-                                               ste,config = <&out_hi>;
-                                       };
-                               };
-
-                               uart2_sleep_mode: uart2_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO29_W2"; /* RXD */
-                                               ste,config = <&in_wkup_pdis>;
-                                       };
-
-                                       sleep_cfg2 {
-                                               pins = "GPIO30_W3"; /* TXD */
-                                               ste,config = <&out_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       /* Settings for all I2C default and sleep states */
-                       i2c0 {
-                               i2c0_default_mode: i2c_default {
-                                       default_mux {
-                                               function = "i2c0";
-                                               groups = "i2c0_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               i2c0_sleep_mode: i2c_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO147_C15", "GPIO148_B16"; /* SDA/SCL */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       i2c1 {
-                               i2c1_default_mode: i2c_default {
-                                       default_mux {
-                                               function = "i2c1";
-                                               groups = "i2c1_b_2";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               i2c1_sleep_mode: i2c_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO16_AD3", "GPIO17_AD4"; /* SDA/SCL */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       i2c2 {
-                               i2c2_default_mode: i2c_default {
-                                       default_mux {
-                                               function = "i2c2";
-                                               groups = "i2c2_b_2";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               i2c2_sleep_mode: i2c_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO10_AF5", "GPIO11_AG4"; /* SDA/SCL */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       i2c3 {
-                               i2c3_default_mode: i2c_default {
-                                       default_mux {
-                                               function = "i2c3";
-                                               groups = "i2c3_c_2";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               i2c3_sleep_mode: i2c_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO229_AG7", "GPIO230_AF7"; /* SDA/SCL */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       /*
-                        * Activating I2C4 will conflict with UART1 about the same pins so do not
-                        * enable I2C4 and UART1 at the same time.
-                        */
-                       i2c4 {
-                               i2c4_default_mode: i2c_default {
-                                       default_mux {
-                                               function = "i2c4";
-                                               groups = "i2c4_b_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               i2c4_sleep_mode: i2c_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO4_AH6", "GPIO5_AG6"; /* SDA/SCL */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-                               };
-                       };
-
                        /* Settings for all SPI default and sleep states */
                        spi2 {
                                spi2_default_mode: spi_default {
                                };
                        };
 
-                       /* Settings for all MMC/SD/SDIO default and sleep states */
-                       sdi0 {
-                               /* This is the external SD card slot, 4 bits wide */
-                               sdi0_default_mode: sdi0_default {
-                                       default_mux {
-                                               function = "mc0";
-                                               groups = "mc0_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins =
-                                               "GPIO18_AC2", /* CMDDIR */
-                                               "GPIO19_AC1", /* DAT0DIR */
-                                               "GPIO20_AB4"; /* DAT2DIR */
-                                               ste,config = <&out_hi>;
-                                       };
-                                       default_cfg2 {
-                                               pins = "GPIO22_AA3"; /* FBCLK */
-                                               ste,config = <&in_nopull>;
-                                       };
-                                       default_cfg3 {
-                                               pins = "GPIO23_AA4"; /* CLK */
-                                               ste,config = <&out_lo>;
-                                       };
-                                       default_cfg4 {
-                                               pins =
-                                               "GPIO24_AB2", /* CMD */
-                                               "GPIO25_Y4", /* DAT0 */
-                                               "GPIO26_Y2", /* DAT1 */
-                                               "GPIO27_AA2", /* DAT2 */
-                                               "GPIO28_AA1"; /* DAT3 */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               sdi0_sleep_mode: sdi0_sleep {
-                                       sleep_cfg1 {
-                                               pins =
-                                               "GPIO18_AC2", /* CMDDIR */
-                                               "GPIO19_AC1", /* DAT0DIR */
-                                               "GPIO20_AB4"; /* DAT2DIR */
-                                               ste,config = <&slpm_out_hi_wkup_pdis>;
-                                       };
-                                       sleep_cfg2 {
-                                               pins =
-                                               "GPIO22_AA3", /* FBCLK */
-                                               "GPIO24_AB2", /* CMD */
-                                               "GPIO25_Y4", /* DAT0 */
-                                               "GPIO26_Y2", /* DAT1 */
-                                               "GPIO27_AA2", /* DAT2 */
-                                               "GPIO28_AA1"; /* DAT3 */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-                                       sleep_cfg3 {
-                                               pins = "GPIO23_AA4"; /* CLK */
-                                               ste,config = <&slpm_out_lo_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       sdi1 {
-                               /* This is the WLAN SDIO 4 bits wide */
-                               sdi1_default_mode: sdi1_default {
-                                       default_mux {
-                                               function = "mc1";
-                                               groups = "mc1_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO208_AH16"; /* CLK */
-                                               ste,config = <&out_lo>;
-                                       };
-                                       default_cfg2 {
-                                               pins = "GPIO209_AG15"; /* FBCLK */
-                                               ste,config = <&in_nopull>;
-                                       };
-                                       default_cfg3 {
-                                               pins =
-                                               "GPIO210_AJ15", /* CMD */
-                                               "GPIO211_AG14", /* DAT0 */
-                                               "GPIO212_AF13", /* DAT1 */
-                                               "GPIO213_AG13", /* DAT2 */
-                                               "GPIO214_AH15"; /* DAT3 */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               sdi1_sleep_mode: sdi1_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO208_AH16"; /* CLK */
-                                               ste,config = <&slpm_out_lo_wkup_pdis>;
-                                       };
-                                       sleep_cfg2 {
-                                               pins =
-                                               "GPIO209_AG15", /* FBCLK */
-                                               "GPIO210_AJ15", /* CMD */
-                                               "GPIO211_AG14", /* DAT0 */
-                                               "GPIO212_AF13", /* DAT1 */
-                                               "GPIO213_AG13", /* DAT2 */
-                                               "GPIO214_AH15"; /* DAT3 */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       sdi2 {
-                               /* This is the eMMC 8 bits wide, usually PoP eMMC */
-                               sdi2_default_mode: sdi2_default {
-                                       default_mux {
-                                               function = "mc2";
-                                               groups = "mc2_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO128_A5"; /* CLK */
-                                               ste,config = <&out_lo>;
-                                       };
-                                       default_cfg2 {
-                                               pins = "GPIO130_C8"; /* FBCLK */
-                                               ste,config = <&in_nopull>;
-                                       };
-                                       default_cfg3 {
-                                               pins =
-                                               "GPIO129_B4", /* CMD */
-                                               "GPIO131_A12", /* DAT0 */
-                                               "GPIO132_C10", /* DAT1 */
-                                               "GPIO133_B10", /* DAT2 */
-                                               "GPIO134_B9", /* DAT3 */
-                                               "GPIO135_A9", /* DAT4 */
-                                               "GPIO136_C7", /* DAT5 */
-                                               "GPIO137_A7", /* DAT6 */
-                                               "GPIO138_C5"; /* DAT7 */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               sdi2_sleep_mode: sdi2_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO128_A5"; /* CLK */
-                                               ste,config = <&out_lo_wkup_pdis>;
-                                       };
-                                       sleep_cfg2 {
-                                               pins =
-                                               "GPIO130_C8", /* FBCLK */
-                                               "GPIO129_B4"; /* CMD */
-                                               ste,config = <&in_wkup_pdis_en>;
-                                       };
-                                       sleep_cfg3 {
-                                               pins =
-                                               "GPIO131_A12", /* DAT0 */
-                                               "GPIO132_C10", /* DAT1 */
-                                               "GPIO133_B10", /* DAT2 */
-                                               "GPIO134_B9", /* DAT3 */
-                                               "GPIO135_A9", /* DAT4 */
-                                               "GPIO136_C7", /* DAT5 */
-                                               "GPIO137_A7", /* DAT6 */
-                                               "GPIO138_C5"; /* DAT7 */
-                                               ste,config = <&in_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       sdi4 {
-                               /* This is the eMMC 8 bits wide, usually PCB-mounted eMMC */
-                               sdi4_default_mode: sdi4_default {
-                                       default_mux {
-                                               function = "mc4";
-                                               groups = "mc4_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO203_AE23"; /* CLK */
-                                               ste,config = <&out_lo>;
-                                       };
-                                       default_cfg2 {
-                                               pins = "GPIO202_AF25"; /* FBCLK */
-                                               ste,config = <&in_nopull>;
-                                       };
-                                       default_cfg3 {
-                                               pins =
-                                               "GPIO201_AF24", /* CMD */
-                                               "GPIO200_AH26", /* DAT0 */
-                                               "GPIO199_AH23", /* DAT1 */
-                                               "GPIO198_AG25", /* DAT2 */
-                                               "GPIO197_AH24", /* DAT3 */
-                                               "GPIO207_AJ23", /* DAT4 */
-                                               "GPIO206_AG24", /* DAT5 */
-                                               "GPIO205_AG23", /* DAT6 */
-                                               "GPIO204_AF23"; /* DAT7 */
-                                               ste,config = <&in_pu>;
-                                       };
-                               };
-
-                               sdi4_sleep_mode: sdi4_sleep {
-                                       sleep_cfg1 {
-                                               pins = "GPIO203_AE23"; /* CLK */
-                                               ste,config = <&out_lo_wkup_pdis>;
-                                       };
-                                       sleep_cfg2 {
-                                               pins =
-                                               "GPIO202_AF25", /* FBCLK */
-                                               "GPIO201_AF24", /* CMD */
-                                               "GPIO200_AH26", /* DAT0 */
-                                               "GPIO199_AH23", /* DAT1 */
-                                               "GPIO198_AG25", /* DAT2 */
-                                               "GPIO197_AH24", /* DAT3 */
-                                               "GPIO207_AJ23", /* DAT4 */
-                                               "GPIO206_AG24", /* DAT5 */
-                                               "GPIO205_AG23", /* DAT6 */
-                                               "GPIO204_AF23"; /* DAT7 */
-                                               ste,config = <&slpm_in_wkup_pdis>;
-                                       };
-                               };
-                       };
-
-                       /*
-                        * Multi-rate serial ports (MSPs) - MSP3 output is internal and
-                        * cannot be muxed onto any pins.
-                        */
-                       msp0 {
-                               msp0_default_mode: msp0_default {
-                                       default_msp0_mux {
-                                               function = "msp0";
-                                               groups = "msp0txrx_a_1", "msp0tfstck_a_1";
-                                       };
-                                       default_msp0_cfg {
-                                               pins =
-                                               "GPIO12_AC4", /* TXD */
-                                               "GPIO15_AC3", /* RXD */
-                                               "GPIO13_AF3", /* TFS */
-                                               "GPIO14_AE3"; /* TCK */
-                                               ste,config = <&in_nopull>;
-                                       };
-                               };
-                       };
-
-                       msp1 {
-                               msp1_default_mode: msp1_default {
-                                       default_mux {
-                                               function = "msp1";
-                                               groups = "msp1txrx_a_1", "msp1_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins = "GPIO33_AF2";
-                                               ste,config = <&out_lo>;
-                                       };
-                                       default_cfg2 {
-                                               pins =
-                                               "GPIO34_AE1",
-                                               "GPIO35_AE2",
-                                               "GPIO36_AG2";
-                                               ste,config = <&in_nopull>;
-                                       };
-
-                               };
-                       };
-
-                       msp2 {
-                               msp2_default_mode: msp2_default {
-                                       /* MSP2 usually used for HDMI audio */
-                                       default_mux {
-                                               function = "msp2";
-                                               groups = "msp2_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins =
-                                               "GPIO193_AH27", /* TXD */
-                                               "GPIO194_AF27", /* TCK */
-                                               "GPIO195_AG28"; /* TFS */
-                                               ste,config = <&in_pd>;
-                                       };
-                                       default_cfg2 {
-                                               pins = "GPIO196_AG26"; /* RXD */
-                                               ste,config = <&out_lo>;
-                                       };
-                               };
-                       };
-
-
-                       musb {
-                               musb_default_mode: musb_default {
-                                       default_mux {
-                                               function = "usb";
-                                               groups = "usb_a_1";
-                                       };
-                                       default_cfg1 {
-                                               pins =
-                                               "GPIO256_AF28", /* NXT */
-                                               "GPIO258_AD29", /* XCLK */
-                                               "GPIO259_AC29", /* DIR */
-                                               "GPIO260_AD28", /* DAT7 */
-                                               "GPIO261_AD26", /* DAT6 */
-                                               "GPIO262_AE26", /* DAT5 */
-                                               "GPIO263_AG29", /* DAT4 */
-                                               "GPIO264_AE27", /* DAT3 */
-                                               "GPIO265_AD27", /* DAT2 */
-                                               "GPIO266_AC28", /* DAT1 */
-                                               "GPIO267_AC27"; /* DAT0 */
-                                               ste,config = <&in_nopull>;
-                                       };
-                                       default_cfg2 {
-                                               pins = "GPIO257_AE29"; /* STP */
-                                               ste,config = <&out_hi>;
-                                       };
-                               };
-
-                               musb_sleep_mode: musb_sleep {
-                                       sleep_cfg1 {
-                                               pins =
-                                               "GPIO256_AF28", /* NXT */
-                                               "GPIO258_AD29", /* XCLK */
-                                               "GPIO259_AC29"; /* DIR */
-                                               ste,config = <&slpm_wkup_pdis_en>;
-                                       };
-                                       sleep_cfg2 {
-                                               pins = "GPIO257_AE29"; /* STP */
-                                               ste,config = <&slpm_out_hi_wkup_pdis>;
-                                       };
-                                       sleep_cfg3 {
-                                               pins =
-                                               "GPIO260_AD28", /* DAT7 */
-                                               "GPIO261_AD26", /* DAT6 */
-                                               "GPIO262_AE26", /* DAT5 */
-                                               "GPIO263_AG29", /* DAT4 */
-                                               "GPIO264_AE27", /* DAT3 */
-                                               "GPIO265_AD27", /* DAT2 */
-                                               "GPIO266_AC28", /* DAT1 */
-                                               "GPIO267_AC27"; /* DAT0 */
-                                               ste,config = <&slpm_in_wkup_pdis_en>;
-                                       };
-                               };
-                       };
-
                        mcde {
                                lcd_default_mode: lcd_default {
                                        default_mux1 {
diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r2.dtsi
new file mode 100644 (file)
index 0000000..e024520
--- /dev/null
@@ -0,0 +1,79 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Device Tree for the TVK1281618 R2 UIB
+ */
+
+#include "ste-href-tvk1281618.dtsi"
+
+/ {
+       soc {
+               i2c@80128000 {
+                       lsm303dlh@18 {
+                               /* Accelerometer */
+                               compatible = "st,lsm303dlh-accel";
+                               st,drdy-int-pin = <1>;
+                               drive-open-drain;
+                               reg = <0x18>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&accel_tvk_mode>;
+                               /*
+                                * These interrupts cannot be used: the other component
+                                * ST-Micro L3D4200D gyro that is connected to the same lines
+                                * cannot set its DRDY line to open drain, so it cannot be
+                                * shared with other peripherals. The should be defined for
+                                * the falling edge if they could be wired together.
+                                *
+                                * interrupts-extended =
+                                * <&gpio1 0 IRQ_TYPE_EDGE_FALLING>,
+                                * <&gpio2 19 IRQ_TYPE_EDGE_FALLING>;
+                                */
+                       };
+                       lsm303dlh@1e {
+                               /* Magnetometer */
+                               compatible = "st,lsm303dlh-magn";
+                               reg = <0x1e>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
+                               /*
+                                * These interrupts cannot be used: the other component
+                                * ST-Micro L3D4200D gyro that is connected to the same lines
+                                * cannot set its DRDY line to open drain, so it cannot be
+                                * shared with other peripherals. The should be defined for
+                                * the falling edge if they could be wired together.
+                                *
+                                * interrupts-extended =
+                                * <&gpio1 0 IRQ_TYPE_EDGE_FALLING>,
+                                * <&gpio2 19 IRQ_TYPE_EDGE_FALLING>;
+                                */
+                       };
+                       lis331dl@1c {
+                               /* Accelerometer */
+                               compatible = "st,lis331dl-accel";
+                               st,drdy-int-pin = <1>;
+                               reg = <0x1c>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&accel_tvk_mode>;
+                               interrupt-parent = <&gpio2>;
+                               /* INT2 would need to be open drain */
+                               interrupts = <18 IRQ_TYPE_EDGE_RISING>,
+                                            <19 IRQ_TYPE_EDGE_RISING>;
+                       };
+               };
+               mcde@a0350000 {
+                       status = "okay";
+
+                       dsi@a0351000 {
+                               panel {
+                                       compatible = "samsung,s6d16d0";
+                                       reg = <0>;
+                                       vdd1-supply = <&ab8500_ldo_aux1_reg>;
+                                       reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+                               };
+                       };
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi b/arch/arm/boot/dts/ste-href-tvk1281618-r3.dtsi
new file mode 100644 (file)
index 0000000..cb3677f
--- /dev/null
@@ -0,0 +1,58 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Device Tree for the TVK1281618 R2 UIB
+ */
+
+#include "ste-href-tvk1281618.dtsi"
+
+/ {
+       soc {
+               i2c@80128000 {
+                       /* Marked:
+                        * 129
+                        * M35
+                        * L3GD20
+                        */
+                       l3gd20@6a {
+                               /* Gyroscope */
+                               compatible = "st,l3gd20";
+                               status = "disabled";
+                               st,drdy-int-pin = <1>;
+                               drive-open-drain;
+                               reg = <0x6a>; // 0x6a or 0x6b
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
+                       };
+                       /*
+                        * Marked:
+                        * 2122
+                        * C3H
+                        * DQEEE
+                        * LIS3DH?
+                        */
+                       lis3dh@18 {
+                               /* Accelerometer */
+                               compatible = "st,lis3dh-accel";
+                               st,drdy-int-pin = <1>;
+                               reg = <0x18>;
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&db8500_vsmps2_reg>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&accel_tvk_mode>;
+                       };
+               };
+
+               mcde@a0350000 {
+                       status = "okay";
+
+                       dsi@a0351000 {
+                               panel {
+                                       compatible = "sony,acx424akp";
+                                       reg = <0>;
+                                       vddi-supply = <&ab8500_ldo_aux1_reg>;
+                                       reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
+                               };
+                       };
+               };
+       };
+};
index 3bafd26..e1dbfae 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Copyright 2012 ST-Ericsson AB
  *
- * Device Tree for the TVK1281618 UIB
+ * Device Tree for the TVK1281618 family of UIBs
  */
 
 #include <dt-bindings/interrupt-controller/irq.h>
                                };
                        };
                };
-               /* Sensors mounted on this board variant */
+               /* Sensors mounted on all board variants */
                i2c@80128000 {
-                       lsm303dlh@18 {
-                               /* Accelerometer */
-                               compatible = "st,lsm303dlh-accel";
-                               st,drdy-int-pin = <1>;
-                               drive-open-drain;
-                               reg = <0x18>;
-                               vdd-supply = <&ab8500_ldo_aux1_reg>;
-                               vddio-supply = <&db8500_vsmps2_reg>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&accel_tvk_mode>;
-                               /*
-                                * These interrupts cannot be used: the other component
-                                * ST-Micro L3D4200D gyro that is connected to the same lines
-                                * cannot set its DRDY line to open drain, so it cannot be
-                                * shared with other peripherals. The should be defined for
-                                * the falling edge if they could be wired together.
-                                *
-                                * interrupts-extended =
-                                * <&gpio1 0 IRQ_TYPE_EDGE_FALLING>,
-                                * <&gpio2 19 IRQ_TYPE_EDGE_FALLING>;
-                                */
-                       };
-                       lsm303dlh@1e {
-                               /* Magnetometer */
-                               compatible = "st,lsm303dlh-magn";
-                               reg = <0x1e>;
-                               vdd-supply = <&ab8500_ldo_aux1_reg>;
-                               vddio-supply = <&db8500_vsmps2_reg>;
-                               /*
-                                * These interrupts cannot be used: the other component
-                                * ST-Micro L3D4200D gyro that is connected to the same lines
-                                * cannot set its DRDY line to open drain, so it cannot be
-                                * shared with other peripherals. The should be defined for
-                                * the falling edge if they could be wired together.
-                                *
-                                * interrupts-extended =
-                                * <&gpio1 0 IRQ_TYPE_EDGE_FALLING>,
-                                * <&gpio2 19 IRQ_TYPE_EDGE_FALLING>;
-                                */
-                       };
-                       lis331dl@1c {
-                               /* Accelerometer */
-                               compatible = "st,lis331dl-accel";
-                               st,drdy-int-pin = <1>;
-                               reg = <0x1c>;
-                               vdd-supply = <&ab8500_ldo_aux1_reg>;
-                               vddio-supply = <&db8500_vsmps2_reg>;
-                               pinctrl-names = "default";
-                               pinctrl-0 = <&accel_tvk_mode>;
-                               interrupt-parent = <&gpio2>;
-                               /* INT2 would need to be open drain */
-                               interrupts = <18 IRQ_TYPE_EDGE_RISING>,
-                                            <19 IRQ_TYPE_EDGE_RISING>;
-                       };
                        ak8974@f {
                                /* Magnetometer */
                                compatible = "asahi-kasei,ak8974";
                                };
                        };
                };
-
-               mcde@a0350000 {
-                       status = "okay";
-
-                       dsi@a0351000 {
-                               panel {
-                                       compatible = "samsung,s6d16d0";
-                                       reg = <0>;
-                                       vdd1-supply = <&ab8500_ldo_aux1_reg>;
-                                       reset-gpios = <&gpio2 1 GPIO_ACTIVE_LOW>;
-                               };
-                       };
-               };
        };
 };
index 4f6acbd..33e3b0b 100644 (file)
@@ -4,7 +4,6 @@
  */
 
 #include <dt-bindings/interrupt-controller/irq.h>
-#include "ste-dbx5x0.dtsi"
 #include "ste-href-family-pinctrl.dtsi"
 
 / {
        soc {
                uart@80120000 {
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&uart0_default_mode>;
-                       pinctrl-1 = <&uart0_sleep_mode>;
+                       pinctrl-0 = <&u0_a_1_default>;
+                       pinctrl-1 = <&u0_a_1_sleep>;
                        status = "okay";
                };
 
                /* This UART is unused and thus left disabled */
                uart@80121000 {
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&uart1_default_mode>;
-                       pinctrl-1 = <&uart1_sleep_mode>;
+                       pinctrl-0 = <&u1rxtx_a_1_default>;
+                       pinctrl-1 = <&u1rxtx_a_1_sleep>;
                };
 
                uart@80007000 {
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&uart2_default_mode>;
-                       pinctrl-1 = <&uart2_sleep_mode>;
+                       pinctrl-0 = <&u2rxtx_c_1_default>;
+                       pinctrl-1 = <&u2rxtx_c_1_sleep>;
                        status = "okay";
                };
 
                i2c@80004000 {
                        pinctrl-names = "default","sleep";
-                       pinctrl-0 = <&i2c0_default_mode>;
-                       pinctrl-1 = <&i2c0_sleep_mode>;
+                       pinctrl-0 = <&i2c0_a_1_default>;
+                       pinctrl-1 = <&i2c0_a_1_sleep>;
+                       status = "okay";
                };
 
                i2c@80122000 {
                        pinctrl-names = "default","sleep";
-                       pinctrl-0 = <&i2c1_default_mode>;
-                       pinctrl-1 = <&i2c1_sleep_mode>;
+                       pinctrl-0 = <&i2c1_b_2_default>;
+                       pinctrl-1 = <&i2c1_b_2_sleep>;
+                       status = "okay";
                };
 
                i2c@80128000 {
                        pinctrl-names = "default","sleep";
-                       pinctrl-0 = <&i2c2_default_mode>;
-                       pinctrl-1 = <&i2c2_sleep_mode>;
+                       pinctrl-0 = <&i2c2_b_2_default>;
+                       pinctrl-1 = <&i2c2_b_2_sleep>;
+                       status = "okay";
                        lp5521@33 {
                                compatible = "national,lp5521";
                                reg = <0x33>;
@@ -96,8 +98,9 @@
 
                i2c@80110000 {
                        pinctrl-names = "default","sleep";
-                       pinctrl-0 = <&i2c3_default_mode>;
-                       pinctrl-1 = <&i2c3_sleep_mode>;
+                       pinctrl-0 = <&i2c3_c_2_default>;
+                       pinctrl-1 = <&i2c3_c_2_sleep>;
+                       status = "okay";
                };
 
                /* ST6G3244ME level translator for 1.8/2.9 V */
                        vmmc-supply = <&ab8500_ldo_aux3_reg>;
                        vqmmc-supply = <&vmmci>;
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&sdi0_default_mode>;
-                       pinctrl-1 = <&sdi0_sleep_mode>;
+                       pinctrl-0 = <&mc0_a_1_default &sdi0_default_mode>;
+                       pinctrl-1 = <&mc0_a_1_sleep>;
 
                        status = "okay";
                };
                        bus-width = <4>;
                        non-removable;
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&sdi1_default_mode>;
-                       pinctrl-1 = <&sdi1_sleep_mode>;
+                       pinctrl-0 = <&mc1_a_1_default>;
+                       pinctrl-1 = <&mc1_a_1_sleep>;
 
                        status = "okay";
                };
                        non-removable;
                        vmmc-supply = <&db8500_vsmps2_reg>;
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&sdi2_default_mode>;
-                       pinctrl-1 = <&sdi2_sleep_mode>;
+                       pinctrl-0 = <&mc2_a_1_default>;
+                       pinctrl-1 = <&mc2_a_1_sleep>;
 
                        status = "okay";
                };
                        non-removable;
                        vmmc-supply = <&ab8500_ldo_aux2_reg>;
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&sdi4_default_mode>;
-                       pinctrl-1 = <&sdi4_sleep_mode>;
+                       pinctrl-0 = <&mc4_a_1_default>;
+                       pinctrl-1 = <&mc4_a_1_sleep>;
 
                        status = "okay";
                };
 
                msp0: msp@80123000 {
                        pinctrl-names = "default";
-                       pinctrl-0 = <&msp0_default_mode>;
+                       pinctrl-0 = <&msp0txrxtfstck_a_1_default>;
                        status = "okay";
                };
 
                msp1: msp@80124000 {
                        pinctrl-names = "default";
-                       pinctrl-0 = <&msp1_default_mode>;
+                       pinctrl-0 = <&msp1txrx_a_1_default>;
                        status = "okay";
                };
 
                msp2: msp@80117000 {
                        pinctrl-names = "default";
-                       pinctrl-0 = <&msp2_default_mode>;
+                       pinctrl-0 = <&msp2_a_1_default>;
                };
 
                msp3: msp@80125000 {
 
                                ab8500_usb {
                                        pinctrl-names = "default", "sleep";
-                                       pinctrl-0 = <&musb_default_mode>;
-                                       pinctrl-1 = <&musb_sleep_mode>;
+                                       pinctrl-0 = <&usb_a_1_default>;
+                                       pinctrl-1 = <&usb_a_1_sleep>;
                                };
 
                                ab8500-regulators {
                        };
                };
 
+               pinctrl {
+                       sdi0 {
+                               sdi0_default_mode: sdi0_default {
+                                       /* Some boards set additional settings here */
+                               };
+                       };
+               };
+
                mcde@a0350000 {
                        pinctrl-names = "default", "sleep";
                        pinctrl-0 = <&lcd_default_mode>;
diff --git a/arch/arm/boot/dts/ste-href520-tvk.dts b/arch/arm/boot/dts/ste-href520-tvk.dts
new file mode 100644 (file)
index 0000000..f8c0c1e
--- /dev/null
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Device Tree for the HREF520 version with the TVK1281618 UIB
+ */
+
+/dts-v1/;
+#include "ste-db8520.dtsi"
+#include "ste-hrefv60plus.dtsi"
+#include "ste-href-tvk1281618-r3.dtsi"
+
+/ {
+       model = "ST-Ericsson HREF520 and TVK1281618 UIB";
+       compatible = "st-ericsson,href520", "st-ericsson,u8500";
+
+       soc {
+               vmmci: regulator-gpio {
+                       gpios = <&gpio0 5 GPIO_ACTIVE_HIGH>;
+                       enable-gpio = <&gpio2 14 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+       };
+};
index b78be5f..8ce6b72 100644 (file)
@@ -4,8 +4,7 @@
  */
 
 /dts-v1/;
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/irq.h>
+#include "ste-db8500.dtsi"
 #include "ste-hrefprev60.dtsi"
 #include "ste-href-stuib.dtsi"
 
        model = "ST-Ericsson HREF (pre-v60) and ST UIB";
        compatible = "st-ericsson,mop500", "st-ericsson,u8500";
 
-       /* This stablilizes the serial port enumeration */
-       aliases {
-               serial0 = &ux500_serial0;
-               serial1 = &ux500_serial1;
-               serial2 = &ux500_serial2;
-       };
-
        soc {
                /* Reset line for the BU21013 touchscreen */
                i2c@80110000 {
index 60eed26..142f547 100644 (file)
@@ -4,17 +4,11 @@
  */
 
 /dts-v1/;
+#include "ste-db8500.dtsi"
 #include "ste-hrefprev60.dtsi"
-#include "ste-href-tvk1281618.dtsi"
+#include "ste-href-tvk1281618-r2.dtsi"
 
 / {
        model = "ST-Ericsson HREF (pre-v60) and TVK1281618 UIB";
        compatible = "st-ericsson,mop500", "st-ericsson,u8500";
-
-       /* This stablilizes the serial port enumeration */
-       aliases {
-               serial0 = &ux500_serial0;
-               serial1 = &ux500_serial1;
-               serial2 = &ux500_serial2;
-       };
 };
index a036def..115495d 100644 (file)
@@ -5,7 +5,6 @@
  * Device Tree for the HREF+ prior to the v60 variant.
  */
 
-#include "ste-dbx5x0.dtsi"
 #include "ste-href-ab8500.dtsi"
 #include "ste-href.dtsi"
 
@@ -58,6 +57,7 @@
                         */
                        pinctrl-names = "default";
                        pinctrl-0 = <&ssp0_hrefprev60_mode>;
+                       status = "okay";
                };
 
                // External Micro SD slot
index 9be513a..1316886 100644 (file)
@@ -6,8 +6,7 @@
  */
 
 /dts-v1/;
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/interrupt-controller/irq.h>
+#include "ste-db8500.dtsi"
 #include "ste-hrefv60plus.dtsi"
 #include "ste-href-stuib.dtsi"
 
        model = "ST-Ericsson HREF (v60+) and ST UIB";
        compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
 
-       /* This stablilizes the serial port enumeration */
-       aliases {
-               serial0 = &ux500_serial0;
-               serial1 = &ux500_serial1;
-               serial2 = &ux500_serial2;
-       };
-
        soc {
                /* Reset line for the BU21013 touchscreen */
                i2c@80110000 {
index 73ea310..5d4b824 100644 (file)
@@ -6,17 +6,11 @@
  */
 
 /dts-v1/;
+#include "ste-db8500.dtsi"
 #include "ste-hrefv60plus.dtsi"
-#include "ste-href-tvk1281618.dtsi"
+#include "ste-href-tvk1281618-r2.dtsi"
 
 / {
        model = "ST-Ericsson HREF (v60+) and TVK1281618 UIB";
        compatible = "st-ericsson,hrefv60+", "st-ericsson,u8500";
-
-       /* This stablilizes the serial port enumeration */
-       aliases {
-               serial0 = &ux500_serial0;
-               serial1 = &ux500_serial1;
-               serial2 = &ux500_serial2;
-       };
 };
index aece8eb..05b4fbb 100644 (file)
@@ -3,7 +3,6 @@
  * Copyright 2012 ST-Ericsson AB
  */
 
-#include "ste-dbx5x0.dtsi"
 #include "ste-href-ab8500.dtsi"
 #include "ste-href.dtsi"
 
index 5673a11..bfdb5d9 100644 (file)
                ste,output = <OUTPUT_LOW>;
        };
 
+       gpio_in_nopull: gpio_input_nopull {
+               ste,gpio = <GPIOMODE_ENABLED>;
+               ste,input = <INPUT_NOPULL>;
+       };
+
        gpio_in_pu: gpio_input_pull_up {
                ste,gpio = <GPIOMODE_ENABLED>;
                ste,input = <INPUT_PULLUP>;
index efbc446..be90e73 100644 (file)
@@ -4,7 +4,7 @@
  */
 
 /dts-v1/;
-#include "ste-dbx5x0.dtsi"
+#include "ste-db8500.dtsi"
 #include "ste-href-ab8500.dtsi"
 #include "ste-href-family-pinctrl.dtsi"
 
        model = "Calao Systems Snowball platform with device tree";
        compatible = "calaosystems,snowball-a9500", "st-ericsson,u9500";
 
-       /* This stablilizes the serial port enumeration */
-       aliases {
-               serial0 = &ux500_serial0;
-               serial1 = &ux500_serial1;
-               serial2 = &ux500_serial2;
-       };
-
        memory {
                device_type = "memory";
                reg = <0x00000000 0x20000000>;
 
                msp0: msp@80123000 {
                        pinctrl-names = "default";
-                       pinctrl-0 = <&msp0_default_mode>;
+                       pinctrl-0 = <&msp0txrxtfstck_a_1_default>;
                        status = "okay";
                };
 
                msp1: msp@80124000 {
                        pinctrl-names = "default";
-                       pinctrl-0 = <&msp1_default_mode>;
+                       pinctrl-0 = <&msp1txrx_a_1_default>;
                        status = "okay";
                };
 
                msp2: msp@80117000 {
                        pinctrl-names = "default";
-                       pinctrl-0 = <&msp2_default_mode>;
+                       pinctrl-0 = <&msp2_a_1_default>;
                };
 
                msp3: msp@80125000 {
                        vmmc-supply = <&ab8500_ldo_aux3_reg>;
                        vqmmc-supply = <&vmmci>;
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&sdi0_default_mode>;
-                       pinctrl-1 = <&sdi0_sleep_mode>;
+                       pinctrl-0 = <&mc0_a_1_default &sdi0_default_mode>;
+                       pinctrl-1 = <&mc0_a_1_sleep>;
 
                        /* GPIO218 MMC_CD */
                        cd-gpios  = <&gpio6 26 GPIO_ACTIVE_LOW>;
                        max-frequency = <100000000>;
                        bus-width = <4>;
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&sdi1_default_mode>;
-                       pinctrl-1 = <&sdi1_sleep_mode>;
+                       pinctrl-0 = <&mc1_a_1_default>;
+                       pinctrl-1 = <&mc1_a_1_sleep>;
 
                        status = "okay";
                };
                sdi2_per3@80005000 {
                        arm,primecell-periphid = <0x10480180>;
                        pinctrl-names = "default";
-                       pinctrl-0 = <&sdi2_sleep_mode>;
+                       pinctrl-0 = <&mc2_a_1_sleep>;
 
                        status = "okay";
                };
                        cap-mmc-highspeed;
                        vmmc-supply = <&ab8500_ldo_aux2_reg>;
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&sdi4_default_mode>;
-                       pinctrl-1 = <&sdi4_sleep_mode>;
+                       pinctrl-0 = <&mc4_a_1_default>;
+                       pinctrl-1 = <&mc4_a_1_sleep>;
 
                        status = "okay";
                };
 
                uart@80120000 {
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&uart0_default_mode>;
-                       pinctrl-1 = <&uart0_sleep_mode>;
+                       pinctrl-0 = <&u0_a_1_default>;
+                       pinctrl-1 = <&u0_a_1_sleep>;
                        status = "okay";
                };
 
                /* This UART is unused and thus left disabled */
                uart@80121000 {
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&uart1_default_mode>;
-                       pinctrl-1 = <&uart1_sleep_mode>;
+                       pinctrl-0 = <&u1rxtx_a_1_default>;
+                       pinctrl-1 = <&u1rxtx_a_1_sleep>;
                };
 
                uart@80007000 {
                        pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&uart2_default_mode>;
-                       pinctrl-1 = <&uart2_sleep_mode>;
+                       pinctrl-0 = <&u2rxtx_c_1_default>;
+                       pinctrl-1 = <&u2rxtx_c_1_sleep>;
                        status = "okay";
                };
 
                i2c@80004000 {
                        pinctrl-names = "default","sleep";
-                       pinctrl-0 = <&i2c0_default_mode>;
-                       pinctrl-1 = <&i2c0_sleep_mode>;
+                       pinctrl-0 = <&i2c0_a_1_default>;
+                       pinctrl-1 = <&i2c0_a_1_sleep>;
+                       status = "okay";
                };
 
                i2c@80122000 {
                        pinctrl-names = "default","sleep";
-                       pinctrl-0 = <&i2c1_default_mode>;
-                       pinctrl-1 = <&i2c1_sleep_mode>;
+                       pinctrl-0 = <&i2c1_b_2_default>;
+                       pinctrl-1 = <&i2c1_b_2_sleep>;
+                       status = "okay";
                };
 
                i2c@80128000 {
                        pinctrl-names = "default","sleep";
-                       pinctrl-0 = <&i2c2_default_mode>;
-                       pinctrl-1 = <&i2c2_sleep_mode>;
+                       pinctrl-0 = <&i2c2_b_2_default>;
+                       pinctrl-1 = <&i2c2_b_2_sleep>;
+                       status = "okay";
                        lsm303dlh@18 {
                                /* Accelerometer */
                                compatible = "st,lsm303dlh-accel";
 
                i2c@80110000 {
                        pinctrl-names = "default","sleep";
-                       pinctrl-0 = <&i2c3_default_mode>;
-                       pinctrl-1 = <&i2c3_sleep_mode>;
+                       pinctrl-0 = <&i2c3_c_2_default>;
+                       pinctrl-1 = <&i2c3_c_2_sleep>;
+                       status = "okay";
                };
 
                spi@80002000 {
                        pinctrl-names = "default";
                        pinctrl-0 = <&ssp0_snowball_mode>;
+                       status = "okay";
                };
 
                prcmu@80157000 {
-                       cpufreq {
-                               status = "okay";
-                       };
-
                        ab8500 {
                                ab8500-gpio {
                                        /*
 
                                ab8500_usb {
                                        pinctrl-names = "default", "sleep";
-                                       pinctrl-0 = <&musb_default_mode>;
-                                       pinctrl-1 = <&musb_sleep_mode>;
+                                       pinctrl-0 = <&usb_a_1_default>;
+                                       pinctrl-1 = <&usb_a_1_sleep>;
                                };
 
                                ext_regulators: ab8500-ext-regulators {
diff --git a/arch/arm/boot/dts/ste-ux500-samsung-golden.dts b/arch/arm/boot/dts/ste-ux500-samsung-golden.dts
new file mode 100644 (file)
index 0000000..313f0ab
--- /dev/null
@@ -0,0 +1,455 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/dts-v1/;
+
+#include "ste-db8500.dtsi"
+#include "ste-ab8505.dtsi"
+#include "ste-dbx5x0-pinctrl.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+
+/*
+ * Note: This device tree cannot be booted directly with the Samsung bootloader.
+ * You need an intermediate, device-tree compatible bootloader
+ * that locks the L2 cache. Otherwise the kernel will crash after decompression.
+ *
+ * There is a port of (mainline) U-Boot, see
+ * https://wiki.postmarketos.org/wiki/ST-Ericsson_NovaThor_U8500#U-Boot
+ */
+/ {
+       model = "Samsung Galaxy S III mini (GT-I8190)";
+       compatible = "samsung,golden", "st-ericsson,u8500";
+
+       chosen {
+               stdout-path = &serial2;
+       };
+
+       soc {
+               /* External Micro SD card slot */
+               sdi0_per1@80126000 {
+                       status = "okay";
+
+                       arm,primecell-periphid = <0x10480180>;
+                       max-frequency = <100000000>;
+                       bus-width = <4>;
+
+                       non-removable;
+                       /*
+                        * Unfortunately, there is no way to enable the UHS
+                        * modes due to a limitation of the SD level translator:
+                        * It will either translate to 2.9V or disconnect the
+                        * DATA lines, so switching to 1.8V signal voltage fails.
+                        */
+                       cap-sd-highspeed;
+                       cap-mmc-highspeed;
+                       st,sig-pin-fbclk;
+                       full-pwr-cycle;
+
+                       vmmc-supply = <&ab8500_ldo_aux3_reg>;
+                       vqmmc-supply = <&sd_level_translator>;
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&mc0_a_2_default>;
+                       pinctrl-1 = <&mc0_a_2_sleep>;
+               };
+
+               /* WLAN SDIO */
+               sdi1_per2@80118000 {
+                       status = "okay";
+
+                       arm,primecell-periphid = <0x10480180>;
+                       max-frequency = <50000000>;
+                       bus-width = <4>;
+
+                       non-removable;
+                       cap-sd-highspeed;
+
+                       vmmc-supply = <&wl_reg_on>;
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&mc1_a_2_default>;
+                       pinctrl-1 = <&mc1_a_2_sleep>;
+
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       wifi@1 {
+                               compatible = "brcm,bcm4329-fmac";
+                               reg = <1>;
+
+                               /* GPIO216 (WLAN_HOST_WAKE) */
+                               interrupt-parent = <&gpio6>;
+                               interrupts = <24 IRQ_TYPE_EDGE_FALLING>;
+                               interrupt-names = "host-wake";
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&wlan_default>;
+                       };
+               };
+
+               /* eMMC */
+               sdi2_per3@80005000 {
+                       status = "okay";
+
+                       arm,primecell-periphid = <0x10480180>;
+                       max-frequency = <100000000>;
+                       bus-width = <8>;
+
+                       non-removable;
+                       cap-mmc-highspeed;
+                       mmc-ddr-1_8v;
+
+                       vmmc-supply = <&vmem_3v3>;
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&mc2_a_1_default>;
+                       pinctrl-1 = <&mc2_a_1_sleep>;
+               };
+
+               /* BT UART */
+               uart@80120000 {
+                       status = "okay";
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&u0_a_1_default>;
+                       pinctrl-1 = <&u0_a_1_sleep>;
+
+                       bluetooth {
+                               compatible = "brcm,bcm4330-bt";
+                               /* GPIO222 (BT_VREG_ON) */
+                               shutdown-gpios = <&gpio6 30 GPIO_ACTIVE_HIGH>;
+                               /* GPIO199 (BT_WAKE) */
+                               device-wakeup-gpios = <&gpio6 7 GPIO_ACTIVE_HIGH>;
+                               /* GPIO97 (BT_HOST_WAKE) */
+                               host-wakeup-gpios = <&gpio3 1 GPIO_ACTIVE_HIGH>;
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&bluetooth_default>;
+                       };
+               };
+
+               /* GPF UART */
+               uart@80121000 {
+                       status = "okay";
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&u1rxtx_a_1_default &u1ctsrts_a_1_default>;
+                       pinctrl-1 = <&u1rxtx_a_1_sleep &u1ctsrts_a_1_sleep>;
+               };
+
+               /* Debugging console UART */
+               uart@80007000 {
+                       status = "okay";
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&u2rxtx_c_1_default>;
+                       pinctrl-1 = <&u2rxtx_c_1_sleep>;
+               };
+
+               i2c@80128000 {
+                       status = "okay";
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&i2c2_b_2_default>;
+                       pinctrl-1 = <&i2c2_b_2_sleep>;
+
+                       imu@68 {
+                               compatible = "invensense,mpu6050";
+                               reg = <0x68>;
+
+                               /* GPIO206 (ACC_INT) */
+                               interrupt-parent = <&gpio6>;
+                               interrupts = <14 IRQ_TYPE_EDGE_RISING>;
+
+                               mount-matrix = "0", "1", "0",
+                                             "-1", "0", "0",
+                                              "0", "0", "1";
+
+                               vdd-supply = <&ab8500_ldo_aux1_reg>;
+                               vddio-supply = <&ab8500_ldo_aux8_reg>;
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&imu_default>;
+                       };
+               };
+
+               i2c@80110000 {
+                       status = "okay";
+
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&i2c3_c_2_default>;
+                       pinctrl-1 = <&i2c3_c_2_sleep>;
+
+                       touchscreen@4a {
+                               compatible = "atmel,maxtouch";
+                               reg = <0x4a>;
+
+                               /* GPIO218 (TSP_INT_1V8) */
+                               interrupt-parent = <&gpio6>;
+                               interrupts = <26 IRQ_TYPE_EDGE_FALLING>;
+
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&tsp_default>;
+                       };
+               };
+
+               prcmu@80157000 {
+                       ab8505 {
+                               ab8500_usb {
+                                       pinctrl-names = "default", "sleep";
+                                       pinctrl-0 = <&usb_a_1_default>;
+                                       pinctrl-1 = <&usb_a_1_sleep>;
+                               };
+
+                               ab8505-regulators {
+                                       ab8500_ldo_aux1 {
+                                               regulator-name = "sensor_3v";
+                                               regulator-min-microvolt = <3000000>;
+                                               regulator-max-microvolt = <3000000>;
+                                       };
+
+                                       ab8500_ldo_aux2 {
+                                               regulator-name = "vreg_tsp_a3v3";
+                                               regulator-min-microvolt = <3300000>;
+                                               regulator-max-microvolt = <3300000>;
+                                               regulator-always-on; /* FIXME */
+                                       };
+
+                                       ab8500_ldo_aux3 {
+                                               regulator-name = "vdd_tf_2v91";
+                                       };
+
+                                       ab8500_ldo_aux4 {
+                                               regulator-name = "key_led_3.3v";
+                                               regulator-min-microvolt = <3300000>;
+                                               regulator-max-microvolt = <3300000>;
+                                       };
+
+                                       ab8500_ldo_aux5 {
+                                               regulator-name = "vreg_tsp_1v8";
+                                               regulator-min-microvolt = <1800000>;
+                                               regulator-max-microvolt = <1800000>;
+                                               regulator-always-on; /* FIXME */
+                                       };
+
+                                       ab8500_ldo_aux6 {
+                                               regulator-name = "touch_key_2.2v";
+                                               regulator-min-microvolt = <2200000>;
+                                               regulator-max-microvolt = <2200000>;
+                                       };
+
+                                       ab8500_ldo_aux8 {
+                                               regulator-name = "sensor_1v8";
+                                       };
+                               };
+                       };
+               };
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&gpio_keys_default>;
+
+               label = "GPIO Buttons";
+
+               volume-up {
+                       label = "Volume Up";
+                       /* GPIO67 (VOL_UP) */
+                       gpios = <&gpio2 3 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEUP>;
+               };
+
+               volume-down {
+                       label = "Volume Down";
+                       /* GPIO92 (VOL_DOWN) */
+                       gpios = <&gpio2 28 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_VOLUMEDOWN>;
+               };
+
+               home {
+                       label = "Home";
+                       /* GPIO91 (HOME_KEY) */
+                       gpios = <&gpio2 27 GPIO_ACTIVE_LOW>;
+                       linux,code = <KEY_HOMEPAGE>;
+               };
+       };
+
+       vibrator {
+               compatible = "gpio-vibrator";
+               /* GPIO195 (MOT_EN) */
+               enable-gpios = <&gpio6 3 GPIO_ACTIVE_HIGH>;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&vibrator_default>;
+       };
+
+       /* External LDO for eMMC */
+       vmem_3v3: regulator-vmem {
+               compatible = "regulator-fixed";
+
+               regulator-name = "vmem_3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+
+               startup-delay-us = <200>;
+
+               /* GPIO223 (MEM_LDO_EN) */
+               gpio = <&gpio6 31 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&mem_ldo_default>;
+       };
+
+       /* TI TXS0206-29 level translator for 2.9 V */
+       sd_level_translator: regulator-sd-level-translator {
+               compatible = "regulator-fixed";
+
+               regulator-name = "sd-level-translator";
+               regulator-min-microvolt = <2900000>;
+               regulator-max-microvolt = <2900000>;
+
+               startup-delay-us = <200>;
+
+               /* GPIO87 (TXS0206-29_EN) */
+               gpios = <&gpio2 23 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&sd_level_translator_default>;
+       };
+
+       /*
+        * WL_REG_ON takes WLAN out of reset and enables the internal regulators.
+        * The voltage specified here is only used to determine the OCR mask,
+        * the BCM chip is actually connected directly to VBAT.
+        */
+       wl_reg_on: regulator-wl-reg-on {
+               compatible = "regulator-fixed";
+
+               regulator-name = "wl-reg-on";
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+
+               startup-delay-us = <100000>;
+
+               /* GPIO215 (WLAN_EN) */
+               gpio = <&gpio6 23 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_en_default>;
+       };
+};
+
+&pinctrl {
+       gpio-keys {
+               gpio_keys_default: gpio_keys_default {
+                       golden_cfg1 {
+                               pins = "GPIO67",        /* VOL_UP */
+                                      "GPIO91",        /* HOME_KEY */
+                                      "GPIO92";        /* VOL_DOWN */
+                               ste,config = <&gpio_in_pu>;
+                       };
+               };
+       };
+
+       sdi0 {
+               sd_level_translator_default: sd_level_translator_default {
+                       golden_cfg1 {
+                               pins = "GPIO87_B3";     /* TXS0206-29_EN */
+                               ste,config = <&gpio_out_lo>;
+                       };
+               };
+       };
+
+       sdi2 {
+               mem_ldo_default: mem_ldo_default {
+                       golden_cfg1 {
+                               pins = "GPIO223_AH9";   /* MEM_LDO_EN */
+                               ste,config = <&gpio_out_hi>;
+                       };
+               };
+       };
+
+       imu {
+               imu_default: imu_default {
+                       golden_cfg1 {
+                               pins = "GPIO206_AG24";  /* ACC_INT */
+                               ste,config = <&gpio_in_pd>;
+                       };
+               };
+       };
+
+       tsp {
+               tsp_default: tsp_default {
+                       golden_cfg1 {
+                               pins = "GPIO218_AH11";  /* TSP_INT_1V8 */
+                               ste,config = <&gpio_in_nopull>;
+                       };
+               };
+       };
+
+       wlan {
+               wlan_default: wlan_default {
+                       golden_cfg1 {
+                               pins = "GPIO216_AG12";  /* WLAN_HOST_WAKE */
+                               ste,config = <&gpio_in_pd>;
+                       };
+               };
+
+               wlan_en_default: wlan_en_default {
+                       golden_cfg1 {
+                               pins = "GPIO215_AH13";  /* WLAN_EN */
+                               ste,config = <&gpio_out_lo>;
+                       };
+               };
+       };
+
+       bluetooth {
+               bluetooth_default: bluetooth_default {
+                       golden_cfg1 {
+                               pins = "GPIO199_AH23",  /* BT_WAKE */
+                                      "GPIO222_AJ9";   /* BT_VREG_ON */
+                               ste,config = <&gpio_out_lo>;
+                       };
+                       golden_cfg2 {
+                               pins = "GPIO97_D9";     /* BT_HOST_WAKE */
+                               ste,config = <&gpio_in_nopull>;
+                       };
+               };
+       };
+
+       vibrator {
+               vibrator_default: vibrator_default {
+                       golden_cfg1 {
+                               pins = "GPIO195_AG28";  /* MOT_EN */
+                               ste,config = <&gpio_out_lo>;
+                       };
+               };
+       };
+};
+
+&ab8505_gpio {
+       /* Hog a few default settings */
+       pinctrl-names = "default";
+       pinctrl-0 = <&gpio_default>;
+
+       gpio {
+               gpio_default: gpio_default {
+                       golden_mux {
+                               /* Change unused pins to GPIO mode */
+                               function = "gpio";
+                               groups = "gpio3_a_1",   /* default: SysClkReq4 */
+                                        "gpio14_a_1";  /* default: PWMOut1 */
+                       };
+                       golden_cfg1 {
+                               pins = "GPIO11_B17", "GPIO13_D17", "GPIO50_L4";
+                               bias-disable;
+                       };
+               };
+       };
+};
index 58288aa..c27fa35 100644 (file)
                regulator-max-microvolt = <3300000>;
        };
 
+       vdd_panel: vdd-panel {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_panel";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
        leds {
                compatible = "gpio-leds";
                green {
 
        panel_rgb: panel-rgb {
                compatible = "ampire,am-480272h3tmqw-t01h";
+               power-supply = <&vdd_panel>;
                status = "okay";
                port {
                        panel_in_rgb: endpoint {
index 3520289..392fa14 100644 (file)
                                st,bank-name = "GPIOK";
                        };
 
-                       usart1_pins_a: usart1@0 {
+                       usart1_pins_a: usart1-0 {
                                pins1 {
                                        pinmux = <STM32_PINMUX('A', 9, AF7)>; /* USART1_TX */
                                        bias-disable;
                                };
                        };
 
-                       usart3_pins_a: usart3@0 {
+                       usart3_pins_a: usart3-0 {
                                pins1 {
                                        pinmux = <STM32_PINMUX('B', 10, AF7)>; /* USART3_TX */
                                        bias-disable;
                                };
                        };
 
-                       usbotg_fs_pins_a: usbotg_fs@0 {
+                       usbotg_fs_pins_a: usbotg-fs-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('A', 10, AF10)>, /* OTG_FS_ID */
                                                 <STM32_PINMUX('A', 11, AF10)>, /* OTG_FS_DM */
                                };
                        };
 
-                       usbotg_fs_pins_b: usbotg_fs@1 {
+                       usbotg_fs_pins_b: usbotg-fs-1 {
                                pins {
                                        pinmux = <STM32_PINMUX('B', 12, AF12)>, /* OTG_HS_ID */
                                                 <STM32_PINMUX('B', 14, AF12)>, /* OTG_HS_DM */
                                };
                        };
 
-                       usbotg_hs_pins_a: usbotg_hs@0 {
+                       usbotg_hs_pins_a: usbotg-hs-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('H', 4, AF10)>, /* OTG_HS_ULPI_NXT*/
                                                 <STM32_PINMUX('I', 11, AF10)>, /* OTG_HS_ULPI_DIR */
                                };
                        };
 
-                       ethernet_mii: mii@0 {
+                       ethernet_mii: mii-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('G', 13, AF11)>, /* ETH_MII_TXD0_ETH_RMII_TXD0 */
                                                 <STM32_PINMUX('G', 14, AF11)>, /* ETH_MII_TXD1_ETH_RMII_TXD1 */
                                };
                        };
 
-                       adc3_in8_pin: adc@200 {
+                       adc3_in8_pin: adc-200 {
                                pins {
                                        pinmux = <STM32_PINMUX('F', 10, ANALOG)>;
                                };
                        };
 
-                       pwm1_pins: pwm@1 {
+                       pwm1_pins: pwm-1 {
                                pins {
                                        pinmux = <STM32_PINMUX('A', 8, AF1)>, /* TIM1_CH1 */
                                                 <STM32_PINMUX('B', 13, AF1)>, /* TIM1_CH1N */
                                };
                        };
 
-                       pwm3_pins: pwm@3 {
+                       pwm3_pins: pwm-3 {
                                pins {
                                        pinmux = <STM32_PINMUX('B', 4, AF2)>, /* TIM3_CH1 */
                                                 <STM32_PINMUX('B', 5, AF2)>; /* TIM3_CH2 */
                                };
                        };
 
-                       i2c1_pins: i2c1@0 {
+                       i2c1_pins: i2c1-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('B', 9, AF4)>, /* I2C1_SDA */
                                                 <STM32_PINMUX('B', 6, AF4)>; /* I2C1_SCL */
                                };
                        };
 
-                       ltdc_pins: ltdc@0 {
+                       ltdc_pins: ltdc-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('I', 12, AF14)>, /* LCD_HSYNC */
                                                 <STM32_PINMUX('I', 13, AF14)>, /* LCD_VSYNC */
                                };
                        };
 
-                       dcmi_pins: dcmi@0 {
+                       dcmi_pins: dcmi-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('A', 4, AF13)>, /* DCMI_HSYNC */
                                                 <STM32_PINMUX('B', 7, AF13)>, /* DCMI_VSYNC */
                                };
                        };
 
-                       sdio_pins: sdio_pins@0 {
+                       sdio_pins: sdio-pins-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDIO_D0 */
                                                 <STM32_PINMUX('C', 9, AF12)>, /* SDIO_D1 */
                                };
                        };
 
-                       sdio_pins_od: sdio_pins_od@0 {
+                       sdio_pins_od: sdio-pins-od-0 {
                                pins1 {
                                        pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDIO_D0 */
                                                 <STM32_PINMUX('C', 9, AF12)>, /* SDIO_D1 */
index 5c8a826..d777069 100644 (file)
@@ -80,7 +80,7 @@
        };
 
        soc {
-               romem: nvmem@1fff7800 {
+               romem: efuse@1fff7800 {
                        compatible = "st,stm32f4-otp";
                        reg = <0x1fff7800 0x400>;
                        #address-cells = <1>;
                        compatible = "st,stm32-rtc";
                        reg = <0x40002800 0x400>;
                        clocks = <&rcc 1 CLK_RTC>;
-                       clock-names = "ck_rtc";
                        assigned-clocks = <&rcc 1 CLK_RTC>;
                        assigned-clock-parents = <&rcc 1 CLK_LSE>;
                        interrupt-parent = <&exti>;
                rng: rng@50060800 {
                        compatible = "st,stm32-rng";
                        reg = <0x50060800 0x400>;
-                       interrupts = <80>;
                        clocks = <&rcc 0 STM32F4_AHB2_CLOCK(RNG)>;
 
                };
index f3ce477..9397db0 100644 (file)
                regulator-max-microvolt = <3300000>;
        };
 
+       vdd_dsi: vdd-dsi {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd_dsi";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+       };
+
        soc {
                dma-ranges = <0xc0000000 0x0 0x10000000>;
        };
                compatible = "orisetech,otm8009a";
                reg = <0>; /* dsi virtual channel (0..3) */
                reset-gpios = <&gpioh 7 GPIO_ACTIVE_LOW>;
+               power-supply = <&vdd_dsi>;
                status = "okay";
 
                port {
index 9314128..fe4cfda 100644 (file)
                                st,bank-name = "GPIOK";
                        };
 
-                       cec_pins_a: cec@0 {
+                       cec_pins_a: cec-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('A', 15, AF4)>; /* HDMI CEC */
                                        slew-rate = <0>;
                                };
                        };
 
-                       usart1_pins_a: usart1@0 {
+                       usart1_pins_a: usart1-0 {
                                pins1 {
                                        pinmux = <STM32_PINMUX('A', 9, AF7)>; /* USART1_TX */
                                        bias-disable;
                                };
                        };
 
-                       usart1_pins_b: usart1@1 {
+                       usart1_pins_b: usart1-1 {
                                pins1 {
                                        pinmux = <STM32_PINMUX('A', 9, AF7)>; /* USART1_TX */
                                        bias-disable;
                                };
                        };
 
-                       i2c1_pins_b: i2c1@0 {
+                       i2c1_pins_b: i2c1-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('B', 9, AF4)>, /* I2C1 SDA */
                                                 <STM32_PINMUX('B', 8, AF4)>; /* I2C1 SCL */
                                };
                        };
 
-                       usbotg_hs_pins_a: usbotg-hs@0 {
+                       usbotg_hs_pins_a: usbotg-hs-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('H', 4, AF10)>, /* OTG_HS_ULPI_NXT */
                                                 <STM32_PINMUX('I', 11, AF10)>, /* OTG_HS_ULPI_DIR */
                                };
                        };
 
-                       usbotg_hs_pins_b: usbotg-hs@1 {
+                       usbotg_hs_pins_b: usbotg-hs-1 {
                                pins {
                                        pinmux = <STM32_PINMUX('H', 4, AF10)>, /* OTG_HS_ULPI_NXT */
                                                 <STM32_PINMUX('C', 2, AF10)>, /* OTG_HS_ULPI_DIR */
                                };
                        };
 
-                       usbotg_fs_pins_a: usbotg-fs@0 {
+                       usbotg_fs_pins_a: usbotg-fs-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('A', 10, AF10)>, /* OTG_FS_ID */
                                                 <STM32_PINMUX('A', 11, AF10)>, /* OTG_FS_DM */
                                };
                        };
 
-                       sdio_pins_a: sdio_pins_a@0 {
+                       sdio_pins_a: sdio-pins-a-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1 D0 */
                                                 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1 D1 */
                                };
                        };
 
-                       sdio_pins_od_a: sdio_pins_od_a@0 {
+                       sdio_pins_od_a: sdio-pins-od-a-0 {
                                pins1 {
                                        pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1 D0 */
                                                 <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1 D1 */
                                };
                        };
 
-                       sdio_pins_b: sdio_pins_b@0 {
+                       sdio_pins_b: sdio-pins-b-0 {
                                pins {
                                        pinmux = <STM32_PINMUX('G', 9, AF11)>, /* SDMMC2 D0 */
                                                 <STM32_PINMUX('G', 10, AF11)>, /* SDMMC2 D1 */
                                };
                        };
 
-                       sdio_pins_od_b: sdio_pins_od_b@0 {
+                       sdio_pins_od_b: sdio-pins-od-b-0 {
                                pins1 {
                                        pinmux = <STM32_PINMUX('G', 9, AF11)>, /* SDMMC2 D0 */
                                                 <STM32_PINMUX('G', 10, AF11)>, /* SDMMC2 D1 */
index d26f93f..93c0637 100644 (file)
                        compatible = "st,stm32-rtc";
                        reg = <0x40002800 0x400>;
                        clocks = <&rcc 1 CLK_RTC>;
-                       clock-names = "ck_rtc";
                        assigned-clocks = <&rcc 1 CLK_RTC>;
                        assigned-clock-parents = <&rcc 1 CLK_LSE>;
                        interrupt-parent = <&exti>;
                        assigned-clock-rates = <1000000>;
                };
 
-               dma1: dma@40026000 {
+               dma1: dma-controller@40026000 {
                        compatible = "st,stm32-dma";
                        reg = <0x40026000 0x400>;
                        interrupts = <11>,
                        status = "disabled";
                };
 
-               dma2: dma@40026400 {
+               dma2: dma-controller@40026400 {
                        compatible = "st,stm32-dma";
                        reg = <0x40026400 0x400>;
                        interrupts = <56>,
index c065266..05eb02e 100644 (file)
                        status = "disabled";
                };
 
-               dma1: dma@40020000 {
+               dma1: dma-controller@40020000 {
                        compatible = "st,stm32-dma";
                        reg = <0x40020000 0x400>;
                        interrupts = <11>,
                        status = "disabled";
                };
 
-               dma2: dma@40020400 {
+               dma2: dma-controller@40020400 {
                        compatible = "st,stm32-dma";
                        reg = <0x40020400 0x400>;
                        interrupts = <56>,
                        status = "disabled";
                };
 
-               mdma1: dma@52000000 {
+               mdma1: dma-controller@52000000 {
                        compatible = "st,stm32h7-mdma";
                        reg = <0x52000000 0x1000>;
                        interrupts = <122>;
diff --git a/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..0237d4d
--- /dev/null
@@ -0,0 +1,1092 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
+ * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
+ */
+#include <dt-bindings/pinctrl/stm32-pinfunc.h>
+
+&pinctrl {
+       adc1_in6_pins_a: adc1-in6 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 12, ANALOG)>;
+               };
+       };
+
+       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)>;
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       cec_pins_sleep_a: cec-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('A', 15, ANALOG)>; /* HDMI_CEC */
+               };
+       };
+
+       cec_pins_b: cec-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('B', 6, AF5)>;
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       cec_pins_sleep_b: cec-sleep-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('B', 6, ANALOG)>; /* HDMI_CEC */
+               };
+       };
+
+       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 */
+                                <STM32_PINMUX('B', 7,  AF13)>,/* DCMI_VSYNC */
+                                <STM32_PINMUX('A', 6,  AF13)>,/* DCMI_PIXCLK */
+                                <STM32_PINMUX('H', 9,  AF13)>,/* DCMI_D0 */
+                                <STM32_PINMUX('H', 10, AF13)>,/* DCMI_D1 */
+                                <STM32_PINMUX('H', 11, AF13)>,/* DCMI_D2 */
+                                <STM32_PINMUX('H', 12, AF13)>,/* DCMI_D3 */
+                                <STM32_PINMUX('H', 14, AF13)>,/* DCMI_D4 */
+                                <STM32_PINMUX('I', 4,  AF13)>,/* DCMI_D5 */
+                                <STM32_PINMUX('B', 8,  AF13)>,/* DCMI_D6 */
+                                <STM32_PINMUX('E', 6,  AF13)>,/* DCMI_D7 */
+                                <STM32_PINMUX('I', 1,  AF13)>,/* DCMI_D8 */
+                                <STM32_PINMUX('H', 7,  AF13)>,/* DCMI_D9 */
+                                <STM32_PINMUX('I', 3,  AF13)>,/* DCMI_D10 */
+                                <STM32_PINMUX('H', 15, AF13)>;/* DCMI_D11 */
+                       bias-disable;
+               };
+       };
+
+       dcmi_sleep_pins_a: dcmi-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 8,  ANALOG)>,/* DCMI_HSYNC */
+                                <STM32_PINMUX('B', 7,  ANALOG)>,/* DCMI_VSYNC */
+                                <STM32_PINMUX('A', 6,  ANALOG)>,/* DCMI_PIXCLK */
+                                <STM32_PINMUX('H', 9,  ANALOG)>,/* DCMI_D0 */
+                                <STM32_PINMUX('H', 10, ANALOG)>,/* DCMI_D1 */
+                                <STM32_PINMUX('H', 11, ANALOG)>,/* DCMI_D2 */
+                                <STM32_PINMUX('H', 12, ANALOG)>,/* DCMI_D3 */
+                                <STM32_PINMUX('H', 14, ANALOG)>,/* DCMI_D4 */
+                                <STM32_PINMUX('I', 4,  ANALOG)>,/* DCMI_D5 */
+                                <STM32_PINMUX('B', 8,  ANALOG)>,/* DCMI_D6 */
+                                <STM32_PINMUX('E', 6,  ANALOG)>,/* DCMI_D7 */
+                                <STM32_PINMUX('I', 1,  ANALOG)>,/* DCMI_D8 */
+                                <STM32_PINMUX('H', 7,  ANALOG)>,/* DCMI_D9 */
+                                <STM32_PINMUX('I', 3,  ANALOG)>,/* DCMI_D10 */
+                                <STM32_PINMUX('H', 15, ANALOG)>;/* DCMI_D11 */
+               };
+       };
+
+       ethernet0_rgmii_pins_a: rgmii-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
+                                <STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */
+                                <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
+                                <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
+                                <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
+                                <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
+                                <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
+                                <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <2>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('A', 2, AF11)>; /* ETH_MDIO */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+               pins3 {
+                       pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
+                                <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
+                                <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
+                                <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
+                                <STM32_PINMUX('A', 1, AF11)>, /* ETH_RGMII_RX_CLK */
+                                <STM32_PINMUX('A', 7, AF11)>; /* ETH_RGMII_RX_CTL */
+                       bias-disable;
+               };
+       };
+
+       ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
+                                <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */
+                                <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */
+                                <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */
+                                <STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */
+                                <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_TXD3 */
+                                <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */
+                                <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
+                                <STM32_PINMUX('C', 1, ANALOG)>, /* ETH_MDC */
+                                <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
+                                <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */
+                                <STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD2 */
+                                <STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD3 */
+                                <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */
+                                <STM32_PINMUX('A', 7, ANALOG)>; /* ETH_RGMII_RX_CTL */
+               };
+       };
+
+       fmc_pins_a: fmc-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
+                                <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
+                                <STM32_PINMUX('D', 11, AF12)>, /* FMC_A16_FMC_CLE */
+                                <STM32_PINMUX('D', 12, AF12)>, /* FMC_A17_FMC_ALE */
+                                <STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */
+                                <STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */
+                                <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */
+                                <STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */
+                                <STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */
+                                <STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */
+                                <STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */
+                                <STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */
+                                <STM32_PINMUX('G', 9, AF12)>; /* FMC_NE2_FMC_NCE */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <1>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('D', 6, AF12)>; /* FMC_NWAIT */
+                       bias-pull-up;
+               };
+       };
+
+       fmc_sleep_pins_a: fmc-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */
+                                <STM32_PINMUX('D', 5, ANALOG)>, /* FMC_NWE */
+                                <STM32_PINMUX('D', 11, ANALOG)>, /* FMC_A16_FMC_CLE */
+                                <STM32_PINMUX('D', 12, ANALOG)>, /* FMC_A17_FMC_ALE */
+                                <STM32_PINMUX('D', 14, ANALOG)>, /* FMC_D0 */
+                                <STM32_PINMUX('D', 15, ANALOG)>, /* FMC_D1 */
+                                <STM32_PINMUX('D', 0, ANALOG)>, /* FMC_D2 */
+                                <STM32_PINMUX('D', 1, ANALOG)>, /* FMC_D3 */
+                                <STM32_PINMUX('E', 7, ANALOG)>, /* FMC_D4 */
+                                <STM32_PINMUX('E', 8, ANALOG)>, /* FMC_D5 */
+                                <STM32_PINMUX('E', 9, ANALOG)>, /* FMC_D6 */
+                                <STM32_PINMUX('E', 10, ANALOG)>, /* FMC_D7 */
+                                <STM32_PINMUX('D', 6, ANALOG)>, /* FMC_NWAIT */
+                                <STM32_PINMUX('G', 9, ANALOG)>; /* FMC_NE2_FMC_NCE */
+               };
+       };
+
+       i2c1_pins_a: i2c1-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
+                                <STM32_PINMUX('F', 15, AF5)>; /* I2C1_SDA */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c1_pins_sleep_a: i2c1-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('D', 12, ANALOG)>, /* I2C1_SCL */
+                                <STM32_PINMUX('F', 15, ANALOG)>; /* I2C1_SDA */
+               };
+       };
+
+       i2c1_pins_b: i2c1-2 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 14, AF5)>, /* I2C1_SCL */
+                                <STM32_PINMUX('F', 15, AF5)>; /* I2C1_SDA */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c1_pins_sleep_b: i2c1-3 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 14, ANALOG)>, /* I2C1_SCL */
+                                <STM32_PINMUX('F', 15, ANALOG)>; /* I2C1_SDA */
+               };
+       };
+
+       i2c2_pins_a: i2c2-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */
+                                <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c2_pins_sleep_a: i2c2-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 4, ANALOG)>, /* I2C2_SCL */
+                                <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
+               };
+       };
+
+       i2c2_pins_b1: i2c2-2 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c2_pins_sleep_b1: i2c2-3 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
+               };
+       };
+
+       i2c5_pins_a: i2c5-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('A', 11, AF4)>, /* I2C5_SCL */
+                                <STM32_PINMUX('A', 12, AF4)>; /* I2C5_SDA */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c5_pins_sleep_a: i2c5-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* I2C5_SCL */
+                                <STM32_PINMUX('A', 12, ANALOG)>; /* I2C5_SDA */
+
+               };
+       };
+
+       i2s2_pins_a: i2s2-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('I', 3, AF5)>, /* I2S2_SDO */
+                                <STM32_PINMUX('B', 9, AF5)>, /* I2S2_WS */
+                                <STM32_PINMUX('A', 9, AF5)>; /* I2S2_CK */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+       };
+
+       i2s2_pins_sleep_a: i2s2-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('I', 3, ANALOG)>, /* I2S2_SDO */
+                                <STM32_PINMUX('B', 9, ANALOG)>, /* I2S2_WS */
+                                <STM32_PINMUX('A', 9, ANALOG)>; /* I2S2_CK */
+               };
+       };
+
+       ltdc_pins_a: ltdc-a-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('G',  7, AF14)>, /* LCD_CLK */
+                                <STM32_PINMUX('I', 10, AF14)>, /* LCD_HSYNC */
+                                <STM32_PINMUX('I',  9, AF14)>, /* LCD_VSYNC */
+                                <STM32_PINMUX('F', 10, AF14)>, /* LCD_DE */
+                                <STM32_PINMUX('H',  2, AF14)>, /* LCD_R0 */
+                                <STM32_PINMUX('H',  3, AF14)>, /* LCD_R1 */
+                                <STM32_PINMUX('H',  8, AF14)>, /* LCD_R2 */
+                                <STM32_PINMUX('H',  9, AF14)>, /* LCD_R3 */
+                                <STM32_PINMUX('H', 10, AF14)>, /* LCD_R4 */
+                                <STM32_PINMUX('C',  0, AF14)>, /* LCD_R5 */
+                                <STM32_PINMUX('H', 12, AF14)>, /* LCD_R6 */
+                                <STM32_PINMUX('E', 15, AF14)>, /* LCD_R7 */
+                                <STM32_PINMUX('E',  5, AF14)>, /* LCD_G0 */
+                                <STM32_PINMUX('E',  6, AF14)>, /* LCD_G1 */
+                                <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
+                                <STM32_PINMUX('H', 14, AF14)>, /* LCD_G3 */
+                                <STM32_PINMUX('H', 15, AF14)>, /* LCD_G4 */
+                                <STM32_PINMUX('I',  0, AF14)>, /* LCD_G5 */
+                                <STM32_PINMUX('I',  1, AF14)>, /* LCD_G6 */
+                                <STM32_PINMUX('I',  2, AF14)>, /* LCD_G7 */
+                                <STM32_PINMUX('D',  9, AF14)>, /* LCD_B0 */
+                                <STM32_PINMUX('G', 12, AF14)>, /* LCD_B1 */
+                                <STM32_PINMUX('G', 10, AF14)>, /* LCD_B2 */
+                                <STM32_PINMUX('D', 10, AF14)>, /* LCD_B3 */
+                                <STM32_PINMUX('I',  4, AF14)>, /* LCD_B4 */
+                                <STM32_PINMUX('A',  3, AF14)>, /* LCD_B5 */
+                                <STM32_PINMUX('B',  8, AF14)>, /* LCD_B6 */
+                                <STM32_PINMUX('D',  8, AF14)>; /* LCD_B7 */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <1>;
+               };
+       };
+
+       ltdc_pins_sleep_a: ltdc-a-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('G',  7, ANALOG)>, /* LCD_CLK */
+                                <STM32_PINMUX('I', 10, ANALOG)>, /* LCD_HSYNC */
+                                <STM32_PINMUX('I',  9, ANALOG)>, /* LCD_VSYNC */
+                                <STM32_PINMUX('F', 10, ANALOG)>, /* LCD_DE */
+                                <STM32_PINMUX('H',  2, ANALOG)>, /* LCD_R0 */
+                                <STM32_PINMUX('H',  3, ANALOG)>, /* LCD_R1 */
+                                <STM32_PINMUX('H',  8, ANALOG)>, /* LCD_R2 */
+                                <STM32_PINMUX('H',  9, ANALOG)>, /* LCD_R3 */
+                                <STM32_PINMUX('H', 10, ANALOG)>, /* LCD_R4 */
+                                <STM32_PINMUX('C',  0, ANALOG)>, /* LCD_R5 */
+                                <STM32_PINMUX('H', 12, ANALOG)>, /* LCD_R6 */
+                                <STM32_PINMUX('E', 15, ANALOG)>, /* LCD_R7 */
+                                <STM32_PINMUX('E',  5, ANALOG)>, /* LCD_G0 */
+                                <STM32_PINMUX('E',  6, ANALOG)>, /* LCD_G1 */
+                                <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
+                                <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_G3 */
+                                <STM32_PINMUX('H', 15, ANALOG)>, /* LCD_G4 */
+                                <STM32_PINMUX('I',  0, ANALOG)>, /* LCD_G5 */
+                                <STM32_PINMUX('I',  1, ANALOG)>, /* LCD_G6 */
+                                <STM32_PINMUX('I',  2, ANALOG)>, /* LCD_G7 */
+                                <STM32_PINMUX('D',  9, ANALOG)>, /* LCD_B0 */
+                                <STM32_PINMUX('G', 12, ANALOG)>, /* LCD_B1 */
+                                <STM32_PINMUX('G', 10, ANALOG)>, /* LCD_B2 */
+                                <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B3 */
+                                <STM32_PINMUX('I',  4, ANALOG)>, /* LCD_B4 */
+                                <STM32_PINMUX('A',  3, ANALOG)>, /* LCD_B5 */
+                                <STM32_PINMUX('B',  8, ANALOG)>, /* LCD_B6 */
+                                <STM32_PINMUX('D',  8, ANALOG)>; /* LCD_B7 */
+               };
+       };
+
+       ltdc_pins_b: ltdc-b-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('I', 14, AF14)>, /* LCD_CLK */
+                                <STM32_PINMUX('I', 12, AF14)>, /* LCD_HSYNC */
+                                <STM32_PINMUX('I', 13, AF14)>, /* LCD_VSYNC */
+                                <STM32_PINMUX('K',  7, AF14)>, /* LCD_DE */
+                                <STM32_PINMUX('I', 15, AF14)>, /* LCD_R0 */
+                                <STM32_PINMUX('J',  0, AF14)>, /* LCD_R1 */
+                                <STM32_PINMUX('J',  1, AF14)>, /* LCD_R2 */
+                                <STM32_PINMUX('J',  2, AF14)>, /* LCD_R3 */
+                                <STM32_PINMUX('J',  3, AF14)>, /* LCD_R4 */
+                                <STM32_PINMUX('J',  4, AF14)>, /* LCD_R5 */
+                                <STM32_PINMUX('J',  5, AF14)>, /* LCD_R6 */
+                                <STM32_PINMUX('J',  6, AF14)>, /* LCD_R7 */
+                                <STM32_PINMUX('J',  7, AF14)>, /* LCD_G0 */
+                                <STM32_PINMUX('J',  8, AF14)>, /* LCD_G1 */
+                                <STM32_PINMUX('J',  9, AF14)>, /* LCD_G2 */
+                                <STM32_PINMUX('J', 10, AF14)>, /* LCD_G3 */
+                                <STM32_PINMUX('J', 11, AF14)>, /* LCD_G4 */
+                                <STM32_PINMUX('K',  0, AF14)>, /* LCD_G5 */
+                                <STM32_PINMUX('K',  1, AF14)>, /* LCD_G6 */
+                                <STM32_PINMUX('K',  2, AF14)>, /* LCD_G7 */
+                                <STM32_PINMUX('J', 12, AF14)>, /* LCD_B0 */
+                                <STM32_PINMUX('J', 13, AF14)>, /* LCD_B1 */
+                                <STM32_PINMUX('J', 14, AF14)>, /* LCD_B2 */
+                                <STM32_PINMUX('J', 15, AF14)>, /* LCD_B3 */
+                                <STM32_PINMUX('K',  3, AF14)>, /* LCD_B4 */
+                                <STM32_PINMUX('K',  4, AF14)>, /* LCD_B5 */
+                                <STM32_PINMUX('K',  5, AF14)>, /* LCD_B6 */
+                                <STM32_PINMUX('K',  6, AF14)>; /* LCD_B7 */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <1>;
+               };
+       };
+
+       ltdc_pins_sleep_b: ltdc-b-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('I', 14, ANALOG)>, /* LCD_CLK */
+                                <STM32_PINMUX('I', 12, ANALOG)>, /* LCD_HSYNC */
+                                <STM32_PINMUX('I', 13, ANALOG)>, /* LCD_VSYNC */
+                                <STM32_PINMUX('K',  7, ANALOG)>, /* LCD_DE */
+                                <STM32_PINMUX('I', 15, ANALOG)>, /* LCD_R0 */
+                                <STM32_PINMUX('J',  0, ANALOG)>, /* LCD_R1 */
+                                <STM32_PINMUX('J',  1, ANALOG)>, /* LCD_R2 */
+                                <STM32_PINMUX('J',  2, ANALOG)>, /* LCD_R3 */
+                                <STM32_PINMUX('J',  3, ANALOG)>, /* LCD_R4 */
+                                <STM32_PINMUX('J',  4, ANALOG)>, /* LCD_R5 */
+                                <STM32_PINMUX('J',  5, ANALOG)>, /* LCD_R6 */
+                                <STM32_PINMUX('J',  6, ANALOG)>, /* LCD_R7 */
+                                <STM32_PINMUX('J',  7, ANALOG)>, /* LCD_G0 */
+                                <STM32_PINMUX('J',  8, ANALOG)>, /* LCD_G1 */
+                                <STM32_PINMUX('J',  9, ANALOG)>, /* LCD_G2 */
+                                <STM32_PINMUX('J', 10, ANALOG)>, /* LCD_G3 */
+                                <STM32_PINMUX('J', 11, ANALOG)>, /* LCD_G4 */
+                                <STM32_PINMUX('K',  0, ANALOG)>, /* LCD_G5 */
+                                <STM32_PINMUX('K',  1, ANALOG)>, /* LCD_G6 */
+                                <STM32_PINMUX('K',  2, ANALOG)>, /* LCD_G7 */
+                                <STM32_PINMUX('J', 12, ANALOG)>, /* LCD_B0 */
+                                <STM32_PINMUX('J', 13, ANALOG)>, /* LCD_B1 */
+                                <STM32_PINMUX('J', 14, ANALOG)>, /* LCD_B2 */
+                                <STM32_PINMUX('J', 15, ANALOG)>, /* LCD_B3 */
+                                <STM32_PINMUX('K',  3, ANALOG)>, /* LCD_B4 */
+                                <STM32_PINMUX('K',  4, ANALOG)>, /* LCD_B5 */
+                                <STM32_PINMUX('K',  5, ANALOG)>, /* LCD_B6 */
+                                <STM32_PINMUX('K',  6, ANALOG)>; /* LCD_B7 */
+               };
+       };
+
+       m_can1_pins_a: m-can1-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('I', 9, AF9)>; /* CAN1_RX */
+                       bias-disable;
+               };
+       };
+
+       m_can1_sleep_pins_a: m_can1-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* CAN1_TX */
+                                <STM32_PINMUX('I', 9, ANALOG)>; /* CAN1_RX */
+               };
+       };
+
+       pwm1_pins_a: pwm1-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('E', 9, AF1)>, /* TIM1_CH1 */
+                                <STM32_PINMUX('E', 11, AF1)>, /* TIM1_CH2 */
+                                <STM32_PINMUX('E', 14, AF1)>; /* TIM1_CH4 */
+                       bias-pull-down;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       pwm1_sleep_pins_a: pwm1-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('E', 9, ANALOG)>, /* TIM1_CH1 */
+                                <STM32_PINMUX('E', 11, ANALOG)>, /* TIM1_CH2 */
+                                <STM32_PINMUX('E', 14, ANALOG)>; /* TIM1_CH4 */
+               };
+       };
+
+       pwm2_pins_a: pwm2-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
+                       bias-pull-down;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       pwm2_sleep_pins_a: pwm2-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('A', 3, ANALOG)>; /* TIM2_CH4 */
+               };
+       };
+
+       pwm3_pins_a: pwm3-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('C', 7, AF2)>; /* TIM3_CH2 */
+                       bias-pull-down;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       pwm3_sleep_pins_a: pwm3-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('C', 7, ANALOG)>; /* TIM3_CH2 */
+               };
+       };
+
+       pwm4_pins_a: pwm4-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('D', 14, AF2)>, /* TIM4_CH3 */
+                                <STM32_PINMUX('D', 15, AF2)>; /* TIM4_CH4 */
+                       bias-pull-down;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       pwm4_sleep_pins_a: pwm4-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('D', 14, ANALOG)>, /* TIM4_CH3 */
+                                <STM32_PINMUX('D', 15, ANALOG)>; /* TIM4_CH4 */
+               };
+       };
+
+       pwm4_pins_b: pwm4-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('D', 13, AF2)>; /* TIM4_CH2 */
+                       bias-pull-down;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       pwm4_sleep_pins_b: pwm4-sleep-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('D', 13, ANALOG)>; /* TIM4_CH2 */
+               };
+       };
+
+       pwm5_pins_a: pwm5-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 11, AF2)>; /* TIM5_CH2 */
+                       bias-pull-down;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       pwm5_sleep_pins_a: pwm5-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 11, ANALOG)>; /* TIM5_CH2 */
+               };
+       };
+
+       pwm8_pins_a: pwm8-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('I', 2, AF3)>; /* TIM8_CH4 */
+                       bias-pull-down;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       pwm8_sleep_pins_a: pwm8-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('I', 2, ANALOG)>; /* TIM8_CH4 */
+               };
+       };
+
+       pwm12_pins_a: pwm12-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 6, AF2)>; /* TIM12_CH1 */
+                       bias-pull-down;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+       };
+
+       pwm12_sleep_pins_a: pwm12-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 6, ANALOG)>; /* TIM12_CH1 */
+               };
+       };
+
+       qspi_clk_pins_a: qspi-clk-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <3>;
+               };
+       };
+
+       qspi_clk_sleep_pins_a: qspi-clk-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 10, ANALOG)>; /* QSPI_CLK */
+               };
+       };
+
+       qspi_bk1_pins_a: qspi-bk1-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
+                                <STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
+                                <STM32_PINMUX('F', 7, AF9)>, /* QSPI_BK1_IO2 */
+                                <STM32_PINMUX('F', 6, AF9)>; /* QSPI_BK1_IO3 */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <1>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
+                       bias-pull-up;
+                       drive-push-pull;
+                       slew-rate = <1>;
+               };
+       };
+
+       qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 8, ANALOG)>, /* QSPI_BK1_IO0 */
+                                <STM32_PINMUX('F', 9, ANALOG)>, /* QSPI_BK1_IO1 */
+                                <STM32_PINMUX('F', 7, ANALOG)>, /* QSPI_BK1_IO2 */
+                                <STM32_PINMUX('F', 6, ANALOG)>, /* QSPI_BK1_IO3 */
+                                <STM32_PINMUX('B', 6, ANALOG)>; /* QSPI_BK1_NCS */
+               };
+       };
+
+       qspi_bk2_pins_a: qspi-bk2-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
+                                <STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
+                                <STM32_PINMUX('G', 10, AF11)>, /* QSPI_BK2_IO2 */
+                                <STM32_PINMUX('G', 7, AF11)>; /* QSPI_BK2_IO3 */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <1>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
+                       bias-pull-up;
+                       drive-push-pull;
+                       slew-rate = <1>;
+               };
+       };
+
+       qspi_bk2_sleep_pins_a: qspi-bk2-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* QSPI_BK2_IO0 */
+                                <STM32_PINMUX('H', 3, ANALOG)>, /* QSPI_BK2_IO1 */
+                                <STM32_PINMUX('G', 10, ANALOG)>, /* QSPI_BK2_IO2 */
+                                <STM32_PINMUX('G', 7, ANALOG)>, /* QSPI_BK2_IO3 */
+                                <STM32_PINMUX('C', 0, ANALOG)>; /* QSPI_BK2_NCS */
+               };
+       };
+
+       sai2a_pins_a: sai2a-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('I', 5, AF10)>, /* SAI2_SCK_A */
+                                <STM32_PINMUX('I', 6, AF10)>, /* SAI2_SD_A */
+                                <STM32_PINMUX('I', 7, AF10)>, /* SAI2_FS_A */
+                                <STM32_PINMUX('E', 0, AF10)>; /* SAI2_MCLK_A */
+                       slew-rate = <0>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+       };
+
+       sai2a_sleep_pins_a: sai2a-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('I', 5, ANALOG)>, /* SAI2_SCK_A */
+                                <STM32_PINMUX('I', 6, ANALOG)>, /* SAI2_SD_A */
+                                <STM32_PINMUX('I', 7, ANALOG)>, /* SAI2_FS_A */
+                                <STM32_PINMUX('E', 0, ANALOG)>; /* SAI2_MCLK_A */
+               };
+       };
+
+       sai2b_pins_a: sai2b-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('E', 12, AF10)>, /* SAI2_SCK_B */
+                                <STM32_PINMUX('E', 13, AF10)>, /* SAI2_FS_B */
+                                <STM32_PINMUX('E', 14, AF10)>; /* SAI2_MCLK_B */
+                       slew-rate = <0>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
+                       bias-disable;
+               };
+       };
+
+       sai2b_sleep_pins_a: sai2b-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 11, ANALOG)>, /* SAI2_SD_B */
+                                <STM32_PINMUX('E', 12, ANALOG)>, /* SAI2_SCK_B */
+                                <STM32_PINMUX('E', 13, ANALOG)>, /* SAI2_FS_B */
+                                <STM32_PINMUX('E', 14, ANALOG)>; /* SAI2_MCLK_B */
+               };
+       };
+
+       sai2b_pins_b: sai2b-2 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
+                       bias-disable;
+               };
+       };
+
+       sai2b_sleep_pins_b: sai2b-3 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 11, ANALOG)>; /* SAI2_SD_B */
+               };
+       };
+
+       sai4a_pins_a: sai4a-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('B', 5, AF10)>; /* SAI4_SD_A */
+                       slew-rate = <0>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+       };
+
+       sai4a_sleep_pins_a: sai4a-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('B', 5, ANALOG)>; /* SAI4_SD_A */
+               };
+       };
+
+       sdmmc1_b4_pins_a: sdmmc1-b4-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
+                                <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
+                                <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
+                                <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
+                                <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+                       slew-rate = <2>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+       };
+
+       sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
+                                <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
+                                <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
+                                <STM32_PINMUX('C', 11, AF12)>; /* SDMMC1_D3 */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
+                       slew-rate = <2>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+               pins3 {
+                       pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
+                       slew-rate = <1>;
+                       drive-open-drain;
+                       bias-disable;
+               };
+       };
+
+       sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
+                                <STM32_PINMUX('C', 9, ANALOG)>, /* SDMMC1_D1 */
+                                <STM32_PINMUX('C', 10, ANALOG)>, /* SDMMC1_D2 */
+                                <STM32_PINMUX('C', 11, ANALOG)>, /* SDMMC1_D3 */
+                                <STM32_PINMUX('C', 12, ANALOG)>, /* SDMMC1_CK */
+                                <STM32_PINMUX('D', 2, ANALOG)>; /* SDMMC1_CMD */
+               };
+       };
+
+       sdmmc1_dir_pins_a: sdmmc1-dir-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
+                                <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
+                                <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+               pins2{
+                       pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
+                       bias-pull-up;
+               };
+       };
+
+       sdmmc1_dir_sleep_pins_a: sdmmc1-dir-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 2, ANALOG)>, /* SDMMC1_D0DIR */
+                                <STM32_PINMUX('C', 7, ANALOG)>, /* SDMMC1_D123DIR */
+                                <STM32_PINMUX('B', 9, ANALOG)>, /* SDMMC1_CDIR */
+                                <STM32_PINMUX('E', 4, ANALOG)>; /* SDMMC1_CKIN */
+               };
+       };
+
+       sdmmc2_b4_pins_a: sdmmc2-b4-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+                                <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+                                <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+                                <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
+                                <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+                       slew-rate = <2>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+       };
+
+       sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+                                <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+                                <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+                                <STM32_PINMUX('B', 4, AF9)>; /* SDMMC2_D3 */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+                       slew-rate = <2>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+               pins3 {
+                       pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+                       slew-rate = <1>;
+                       drive-open-drain;
+                       bias-pull-up;
+               };
+       };
+
+       sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC2_D0 */
+                                <STM32_PINMUX('B', 15, ANALOG)>, /* SDMMC2_D1 */
+                                <STM32_PINMUX('B', 3, ANALOG)>, /* SDMMC2_D2 */
+                                <STM32_PINMUX('B', 4, ANALOG)>, /* SDMMC2_D3 */
+                                <STM32_PINMUX('E', 3, ANALOG)>, /* SDMMC2_CK */
+                                <STM32_PINMUX('G', 6, ANALOG)>; /* SDMMC2_CMD */
+               };
+       };
+
+       sdmmc2_b4_pins_b: sdmmc2-b4-1 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+                                <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+                                <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+                                <STM32_PINMUX('B', 4, AF9)>, /* SDMMC2_D3 */
+                                <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+                       slew-rate = <2>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+       };
+
+       sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('B', 14, AF9)>, /* SDMMC2_D0 */
+                                <STM32_PINMUX('B', 15, AF9)>, /* SDMMC2_D1 */
+                                <STM32_PINMUX('B', 3, AF9)>, /* SDMMC2_D2 */
+                                <STM32_PINMUX('B', 4, AF9)>; /* SDMMC2_D3 */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('E', 3, AF9)>; /* SDMMC2_CK */
+                       slew-rate = <2>;
+                       drive-push-pull;
+                       bias-disable;
+               };
+               pins3 {
+                       pinmux = <STM32_PINMUX('G', 6, AF10)>; /* SDMMC2_CMD */
+                       slew-rate = <1>;
+                       drive-open-drain;
+                       bias-disable;
+               };
+       };
+
+       sdmmc2_d47_pins_a: sdmmc2-d47-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('A', 8, AF9)>, /* SDMMC2_D4 */
+                                <STM32_PINMUX('A', 9, AF10)>, /* SDMMC2_D5 */
+                                <STM32_PINMUX('E', 5, AF9)>, /* SDMMC2_D6 */
+                                <STM32_PINMUX('D', 3, AF9)>; /* SDMMC2_D7 */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+       };
+
+       sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('A', 8, ANALOG)>, /* SDMMC2_D4 */
+                                <STM32_PINMUX('A', 9, ANALOG)>, /* SDMMC2_D5 */
+                                <STM32_PINMUX('E', 5, ANALOG)>, /* SDMMC2_D6 */
+                                <STM32_PINMUX('D', 3, ANALOG)>; /* SDMMC2_D7 */
+               };
+       };
+
+       sdmmc3_b4_pins_a: sdmmc3-b4-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
+                                <STM32_PINMUX('F', 4, AF9)>, /* SDMMC3_D1 */
+                                <STM32_PINMUX('F', 5, AF9)>, /* SDMMC3_D2 */
+                                <STM32_PINMUX('D', 7, AF10)>, /* SDMMC3_D3 */
+                                <STM32_PINMUX('F', 1, AF9)>; /* SDMMC3_CMD */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('G', 15, AF10)>; /* SDMMC3_CK */
+                       slew-rate = <2>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+       };
+
+       sdmmc3_b4_od_pins_a: sdmmc3-b4-od-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('F', 0, AF9)>, /* SDMMC3_D0 */
+                                <STM32_PINMUX('F', 4, AF9)>, /* SDMMC3_D1 */
+                                <STM32_PINMUX('F', 5, AF9)>, /* SDMMC3_D2 */
+                                <STM32_PINMUX('D', 7, AF10)>; /* SDMMC3_D3 */
+                       slew-rate = <1>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('G', 15, AF10)>; /* SDMMC3_CK */
+                       slew-rate = <2>;
+                       drive-push-pull;
+                       bias-pull-up;
+               };
+               pins3 {
+                       pinmux = <STM32_PINMUX('F', 1, AF9)>; /* SDMMC2_CMD */
+                       slew-rate = <1>;
+                       drive-open-drain;
+                       bias-pull-up;
+               };
+       };
+
+       sdmmc3_b4_sleep_pins_a: sdmmc3-b4-sleep-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('F', 0, ANALOG)>, /* SDMMC3_D0 */
+                                <STM32_PINMUX('F', 4, ANALOG)>, /* SDMMC3_D1 */
+                                <STM32_PINMUX('F', 5, ANALOG)>, /* SDMMC3_D2 */
+                                <STM32_PINMUX('D', 7, ANALOG)>, /* SDMMC3_D3 */
+                                <STM32_PINMUX('G', 15, ANALOG)>, /* SDMMC3_CK */
+                                <STM32_PINMUX('F', 1, ANALOG)>; /* SDMMC3_CMD */
+               };
+       };
+
+       spdifrx_pins_a: spdifrx-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('G', 12, AF8)>; /* SPDIF_IN1 */
+                       bias-disable;
+               };
+       };
+
+       spdifrx_sleep_pins_a: spdifrx-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('G', 12, ANALOG)>; /* SPDIF_IN1 */
+               };
+       };
+
+       uart4_pins_a: uart4-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+                       bias-disable;
+               };
+       };
+
+       uart4_pins_b: uart4-1 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
+                       bias-disable;
+               };
+       };
+
+       uart7_pins_a: uart7-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART4_TX */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <0>;
+               };
+               pins2 {
+                       pinmux = <STM32_PINMUX('E', 7, AF7)>, /* UART4_RX */
+                                <STM32_PINMUX('E', 10, AF7)>, /* UART4_CTS */
+                                <STM32_PINMUX('E', 9, AF7)>; /* UART4_RTS */
+                       bias-disable;
+               };
+       };
+};
+
+&pinctrl_z {
+       i2c2_pins_b2: i2c2-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('Z', 0, AF3)>; /* I2C2_SCL */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c2_pins_sleep_b2: i2c2-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('Z', 0, ANALOG)>; /* I2C2_SCL */
+               };
+       };
+
+       i2c4_pins_a: i2c4-0 {
+               pins {
+                       pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
+                                <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
+                       bias-disable;
+                       drive-open-drain;
+                       slew-rate = <0>;
+               };
+       };
+
+       i2c4_pins_sleep_a: i2c4-1 {
+               pins {
+                       pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C4_SCL */
+                                <STM32_PINMUX('Z', 5, ANALOG)>; /* I2C4_SDA */
+               };
+       };
+
+       spi1_pins_a: spi1-0 {
+               pins1 {
+                       pinmux = <STM32_PINMUX('Z', 0, AF5)>, /* SPI1_SCK */
+                                <STM32_PINMUX('Z', 2, AF5)>; /* SPI1_MOSI */
+                       bias-disable;
+                       drive-push-pull;
+                       slew-rate = <1>;
+               };
+
+               pins2 {
+                       pinmux = <STM32_PINMUX('Z', 1, AF5)>; /* SPI1_MISO */
+                       bias-disable;
+               };
+       };
+};
similarity index 87%
rename from arch/arm/boot/dts/stm32mp157c.dtsi
rename to arch/arm/boot/dts/stm32mp151.dtsi
index ed8b258..fb41d07 100644 (file)
                        device_type = "cpu";
                        reg = <0>;
                };
-
-               cpu1: cpu@1 {
-                       compatible = "arm,cortex-a7";
-                       device_type = "cpu";
-                       reg = <1>;
-               };
        };
 
        psci {
                                reg = <1>;
                                status = "disabled";
                        };
+
+                       counter {
+                               compatible = "st,stm32-timer-counter";
+                               status = "disabled";
+                       };
                };
 
                timers3: timer@40001000 {
                                reg = <2>;
                                status = "disabled";
                        };
+
+                       counter {
+                               compatible = "st,stm32-timer-counter";
+                               status = "disabled";
+                       };
                };
 
                timers4: timer@40002000 {
                                reg = <3>;
                                status = "disabled";
                        };
+
+                       counter {
+                               compatible = "st,stm32-timer-counter";
+                               status = "disabled";
+                       };
                };
 
                timers5: timer@40003000 {
                                reg = <4>;
                                status = "disabled";
                        };
+
+                       counter {
+                               compatible = "st,stm32-timer-counter";
+                               status = "disabled";
+                       };
                };
 
                timers6: timer@40004000 {
                                reg = <0>;
                                status = "disabled";
                        };
+
+                       counter {
+                               compatible = "st,stm32-timer-counter";
+                               status = "disabled";
+                       };
                };
 
                timers8: timer@44001000 {
                                reg = <7>;
                                status = "disabled";
                        };
+
+                       counter {
+                               compatible = "st,stm32-timer-counter";
+                               status = "disabled";
+                       };
                };
 
                usart6: serial@44003000 {
                        };
                };
 
-               m_can1: can@4400e000 {
-                       compatible = "bosch,m_can";
-                       reg = <0x4400e000 0x400>, <0x44011000 0x1400>;
-                       reg-names = "m_can", "message_ram";
-                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "int0", "int1";
-                       clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
-                       clock-names = "hclk", "cclk";
-                       bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
-                       status = "disabled";
-               };
-
-               m_can2: can@4400f000 {
-                       compatible = "bosch,m_can";
-                       reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
-                       reg-names = "m_can", "message_ram";
-                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "int0", "int1";
-                       clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
-                       clock-names = "hclk", "cclk";
-                       bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
-                       status = "disabled";
-               };
-
-               dma1: dma@48000000 {
+               dma1: dma-controller@48000000 {
                        compatible = "st,stm32-dma";
                        reg = <0x48000000 0x400>;
                        interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
                        dma-requests = <8>;
                };
 
-               dma2: dma@48001000 {
+               dma2: dma-controller@48001000 {
                        compatible = "st,stm32-dma";
                        reg = <0x48001000 0x400>;
                        interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
                        };
                };
 
+               sdmmc3: sdmmc@48004000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       arm,primecell-periphid = <0x10153180>;
+                       reg = <0x48004000 0x400>;
+                       interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "cmd_irq";
+                       clocks = <&rcc SDMMC3_K>;
+                       clock-names = "apb_pclk";
+                       resets = <&rcc SDMMC3_R>;
+                       cap-sd-highspeed;
+                       cap-mmc-highspeed;
+                       max-frequency = <120000000>;
+                       status = "disabled";
+               };
+
                usbotg_hs: usb-otg@49000000 {
                        compatible = "snps,dwc2";
                        reg = <0x49000000 0x10000>;
                        status = "disabled";
                };
 
-               cryp1: cryp@54001000 {
-                       compatible = "st,stm32mp1-cryp";
-                       reg = <0x54001000 0x400>;
-                       interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc CRYP1>;
-                       resets = <&rcc CRYP1_R>;
-                       status = "disabled";
-               };
-
                hash1: hash@54002000 {
                        compatible = "st,stm32f756-hash";
                        reg = <0x54002000 0x400>;
                        status = "disabled";
                };
 
-               mdma1: dma@58000000 {
+               mdma1: dma-controller@58000000 {
                        compatible = "st,stm32h7-mdma";
                        reg = <0x58000000 0x1000>;
                        interrupts = <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>;
                        arm,primecell-periphid = <0x10153180>;
                        reg = <0x58005000 0x1000>;
                        interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "cmd_irq";
+                       interrupt-names = "cmd_irq";
                        clocks = <&rcc SDMMC1_K>;
                        clock-names = "apb_pclk";
                        resets = <&rcc SDMMC1_R>;
                        cap-sd-highspeed;
                        cap-mmc-highspeed;
                        max-frequency = <120000000>;
+                       status = "disabled";
+               };
+
+               sdmmc2: sdmmc@58007000 {
+                       compatible = "arm,pl18x", "arm,primecell";
+                       arm,primecell-periphid = <0x10153180>;
+                       reg = <0x58007000 0x1000>;
+                       interrupts = <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "cmd_irq";
+                       clocks = <&rcc SDMMC2_K>;
+                       clock-names = "apb_pclk";
+                       resets = <&rcc SDMMC2_R>;
+                       cap-sd-highspeed;
+                       cap-mmc-highspeed;
+                       max-frequency = <120000000>;
+                       status = "disabled";
                };
 
                crc1: crc@58009000 {
                        clock-names = "stmmaceth",
                                      "mac-clk-tx",
                                      "mac-clk-rx",
-                                     "ethstp",
-                                     "syscfg-clk";
+                                     "ethstp";
                        clocks = <&rcc ETHMAC>,
                                 <&rcc ETHTX>,
                                 <&rcc ETHRX>,
-                                <&rcc ETHSTP>,
-                                <&rcc SYSCFG>;
+                                <&rcc ETHSTP>;
                        st,syscon = <&syscfg 0x4>;
                        snps,mixed-burst;
                        snps,pbl = <2>;
+                       snps,en-tx-lpi-clockgating;
                        snps,axi-config = <&stmmac_axi_config_0>;
                        snps,tso;
                        status = "disabled";
                        status = "disabled";
                };
 
-               gpu: gpu@59000000 {
-                       compatible = "vivante,gc";
-                       reg = <0x59000000 0x800>;
-                       interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&rcc GPU>, <&rcc GPU_K>;
-                       clock-names = "bus" ,"core";
-                       resets = <&rcc GPU_R>;
-                       status = "disabled";
-               };
-
-               dsi: dsi@5a000000 {
-                       compatible = "st,stm32-dsi";
-                       reg = <0x5a000000 0x800>;
-                       clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>;
-                       clock-names = "pclk", "ref", "px_clk";
-                       resets = <&rcc DSI_R>;
-                       reset-names = "apb";
-                       status = "disabled";
-               };
-
                ltdc: display-controller@5a001000 {
                        compatible = "st,stm32-ltdc";
                        reg = <0x5a001000 0x400>;
                        status = "disabled";
                };
 
-               bsec: nvmem@5c005000 {
+               bsec: efuse@5c005000 {
                        compatible = "st,stm32mp15-bsec";
                        reg = <0x5c005000 0x400>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        status = "disabled";
                };
+
+               /*
+                * Break node order to solve dependency probe issue between
+                * pinctrl and exti.
+                */
+               pinctrl: pin-controller@50002000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "st,stm32mp157-pinctrl";
+                       ranges = <0 0x50002000 0xa400>;
+                       interrupt-parent = <&exti>;
+                       st,syscfg = <&exti 0x60 0xff>;
+                       pins-are-numbered;
+
+                       gpioa: gpio@50002000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x0 0x400>;
+                               clocks = <&rcc GPIOA>;
+                               st,bank-name = "GPIOA";
+                               status = "disabled";
+                       };
+
+                       gpiob: gpio@50003000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x1000 0x400>;
+                               clocks = <&rcc GPIOB>;
+                               st,bank-name = "GPIOB";
+                               status = "disabled";
+                       };
+
+                       gpioc: gpio@50004000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x2000 0x400>;
+                               clocks = <&rcc GPIOC>;
+                               st,bank-name = "GPIOC";
+                               status = "disabled";
+                       };
+
+                       gpiod: gpio@50005000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x3000 0x400>;
+                               clocks = <&rcc GPIOD>;
+                               st,bank-name = "GPIOD";
+                               status = "disabled";
+                       };
+
+                       gpioe: gpio@50006000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x4000 0x400>;
+                               clocks = <&rcc GPIOE>;
+                               st,bank-name = "GPIOE";
+                               status = "disabled";
+                       };
+
+                       gpiof: gpio@50007000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x5000 0x400>;
+                               clocks = <&rcc GPIOF>;
+                               st,bank-name = "GPIOF";
+                               status = "disabled";
+                       };
+
+                       gpiog: gpio@50008000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x6000 0x400>;
+                               clocks = <&rcc GPIOG>;
+                               st,bank-name = "GPIOG";
+                               status = "disabled";
+                       };
+
+                       gpioh: gpio@50009000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x7000 0x400>;
+                               clocks = <&rcc GPIOH>;
+                               st,bank-name = "GPIOH";
+                               status = "disabled";
+                       };
+
+                       gpioi: gpio@5000a000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x8000 0x400>;
+                               clocks = <&rcc GPIOI>;
+                               st,bank-name = "GPIOI";
+                               status = "disabled";
+                       };
+
+                       gpioj: gpio@5000b000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0x9000 0x400>;
+                               clocks = <&rcc GPIOJ>;
+                               st,bank-name = "GPIOJ";
+                               status = "disabled";
+                       };
+
+                       gpiok: gpio@5000c000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0xa000 0x400>;
+                               clocks = <&rcc GPIOK>;
+                               st,bank-name = "GPIOK";
+                               status = "disabled";
+                       };
+               };
+
+               pinctrl_z: pin-controller-z@54004000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       compatible = "st,stm32mp157-z-pinctrl";
+                       ranges = <0 0x54004000 0x400>;
+                       pins-are-numbered;
+                       interrupt-parent = <&exti>;
+                       st,syscfg = <&exti 0x60 0xff>;
+
+                       gpioz: gpio@54004000 {
+                               gpio-controller;
+                               #gpio-cells = <2>;
+                               interrupt-controller;
+                               #interrupt-cells = <2>;
+                               reg = <0 0x400>;
+                               clocks = <&rcc GPIOZ>;
+                               st,bank-name = "GPIOZ";
+                               st,bank-ioport = <11>;
+                               status = "disabled";
+                       };
+               };
        };
 
-       mlahb {
-               compatible = "simple-bus";
+       mlahb: ahb {
+               compatible = "st,mlahb", "simple-bus";
                #address-cells = <1>;
                #size-cells = <1>;
+               ranges;
                dma-ranges = <0x00000000 0x38000000 0x10000>,
                             <0x10000000 0x10000000 0x60000>,
                             <0x30000000 0x30000000 0x60000>;
diff --git a/arch/arm/boot/dts/stm32mp153.dtsi b/arch/arm/boot/dts/stm32mp153.dtsi
new file mode 100644 (file)
index 0000000..2d759fc
--- /dev/null
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include "stm32mp151.dtsi"
+
+/ {
+       cpus {
+               cpu1: cpu@1 {
+                       compatible = "arm,cortex-a7";
+                       device_type = "cpu";
+                       reg = <1>;
+               };
+       };
+
+       soc {
+               m_can1: can@4400e000 {
+                       compatible = "bosch,m_can";
+                       reg = <0x4400e000 0x400>, <0x44011000 0x1400>;
+                       reg-names = "m_can", "message_ram";
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "int0", "int1";
+                       clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+                       clock-names = "hclk", "cclk";
+                       bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>;
+                       status = "disabled";
+               };
+
+               m_can2: can@4400f000 {
+                       compatible = "bosch,m_can";
+                       reg = <0x4400f000 0x400>, <0x44011000 0x2800>;
+                       reg-names = "m_can", "message_ram";
+                       interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "int0", "int1";
+                       clocks = <&rcc CK_HSE>, <&rcc FDCAN_K>;
+                       clock-names = "hclk", "cclk";
+                       bosch,mram-cfg = <0x1400 0 0 32 0 0 2 2>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp157-pinctrl.dtsi
deleted file mode 100644 (file)
index 3d1ecb4..0000000
+++ /dev/null
@@ -1,953 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2017 - All Rights Reserved
- * Author: Ludovic Barre <ludovic.barre@st.com> for STMicroelectronics.
- */
-#include <dt-bindings/pinctrl/stm32-pinfunc.h>
-
-/ {
-       soc {
-               pinctrl: pin-controller@50002000 {
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       compatible = "st,stm32mp157-pinctrl";
-                       ranges = <0 0x50002000 0xa400>;
-                       interrupt-parent = <&exti>;
-                       st,syscfg = <&exti 0x60 0xff>;
-                       pins-are-numbered;
-
-                       gpioa: gpio@50002000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x0 0x400>;
-                               clocks = <&rcc GPIOA>;
-                               st,bank-name = "GPIOA";
-                               status = "disabled";
-                       };
-
-                       gpiob: gpio@50003000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x1000 0x400>;
-                               clocks = <&rcc GPIOB>;
-                               st,bank-name = "GPIOB";
-                               status = "disabled";
-                       };
-
-                       gpioc: gpio@50004000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x2000 0x400>;
-                               clocks = <&rcc GPIOC>;
-                               st,bank-name = "GPIOC";
-                               status = "disabled";
-                       };
-
-                       gpiod: gpio@50005000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x3000 0x400>;
-                               clocks = <&rcc GPIOD>;
-                               st,bank-name = "GPIOD";
-                               status = "disabled";
-                       };
-
-                       gpioe: gpio@50006000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x4000 0x400>;
-                               clocks = <&rcc GPIOE>;
-                               st,bank-name = "GPIOE";
-                               status = "disabled";
-                       };
-
-                       gpiof: gpio@50007000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x5000 0x400>;
-                               clocks = <&rcc GPIOF>;
-                               st,bank-name = "GPIOF";
-                               status = "disabled";
-                       };
-
-                       gpiog: gpio@50008000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x6000 0x400>;
-                               clocks = <&rcc GPIOG>;
-                               st,bank-name = "GPIOG";
-                               status = "disabled";
-                       };
-
-                       gpioh: gpio@50009000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x7000 0x400>;
-                               clocks = <&rcc GPIOH>;
-                               st,bank-name = "GPIOH";
-                               status = "disabled";
-                       };
-
-                       gpioi: gpio@5000a000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x8000 0x400>;
-                               clocks = <&rcc GPIOI>;
-                               st,bank-name = "GPIOI";
-                               status = "disabled";
-                       };
-
-                       gpioj: gpio@5000b000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0x9000 0x400>;
-                               clocks = <&rcc GPIOJ>;
-                               st,bank-name = "GPIOJ";
-                               status = "disabled";
-                       };
-
-                       gpiok: gpio@5000c000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0xa000 0x400>;
-                               clocks = <&rcc GPIOK>;
-                               st,bank-name = "GPIOK";
-                               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)>;
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       cec_pins_sleep_a: cec-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('A', 15, ANALOG)>; /* HDMI_CEC */
-                               };
-                       };
-
-                       cec_pins_b: cec-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('B', 6, AF5)>;
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       cec_pins_sleep_b: cec-sleep-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('B', 6, ANALOG)>; /* HDMI_CEC */
-                               };
-                       };
-
-                       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 */
-                                                <STM32_PINMUX('B', 7,  AF13)>,/* DCMI_VSYNC */
-                                                <STM32_PINMUX('A', 6,  AF13)>,/* DCMI_PIXCLK */
-                                                <STM32_PINMUX('H', 9,  AF13)>,/* DCMI_D0 */
-                                                <STM32_PINMUX('H', 10, AF13)>,/* DCMI_D1 */
-                                                <STM32_PINMUX('H', 11, AF13)>,/* DCMI_D2 */
-                                                <STM32_PINMUX('H', 12, AF13)>,/* DCMI_D3 */
-                                                <STM32_PINMUX('H', 14, AF13)>,/* DCMI_D4 */
-                                                <STM32_PINMUX('I', 4,  AF13)>,/* DCMI_D5 */
-                                                <STM32_PINMUX('B', 8,  AF13)>,/* DCMI_D6 */
-                                                <STM32_PINMUX('E', 6,  AF13)>,/* DCMI_D7 */
-                                                <STM32_PINMUX('I', 1,  AF13)>,/* DCMI_D8 */
-                                                <STM32_PINMUX('H', 7,  AF13)>,/* DCMI_D9 */
-                                                <STM32_PINMUX('I', 3,  AF13)>,/* DCMI_D10 */
-                                                <STM32_PINMUX('H', 15, AF13)>;/* DCMI_D11 */
-                                       bias-disable;
-                               };
-                       };
-
-                       dcmi_sleep_pins_a: dcmi-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('H', 8,  ANALOG)>,/* DCMI_HSYNC */
-                                                <STM32_PINMUX('B', 7,  ANALOG)>,/* DCMI_VSYNC */
-                                                <STM32_PINMUX('A', 6,  ANALOG)>,/* DCMI_PIXCLK */
-                                                <STM32_PINMUX('H', 9,  ANALOG)>,/* DCMI_D0 */
-                                                <STM32_PINMUX('H', 10, ANALOG)>,/* DCMI_D1 */
-                                                <STM32_PINMUX('H', 11, ANALOG)>,/* DCMI_D2 */
-                                                <STM32_PINMUX('H', 12, ANALOG)>,/* DCMI_D3 */
-                                                <STM32_PINMUX('H', 14, ANALOG)>,/* DCMI_D4 */
-                                                <STM32_PINMUX('I', 4,  ANALOG)>,/* DCMI_D5 */
-                                                <STM32_PINMUX('B', 8,  ANALOG)>,/* DCMI_D6 */
-                                                <STM32_PINMUX('E', 6,  ANALOG)>,/* DCMI_D7 */
-                                                <STM32_PINMUX('I', 1,  ANALOG)>,/* DCMI_D8 */
-                                                <STM32_PINMUX('H', 7,  ANALOG)>,/* DCMI_D9 */
-                                                <STM32_PINMUX('I', 3,  ANALOG)>,/* DCMI_D10 */
-                                                <STM32_PINMUX('H', 15, ANALOG)>;/* DCMI_D11 */
-                               };
-                       };
-
-                       ethernet0_rgmii_pins_a: rgmii-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('G', 5, AF11)>, /* ETH_RGMII_CLK125 */
-                                                <STM32_PINMUX('G', 4, AF11)>, /* ETH_RGMII_GTX_CLK */
-                                                <STM32_PINMUX('G', 13, AF11)>, /* ETH_RGMII_TXD0 */
-                                                <STM32_PINMUX('G', 14, AF11)>, /* ETH_RGMII_TXD1 */
-                                                <STM32_PINMUX('C', 2, AF11)>, /* ETH_RGMII_TXD2 */
-                                                <STM32_PINMUX('E', 2, AF11)>, /* ETH_RGMII_TXD3 */
-                                                <STM32_PINMUX('B', 11, AF11)>, /* ETH_RGMII_TX_CTL */
-                                                <STM32_PINMUX('A', 2, AF11)>, /* ETH_MDIO */
-                                                <STM32_PINMUX('C', 1, AF11)>; /* ETH_MDC */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <3>;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('C', 4, AF11)>, /* ETH_RGMII_RXD0 */
-                                                <STM32_PINMUX('C', 5, AF11)>, /* ETH_RGMII_RXD1 */
-                                                <STM32_PINMUX('B', 0, AF11)>, /* ETH_RGMII_RXD2 */
-                                                <STM32_PINMUX('B', 1, AF11)>, /* ETH_RGMII_RXD3 */
-                                                <STM32_PINMUX('A', 1, AF11)>, /* ETH_RGMII_RX_CLK */
-                                                <STM32_PINMUX('A', 7, AF11)>; /* ETH_RGMII_RX_CTL */
-                                       bias-disable;
-                               };
-                       };
-
-                       ethernet0_rgmii_pins_sleep_a: rgmii-sleep-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('G', 5, ANALOG)>, /* ETH_RGMII_CLK125 */
-                                                <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_RGMII_GTX_CLK */
-                                                <STM32_PINMUX('G', 13, ANALOG)>, /* ETH_RGMII_TXD0 */
-                                                <STM32_PINMUX('G', 14, ANALOG)>, /* ETH_RGMII_TXD1 */
-                                                <STM32_PINMUX('C', 2, ANALOG)>, /* ETH_RGMII_TXD2 */
-                                                <STM32_PINMUX('E', 2, ANALOG)>, /* ETH_RGMII_TXD3 */
-                                                <STM32_PINMUX('B', 11, ANALOG)>, /* ETH_RGMII_TX_CTL */
-                                                <STM32_PINMUX('A', 2, ANALOG)>, /* ETH_MDIO */
-                                                <STM32_PINMUX('C', 1, ANALOG)>, /* ETH_MDC */
-                                                <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_RXD0 */
-                                                <STM32_PINMUX('C', 5, ANALOG)>, /* ETH_RGMII_RXD1 */
-                                                <STM32_PINMUX('B', 0, ANALOG)>, /* ETH_RGMII_RXD2 */
-                                                <STM32_PINMUX('B', 1, ANALOG)>, /* ETH_RGMII_RXD3 */
-                                                <STM32_PINMUX('A', 1, ANALOG)>, /* ETH_RGMII_RX_CLK */
-                                                <STM32_PINMUX('A', 7, ANALOG)>; /* ETH_RGMII_RX_CTL */
-                               };
-                       };
-
-                       fmc_pins_a: fmc-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('D', 4, AF12)>, /* FMC_NOE */
-                                                <STM32_PINMUX('D', 5, AF12)>, /* FMC_NWE */
-                                                <STM32_PINMUX('D', 11, AF12)>, /* FMC_A16_FMC_CLE */
-                                                <STM32_PINMUX('D', 12, AF12)>, /* FMC_A17_FMC_ALE */
-                                                <STM32_PINMUX('D', 14, AF12)>, /* FMC_D0 */
-                                                <STM32_PINMUX('D', 15, AF12)>, /* FMC_D1 */
-                                                <STM32_PINMUX('D', 0, AF12)>, /* FMC_D2 */
-                                                <STM32_PINMUX('D', 1, AF12)>, /* FMC_D3 */
-                                                <STM32_PINMUX('E', 7, AF12)>, /* FMC_D4 */
-                                                <STM32_PINMUX('E', 8, AF12)>, /* FMC_D5 */
-                                                <STM32_PINMUX('E', 9, AF12)>, /* FMC_D6 */
-                                                <STM32_PINMUX('E', 10, AF12)>, /* FMC_D7 */
-                                                <STM32_PINMUX('G', 9, AF12)>; /* FMC_NE2_FMC_NCE */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <1>;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('D', 6, AF12)>; /* FMC_NWAIT */
-                                       bias-pull-up;
-                               };
-                       };
-
-                       fmc_sleep_pins_a: fmc-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('D', 4, ANALOG)>, /* FMC_NOE */
-                                                <STM32_PINMUX('D', 5, ANALOG)>, /* FMC_NWE */
-                                                <STM32_PINMUX('D', 11, ANALOG)>, /* FMC_A16_FMC_CLE */
-                                                <STM32_PINMUX('D', 12, ANALOG)>, /* FMC_A17_FMC_ALE */
-                                                <STM32_PINMUX('D', 14, ANALOG)>, /* FMC_D0 */
-                                                <STM32_PINMUX('D', 15, ANALOG)>, /* FMC_D1 */
-                                                <STM32_PINMUX('D', 0, ANALOG)>, /* FMC_D2 */
-                                                <STM32_PINMUX('D', 1, ANALOG)>, /* FMC_D3 */
-                                                <STM32_PINMUX('E', 7, ANALOG)>, /* FMC_D4 */
-                                                <STM32_PINMUX('E', 8, ANALOG)>, /* FMC_D5 */
-                                                <STM32_PINMUX('E', 9, ANALOG)>, /* FMC_D6 */
-                                                <STM32_PINMUX('E', 10, ANALOG)>, /* FMC_D7 */
-                                                <STM32_PINMUX('D', 6, ANALOG)>, /* FMC_NWAIT */
-                                                <STM32_PINMUX('G', 9, ANALOG)>; /* FMC_NE2_FMC_NCE */
-                               };
-                       };
-
-                       i2c1_pins_a: i2c1-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('D', 12, AF5)>, /* I2C1_SCL */
-                                                <STM32_PINMUX('F', 15, AF5)>; /* I2C1_SDA */
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       i2c1_pins_sleep_a: i2c1-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('D', 12, ANALOG)>, /* I2C1_SCL */
-                                                <STM32_PINMUX('F', 15, ANALOG)>; /* I2C1_SDA */
-                               };
-                       };
-
-                       i2c1_pins_b: i2c1-2 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 14, AF5)>, /* I2C1_SCL */
-                                                <STM32_PINMUX('F', 15, AF5)>; /* I2C1_SDA */
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       i2c1_pins_sleep_b: i2c1-3 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 14, ANALOG)>, /* I2C1_SCL */
-                                                <STM32_PINMUX('F', 15, ANALOG)>; /* I2C1_SDA */
-                               };
-                       };
-
-                       i2c2_pins_a: i2c2-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('H', 4, AF4)>, /* I2C2_SCL */
-                                                <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       i2c2_pins_sleep_a: i2c2-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('H', 4, ANALOG)>, /* I2C2_SCL */
-                                                <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
-                               };
-                       };
-
-                       i2c2_pins_b1: i2c2-2 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('H', 5, AF4)>; /* I2C2_SDA */
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       i2c2_pins_sleep_b1: i2c2-3 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('H', 5, ANALOG)>; /* I2C2_SDA */
-                               };
-                       };
-
-                       i2c5_pins_a: i2c5-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('A', 11, AF4)>, /* I2C5_SCL */
-                                                <STM32_PINMUX('A', 12, AF4)>; /* I2C5_SDA */
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       i2c5_pins_sleep_a: i2c5-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('A', 11, ANALOG)>, /* I2C5_SCL */
-                                                <STM32_PINMUX('A', 12, ANALOG)>; /* I2C5_SDA */
-
-                               };
-                       };
-
-                       i2s2_pins_a: i2s2-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('I', 3, AF5)>, /* I2S2_SDO */
-                                                <STM32_PINMUX('B', 9, AF5)>, /* I2S2_WS */
-                                                <STM32_PINMUX('A', 9, AF5)>; /* I2S2_CK */
-                                       slew-rate = <1>;
-                                       drive-push-pull;
-                                       bias-disable;
-                               };
-                       };
-
-                       i2s2_pins_sleep_a: i2s2-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('I', 3, ANALOG)>, /* I2S2_SDO */
-                                                <STM32_PINMUX('B', 9, ANALOG)>, /* I2S2_WS */
-                                                <STM32_PINMUX('A', 9, ANALOG)>; /* I2S2_CK */
-                               };
-                       };
-
-                       ltdc_pins_a: ltdc-a-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('G',  7, AF14)>, /* LCD_CLK */
-                                                <STM32_PINMUX('I', 10, AF14)>, /* LCD_HSYNC */
-                                                <STM32_PINMUX('I',  9, AF14)>, /* LCD_VSYNC */
-                                                <STM32_PINMUX('F', 10, AF14)>, /* LCD_DE */
-                                                <STM32_PINMUX('H',  2, AF14)>, /* LCD_R0 */
-                                                <STM32_PINMUX('H',  3, AF14)>, /* LCD_R1 */
-                                                <STM32_PINMUX('H',  8, AF14)>, /* LCD_R2 */
-                                                <STM32_PINMUX('H',  9, AF14)>, /* LCD_R3 */
-                                                <STM32_PINMUX('H', 10, AF14)>, /* LCD_R4 */
-                                                <STM32_PINMUX('C',  0, AF14)>, /* LCD_R5 */
-                                                <STM32_PINMUX('H', 12, AF14)>, /* LCD_R6 */
-                                                <STM32_PINMUX('E', 15, AF14)>, /* LCD_R7 */
-                                                <STM32_PINMUX('E',  5, AF14)>, /* LCD_G0 */
-                                                <STM32_PINMUX('E',  6, AF14)>, /* LCD_G1 */
-                                                <STM32_PINMUX('H', 13, AF14)>, /* LCD_G2 */
-                                                <STM32_PINMUX('H', 14, AF14)>, /* LCD_G3 */
-                                                <STM32_PINMUX('H', 15, AF14)>, /* LCD_G4 */
-                                                <STM32_PINMUX('I',  0, AF14)>, /* LCD_G5 */
-                                                <STM32_PINMUX('I',  1, AF14)>, /* LCD_G6 */
-                                                <STM32_PINMUX('I',  2, AF14)>, /* LCD_G7 */
-                                                <STM32_PINMUX('D',  9, AF14)>, /* LCD_B0 */
-                                                <STM32_PINMUX('G', 12, AF14)>, /* LCD_B1 */
-                                                <STM32_PINMUX('G', 10, AF14)>, /* LCD_B2 */
-                                                <STM32_PINMUX('D', 10, AF14)>, /* LCD_B3 */
-                                                <STM32_PINMUX('I',  4, AF14)>, /* LCD_B4 */
-                                                <STM32_PINMUX('A',  3, AF14)>, /* LCD_B5 */
-                                                <STM32_PINMUX('B',  8, AF14)>, /* LCD_B6 */
-                                                <STM32_PINMUX('D',  8, AF14)>; /* LCD_B7 */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <1>;
-                               };
-                       };
-
-                       ltdc_pins_sleep_a: ltdc-a-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('G',  7, ANALOG)>, /* LCD_CLK */
-                                                <STM32_PINMUX('I', 10, ANALOG)>, /* LCD_HSYNC */
-                                                <STM32_PINMUX('I',  9, ANALOG)>, /* LCD_VSYNC */
-                                                <STM32_PINMUX('F', 10, ANALOG)>, /* LCD_DE */
-                                                <STM32_PINMUX('H',  2, ANALOG)>, /* LCD_R0 */
-                                                <STM32_PINMUX('H',  3, ANALOG)>, /* LCD_R1 */
-                                                <STM32_PINMUX('H',  8, ANALOG)>, /* LCD_R2 */
-                                                <STM32_PINMUX('H',  9, ANALOG)>, /* LCD_R3 */
-                                                <STM32_PINMUX('H', 10, ANALOG)>, /* LCD_R4 */
-                                                <STM32_PINMUX('C',  0, ANALOG)>, /* LCD_R5 */
-                                                <STM32_PINMUX('H', 12, ANALOG)>, /* LCD_R6 */
-                                                <STM32_PINMUX('E', 15, ANALOG)>, /* LCD_R7 */
-                                                <STM32_PINMUX('E',  5, ANALOG)>, /* LCD_G0 */
-                                                <STM32_PINMUX('E',  6, ANALOG)>, /* LCD_G1 */
-                                                <STM32_PINMUX('H', 13, ANALOG)>, /* LCD_G2 */
-                                                <STM32_PINMUX('H', 14, ANALOG)>, /* LCD_G3 */
-                                                <STM32_PINMUX('H', 15, ANALOG)>, /* LCD_G4 */
-                                                <STM32_PINMUX('I',  0, ANALOG)>, /* LCD_G5 */
-                                                <STM32_PINMUX('I',  1, ANALOG)>, /* LCD_G6 */
-                                                <STM32_PINMUX('I',  2, ANALOG)>, /* LCD_G7 */
-                                                <STM32_PINMUX('D',  9, ANALOG)>, /* LCD_B0 */
-                                                <STM32_PINMUX('G', 12, ANALOG)>, /* LCD_B1 */
-                                                <STM32_PINMUX('G', 10, ANALOG)>, /* LCD_B2 */
-                                                <STM32_PINMUX('D', 10, ANALOG)>, /* LCD_B3 */
-                                                <STM32_PINMUX('I',  4, ANALOG)>, /* LCD_B4 */
-                                                <STM32_PINMUX('A',  3, ANALOG)>, /* LCD_B5 */
-                                                <STM32_PINMUX('B',  8, ANALOG)>, /* LCD_B6 */
-                                                <STM32_PINMUX('D',  8, ANALOG)>; /* LCD_B7 */
-                               };
-                       };
-
-                       ltdc_pins_b: ltdc-b-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('I', 14, AF14)>, /* LCD_CLK */
-                                                <STM32_PINMUX('I', 12, AF14)>, /* LCD_HSYNC */
-                                                <STM32_PINMUX('I', 13, AF14)>, /* LCD_VSYNC */
-                                                <STM32_PINMUX('K',  7, AF14)>, /* LCD_DE */
-                                                <STM32_PINMUX('I', 15, AF14)>, /* LCD_R0 */
-                                                <STM32_PINMUX('J',  0, AF14)>, /* LCD_R1 */
-                                                <STM32_PINMUX('J',  1, AF14)>, /* LCD_R2 */
-                                                <STM32_PINMUX('J',  2, AF14)>, /* LCD_R3 */
-                                                <STM32_PINMUX('J',  3, AF14)>, /* LCD_R4 */
-                                                <STM32_PINMUX('J',  4, AF14)>, /* LCD_R5 */
-                                                <STM32_PINMUX('J',  5, AF14)>, /* LCD_R6 */
-                                                <STM32_PINMUX('J',  6, AF14)>, /* LCD_R7 */
-                                                <STM32_PINMUX('J',  7, AF14)>, /* LCD_G0 */
-                                                <STM32_PINMUX('J',  8, AF14)>, /* LCD_G1 */
-                                                <STM32_PINMUX('J',  9, AF14)>, /* LCD_G2 */
-                                                <STM32_PINMUX('J', 10, AF14)>, /* LCD_G3 */
-                                                <STM32_PINMUX('J', 11, AF14)>, /* LCD_G4 */
-                                                <STM32_PINMUX('K',  0, AF14)>, /* LCD_G5 */
-                                                <STM32_PINMUX('K',  1, AF14)>, /* LCD_G6 */
-                                                <STM32_PINMUX('K',  2, AF14)>, /* LCD_G7 */
-                                                <STM32_PINMUX('J', 12, AF14)>, /* LCD_B0 */
-                                                <STM32_PINMUX('J', 13, AF14)>, /* LCD_B1 */
-                                                <STM32_PINMUX('J', 14, AF14)>, /* LCD_B2 */
-                                                <STM32_PINMUX('J', 15, AF14)>, /* LCD_B3 */
-                                                <STM32_PINMUX('K',  3, AF14)>, /* LCD_B4 */
-                                                <STM32_PINMUX('K',  4, AF14)>, /* LCD_B5 */
-                                                <STM32_PINMUX('K',  5, AF14)>, /* LCD_B6 */
-                                                <STM32_PINMUX('K',  6, AF14)>; /* LCD_B7 */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <1>;
-                               };
-                       };
-
-                       ltdc_pins_sleep_b: ltdc-b-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('I', 14, ANALOG)>, /* LCD_CLK */
-                                                <STM32_PINMUX('I', 12, ANALOG)>, /* LCD_HSYNC */
-                                                <STM32_PINMUX('I', 13, ANALOG)>, /* LCD_VSYNC */
-                                                <STM32_PINMUX('K',  7, ANALOG)>, /* LCD_DE */
-                                                <STM32_PINMUX('I', 15, ANALOG)>, /* LCD_R0 */
-                                                <STM32_PINMUX('J',  0, ANALOG)>, /* LCD_R1 */
-                                                <STM32_PINMUX('J',  1, ANALOG)>, /* LCD_R2 */
-                                                <STM32_PINMUX('J',  2, ANALOG)>, /* LCD_R3 */
-                                                <STM32_PINMUX('J',  3, ANALOG)>, /* LCD_R4 */
-                                                <STM32_PINMUX('J',  4, ANALOG)>, /* LCD_R5 */
-                                                <STM32_PINMUX('J',  5, ANALOG)>, /* LCD_R6 */
-                                                <STM32_PINMUX('J',  6, ANALOG)>, /* LCD_R7 */
-                                                <STM32_PINMUX('J',  7, ANALOG)>, /* LCD_G0 */
-                                                <STM32_PINMUX('J',  8, ANALOG)>, /* LCD_G1 */
-                                                <STM32_PINMUX('J',  9, ANALOG)>, /* LCD_G2 */
-                                                <STM32_PINMUX('J', 10, ANALOG)>, /* LCD_G3 */
-                                                <STM32_PINMUX('J', 11, ANALOG)>, /* LCD_G4 */
-                                                <STM32_PINMUX('K',  0, ANALOG)>, /* LCD_G5 */
-                                                <STM32_PINMUX('K',  1, ANALOG)>, /* LCD_G6 */
-                                                <STM32_PINMUX('K',  2, ANALOG)>, /* LCD_G7 */
-                                                <STM32_PINMUX('J', 12, ANALOG)>, /* LCD_B0 */
-                                                <STM32_PINMUX('J', 13, ANALOG)>, /* LCD_B1 */
-                                                <STM32_PINMUX('J', 14, ANALOG)>, /* LCD_B2 */
-                                                <STM32_PINMUX('J', 15, ANALOG)>, /* LCD_B3 */
-                                                <STM32_PINMUX('K',  3, ANALOG)>, /* LCD_B4 */
-                                                <STM32_PINMUX('K',  4, ANALOG)>, /* LCD_B5 */
-                                                <STM32_PINMUX('K',  5, ANALOG)>, /* LCD_B6 */
-                                                <STM32_PINMUX('K',  6, ANALOG)>; /* LCD_B7 */
-                               };
-                       };
-
-                       m_can1_pins_a: m-can1-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('H', 13, AF9)>; /* CAN1_TX */
-                                       slew-rate = <1>;
-                                       drive-push-pull;
-                                       bias-disable;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('I', 9, AF9)>; /* CAN1_RX */
-                                       bias-disable;
-                               };
-                       };
-
-                       m_can1_sleep_pins_a: m_can1-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('H', 13, ANALOG)>, /* CAN1_TX */
-                                                <STM32_PINMUX('I', 9, ANALOG)>; /* CAN1_RX */
-                               };
-                       };
-
-                       pwm2_pins_a: pwm2-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('A', 3, AF1)>; /* TIM2_CH4 */
-                                       bias-pull-down;
-                                       drive-push-pull;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       pwm8_pins_a: pwm8-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('I', 2, AF3)>; /* TIM8_CH4 */
-                                       bias-pull-down;
-                                       drive-push-pull;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       pwm12_pins_a: pwm12-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('H', 6, AF2)>; /* TIM12_CH1 */
-                                       bias-pull-down;
-                                       drive-push-pull;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       qspi_clk_pins_a: qspi-clk-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 10, AF9)>; /* QSPI_CLK */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <3>;
-                               };
-                       };
-
-                       qspi_clk_sleep_pins_a: qspi-clk-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 10, ANALOG)>; /* QSPI_CLK */
-                               };
-                       };
-
-                       qspi_bk1_pins_a: qspi-bk1-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('F', 8, AF10)>, /* QSPI_BK1_IO0 */
-                                                <STM32_PINMUX('F', 9, AF10)>, /* QSPI_BK1_IO1 */
-                                                <STM32_PINMUX('F', 7, AF9)>, /* QSPI_BK1_IO2 */
-                                                <STM32_PINMUX('F', 6, AF9)>; /* QSPI_BK1_IO3 */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <1>;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('B', 6, AF10)>; /* QSPI_BK1_NCS */
-                                       bias-pull-up;
-                                       drive-push-pull;
-                                       slew-rate = <1>;
-                               };
-                       };
-
-                       qspi_bk1_sleep_pins_a: qspi-bk1-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 8, ANALOG)>, /* QSPI_BK1_IO0 */
-                                                <STM32_PINMUX('F', 9, ANALOG)>, /* QSPI_BK1_IO1 */
-                                                <STM32_PINMUX('F', 7, ANALOG)>, /* QSPI_BK1_IO2 */
-                                                <STM32_PINMUX('F', 6, ANALOG)>, /* QSPI_BK1_IO3 */
-                                                <STM32_PINMUX('B', 6, ANALOG)>; /* QSPI_BK1_NCS */
-                               };
-                       };
-
-                       qspi_bk2_pins_a: qspi-bk2-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('H', 2, AF9)>, /* QSPI_BK2_IO0 */
-                                                <STM32_PINMUX('H', 3, AF9)>, /* QSPI_BK2_IO1 */
-                                                <STM32_PINMUX('G', 10, AF11)>, /* QSPI_BK2_IO2 */
-                                                <STM32_PINMUX('G', 7, AF11)>; /* QSPI_BK2_IO3 */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <1>;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('C', 0, AF10)>; /* QSPI_BK2_NCS */
-                                       bias-pull-up;
-                                       drive-push-pull;
-                                       slew-rate = <1>;
-                               };
-                       };
-
-                       qspi_bk2_sleep_pins_a: qspi-bk2-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('H', 2, ANALOG)>, /* QSPI_BK2_IO0 */
-                                                <STM32_PINMUX('H', 3, ANALOG)>, /* QSPI_BK2_IO1 */
-                                                <STM32_PINMUX('G', 10, ANALOG)>, /* QSPI_BK2_IO2 */
-                                                <STM32_PINMUX('G', 7, ANALOG)>, /* QSPI_BK2_IO3 */
-                                                <STM32_PINMUX('C', 0, ANALOG)>; /* QSPI_BK2_NCS */
-                               };
-                       };
-
-                       sai2a_pins_a: sai2a-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('I', 5, AF10)>, /* SAI2_SCK_A */
-                                                <STM32_PINMUX('I', 6, AF10)>, /* SAI2_SD_A */
-                                                <STM32_PINMUX('I', 7, AF10)>, /* SAI2_FS_A */
-                                                <STM32_PINMUX('E', 0, AF10)>; /* SAI2_MCLK_A */
-                                       slew-rate = <0>;
-                                       drive-push-pull;
-                                       bias-disable;
-                               };
-                       };
-
-                       sai2a_sleep_pins_a: sai2a-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('I', 5, ANALOG)>, /* SAI2_SCK_A */
-                                                <STM32_PINMUX('I', 6, ANALOG)>, /* SAI2_SD_A */
-                                                <STM32_PINMUX('I', 7, ANALOG)>, /* SAI2_FS_A */
-                                                <STM32_PINMUX('E', 0, ANALOG)>; /* SAI2_MCLK_A */
-                               };
-                       };
-
-                       sai2b_pins_a: sai2b-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('E', 12, AF10)>, /* SAI2_SCK_B */
-                                                <STM32_PINMUX('E', 13, AF10)>, /* SAI2_FS_B */
-                                                <STM32_PINMUX('E', 14, AF10)>; /* SAI2_MCLK_B */
-                                       slew-rate = <0>;
-                                       drive-push-pull;
-                                       bias-disable;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
-                                       bias-disable;
-                               };
-                       };
-
-                       sai2b_sleep_pins_a: sai2b-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 11, ANALOG)>, /* SAI2_SD_B */
-                                                <STM32_PINMUX('E', 12, ANALOG)>, /* SAI2_SCK_B */
-                                                <STM32_PINMUX('E', 13, ANALOG)>, /* SAI2_FS_B */
-                                                <STM32_PINMUX('E', 14, ANALOG)>; /* SAI2_MCLK_B */
-                               };
-                       };
-
-                       sai2b_pins_b: sai2b-2 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 11, AF10)>; /* SAI2_SD_B */
-                                       bias-disable;
-                               };
-                       };
-
-                       sai2b_sleep_pins_b: sai2b-3 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 11, ANALOG)>; /* SAI2_SD_B */
-                               };
-                       };
-
-                       sai4a_pins_a: sai4a-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('B', 5, AF10)>; /* SAI4_SD_A */
-                                       slew-rate = <0>;
-                                       drive-push-pull;
-                                       bias-disable;
-                               };
-                       };
-
-                       sai4a_sleep_pins_a: sai4a-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('B', 5, ANALOG)>; /* SAI4_SD_A */
-                               };
-                       };
-
-                       sdmmc1_b4_pins_a: sdmmc1-b4-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
-                                                <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
-                                                <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
-                                                <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
-                                                <STM32_PINMUX('C', 12, AF12)>, /* SDMMC1_CK */
-                                                <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
-                                       slew-rate = <3>;
-                                       drive-push-pull;
-                                       bias-disable;
-                               };
-                       };
-
-                       sdmmc1_b4_od_pins_a: sdmmc1-b4-od-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('C', 8, AF12)>, /* SDMMC1_D0 */
-                                                <STM32_PINMUX('C', 9, AF12)>, /* SDMMC1_D1 */
-                                                <STM32_PINMUX('C', 10, AF12)>, /* SDMMC1_D2 */
-                                                <STM32_PINMUX('C', 11, AF12)>, /* SDMMC1_D3 */
-                                                <STM32_PINMUX('C', 12, AF12)>; /* SDMMC1_CK */
-                                       slew-rate = <3>;
-                                       drive-push-pull;
-                                       bias-disable;
-                               };
-                               pins2{
-                                       pinmux = <STM32_PINMUX('D', 2, AF12)>; /* SDMMC1_CMD */
-                                       slew-rate = <3>;
-                                       drive-open-drain;
-                                       bias-disable;
-                               };
-                       };
-
-                       sdmmc1_b4_sleep_pins_a: sdmmc1-b4-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('C', 8, ANALOG)>, /* SDMMC1_D0 */
-                                                <STM32_PINMUX('C', 9, ANALOG)>, /* SDMMC1_D1 */
-                                                <STM32_PINMUX('C', 10, ANALOG)>, /* SDMMC1_D2 */
-                                                <STM32_PINMUX('C', 11, ANALOG)>, /* SDMMC1_D3 */
-                                                <STM32_PINMUX('C', 12, ANALOG)>, /* SDMMC1_CK */
-                                                <STM32_PINMUX('D', 2, ANALOG)>; /* SDMMC1_CMD */
-                               };
-                       };
-
-                       sdmmc1_dir_pins_a: sdmmc1-dir-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('F', 2, AF11)>, /* SDMMC1_D0DIR */
-                                                <STM32_PINMUX('C', 7, AF8)>, /* SDMMC1_D123DIR */
-                                                <STM32_PINMUX('B', 9, AF11)>; /* SDMMC1_CDIR */
-                                       slew-rate = <3>;
-                                       drive-push-pull;
-                                       bias-pull-up;
-                               };
-                               pins2{
-                                       pinmux = <STM32_PINMUX('E', 4, AF8)>; /* SDMMC1_CKIN */
-                                       bias-pull-up;
-                               };
-                       };
-
-                       sdmmc1_dir_sleep_pins_a: sdmmc1-dir-sleep-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('F', 2, ANALOG)>, /* SDMMC1_D0DIR */
-                                                <STM32_PINMUX('C', 7, ANALOG)>, /* SDMMC1_D123DIR */
-                                                <STM32_PINMUX('B', 9, ANALOG)>, /* SDMMC1_CDIR */
-                                                <STM32_PINMUX('E', 4, ANALOG)>; /* SDMMC1_CKIN */
-                               };
-                       };
-
-                       spdifrx_pins_a: spdifrx-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('G', 12, AF8)>; /* SPDIF_IN1 */
-                                       bias-disable;
-                               };
-                       };
-
-                       spdifrx_sleep_pins_a: spdifrx-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('G', 12, ANALOG)>; /* SPDIF_IN1 */
-                               };
-                       };
-
-                       uart4_pins_a: uart4-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('G', 11, AF6)>; /* UART4_TX */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <0>;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
-                                       bias-disable;
-                               };
-                       };
-
-                       uart4_pins_b: uart4-1 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('D', 1, AF8)>; /* UART4_TX */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <0>;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('B', 2, AF8)>; /* UART4_RX */
-                                       bias-disable;
-                               };
-                       };
-
-                       uart7_pins_a: uart7-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('E', 8, AF7)>; /* UART4_TX */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <0>;
-                               };
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('E', 7, AF7)>, /* UART4_RX */
-                                                <STM32_PINMUX('E', 10, AF7)>, /* UART4_CTS */
-                                                <STM32_PINMUX('E', 9, AF7)>; /* UART4_RTS */
-                                       bias-disable;
-                               };
-                       };
-               };
-
-               pinctrl_z: pin-controller-z@54004000 {
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       compatible = "st,stm32mp157-z-pinctrl";
-                       ranges = <0 0x54004000 0x400>;
-                       pins-are-numbered;
-                       interrupt-parent = <&exti>;
-                       st,syscfg = <&exti 0x60 0xff>;
-
-                       gpioz: gpio@54004000 {
-                               gpio-controller;
-                               #gpio-cells = <2>;
-                               interrupt-controller;
-                               #interrupt-cells = <2>;
-                               reg = <0 0x400>;
-                               clocks = <&rcc GPIOZ>;
-                               st,bank-name = "GPIOZ";
-                               st,bank-ioport = <11>;
-                               status = "disabled";
-                       };
-
-                       i2c2_pins_b2: i2c2-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('Z', 0, AF3)>; /* I2C2_SCL */
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       i2c2_pins_sleep_b2: i2c2-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('Z', 0, ANALOG)>; /* I2C2_SCL */
-                               };
-                       };
-
-                       i2c4_pins_a: i2c4-0 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('Z', 4, AF6)>, /* I2C4_SCL */
-                                                <STM32_PINMUX('Z', 5, AF6)>; /* I2C4_SDA */
-                                       bias-disable;
-                                       drive-open-drain;
-                                       slew-rate = <0>;
-                               };
-                       };
-
-                       i2c4_pins_sleep_a: i2c4-1 {
-                               pins {
-                                       pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C4_SCL */
-                                                <STM32_PINMUX('Z', 5, ANALOG)>; /* I2C4_SDA */
-                               };
-                       };
-
-                       spi1_pins_a: spi1-0 {
-                               pins1 {
-                                       pinmux = <STM32_PINMUX('Z', 0, AF5)>, /* SPI1_SCK */
-                                                <STM32_PINMUX('Z', 2, AF5)>; /* SPI1_MOSI */
-                                       bias-disable;
-                                       drive-push-pull;
-                                       slew-rate = <1>;
-                               };
-
-                               pins2 {
-                                       pinmux = <STM32_PINMUX('Z', 1, AF5)>; /* SPI1_MISO */
-                                       bias-disable;
-                               };
-                       };
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/stm32mp157.dtsi b/arch/arm/boot/dts/stm32mp157.dtsi
new file mode 100644 (file)
index 0000000..3f0a4a9
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include "stm32mp153.dtsi"
+
+/ {
+       soc {
+               gpu: gpu@59000000 {
+                       compatible = "vivante,gc";
+                       reg = <0x59000000 0x800>;
+                       interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc GPU>, <&rcc GPU_K>;
+                       clock-names = "bus" ,"core";
+                       resets = <&rcc GPU_R>;
+                       status = "disabled";
+               };
+
+               dsi: dsi@5a000000 {
+                       compatible = "st,stm32-dsi";
+                       reg = <0x5a000000 0x800>;
+                       clocks = <&rcc DSI_K>, <&clk_hse>, <&rcc DSI_PX>;
+                       clock-names = "pclk", "ref", "px_clk";
+                       resets = <&rcc DSI_R>;
+                       reset-names = "apb";
+                       status = "disabled";
+               };
+       };
+};
index 628c74a..cbfa407 100644 (file)
@@ -6,8 +6,9 @@
 
 /dts-v1/;
 
-#include "stm32mp157c.dtsi"
-#include "stm32mp157xac-pinctrl.dtsi"
+#include "stm32mp157.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/mfd/st,stpmic1.h>
 
index 984a47c..d03d4cd 100644 (file)
@@ -6,10 +6,10 @@
 
 /dts-v1/;
 
-#include "stm32mp157c.dtsi"
-#include "stm32mp157xac-pinctrl.dtsi"
-#include <dt-bindings/gpio/gpio.h>
-#include <dt-bindings/mfd/st,stpmic1.h>
+#include "stm32mp157.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
+#include "stm32mp15xx-dkx.dtsi"
 
 / {
        model = "STMicroelectronics STM32MP157A-DK1 Discovery Board";
        chosen {
                stdout-path = "serial0:115200n8";
        };
-
-       memory@c0000000 {
-               device_type = "memory";
-               reg = <0xc0000000 0x20000000>;
-       };
-
-       reserved-memory {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges;
-
-               mcuram2: mcuram2@10000000 {
-                       compatible = "shared-dma-pool";
-                       reg = <0x10000000 0x40000>;
-                       no-map;
-               };
-
-               vdev0vring0: vdev0vring0@10040000 {
-                       compatible = "shared-dma-pool";
-                       reg = <0x10040000 0x1000>;
-                       no-map;
-               };
-
-               vdev0vring1: vdev0vring1@10041000 {
-                       compatible = "shared-dma-pool";
-                       reg = <0x10041000 0x1000>;
-                       no-map;
-               };
-
-               vdev0buffer: vdev0buffer@10042000 {
-                       compatible = "shared-dma-pool";
-                       reg = <0x10042000 0x4000>;
-                       no-map;
-               };
-
-               mcuram: mcuram@30000000 {
-                       compatible = "shared-dma-pool";
-                       reg = <0x30000000 0x40000>;
-                       no-map;
-               };
-
-               retram: retram@38000000 {
-                       compatible = "shared-dma-pool";
-                       reg = <0x38000000 0x10000>;
-                       no-map;
-               };
-
-               gpu_reserved: gpu@d4000000 {
-                       reg = <0xd4000000 0x4000000>;
-                       no-map;
-               };
-       };
-
-       led {
-               compatible = "gpio-leds";
-               blue {
-                       label = "heartbeat";
-                       gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>;
-                       linux,default-trigger = "heartbeat";
-                       default-state = "off";
-               };
-       };
-
-       sound {
-               compatible = "audio-graph-card";
-               label = "STM32MP1-DK";
-               routing =
-                       "Playback" , "MCLK",
-                       "Capture" , "MCLK",
-                       "MICL" , "Mic Bias";
-               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";
-       };
-};
-
-&cec {
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&cec_pins_b>;
-       pinctrl-1 = <&cec_pins_sleep_b>;
-       status = "okay";
-};
-
-&ethernet0 {
-       status = "okay";
-       pinctrl-0 = <&ethernet0_rgmii_pins_a>;
-       pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
-       pinctrl-names = "default", "sleep";
-       phy-mode = "rgmii-id";
-       max-speed = <1000>;
-       phy-handle = <&phy0>;
-
-       mdio0 {
-               #address-cells = <1>;
-               #size-cells = <0>;
-               compatible = "snps,dwmac-mdio";
-               phy0: ethernet-phy@0 {
-                       reg = <0>;
-               };
-       };
-};
-
-&gpu {
-       contiguous-area = <&gpu_reserved>;
-       status = "okay";
-};
-
-&i2c1 {
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&i2c1_pins_a>;
-       pinctrl-1 = <&i2c1_pins_sleep_a>;
-       i2c-scl-rising-time-ns = <100>;
-       i2c-scl-falling-time-ns = <7>;
-       status = "okay";
-       /delete-property/dmas;
-       /delete-property/dma-names;
-
-       hdmi-transmitter@39 {
-               compatible = "sil,sii9022";
-               reg = <0x39>;
-               iovcc-supply = <&v3v3_hdmi>;
-               cvcc12-supply = <&v1v2_hdmi>;
-               reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;
-               interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
-               interrupt-parent = <&gpiog>;
-               #sound-dai-cells = <0>;
-               status = "okay";
-
-               ports {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       port@0 {
-                               reg = <0>;
-                               sii9022_in: endpoint {
-                                       remote-endpoint = <&ltdc_ep0_out>;
-                               };
-                       };
-
-                       port@3 {
-                               reg = <3>;
-                               sii9022_tx_endpoint: endpoint {
-                                       remote-endpoint = <&i2s2_endpoint>;
-                               };
-                       };
-               };
-       };
-
-       cs42l51: cs42l51@4a {
-               compatible = "cirrus,cs42l51";
-               reg = <0x4a>;
-               #sound-dai-cells = <0>;
-               VL-supply = <&v3v3>;
-               VD-supply = <&v1v8_audio>;
-               VA-supply = <&v1v8_audio>;
-               VAHP-supply = <&v1v8_audio>;
-               reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>;
-               clocks = <&sai2a>;
-               clock-names = "MCLK";
-               status = "okay";
-
-               cs42l51_port: port {
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-
-                       cs42l51_tx_endpoint: endpoint@0 {
-                               reg = <0>;
-                               remote-endpoint = <&sai2a_endpoint>;
-                               frame-master;
-                               bitclock-master;
-                       };
-
-                       cs42l51_rx_endpoint: endpoint@1 {
-                               reg = <1>;
-                               remote-endpoint = <&sai2b_endpoint>;
-                               frame-master;
-                               bitclock-master;
-                       };
-               };
-       };
-};
-
-&i2c4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&i2c4_pins_a>;
-       i2c-scl-rising-time-ns = <185>;
-       i2c-scl-falling-time-ns = <20>;
-       status = "okay";
-       /* spare dmas for other usage */
-       /delete-property/dmas;
-       /delete-property/dma-names;
-
-       pmic: stpmic@33 {
-               compatible = "st,stpmic1";
-               reg = <0x33>;
-               interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
-               interrupt-controller;
-               #interrupt-cells = <2>;
-               status = "okay";
-
-               regulators {
-                       compatible = "st,stpmic1-regulators";
-                       ldo1-supply = <&v3v3>;
-                       ldo3-supply = <&vdd_ddr>;
-                       ldo6-supply = <&v3v3>;
-                       pwr_sw1-supply = <&bst_out>;
-                       pwr_sw2-supply = <&bst_out>;
-
-                       vddcore: buck1 {
-                               regulator-name = "vddcore";
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <1350000>;
-                               regulator-always-on;
-                               regulator-initial-mode = <0>;
-                               regulator-over-current-protection;
-                       };
-
-                       vdd_ddr: buck2 {
-                               regulator-name = "vdd_ddr";
-                               regulator-min-microvolt = <1350000>;
-                               regulator-max-microvolt = <1350000>;
-                               regulator-always-on;
-                               regulator-initial-mode = <0>;
-                               regulator-over-current-protection;
-                       };
-
-                       vdd: buck3 {
-                               regulator-name = "vdd";
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                               st,mask-reset;
-                               regulator-initial-mode = <0>;
-                               regulator-over-current-protection;
-                       };
-
-                       v3v3: buck4 {
-                               regulator-name = "v3v3";
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                               regulator-over-current-protection;
-                               regulator-initial-mode = <0>;
-                       };
-
-                       v1v8_audio: ldo1 {
-                               regulator-name = "v1v8_audio";
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-always-on;
-                               interrupts = <IT_CURLIM_LDO1 0>;
-                       };
-
-                       v3v3_hdmi: ldo2 {
-                               regulator-name = "v3v3_hdmi";
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                               regulator-always-on;
-                               interrupts = <IT_CURLIM_LDO2 0>;
-                       };
-
-                       vtt_ddr: ldo3 {
-                               regulator-name = "vtt_ddr";
-                               regulator-min-microvolt = <500000>;
-                               regulator-max-microvolt = <750000>;
-                               regulator-always-on;
-                               regulator-over-current-protection;
-                       };
-
-                       vdd_usb: ldo4 {
-                               regulator-name = "vdd_usb";
-                               regulator-min-microvolt = <3300000>;
-                               regulator-max-microvolt = <3300000>;
-                               interrupts = <IT_CURLIM_LDO4 0>;
-                       };
-
-                       vdda: ldo5 {
-                               regulator-name = "vdda";
-                               regulator-min-microvolt = <2900000>;
-                               regulator-max-microvolt = <2900000>;
-                               interrupts = <IT_CURLIM_LDO5 0>;
-                               regulator-boot-on;
-                       };
-
-                       v1v2_hdmi: ldo6 {
-                               regulator-name = "v1v2_hdmi";
-                               regulator-min-microvolt = <1200000>;
-                               regulator-max-microvolt = <1200000>;
-                               regulator-always-on;
-                               interrupts = <IT_CURLIM_LDO6 0>;
-                       };
-
-                       vref_ddr: vref_ddr {
-                               regulator-name = "vref_ddr";
-                               regulator-always-on;
-                               regulator-over-current-protection;
-                       };
-
-                        bst_out: boost {
-                               regulator-name = "bst_out";
-                               interrupts = <IT_OCP_BOOST 0>;
-                        };
-
-                       vbus_otg: pwr_sw1 {
-                               regulator-name = "vbus_otg";
-                               interrupts = <IT_OCP_OTG 0>;
-                        };
-
-                        vbus_sw: pwr_sw2 {
-                               regulator-name = "vbus_sw";
-                               interrupts = <IT_OCP_SWOUT 0>;
-                               regulator-active-discharge = <1>;
-                        };
-               };
-
-               onkey {
-                       compatible = "st,stpmic1-onkey";
-                       interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>;
-                       interrupt-names = "onkey-falling", "onkey-rising";
-                       power-off-time-sec = <10>;
-                       status = "okay";
-               };
-
-               watchdog {
-                       compatible = "st,stpmic1-wdt";
-                       status = "disabled";
-               };
-       };
-};
-
-&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";
-};
-
-&iwdg2 {
-       timeout-sec = <32>;
-       status = "okay";
-};
-
-&ltdc {
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&ltdc_pins_a>;
-       pinctrl-1 = <&ltdc_pins_sleep_a>;
-       status = "okay";
-
-       port {
-               #address-cells = <1>;
-               #size-cells = <0>;
-
-               ltdc_ep0_out: endpoint@0 {
-                       reg = <0>;
-                       remote-endpoint = <&sii9022_in>;
-               };
-       };
-};
-
-&m4_rproc {
-       memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
-                       <&vdev0vring1>, <&vdev0buffer>;
-       mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
-       mbox-names = "vq0", "vq1", "shutdown";
-       interrupt-parent = <&exti>;
-       interrupts = <68 1>;
-       status = "okay";
-};
-
-&pwr_regulators {
-       vdd-supply = <&vdd>;
-       vdd_3v3_usbfs-supply = <&vdd_usb>;
-};
-
-&rng1 {
-       status = "okay";
-};
-
-&rtc {
-       status = "okay";
-};
-
-&sai2 {
-       clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
-       clock-names = "pclk", "x8k", "x11k";
-       pinctrl-names = "default", "sleep";
-       pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
-       pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
-       status = "okay";
-
-       sai2a: audio-controller@4400b004 {
-               #clock-cells = <0>;
-               dma-names = "tx";
-               clocks = <&rcc SAI2_K>;
-               clock-names = "sai_ck";
-               status = "okay";
-
-               sai2a_port: port {
-                       sai2a_endpoint: endpoint {
-                               remote-endpoint = <&cs42l51_tx_endpoint>;
-                               format = "i2s";
-                               mclk-fs = <256>;
-                               dai-tdm-slot-num = <2>;
-                               dai-tdm-slot-width = <32>;
-                       };
-               };
-       };
-
-       sai2b: audio-controller@4400b024 {
-               dma-names = "rx";
-               st,sync = <&sai2a 2>;
-               clocks = <&rcc SAI2_K>, <&sai2a>;
-               clock-names = "sai_ck", "MCLK";
-               status = "okay";
-
-               sai2b_port: port {
-                       sai2b_endpoint: endpoint {
-                               remote-endpoint = <&cs42l51_rx_endpoint>;
-                               format = "i2s";
-                               mclk-fs = <256>;
-                               dai-tdm-slot-num = <2>;
-                               dai-tdm-slot-width = <32>;
-                       };
-               };
-       };
-};
-
-&sdmmc1 {
-       pinctrl-names = "default", "opendrain", "sleep";
-       pinctrl-0 = <&sdmmc1_b4_pins_a>;
-       pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
-       pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
-       broken-cd;
-       st,neg-edge;
-       bus-width = <4>;
-       vmmc-supply = <&v3v3>;
-       status = "okay";
-};
-
-&uart4 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart4_pins_a>;
-       status = "okay";
-};
-
-&vrefbuf {
-       regulator-min-microvolt = <2500000>;
-       regulator-max-microvolt = <2500000>;
-       vdda-supply = <&vdd>;
-       status = "okay";
 };
index d26adcb..7985b80 100644 (file)
@@ -6,11 +6,24 @@
 
 /dts-v1/;
 
-#include "stm32mp157a-dk1.dts"
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxac-pinctrl.dtsi"
+#include "stm32mp15xx-dkx.dtsi"
 
 / {
        model = "STMicroelectronics STM32MP157C-DK2 Discovery Board";
        compatible = "st,stm32mp157c-dk2", "st,stm32mp157";
+
+       aliases {
+               ethernet0 = &ethernet0;
+               serial0 = &uart4;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
 };
 
 &dsi {
index b8cc0fb..1fc4325 100644 (file)
@@ -5,8 +5,10 @@
  */
 /dts-v1/;
 
-#include "stm32mp157c.dtsi"
-#include "stm32mp157xaa-pinctrl.dtsi"
+#include "stm32mp157.dtsi"
+#include "stm32mp15xc.dtsi"
+#include "stm32mp15-pinctrl.dtsi"
+#include "stm32mp15xxaa-pinctrl.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/mfd/st,stpmic1.h>
 
        };
 };
 
+&adc {
+       /* ANA0, ANA1 are dedicated pins and don't need pinctrl: only in6. */
+       pinctrl-0 = <&adc1_in6_pins_a>;
+       pinctrl-names = "default";
+       vdd-supply = <&vdd>;
+       vdda-supply = <&vdda>;
+       vref-supply = <&vdda>;
+       status = "disabled";
+       adc1: adc@0 {
+               st,adc-channels = <0 1 6>;
+               /* 16.5 ck_cycles sampling time */
+               st,min-sample-time-nsecs = <400>;
+               status = "okay";
+       };
+};
+
 &dac {
        pinctrl-names = "default";
        pinctrl-0 = <&dac_ch1_pins_a &dac_ch2_pins_a>;
        status = "okay";
 };
 
+&sdmmc2 {
+       pinctrl-names = "default", "opendrain", "sleep";
+       pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>;
+       pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>;
+       pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>;
+       non-removable;
+       no-sd;
+       no-sdio;
+       st,neg-edge;
+       bus-width = <8>;
+       vmmc-supply = <&v3v3>;
+       vqmmc-supply = <&v3v3>;
+       mmc-ddr-3_3v;
+       status = "okay";
+};
+
 &timers6 {
        status = "okay";
        /* spare dmas for other usage */
index 3789312..228e35e 100644 (file)
        };
 };
 
+&sdmmc3 {
+       pinctrl-names = "default", "opendrain", "sleep";
+       pinctrl-0 = <&sdmmc3_b4_pins_a>;
+       pinctrl-1 = <&sdmmc3_b4_od_pins_a>;
+       pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>;
+       broken-cd;
+       st,neg-edge;
+       bus-width = <4>;
+       vmmc-supply = <&v3v3>;
+       status = "disabled";
+};
+
 &spi1 {
        pinctrl-names = "default";
        pinctrl-0 = <&spi1_pins_a>;
        status = "disabled";
        pwm {
                pinctrl-0 = <&pwm2_pins_a>;
-               pinctrl-names = "default";
+               pinctrl-1 = <&pwm2_sleep_pins_a>;
+               pinctrl-names = "default", "sleep";
                status = "okay";
        };
        timer@1 {
        status = "disabled";
        pwm {
                pinctrl-0 = <&pwm8_pins_a>;
-               pinctrl-names = "default";
+               pinctrl-1 = <&pwm8_sleep_pins_a>;
+               pinctrl-names = "default", "sleep";
                status = "okay";
        };
        timer@7 {
        status = "disabled";
        pwm {
                pinctrl-0 = <&pwm12_pins_a>;
-               pinctrl-names = "default";
+               pinctrl-1 = <&pwm12_sleep_pins_a>;
+               pinctrl-names = "default", "sleep";
                status = "okay";
        };
        timer@11 {
 &usbotg_hs {
        dr_mode = "peripheral";
        phys = <&usbphyc_port1 0>;
+       phy-names = "usb2-phy";
        status = "okay";
 };
 
diff --git a/arch/arm/boot/dts/stm32mp157xaa-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp157xaa-pinctrl.dtsi
deleted file mode 100644 (file)
index 875adf5..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
- * Author: Alexandre Torgue <alexandre.torgue@st.com>
- */
-
-#include "stm32mp157-pinctrl.dtsi"
-/ {
-       soc {
-               pinctrl: pin-controller@50002000 {
-                       st,package = <STM32MP_PKG_AA>;
-
-                       gpioa: gpio@50002000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 0 16>;
-                       };
-
-                       gpiob: gpio@50003000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 16 16>;
-                       };
-
-                       gpioc: gpio@50004000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 32 16>;
-                       };
-
-                       gpiod: gpio@50005000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 48 16>;
-                       };
-
-                       gpioe: gpio@50006000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 64 16>;
-                       };
-
-                       gpiof: gpio@50007000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 80 16>;
-                       };
-
-                       gpiog: gpio@50008000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 96 16>;
-                       };
-
-                       gpioh: gpio@50009000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 112 16>;
-                       };
-
-                       gpioi: gpio@5000a000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 128 16>;
-                       };
-
-                       gpioj: gpio@5000b000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 144 16>;
-                       };
-
-                       gpiok: gpio@5000c000 {
-                               status = "okay";
-                               ngpios = <8>;
-                               gpio-ranges = <&pinctrl 0 160 8>;
-                       };
-               };
-
-               pinctrl_z: pin-controller-z@54004000 {
-                       st,package = <STM32MP_PKG_AA>;
-
-                       gpioz: gpio@54004000 {
-                               status = "okay";
-                               ngpios = <8>;
-                               gpio-ranges = <&pinctrl_z 0 400 8>;
-                       };
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/stm32mp157xab-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp157xab-pinctrl.dtsi
deleted file mode 100644 (file)
index 961fa12..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
- * Author: Alexandre Torgue <alexandre.torgue@st.com>
- */
-
-#include "stm32mp157-pinctrl.dtsi"
-/ {
-       soc {
-               pinctrl: pin-controller@50002000 {
-                       st,package = <STM32MP_PKG_AB>;
-
-                       gpioa: gpio@50002000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 0 16>;
-                       };
-
-                       gpiob: gpio@50003000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 16 16>;
-                       };
-
-                       gpioc: gpio@50004000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 32 16>;
-                       };
-
-                       gpiod: gpio@50005000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 48 16>;
-                       };
-
-                       gpioe: gpio@50006000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 64 16>;
-                       };
-
-                       gpiof: gpio@50007000 {
-                               status = "okay";
-                               ngpios = <6>;
-                               gpio-ranges = <&pinctrl 6 86 6>;
-                       };
-
-                       gpiog: gpio@50008000 {
-                               status = "okay";
-                               ngpios = <10>;
-                               gpio-ranges = <&pinctrl 6 102 10>;
-                       };
-
-                       gpioh: gpio@50009000 {
-                               status = "okay";
-                               ngpios = <2>;
-                               gpio-ranges = <&pinctrl 0 112 2>;
-                       };
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/stm32mp157xac-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp157xac-pinctrl.dtsi
deleted file mode 100644 (file)
index 26600f1..0000000
+++ /dev/null
@@ -1,78 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
- * Author: Alexandre Torgue <alexandre.torgue@st.com>
- */
-
-#include "stm32mp157-pinctrl.dtsi"
-/ {
-       soc {
-               pinctrl: pin-controller@50002000 {
-                       st,package = <STM32MP_PKG_AC>;
-
-                       gpioa: gpio@50002000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 0 16>;
-                       };
-
-                       gpiob: gpio@50003000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 16 16>;
-                       };
-
-                       gpioc: gpio@50004000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 32 16>;
-                       };
-
-                       gpiod: gpio@50005000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 48 16>;
-                       };
-
-                       gpioe: gpio@50006000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 64 16>;
-                       };
-
-                       gpiof: gpio@50007000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 80 16>;
-                       };
-
-                       gpiog: gpio@50008000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 96 16>;
-                       };
-
-                       gpioh: gpio@50009000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 112 16>;
-                       };
-
-                       gpioi: gpio@5000a000 {
-                               status = "okay";
-                               ngpios = <12>;
-                               gpio-ranges = <&pinctrl 0 128 12>;
-                       };
-               };
-
-               pinctrl_z: pin-controller-z@54004000 {
-                       st,package = <STM32MP_PKG_AC>;
-
-                       gpioz: gpio@54004000 {
-                               status = "okay";
-                               ngpios = <8>;
-                               gpio-ranges = <&pinctrl_z 0 400 8>;
-                       };
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/stm32mp157xad-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp157xad-pinctrl.dtsi
deleted file mode 100644 (file)
index 910113f..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
-/*
- * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
- * Author: Alexandre Torgue <alexandre.torgue@st.com>
- */
-
-#include "stm32mp157-pinctrl.dtsi"
-/ {
-       soc {
-               pinctrl: pin-controller@50002000 {
-                       st,package = <STM32MP_PKG_AD>;
-
-                       gpioa: gpio@50002000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 0 16>;
-                       };
-
-                       gpiob: gpio@50003000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 16 16>;
-                       };
-
-                       gpioc: gpio@50004000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 32 16>;
-                       };
-
-                       gpiod: gpio@50005000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 48 16>;
-                       };
-
-                       gpioe: gpio@50006000 {
-                               status = "okay";
-                               ngpios = <16>;
-                               gpio-ranges = <&pinctrl 0 64 16>;
-                       };
-
-                       gpiof: gpio@50007000 {
-                               status = "okay";
-                               ngpios = <6>;
-                               gpio-ranges = <&pinctrl 6 86 6>;
-                       };
-
-                       gpiog: gpio@50008000 {
-                               status = "okay";
-                               ngpios = <10>;
-                               gpio-ranges = <&pinctrl 6 102 10>;
-                       };
-
-                       gpioh: gpio@50009000 {
-                               status = "okay";
-                               ngpios = <2>;
-                               gpio-ranges = <&pinctrl 0 112 2>;
-                       };
-               };
-       };
-};
diff --git a/arch/arm/boot/dts/stm32mp15xc.dtsi b/arch/arm/boot/dts/stm32mp15xc.dtsi
new file mode 100644 (file)
index 0000000..b06a55a
--- /dev/null
@@ -0,0 +1,18 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+/ {
+       soc {
+               cryp1: cryp@54001000 {
+                       compatible = "st,stm32mp1-cryp";
+                       reg = <0x54001000 0x400>;
+                       interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&rcc CRYP1>;
+                       resets = <&rcc CRYP1_R>;
+                       status = "disabled";
+               };
+       };
+};
diff --git a/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/stm32mp15xx-dkx.dtsi
new file mode 100644 (file)
index 0000000..f6672e8
--- /dev/null
@@ -0,0 +1,625 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/mfd/st,stpmic1.h>
+
+/ {
+       memory@c0000000 {
+               device_type = "memory";
+               reg = <0xc0000000 0x20000000>;
+       };
+
+       reserved-memory {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges;
+
+               mcuram2: mcuram2@10000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10000000 0x40000>;
+                       no-map;
+               };
+
+               vdev0vring0: vdev0vring0@10040000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10040000 0x1000>;
+                       no-map;
+               };
+
+               vdev0vring1: vdev0vring1@10041000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10041000 0x1000>;
+                       no-map;
+               };
+
+               vdev0buffer: vdev0buffer@10042000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x10042000 0x4000>;
+                       no-map;
+               };
+
+               mcuram: mcuram@30000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x30000000 0x40000>;
+                       no-map;
+               };
+
+               retram: retram@38000000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x38000000 0x10000>;
+                       no-map;
+               };
+
+               gpu_reserved: gpu@d4000000 {
+                       reg = <0xd4000000 0x4000000>;
+                       no-map;
+               };
+       };
+
+       led {
+               compatible = "gpio-leds";
+               blue {
+                       label = "heartbeat";
+                       gpios = <&gpiod 11 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       default-state = "off";
+               };
+       };
+
+       sound {
+               compatible = "audio-graph-card";
+               label = "STM32MP1-DK";
+               routing =
+                       "Playback" , "MCLK",
+                       "Capture" , "MCLK",
+                       "MICL" , "Mic Bias";
+               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";
+       };
+};
+
+&cec {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&cec_pins_b>;
+       pinctrl-1 = <&cec_pins_sleep_b>;
+       status = "okay";
+};
+
+&ethernet0 {
+       status = "okay";
+       pinctrl-0 = <&ethernet0_rgmii_pins_a>;
+       pinctrl-1 = <&ethernet0_rgmii_pins_sleep_a>;
+       pinctrl-names = "default", "sleep";
+       phy-mode = "rgmii-id";
+       max-speed = <1000>;
+       phy-handle = <&phy0>;
+
+       mdio0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "snps,dwmac-mdio";
+               phy0: ethernet-phy@0 {
+                       reg = <0>;
+               };
+       };
+};
+
+&gpu {
+       contiguous-area = <&gpu_reserved>;
+       status = "okay";
+};
+
+&i2c1 {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&i2c1_pins_a>;
+       pinctrl-1 = <&i2c1_pins_sleep_a>;
+       i2c-scl-rising-time-ns = <100>;
+       i2c-scl-falling-time-ns = <7>;
+       status = "okay";
+       /delete-property/dmas;
+       /delete-property/dma-names;
+
+       hdmi-transmitter@39 {
+               compatible = "sil,sii9022";
+               reg = <0x39>;
+               iovcc-supply = <&v3v3_hdmi>;
+               cvcc12-supply = <&v1v2_hdmi>;
+               reset-gpios = <&gpioa 10 GPIO_ACTIVE_LOW>;
+               interrupts = <1 IRQ_TYPE_EDGE_FALLING>;
+               interrupt-parent = <&gpiog>;
+               #sound-dai-cells = <0>;
+               status = "okay";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               sii9022_in: endpoint {
+                                       remote-endpoint = <&ltdc_ep0_out>;
+                               };
+                       };
+
+                       port@3 {
+                               reg = <3>;
+                               sii9022_tx_endpoint: endpoint {
+                                       remote-endpoint = <&i2s2_endpoint>;
+                               };
+                       };
+               };
+       };
+
+       cs42l51: cs42l51@4a {
+               compatible = "cirrus,cs42l51";
+               reg = <0x4a>;
+               #sound-dai-cells = <0>;
+               VL-supply = <&v3v3>;
+               VD-supply = <&v1v8_audio>;
+               VA-supply = <&v1v8_audio>;
+               VAHP-supply = <&v1v8_audio>;
+               reset-gpios = <&gpiog 9 GPIO_ACTIVE_LOW>;
+               clocks = <&sai2a>;
+               clock-names = "MCLK";
+               status = "okay";
+
+               cs42l51_port: port {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       cs42l51_tx_endpoint: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&sai2a_endpoint>;
+                               frame-master;
+                               bitclock-master;
+                       };
+
+                       cs42l51_rx_endpoint: endpoint@1 {
+                               reg = <1>;
+                               remote-endpoint = <&sai2b_endpoint>;
+                               frame-master;
+                               bitclock-master;
+                       };
+               };
+       };
+};
+
+&i2c4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&i2c4_pins_a>;
+       i2c-scl-rising-time-ns = <185>;
+       i2c-scl-falling-time-ns = <20>;
+       status = "okay";
+       /* spare dmas for other usage */
+       /delete-property/dmas;
+       /delete-property/dma-names;
+
+       pmic: stpmic@33 {
+               compatible = "st,stpmic1";
+               reg = <0x33>;
+               interrupts-extended = <&gpioa 0 IRQ_TYPE_EDGE_FALLING>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+               status = "okay";
+
+               regulators {
+                       compatible = "st,stpmic1-regulators";
+                       ldo1-supply = <&v3v3>;
+                       ldo3-supply = <&vdd_ddr>;
+                       ldo6-supply = <&v3v3>;
+                       pwr_sw1-supply = <&bst_out>;
+                       pwr_sw2-supply = <&bst_out>;
+
+                       vddcore: buck1 {
+                               regulator-name = "vddcore";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-initial-mode = <0>;
+                               regulator-over-current-protection;
+                       };
+
+                       vdd_ddr: buck2 {
+                               regulator-name = "vdd_ddr";
+                               regulator-min-microvolt = <1350000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-always-on;
+                               regulator-initial-mode = <0>;
+                               regulator-over-current-protection;
+                       };
+
+                       vdd: buck3 {
+                               regulator-name = "vdd";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               st,mask-reset;
+                               regulator-initial-mode = <0>;
+                               regulator-over-current-protection;
+                       };
+
+                       v3v3: buck4 {
+                               regulator-name = "v3v3";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               regulator-over-current-protection;
+                               regulator-initial-mode = <0>;
+                       };
+
+                       v1v8_audio: ldo1 {
+                               regulator-name = "v1v8_audio";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-always-on;
+                               interrupts = <IT_CURLIM_LDO1 0>;
+                       };
+
+                       v3v3_hdmi: ldo2 {
+                               regulator-name = "v3v3_hdmi";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                               interrupts = <IT_CURLIM_LDO2 0>;
+                       };
+
+                       vtt_ddr: ldo3 {
+                               regulator-name = "vtt_ddr";
+                               regulator-min-microvolt = <500000>;
+                               regulator-max-microvolt = <750000>;
+                               regulator-always-on;
+                               regulator-over-current-protection;
+                       };
+
+                       vdd_usb: ldo4 {
+                               regulator-name = "vdd_usb";
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               interrupts = <IT_CURLIM_LDO4 0>;
+                       };
+
+                       vdda: ldo5 {
+                               regulator-name = "vdda";
+                               regulator-min-microvolt = <2900000>;
+                               regulator-max-microvolt = <2900000>;
+                               interrupts = <IT_CURLIM_LDO5 0>;
+                               regulator-boot-on;
+                       };
+
+                       v1v2_hdmi: ldo6 {
+                               regulator-name = "v1v2_hdmi";
+                               regulator-min-microvolt = <1200000>;
+                               regulator-max-microvolt = <1200000>;
+                               regulator-always-on;
+                               interrupts = <IT_CURLIM_LDO6 0>;
+                       };
+
+                       vref_ddr: vref_ddr {
+                               regulator-name = "vref_ddr";
+                               regulator-always-on;
+                               regulator-over-current-protection;
+                       };
+
+                        bst_out: boost {
+                               regulator-name = "bst_out";
+                               interrupts = <IT_OCP_BOOST 0>;
+                        };
+
+                       vbus_otg: pwr_sw1 {
+                               regulator-name = "vbus_otg";
+                               interrupts = <IT_OCP_OTG 0>;
+                        };
+
+                        vbus_sw: pwr_sw2 {
+                               regulator-name = "vbus_sw";
+                               interrupts = <IT_OCP_SWOUT 0>;
+                               regulator-active-discharge = <1>;
+                        };
+               };
+
+               onkey {
+                       compatible = "st,stpmic1-onkey";
+                       interrupts = <IT_PONKEY_F 0>, <IT_PONKEY_R 0>;
+                       interrupt-names = "onkey-falling", "onkey-rising";
+                       power-off-time-sec = <10>;
+                       status = "okay";
+               };
+
+               watchdog {
+                       compatible = "st,stpmic1-wdt";
+                       status = "disabled";
+               };
+       };
+};
+
+&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";
+};
+
+&iwdg2 {
+       timeout-sec = <32>;
+       status = "okay";
+};
+
+&ltdc {
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&ltdc_pins_a>;
+       pinctrl-1 = <&ltdc_pins_sleep_a>;
+       status = "okay";
+
+       port {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ltdc_ep0_out: endpoint@0 {
+                       reg = <0>;
+                       remote-endpoint = <&sii9022_in>;
+               };
+       };
+};
+
+&m4_rproc {
+       memory-region = <&retram>, <&mcuram>, <&mcuram2>, <&vdev0vring0>,
+                       <&vdev0vring1>, <&vdev0buffer>;
+       mboxes = <&ipcc 0>, <&ipcc 1>, <&ipcc 2>;
+       mbox-names = "vq0", "vq1", "shutdown";
+       interrupt-parent = <&exti>;
+       interrupts = <68 1>;
+       status = "okay";
+};
+
+&pwr_regulators {
+       vdd-supply = <&vdd>;
+       vdd_3v3_usbfs-supply = <&vdd_usb>;
+};
+
+&rng1 {
+       status = "okay";
+};
+
+&rtc {
+       status = "okay";
+};
+
+&sai2 {
+       clocks = <&rcc SAI2>, <&rcc PLL3_Q>, <&rcc PLL3_R>;
+       clock-names = "pclk", "x8k", "x11k";
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&sai2a_pins_a>, <&sai2b_pins_b>;
+       pinctrl-1 = <&sai2a_sleep_pins_a>, <&sai2b_sleep_pins_b>;
+       status = "okay";
+
+       sai2a: audio-controller@4400b004 {
+               #clock-cells = <0>;
+               dma-names = "tx";
+               clocks = <&rcc SAI2_K>;
+               clock-names = "sai_ck";
+               status = "okay";
+
+               sai2a_port: port {
+                       sai2a_endpoint: endpoint {
+                               remote-endpoint = <&cs42l51_tx_endpoint>;
+                               format = "i2s";
+                               mclk-fs = <256>;
+                               dai-tdm-slot-num = <2>;
+                               dai-tdm-slot-width = <32>;
+                       };
+               };
+       };
+
+       sai2b: audio-controller@4400b024 {
+               dma-names = "rx";
+               st,sync = <&sai2a 2>;
+               clocks = <&rcc SAI2_K>, <&sai2a>;
+               clock-names = "sai_ck", "MCLK";
+               status = "okay";
+
+               sai2b_port: port {
+                       sai2b_endpoint: endpoint {
+                               remote-endpoint = <&cs42l51_rx_endpoint>;
+                               format = "i2s";
+                               mclk-fs = <256>;
+                               dai-tdm-slot-num = <2>;
+                               dai-tdm-slot-width = <32>;
+                       };
+               };
+       };
+};
+
+&sdmmc1 {
+       pinctrl-names = "default", "opendrain", "sleep";
+       pinctrl-0 = <&sdmmc1_b4_pins_a>;
+       pinctrl-1 = <&sdmmc1_b4_od_pins_a>;
+       pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>;
+       broken-cd;
+       st,neg-edge;
+       bus-width = <4>;
+       vmmc-supply = <&v3v3>;
+       status = "okay";
+};
+
+&sdmmc3 {
+       pinctrl-names = "default", "opendrain", "sleep";
+       pinctrl-0 = <&sdmmc3_b4_pins_a>;
+       pinctrl-1 = <&sdmmc3_b4_od_pins_a>;
+       pinctrl-2 = <&sdmmc3_b4_sleep_pins_a>;
+       broken-cd;
+       st,neg-edge;
+       bus-width = <4>;
+       vmmc-supply = <&v3v3>;
+       status = "disabled";
+};
+
+&timers1 {
+       /* spare dmas for other usage */
+       /delete-property/dmas;
+       /delete-property/dma-names;
+       status = "disabled";
+       pwm {
+               pinctrl-0 = <&pwm1_pins_a>;
+               pinctrl-1 = <&pwm1_sleep_pins_a>;
+               pinctrl-names = "default", "sleep";
+               status = "okay";
+       };
+       timer@0 {
+               status = "okay";
+       };
+};
+
+&timers3 {
+       /delete-property/dmas;
+       /delete-property/dma-names;
+       status = "disabled";
+       pwm {
+               pinctrl-0 = <&pwm3_pins_a>;
+               pinctrl-1 = <&pwm3_sleep_pins_a>;
+               pinctrl-names = "default", "sleep";
+               status = "okay";
+       };
+       timer@2 {
+               status = "okay";
+       };
+};
+
+&timers4 {
+       /delete-property/dmas;
+       /delete-property/dma-names;
+       status = "disabled";
+       pwm {
+               pinctrl-0 = <&pwm4_pins_a &pwm4_pins_b>;
+               pinctrl-1 = <&pwm4_sleep_pins_a &pwm4_sleep_pins_b>;
+               pinctrl-names = "default", "sleep";
+               status = "okay";
+       };
+       timer@3 {
+               status = "okay";
+       };
+};
+
+&timers5 {
+       /delete-property/dmas;
+       /delete-property/dma-names;
+       status = "disabled";
+       pwm {
+               pinctrl-0 = <&pwm5_pins_a>;
+               pinctrl-1 = <&pwm5_sleep_pins_a>;
+               pinctrl-names = "default", "sleep";
+               status = "okay";
+       };
+       timer@4 {
+               status = "okay";
+       };
+};
+
+&timers6 {
+       /delete-property/dmas;
+       /delete-property/dma-names;
+       status = "disabled";
+       timer@5 {
+               status = "okay";
+       };
+};
+
+&timers12 {
+       /delete-property/dmas;
+       /delete-property/dma-names;
+       status = "disabled";
+       pwm {
+               pinctrl-0 = <&pwm12_pins_a>;
+               pinctrl-1 = <&pwm12_sleep_pins_a>;
+               pinctrl-names = "default", "sleep";
+               status = "okay";
+       };
+       timer@11 {
+               status = "okay";
+       };
+};
+
+&uart4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart4_pins_a>;
+       status = "okay";
+};
+
+&usbh_ehci {
+       phys = <&usbphyc_port0>;
+       status = "okay";
+};
+
+&usbotg_hs {
+       dr_mode = "peripheral";
+       phys = <&usbphyc_port1 0>;
+       phy-names = "usb2-phy";
+       status = "okay";
+};
+
+&usbphyc {
+       status = "okay";
+};
+
+&usbphyc_port0 {
+       phy-supply = <&vdd_usb>;
+       vdda1v1-supply = <&reg11>;
+       vdda1v8-supply = <&reg18>;
+};
+
+&usbphyc_port1 {
+       phy-supply = <&vdd_usb>;
+       vdda1v1-supply = <&reg11>;
+       vdda1v8-supply = <&reg18>;
+};
+
+&vrefbuf {
+       regulator-min-microvolt = <2500000>;
+       regulator-max-microvolt = <2500000>;
+       vdda-supply = <&vdd>;
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/stm32mp15xxaa-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15xxaa-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..04f7a43
--- /dev/null
@@ -0,0 +1,85 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+&pinctrl {
+       st,package = <STM32MP_PKG_AA>;
+
+       gpioa: gpio@50002000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 0 16>;
+       };
+
+       gpiob: gpio@50003000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 16 16>;
+       };
+
+       gpioc: gpio@50004000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 32 16>;
+       };
+
+       gpiod: gpio@50005000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 48 16>;
+       };
+
+       gpioe: gpio@50006000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 64 16>;
+       };
+
+       gpiof: gpio@50007000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 80 16>;
+       };
+
+       gpiog: gpio@50008000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 96 16>;
+       };
+
+       gpioh: gpio@50009000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 112 16>;
+       };
+
+       gpioi: gpio@5000a000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 128 16>;
+       };
+
+       gpioj: gpio@5000b000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 144 16>;
+       };
+
+       gpiok: gpio@5000c000 {
+               status = "okay";
+               ngpios = <8>;
+               gpio-ranges = <&pinctrl 0 160 8>;
+       };
+};
+
+&pinctrl_z {
+       st,package = <STM32MP_PKG_AA>;
+
+       gpioz: gpio@54004000 {
+               status = "okay";
+               ngpios = <8>;
+               gpio-ranges = <&pinctrl_z 0 400 8>;
+       };
+};
diff --git a/arch/arm/boot/dts/stm32mp15xxab-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15xxab-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..328dad1
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+&pinctrl {
+       st,package = <STM32MP_PKG_AB>;
+
+       gpioa: gpio@50002000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 0 16>;
+       };
+
+       gpiob: gpio@50003000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 16 16>;
+       };
+
+       gpioc: gpio@50004000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 32 16>;
+       };
+
+       gpiod: gpio@50005000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 48 16>;
+       };
+
+       gpioe: gpio@50006000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 64 16>;
+       };
+
+       gpiof: gpio@50007000 {
+               status = "okay";
+               ngpios = <6>;
+               gpio-ranges = <&pinctrl 6 86 6>;
+       };
+
+       gpiog: gpio@50008000 {
+               status = "okay";
+               ngpios = <10>;
+               gpio-ranges = <&pinctrl 6 102 10>;
+       };
+
+       gpioh: gpio@50009000 {
+               status = "okay";
+               ngpios = <2>;
+               gpio-ranges = <&pinctrl 0 112 2>;
+       };
+};
diff --git a/arch/arm/boot/dts/stm32mp15xxac-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15xxac-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..7eaa245
--- /dev/null
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+&pinctrl {
+       st,package = <STM32MP_PKG_AC>;
+
+       gpioa: gpio@50002000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 0 16>;
+       };
+
+       gpiob: gpio@50003000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 16 16>;
+       };
+
+       gpioc: gpio@50004000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 32 16>;
+       };
+
+       gpiod: gpio@50005000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 48 16>;
+       };
+
+       gpioe: gpio@50006000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 64 16>;
+       };
+
+       gpiof: gpio@50007000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 80 16>;
+       };
+
+       gpiog: gpio@50008000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 96 16>;
+       };
+
+       gpioh: gpio@50009000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 112 16>;
+       };
+
+       gpioi: gpio@5000a000 {
+               status = "okay";
+               ngpios = <12>;
+               gpio-ranges = <&pinctrl 0 128 12>;
+       };
+};
+
+&pinctrl_z {
+       st,package = <STM32MP_PKG_AC>;
+
+       gpioz: gpio@54004000 {
+               status = "okay";
+               ngpios = <8>;
+               gpio-ranges = <&pinctrl_z 0 400 8>;
+       };
+};
diff --git a/arch/arm/boot/dts/stm32mp15xxad-pinctrl.dtsi b/arch/arm/boot/dts/stm32mp15xxad-pinctrl.dtsi
new file mode 100644 (file)
index 0000000..b63e207
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
+/*
+ * Copyright (C) STMicroelectronics 2019 - All Rights Reserved
+ * Author: Alexandre Torgue <alexandre.torgue@st.com> for STMicroelectronics.
+ */
+
+&pinctrl {
+       st,package = <STM32MP_PKG_AD>;
+
+       gpioa: gpio@50002000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 0 16>;
+       };
+
+       gpiob: gpio@50003000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 16 16>;
+       };
+
+       gpioc: gpio@50004000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 32 16>;
+       };
+
+       gpiod: gpio@50005000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 48 16>;
+       };
+
+       gpioe: gpio@50006000 {
+               status = "okay";
+               ngpios = <16>;
+               gpio-ranges = <&pinctrl 0 64 16>;
+       };
+
+       gpiof: gpio@50007000 {
+               status = "okay";
+               ngpios = <6>;
+               gpio-ranges = <&pinctrl 6 86 6>;
+       };
+
+       gpiog: gpio@50008000 {
+               status = "okay";
+               ngpios = <10>;
+               gpio-ranges = <&pinctrl 6 102 10>;
+       };
+
+       gpioh: gpio@50009000 {
+               status = "okay";
+               ngpios = <2>;
+               gpio-ranges = <&pinctrl 0 112 2>;
+       };
+};
index 4c268b7..bf531ef 100644 (file)
                        status = "disabled";
                };
 
+               csi1: csi@1c1d000 {
+                       compatible = "allwinner,sun4i-a10-csi1";
+                       reg = <0x01c1d000 0x1000>;
+                       interrupts = <43>;
+                       clocks = <&ccu CLK_AHB_CSI1>, <&ccu CLK_DRAM_CSI1>;
+                       clock-names = "bus", "ram";
+                       resets = <&ccu RST_CSI1>;
+                       status = "disabled";
+               };
+
                spi3: spi@1c1f000 {
                        compatible = "allwinner,sun4i-a10-spi";
                        reg = <0x01c1f000 0x1000>;
                                function = "can";
                        };
 
+                       /omit-if-no-ref/
+                       csi1_8bits_pg_pins: csi1-8bits-pg-pins {
+                               pins = "PG0", "PG2", "PG3", "PG4", "PG5",
+                                      "PG6", "PG7", "PG8", "PG9", "PG10",
+                                      "PG11";
+                               function = "csi1";
+                       };
+
+                       /omit-if-no-ref/
+                       csi1_24bits_ph_pins: csi1-24bits-ph-pins {
+                               pins = "PH0", "PH1", "PH2", "PH3", "PH4",
+                                      "PH5", "PH6", "PH7", "PH8", "PH9",
+                                      "PH10", "PH11", "PH12", "PH13", "PH14",
+                                      "PH15", "PH16", "PH17", "PH18", "PH19",
+                                      "PH20", "PH21", "PH22", "PH23", "PH24",
+                                      "PH25", "PH26", "PH27";
+                               function = "csi1";
+                       };
+
+                       /omit-if-no-ref/
+                       csi1_clk_pg_pin: csi1-clk-pg-pin {
+                               pins = "PG1";
+                               function = "csi1";
+                       };
+
                        emac_pins: emac0-pins {
                                pins = "PA0", "PA1", "PA2",
                                       "PA3", "PA4", "PA5", "PA6",
index 6befa23..0b526e6 100644 (file)
                mbus: dram-controller@1c01000 {
                        compatible = "allwinner,sun5i-a13-mbus";
                        reg = <0x01c01000 0x1000>;
-                       clocks = <&ccu 99>;
+                       clocks = <&ccu CLK_MBUS>;
                        dma-ranges = <0x00000000 0x40000000 0x20000000>;
                        #interconnect-cells = <1>;
                };
                        compatible = "allwinner,sun5i-a13-tcon";
                        reg = <0x01c0c000 0x1000>;
                        interrupts = <44>;
+                       dmas = <&dma SUN4I_DMA_DEDICATED 14>;
                        resets = <&ccu RST_LCD>;
                        reset-names = "lcd";
                        clocks = <&ccu CLK_AHB_LCD>,
index 2cf34ae..7762fbd 100644 (file)
                        compatible = "allwinner,sun6i-a31-tcon";
                        reg = <0x01c0c000 0x1000>;
                        interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
-                       resets = <&ccu RST_AHB1_LCD0>;
-                       reset-names = "lcd";
+                       dmas = <&dma 11>;
+                       resets = <&ccu RST_AHB1_LCD0>,
+                                <&ccu RST_AHB1_LVDS>;
+                       reset-names = "lcd",
+                                     "lvds";
                        clocks = <&ccu CLK_AHB1_LCD0>,
                                 <&ccu CLK_LCD0_CH0>,
-                                <&ccu CLK_LCD0_CH1>;
+                                <&ccu CLK_LCD0_CH1>,
+                                <&ccu 15>;
                        clock-names = "ahb",
                                      "tcon-ch0",
-                                     "tcon-ch1";
+                                     "tcon-ch1",
+                                     "lvds-alt";
                        clock-output-names = "tcon0-pixel-clock";
                        #clock-cells = <0>;
 
                        compatible = "allwinner,sun6i-a31-tcon";
                        reg = <0x01c0d000 0x1000>;
                        interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
-                       resets = <&ccu RST_AHB1_LCD1>;
-                       reset-names = "lcd";
+                       dmas = <&dma 12>;
+                       resets = <&ccu RST_AHB1_LCD1>,
+                                <&ccu RST_AHB1_LVDS>;
+                       reset-names = "lcd", "lvds";
                        clocks = <&ccu CLK_AHB1_LCD1>,
                                 <&ccu CLK_LCD1_CH0>,
-                                <&ccu CLK_LCD1_CH1>;
+                                <&ccu CLK_LCD1_CH1>,
+                                <&ccu 15>;
                        clock-names = "ahb",
                                      "tcon-ch0",
-                                     "tcon-ch1";
+                                     "tcon-ch1",
+                                     "lvds-alt";
                        clock-output-names = "tcon1-pixel-clock";
                        #clock-cells = <0>;
 
index 8aebefd..92b5be9 100644 (file)
                        status = "disabled";
                };
 
+               csi1: csi@1c1d000 {
+                       compatible = "allwinner,sun7i-a20-csi1",
+                                    "allwinner,sun4i-a10-csi1";
+                       reg = <0x01c1d000 0x1000>;
+                       interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_AHB_CSI1>, <&ccu CLK_DRAM_CSI1>;
+                       clock-names = "bus", "ram";
+                       resets = <&ccu RST_CSI1>;
+                       status = "disabled";
+               };
+
                spi3: spi@1c1f000 {
                        compatible = "allwinner,sun4i-a10-spi";
                        reg = <0x01c1f000 0x1000>;
                        };
 
                        /omit-if-no-ref/
+                       csi1_8bits_pg_pins: csi1-8bits-pg-pins {
+                               pins = "PG0", "PG2", "PG3", "PG4", "PG5",
+                                      "PG6", "PG7", "PG8", "PG9", "PG10",
+                                      "PG11";
+                               function = "csi1";
+                       };
+
+                       /omit-if-no-ref/
+                       csi1_24bits_ph_pins: csi1-24bits-ph-pins {
+                               pins = "PH0", "PH1", "PH2", "PH3", "PH4",
+                                      "PH5", "PH6", "PH7", "PH8", "PH9",
+                                      "PH10", "PH11", "PH12", "PH13", "PH14",
+                                      "PH15", "PH16", "PH17", "PH18", "PH19",
+                                      "PH20", "PH21", "PH22", "PH23", "PH24",
+                                      "PH25", "PH26", "PH27";
+                               function = "csi1";
+                       };
+
+                       /omit-if-no-ref/
+                       csi1_clk_pg_pin: csi1-clk-pg-pin {
+                               pins = "PG1";
+                               function = "csi1";
+                       };
+
+                       /omit-if-no-ref/
                        emac_pa_pins: emac-pa-pins {
                                pins = "PA0", "PA1", "PA2",
                                       "PA3", "PA4", "PA5", "PA6",
index f292f96..48487f6 100644 (file)
                        /* compatible gets set in SoC specific dtsi file */
                        reg = <0x01c0c000 0x1000>;
                        interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas = <&dma 12>;
                        clocks = <&ccu CLK_BUS_LCD>,
-                                <&ccu CLK_LCD_CH0>;
+                                <&ccu CLK_LCD_CH0>,
+                                <&ccu 13>;
                        clock-names = "ahb",
-                                     "tcon-ch0";
+                                     "tcon-ch0",
+                                     "lvds-alt";
                        clock-output-names = "tcon-pixel-clock";
                        #clock-cells = <0>;
-                       resets = <&ccu RST_BUS_LCD>;
-                       reset-names = "lcd";
+                       resets = <&ccu RST_BUS_LCD>,
+                                <&ccu RST_BUS_LVDS>;
+                       reset-names = "lcd",
+                                     "lvds";
                        status = "disabled";
 
                        ports {
index 53c38de..74ac7ee 100644 (file)
@@ -50,6 +50,7 @@
 #include <dt-bindings/reset/sun8i-a83t-ccu.h>
 #include <dt-bindings/reset/sun8i-de2.h>
 #include <dt-bindings/reset/sun8i-r-ccu.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
        interrupt-parent = <&gic>;
                sid: eeprom@1c14000 {
                        compatible = "allwinner,sun8i-a83t-sid";
                        reg = <0x1c14000 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       ths_calibration: thermal-sensor-calibration@34 {
+                               reg = <0x34 8>;
+                       };
                };
 
                crypto: crypto@1c15000 {
                        reg = <0x01c30000 0x104>;
                        interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "macirq";
-                       resets = <&ccu 13>;
+                       resets = <&ccu CLK_BUS_EMAC>;
                        reset-names = "stmmaceth";
-                       clocks = <&ccu 27>;
+                       clocks = <&ccu RST_BUS_EMAC>;
                        clock-names = "stmmaceth";
                        status = "disabled";
 
                        compatible = "allwinner,sun8i-a83t-r-ccu";
                        reg = <0x01f01400 0x400>;
                        clocks = <&osc24M>, <&osc16Md512>, <&osc16M>,
-                                <&ccu 6>;
+                                <&ccu CLK_PLL_PERIPH>;
                        clock-names = "hosc", "losc", "iosc", "pll-periph";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                };
+
+               ths: thermal-sensor@1f04000 {
+                       compatible = "allwinner,sun8i-a83t-ths";
+                       reg = <0x01f04000 0x100>;
+                       interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>;
+                       nvmem-cells = <&ths_calibration>;
+                       nvmem-cell-names = "calibration";
+                       #thermal-sensor-cells = <1>;
+               };
+       };
+
+       thermal-zones {
+               cpu0_thermal: cpu0-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 0>;
+               };
+
+               cpu1_thermal: cpu1-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 1>;
+               };
+
+               gpu_thermal: gpu-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 2>;
+               };
        };
 };
index ac9e26b..45a2444 100644 (file)
 };
 
 &ir {
+       linux,rc-map-name = "rc-tanix-tx3mini";
        pinctrl-names = "default";
        pinctrl-0 = <&r_ir_rx_pin>;
        status = "okay";
diff --git a/arch/arm/boot/dts/sun8i-h3-emlid-neutis-n5h3-devboard.dts b/arch/arm/boot/dts/sun8i-h3-emlid-neutis-n5h3-devboard.dts
new file mode 100644 (file)
index 0000000..02fbe00
--- /dev/null
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * DTS for Emlid Neutis N5 Dev board.
+ *
+ * Copyright (C) 2019 Georgii Staroselskii <georgiii.staroselskii@emlid.com>
+ */
+
+/dts-v1/;
+
+#include "sun8i-h3-emlid-neutis-n5h3.dtsi"
+
+/ {
+       model = "Emlid Neutis N5H3 Developer board";
+       compatible = "emlid,neutis-n5h3-devboard",
+                    "emlid,neutis-n5h3",
+                    "allwinner,sun8i-h3";
+
+       vdd_cpux: gpio-regulator {
+               compatible = "regulator-gpio";
+               regulator-name = "vdd-cpux";
+               regulator-type = "voltage";
+               regulator-boot-on;
+               regulator-always-on;
+               regulator-min-microvolt = <1100000>;
+               regulator-max-microvolt = <1300000>;
+               regulator-ramp-delay = <50>; /* 4ms */
+               gpios = <&r_pio 0 6 GPIO_ACTIVE_HIGH>; /* PL6 */
+               gpios-states = <0x1>;
+               states = <1100000 0x0>, <1300000 0x1>;
+       };
+
+       connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_cpux>;
+};
+
+&codec {
+       status = "okay";
+};
+
+&emac {
+       phy-handle = <&int_mii_phy>;
+       phy-mode = "mii";
+       allwinner,leds-active-low;
+       status = "okay";
+};
+
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
+&i2c1 {
+       status = "okay";
+};
diff --git a/arch/arm/boot/dts/sun8i-h3-emlid-neutis-n5h3.dtsi b/arch/arm/boot/dts/sun8i-h3-emlid-neutis-n5h3.dtsi
new file mode 100644 (file)
index 0000000..eedd5da
--- /dev/null
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * DTSI for Emlid Neutis N5 SoM.
+ *
+ * Copyright (C) 2019 Georgii Staroselskii <georgii.staroselskii@emlid.com>
+ */
+
+/dts-v1/;
+
+#include "sun8i-h3.dtsi"
+#include <arm/sunxi-h3-h5-emlid-neutis.dtsi>
index c73f599..6b14927 100644 (file)
@@ -60,8 +60,7 @@
                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>;
+               states = <1100000 0>, <1300000 1>;
        };
 
        reg_vcc_dram: vcc-dram {
index fe773c7..20217e2 100644 (file)
@@ -80,7 +80,7 @@
                        #cooling-cells = <2>;
                };
 
-               cpu@1 {
+               cpu1: cpu@1 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <1>;
@@ -90,7 +90,7 @@
                        #cooling-cells = <2>;
                };
 
-               cpu@2 {
+               cpu2: cpu@2 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <2>;
                        #cooling-cells = <2>;
                };
 
-               cpu@3 {
+               cpu3: cpu@3 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <3>;
                };
        };
 
+       pmu {
+               compatible = "arm,cortex-a7-pmu";
+               interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
        timer {
                compatible = "arm,armv7-timer";
                interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
                        assigned-clocks = <&ccu CLK_GPU>;
                        assigned-clock-rates = <384000000>;
                };
+
+               ths: thermal-sensor@1c25000 {
+                       compatible = "allwinner,sun8i-h3-ths";
+                       reg = <0x01c25000 0x400>;
+                       interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+                       resets = <&ccu RST_BUS_THS>;
+                       clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
+                       clock-names = "bus", "mod";
+                       nvmem-cells = <&ths_calibration>;
+                       nvmem-cell-names = "calibration";
+                       #thermal-sensor-cells = <0>;
+               };
+       };
+
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 0>;
+               };
        };
 };
 
index 421dfbb..8f09a24 100644 (file)
@@ -44,6 +44,7 @@
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/sun8i-de2.h>
 #include <dt-bindings/clock/sun8i-r40-ccu.h>
+#include <dt-bindings/clock/sun8i-tcon-top.h>
 #include <dt-bindings/reset/sun8i-r40-ccu.h>
 #include <dt-bindings/reset/sun8i-de2.h>
 
                #address-cells = <1>;
                #size-cells = <0>;
 
-               cpu@0 {
+               cpu0: cpu@0 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <0>;
                };
 
-               cpu@1 {
+               cpu1: cpu@1 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <1>;
                };
 
-               cpu@2 {
+               cpu2: cpu@2 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <2>;
                };
 
-               cpu@3 {
+               cpu3: cpu@3 {
                        compatible = "arm,cortex-a7";
                        device_type = "cpu";
                        reg = <3>;
                        interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+               csi0: csi@1c09000 {
+                       compatible = "allwinner,sun8i-r40-csi0",
+                                    "allwinner,sun7i-a20-csi0";
+                       reg = <0x01c09000 0x1000>;
+                       interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_CSI0>, <&ccu CLK_CSI_SCLK>,
+                                <&ccu CLK_DRAM_CSI0>;
+                       clock-names = "bus", "isp", "ram";
+                       resets = <&ccu RST_BUS_CSI0>;
+                       interconnects = <&mbus 5>;
+                       interconnect-names = "dma-mem";
+                       status = "disabled";
+               };
+
                mmc0: mmc@1c0f000 {
                        compatible = "allwinner,sun8i-r40-mmc",
                                     "allwinner,sun50i-a64-mmc";
                                function = "clk_out_a";
                        };
 
+                       /omit-if-no-ref/
+                       csi0_8bits_pins: csi0-8bits-pins {
+                               pins = "PE0", "PE2", "PE3", "PE4", "PE5",
+                                      "PE6", "PE7", "PE8", "PE9", "PE10",
+                                      "PE11";
+                               function = "csi0";
+                       };
+
+                       /omit-if-no-ref/
+                       csi0_mclk_pin: csi0-mclk-pin {
+                               pins = "PE1";
+                               function = "csi0";
+                       };
+
                        gmac_rgmii_pins: gmac-rgmii-pins {
                                pins = "PA0", "PA1", "PA2", "PA3",
                                       "PA4", "PA5", "PA6", "PA7",
                                function = "i2c0";
                        };
 
+                       i2c1_pins: i2c1-pins {
+                               pins = "PB18", "PB19";
+                               function = "i2c1";
+                       };
+
+                       i2c2_pins: i2c2-pins {
+                               pins = "PB20", "PB21";
+                               function = "i2c2";
+                       };
+
+                       i2c3_pins: i2c3-pins {
+                               pins = "PI0", "PI1";
+                               function = "i2c3";
+                       };
+
+                       i2c4_pins: i2c4-pins {
+                               pins = "PI2", "PI3";
+                               function = "i2c4";
+                       };
+
                        mmc0_pins: mmc0-pins {
                                pins = "PF0", "PF1", "PF2",
                                       "PF3", "PF4", "PF5";
                                bias-pull-up;
                        };
 
+                       /omit-if-no-ref/
+                       spi0_pc_pins: spi0-pc-pins {
+                               pins = "PC0", "PC1", "PC2";
+                               function = "spi0";
+                       };
+
+                       /omit-if-no-ref/
+                       spi0_cs0_pc_pin: spi0-cs0-pc-pin {
+                               pins = "PC23";
+                               function = "spi0";
+                       };
+
+                       /omit-if-no-ref/
+                       spi1_pi_pins: spi1-pi-pins {
+                               pins = "PI17", "PI18", "PI19";
+                               function = "spi1";
+                       };
+
+                       /omit-if-no-ref/
+                       spi1_cs0_pi_pin: spi1-cs0-pi-pin {
+                               pins = "PI16";
+                               function = "spi1";
+                       };
+
+                       /omit-if-no-ref/
+                       spi1_cs1_pi_pin: spi1-cs1-pi-pin {
+                               pins = "PI15";
+                               function = "spi1";
+                       };
+
                        uart0_pb_pins: uart0-pb-pins {
                                pins = "PB22", "PB23";
                                function = "uart0";
                        interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ccu CLK_BUS_I2C1>;
                        resets = <&ccu RST_BUS_I2C1>;
+                       pinctrl-0 = <&i2c1_pins>;
+                       pinctrl-names = "default";
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ccu CLK_BUS_I2C2>;
                        resets = <&ccu RST_BUS_I2C2>;
+                       pinctrl-0 = <&i2c2_pins>;
+                       pinctrl-names = "default";
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ccu CLK_BUS_I2C3>;
                        resets = <&ccu RST_BUS_I2C3>;
+                       pinctrl-0 = <&i2c3_pins>;
+                       pinctrl-names = "default";
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ccu CLK_BUS_I2C4>;
                        resets = <&ccu RST_BUS_I2C4>;
+                       pinctrl-0 = <&i2c4_pins>;
+                       pinctrl-names = "default";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi0: spi@1c05000 {
+                       compatible = "allwinner,sun8i-r40-spi",
+                                    "allwinner,sun8i-h3-spi";
+                       reg = <0x01c05000 0x1000>;
+                       interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>;
+                       clock-names = "ahb", "mod";
+                       resets = <&ccu RST_BUS_SPI0>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi1: spi@1c06000 {
+                       compatible = "allwinner,sun8i-r40-spi",
+                                    "allwinner,sun8i-h3-spi";
+                       reg = <0x01c06000 0x1000>;
+                       interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_SPI1>, <&ccu CLK_SPI1>;
+                       clock-names = "ahb", "mod";
+                       resets = <&ccu RST_BUS_SPI1>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi2: spi@1c07000 {
+                       compatible = "allwinner,sun8i-r40-spi",
+                                    "allwinner,sun8i-h3-spi";
+                       reg = <0x01c07000 0x1000>;
+                       interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_SPI2>, <&ccu CLK_SPI2>;
+                       clock-names = "ahb", "mod";
+                       resets = <&ccu RST_BUS_SPI2>;
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               spi3: spi@1c0f000 {
+                       compatible = "allwinner,sun8i-r40-spi",
+                                    "allwinner,sun8i-h3-spi";
+                       reg = <0x01c0f000 0x1000>;
+                       interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_SPI3>, <&ccu CLK_SPI3>;
+                       clock-names = "ahb", "mod";
+                       resets = <&ccu RST_BUS_SPI3>;
                        status = "disabled";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        };
                };
 
+               mbus: dram-controller@1c62000 {
+                       compatible = "allwinner,sun8i-r40-mbus";
+                       reg = <0x01c62000 0x1000>;
+                       clocks = <&ccu 155>;
+                       dma-ranges = <0x00000000 0x40000000 0x80000000>;
+                       #interconnect-cells = <1>;
+               };
+
                tcon_top: tcon-top@1c70000 {
                        compatible = "allwinner,sun8i-r40-tcon-top";
                        reg = <0x01c70000 0x1000>;
                        compatible = "allwinner,sun8i-r40-tcon-tv";
                        reg = <0x01c73000 0x1000>;
                        interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top 0>;
+                       clocks = <&ccu CLK_BUS_TCON_TV0>, <&tcon_top CLK_TCON_TOP_TV0>;
                        clock-names = "ahb", "tcon-ch1";
                        resets = <&ccu RST_BUS_TCON_TV0>;
                        reset-names = "lcd";
                        compatible = "allwinner,sun8i-r40-tcon-tv";
                        reg = <0x01c74000 0x1000>;
                        interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top 1>;
+                       clocks = <&ccu CLK_BUS_TCON_TV1>, <&tcon_top CLK_TCON_TOP_TV1>;
                        clock-names = "ahb", "tcon-ch1";
                        resets = <&ccu RST_BUS_TCON_TV1>;
                        reset-names = "lcd";
                gic: interrupt-controller@1c81000 {
                        compatible = "arm,gic-400";
                        reg = <0x01c81000 0x1000>,
-                             <0x01c82000 0x1000>,
+                             <0x01c82000 0x2000>,
                              <0x01c84000 0x2000>,
                              <0x01c86000 0x2000>;
                        interrupt-controller;
                        compatible = "allwinner,sun8i-r40-hdmi-phy";
                        reg = <0x01ef0000 0x10000>;
                        clocks = <&ccu CLK_BUS_HDMI1>, <&ccu CLK_HDMI_SLOW>,
-                                <&ccu 7>, <&ccu 16>;
+                                <&ccu CLK_PLL_VIDEO0>, <&ccu CLK_PLL_VIDEO1>;
                        clock-names = "bus", "mod", "pll-0", "pll-1";
                        resets = <&ccu RST_BUS_HDMI0>;
                        reset-names = "phy";
                };
        };
 
+       pmu {
+               compatible = "arm,cortex-a7-pmu";
+               interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
        timer {
                compatible = "arm,armv7-timer";
                interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>,
index 23ba56d..81ea508 100644 (file)
                        clock-names = "bus",
                                      "mod";
                        resets = <&display_clocks 0>;
-                       assigned-clocks = <&display_clocks 6>;
-                       assigned-clock-rates = <150000000>;
 
                        ports {
                                #address-cells = <1>;
index 1d900f5..ce4fa67 100644 (file)
                usbphy2: phy@a01800 {
                        compatible = "allwinner,sun9i-a80-usb-phy";
                        reg = <0x00a01800 0x4>;
-                       clocks = <&usb_clocks CLK_USB1_HSIC>,
+                       clocks = <&usb_clocks CLK_USB1_PHY>,
                                 <&usb_clocks CLK_USB_HSIC>,
-                                <&usb_clocks CLK_USB1_PHY>;
-                       clock-names = "hsic_480M",
+                                <&usb_clocks CLK_USB1_HSIC>;
+                       clock-names = "phy",
                                      "hsic_12M",
-                                     "phy";
-                       resets = <&usb_clocks RST_USB1_HSIC>,
-                                <&usb_clocks RST_USB1_PHY>;
-                       reset-names = "hsic",
-                                     "phy";
+                                     "hsic_480M";
+                       resets = <&usb_clocks RST_USB1_PHY>,
+                                <&usb_clocks RST_USB1_HSIC>;
+                       reset-names = "phy",
+                                     "hsic";
                        status = "disabled";
                        #phy-cells = <0>;
                        /* usb1 is always used with HSIC */
                usbphy3: phy@a02800 {
                        compatible = "allwinner,sun9i-a80-usb-phy";
                        reg = <0x00a02800 0x4>;
-                       clocks = <&usb_clocks CLK_USB2_HSIC>,
+                       clocks = <&usb_clocks CLK_USB2_PHY>,
                                 <&usb_clocks CLK_USB_HSIC>,
-                                <&usb_clocks CLK_USB2_PHY>;
-                       clock-names = "hsic_480M",
+                                <&usb_clocks CLK_USB2_HSIC>;
+                       clock-names = "phy",
                                      "hsic_12M",
-                                     "phy";
-                       resets = <&usb_clocks RST_USB2_HSIC>,
-                                <&usb_clocks RST_USB2_PHY>;
-                       reset-names = "hsic",
-                                     "phy";
+                                     "hsic_480M";
+                       resets = <&usb_clocks RST_USB2_PHY>,
+                                <&usb_clocks RST_USB2_HSIC>;
+                       reset-names = "phy",
+                                     "hsic";
                        status = "disabled";
                        #phy-cells = <0>;
                };
                        compatible = "allwinner,sun9i-a80-mmc-config-clk";
                        reg = <0x01c13000 0x10>;
                        clocks = <&ccu CLK_BUS_MMC>;
-                       clock-names = "ahb";
                        resets = <&ccu RST_BUS_MMC>;
-                       reset-names = "ahb";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
                        clock-output-names = "mmc0_config", "mmc1_config",
                        interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&ccu CLK_BUS_LCD0>, <&ccu CLK_LCD0>;
                        clock-names = "ahb", "tcon-ch0";
-                       resets = <&ccu RST_BUS_LCD0>, <&ccu RST_BUS_EDP>;
-                       reset-names = "lcd", "edp";
+                       resets = <&ccu RST_BUS_LCD0>,
+                                <&ccu RST_BUS_EDP>,
+                                <&ccu RST_BUS_LVDS>;
+                       reset-names = "lcd",
+                                     "edp",
+                                     "lvds";
                        clock-output-names = "tcon0-pixel-clock";
                        #clock-cells = <0>;
 
diff --git a/arch/arm/boot/dts/sunxi-h3-h5-emlid-neutis.dtsi b/arch/arm/boot/dts/sunxi-h3-h5-emlid-neutis.dtsi
new file mode 100644 (file)
index 0000000..fc67e30
--- /dev/null
@@ -0,0 +1,170 @@
+// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+/*
+ * DTSI for Emlid Neutis SoMs.
+ *
+ * Copyright (C) 2019 Georgii Staroselskii <georgii.staroselskii@emlid.com>
+ */
+
+#include "sunxi-common-regulators.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+
+/ {
+       aliases {
+               serial0 = &uart0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       wifi_pwrseq: wifi_pwrseq {
+               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";
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&vdd_cpux>;
+};
+
+&reg_usb0_vbus {
+       gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>;   /* PL9 */
+       status = "okay";
+};
+
+
+&de {
+       status = "okay";
+};
+
+&ohci0 {
+       status = "okay";
+};
+
+&ohci1 {
+       status = "okay";
+};
+
+&ohci2 {
+       status = "okay";
+};
+
+&ohci3 {
+       status = "okay";
+};
+
+
+&ehci0 {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&ehci2 {
+       status = "okay";
+};
+
+&ehci3 {
+       status = "okay";
+};
+
+&mmc0 {
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <4>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+       status = "okay";
+};
+
+
+&mmc1 {
+       vmmc-supply = <&reg_vcc3v3>;
+       vqmmc-supply = <&reg_vcc3v3>;
+       mmc-pwrseq = <&wifi_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       status = "okay";
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+               interrupt-parent = <&r_pio>;
+               interrupts = <0 5 IRQ_TYPE_LEVEL_LOW>;  /* PL5 */
+               interrupt-names = "host-wake";
+       };
+};
+
+&mmc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mmc2_8bit_pins>;
+       vmmc-supply = <&reg_vcc3v3>;
+       bus-width = <8>;
+       non-removable;
+       cap-mmc-hw-reset;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pa_pins>;
+       status = "okay";
+};
+
+
+&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 */
+       };
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart2_pins>;
+       status = "okay";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart3_pins>;
+       status = "okay";
+};
+
+&usbphy {
+       usb0_id_det-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+       usb0_vbus-supply = <&reg_usb0_vbus>;
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&codec {
+       allwinner,audio-routing =
+               "Line Out", "LINEOUT",
+               "LINEIN", "Line In",
+               "MIC1", "Mic",
+               "MIC2", "Mic",
+               "Mic",  "MBIAS";
+};
+
+&i2c0 {
+       status = "okay";
+};
index 0afea59..5e9c306 100644 (file)
                sid: eeprom@1c14000 {
                        /* compatible is in per SoC .dtsi file */
                        reg = <0x1c14000 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       ths_calibration: thermal-sensor-calibration@34 {
+                               reg = <0x34 4>;
+                       };
                };
 
                usb_otg: usb@1c19000 {
                mbus: dram-controller@1c62000 {
                        compatible = "allwinner,sun8i-h3-mbus";
                        reg = <0x01c62000 0x1000>;
-                       clocks = <&ccu 113>;
+                       clocks = <&ccu CLK_MBUS>;
                        dma-ranges = <0x00000000 0x40000000 0xc0000000>;
                        #interconnect-cells = <1>;
                };
                        compatible = "allwinner,sun8i-h3-hdmi-phy";
                        reg = <0x01ef0000 0x10000>;
                        clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_DDC>,
-                                <&ccu 6>;
+                                <&ccu CLK_PLL_VIDEO>;
                        clock-names = "bus", "mod", "pll-0";
                        resets = <&ccu RST_BUS_HDMI0>;
                        reset-names = "phy";
                r_ccu: clock@1f01400 {
                        compatible = "allwinner,sun8i-h3-r-ccu";
                        reg = <0x01f01400 0x100>;
-                       clocks = <&osc24M>, <&rtc 0>, <&rtc 2>, <&ccu 9>;
+                       clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
+                                <&ccu CLK_PLL_PERIPH0>;
                        clock-names = "hosc", "losc", "iosc", "pll-periph";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
diff --git a/arch/arm/boot/dts/sunxi-libretech-all-h3-it.dtsi b/arch/arm/boot/dts/sunxi-libretech-all-h3-it.dtsi
new file mode 100644 (file)
index 0000000..204fba3
--- /dev/null
@@ -0,0 +1,180 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2019 Chen-Yu Tsai <wens@csie.org>
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+
+/ {
+       aliases {
+               serial0 = &uart0;
+               spi0 = &spi0;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       connector {
+               compatible = "hdmi-connector";
+               type = "d";
+
+               port {
+                       hdmi_con_in: endpoint {
+                               remote-endpoint = <&hdmi_out_con>;
+                       };
+               };
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               status_led {
+                       label = "librecomputer:blue:status";
+                       gpios = <&pio 0 7 GPIO_ACTIVE_HIGH>; /* PA7 */
+               };
+       };
+
+       reg_vcc3v3: vcc3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&reg_vcc5v0>;
+       };
+
+       /* This represents the board's 5V input */
+       reg_vcc5v0: vcc5v0 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+               regulator-boot-on;
+       };
+
+       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;
+               vin-supply = <&reg_vcc5v0>;
+               gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>; /* PL9 */
+               enable-active-high;
+       };
+
+       reg_vcc_io: vcc-io {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc-io";
+               /* This is simply a MOSFET switch */
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&reg_vcc3v3>;
+               gpio = <&r_pio 0 5 GPIO_ACTIVE_LOW>; /* PL5 */
+       };
+
+       reg_vcc_usbwifi: vcc-usbwifi {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc-usbwifi";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&reg_vcc5v0>;
+               gpio = <&pio 6 4 GPIO_ACTIVE_HIGH>; /* PG4 */
+               enable-active-high;
+       };
+
+       reg_vdd_cpux: vdd-cpux {
+               compatible = "regulator-fixed";
+               regulator-name = "vdd-cpux";
+               regulator-min-microvolt = <1100000>;
+               regulator-max-microvolt = <1100000>;
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&reg_vcc5v0>;
+               gpio = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
+               enable-active-high;
+       };
+};
+
+&cpu0 {
+       cpu-supply = <&reg_vdd_cpux>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_vdd_cpux>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_vdd_cpux>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_vdd_cpux>;
+};
+
+&de {
+       status = "okay";
+};
+
+&ehci1 {
+       status = "okay";
+};
+
+&hdmi {
+       status = "okay";
+};
+
+&hdmi_out {
+       hdmi_out_con: endpoint {
+               remote-endpoint = <&hdmi_con_in>;
+       };
+};
+
+&mmc0 {
+       vmmc-supply = <&reg_vcc_io>;
+       bus-width = <4>;
+       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
+       status = "okay";
+};
+
+&pio {
+       vcc-pa-supply = <&reg_vcc_io>;
+       vcc-pc-supply = <&reg_vcc_io>;
+       vcc-pd-supply = <&reg_vcc_io>;
+       vcc-pe-supply = <&reg_vcc_io>;
+       vcc-pf-supply = <&reg_vcc_io>;
+       vcc-pg-supply = <&reg_vcc_io>;
+};
+
+&r_pio {
+       vcc-pl-supply = <&reg_vcc3v3>;
+};
+
+&spi0 {
+       status = "okay";
+
+       spiflash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_pa_pins>;
+       status = "okay";
+};
+
+&usb_otg {
+       dr_mode = "peripheral";
+       status = "okay";
+};
+
+&usbphy {
+       usb1_vbus-supply = <&reg_vcc_usbwifi>;
+       status = "okay";
+};
index d18eaf4..3240145 100644 (file)
@@ -84,7 +84,7 @@
                };
        };
 
-       emc@7001b000 {
+       external-memory-controller@7001b000 {
                emc-timings-1 {
                        nvidia,ram-code = <1>;
 
index 784a529..861d3f2 100644 (file)
@@ -79,7 +79,7 @@
                };
        };
 
-       emc@7001b000 {
+       external-memory-controller@7001b000 {
                emc-timings-3 {
                        nvidia,ram-code = <3>;
 
index fb6b3e1..c91647d 100644 (file)
                };
        };
 
-       emc@7001b000 {
+       external-memory-controller@7001b000 {
                emc-timings-1 {
                        nvidia,ram-code = <1>;
 
index c7c31d4..d2beea0 100644 (file)
@@ -68,7 +68,7 @@
                };
        };
 
-       emc@7001b000 {
+       external-memory-controller@7001b000 {
                emc-timings-1 {
                        nvidia,ram-code = <1>;
 
index 413bfb9..7f330b1 100644 (file)
                #iommu-cells = <1>;
        };
 
-       emc: emc@7001b000 {
+       emc: external-memory-controller@7001b000 {
                compatible = "nvidia,tegra124-emc";
                reg = <0x0 0x7001b000 0x0 0x1000>;
+               clocks = <&tegra_car TEGRA124_CLK_EMC>;
+               clock-names = "emc";
 
                nvidia,memory-controller = <&mc>;
        };
index 85fce5b..be0ab9b 100644 (file)
                reset-names = "i2c";
        };
 
+       memory-controller@7000f400 {
+               nvidia,use-ram-code;
+
+               emc-tables@hynix {
+                       nvidia,ram-code = <0x0>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       emc-table@166500 {
+                               reg = <166500>;
+                               compatible = "nvidia,tegra20-emc-table";
+                               clock-frequency = <166500>;
+                               nvidia,emc-registers = <0x0000000a 0x00000016
+                                       0x00000008 0x00000003 0x00000004 0x00000004
+                                       0x00000002 0x0000000c 0x00000003 0x00000003
+                                       0x00000002 0x00000001 0x00000004 0x00000005
+                                       0x00000004 0x00000009 0x0000000d 0x000004df
+                                       0x00000000 0x00000003 0x00000003 0x00000003
+                                       0x00000003 0x00000001 0x0000000a 0x000000c8
+                                       0x00000003 0x00000006 0x00000004 0x00000008
+                                       0x00000002 0x00000000 0x00000000 0x00000002
+                                       0x00000000 0x00000000 0x00000083 0xe03b0323
+                                       0x007fe010 0x00001414 0x00000000 0x00000000
+                                       0x00000000 0x00000000 0x00000000 0x00000000>;
+                       };
+
+                       emc-table@333000 {
+                               reg = <333000>;
+                               compatible = "nvidia,tegra20-emc-table";
+                               clock-frequency = <333000>;
+                               nvidia,emc-registers = <0x00000018 0x00000033
+                                       0x00000012 0x00000004 0x00000004 0x00000005
+                                       0x00000003 0x0000000c 0x00000006 0x00000006
+                                       0x00000003 0x00000001 0x00000004 0x00000005
+                                       0x00000004 0x00000009 0x0000000d 0x00000bff
+                                       0x00000000 0x00000003 0x00000003 0x00000006
+                                       0x00000006 0x00000001 0x00000011 0x000000c8
+                                       0x00000003 0x0000000e 0x00000007 0x00000008
+                                       0x00000002 0x00000000 0x00000000 0x00000002
+                                       0x00000000 0x00000000 0x00000083 0xf0440303
+                                       0x007fe010 0x00001414 0x00000000 0x00000000
+                                       0x00000000 0x00000000 0x00000000 0x00000000>;
+                       };
+               };
+       };
+
        i2c@7000d000 {
                status = "okay";
                clock-frequency = <400000>;
index 58cd4e8..64ec46c 100644 (file)
                        pinctrl-0 = <&pinctrl_nand>;
                        clock-names = "nand", "nand_x", "ecc";
                        clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
-                       resets = <&sys_rst 2>;
+                       reset-names = "nand", "reg";
+                       resets = <&sys_rst 2>, <&sys_rst 2>;
                };
        };
 };
index 1fee5ff..bfdfb76 100644 (file)
                function = "i2c4";
        };
 
+       pinctrl_i2c5: i2c5 {
+               groups = "i2c5";
+               function = "i2c5";
+       };
+
+       pinctrl_i2c6: i2c6 {
+               groups = "i2c6";
+               function = "i2c6";
+       };
+
        pinctrl_nand: nand {
                groups = "nand";
                function = "nand";
index 7f64e5a..2ec04d7 100644 (file)
                        pinctrl-0 = <&pinctrl_nand>;
                        clock-names = "nand", "nand_x", "ecc";
                        clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
-                       resets = <&sys_rst 2>;
+                       reset-names = "nand", "reg";
+                       resets = <&sys_rst 2>, <&sys_rst 2>;
                };
        };
 };
index eff7471..ea3961f 100644 (file)
                        pinctrl-0 = <&pinctrl_nand>;
                        clock-names = "nand", "nand_x", "ecc";
                        clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
-                       resets = <&sys_rst 2>;
+                       reset-names = "nand", "reg";
+                       resets = <&sys_rst 2>, <&sys_rst 2>;
                };
 
                emmc: sdhc@68400000 {
index 4eddbb8..13b0d4a 100644 (file)
                        pinctrl-0 = <&pinctrl_nand>;
                        clock-names = "nand", "nand_x", "ecc";
                        clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
-                       resets = <&sys_rst 2>;
+                       reset-names = "nand", "reg";
+                       resets = <&sys_rst 2>, <&sys_rst 2>;
                };
        };
 };
index cbebb6e..4fc6676 100644 (file)
                        pinctrl-0 = <&pinctrl_nand>;
                        clock-names = "nand", "nand_x", "ecc";
                        clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
-                       resets = <&sys_rst 2>;
+                       reset-names = "nand", "reg";
+                       resets = <&sys_rst 2>, <&sys_rst 2>;
                };
        };
 };
index 48086c5..e500911 100644 (file)
 };
 
 &i2c0 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c0>;
-       status = "okay";
-
        gpio5: io-expander@20 {
                compatible = "nxp,pca9554";
                reg = <0x20>;
 };
 
 &i2c2 {
-       clock-frequency = <100000>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pinctrl_i2c2>;
-       status = "okay";
-
        tca9548@70 {
                compatible = "nxp,pca9548";
                pinctrl-0 = <&pinctrl_i2c_mux_reset>;
index d7caf61..b642520 100644 (file)
        pinctrl-0 = <&pinctrl_dspi1>;
        status = "okay";
 
-       spi-flash@0 {
+       flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "jedec,spi-nor";
                };
        };
 
-       spi-flash@1 {
+       flash@1 {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "jedec,spi-nor";
                #gpio-cells = <2>;
        };
 
-       lm75@48 {
+       temp-sensor@48 {
                compatible = "national,lm75";
                reg = <0x48>;
        };
                reg = <0x52>;
        };
 
-       ds1682@6b {
+       elapsed-time-recorder@6b {
                compatible = "dallas,ds1682";
                reg = <0x6b>;
        };
        pinctrl-0 = <&pinctrl_i2c1>;
        status = "okay";
 
-       adt7411@4a {
+       watchdog@38 {
+               compatible = "zii,rave-wdt";
+               reg = <0x38>;
+       };
+
+       adc@4a {
                compatible = "adi,adt7411";
                reg = <0x4a>;
        };
        pinctrl-0 = <&pinctrl_i2c2>;
        status = "okay";
 
-       gpio9: sx1503q@20 {
+       gpio9: io-expander@20 {
                compatible = "semtech,sx1503q";
                pinctrl-names = "default";
                pinctrl-0 = <&pinctrl_sx1503_20>;
                interrupts = <31 IRQ_TYPE_EDGE_FALLING>;
        };
 
-       lm75@4e {
+       temp-sensor@4e {
                compatible = "national,lm75";
                reg = <0x4e>;
        };
 
-       lm75@4f {
+       temp-sensor@4f {
                compatible = "national,lm75";
                reg = <0x4f>;
        };
                reg = <0x23>;
        };
 
-       adt7411@4a {
+       adc@4a {
                compatible = "adi,adt7411";
                reg = <0x4a>;
        };
 
-       at24c08@54 {
+       eeprom@54 {
                compatible = "atmel,24c08";
                reg = <0x54>;
        };
 
-       tca9548@70 {
+       i2c-mux@70 {
                compatible = "nxp,pca9548";
                pinctrl-names = "default";
                #address-cells = <1>;
                };
        };
 
-       tca9548@71 {
+       i2c-mux@71 {
                compatible = "nxp,pca9548";
                pinctrl-names = "default";
                reg = <0x71>;
index ca6425a..db3899b 100644 (file)
                regulator-always-on;
        };
 
+       replicator {
+               compatible = "arm,coresight-static-replicator";
+               clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
+               clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
+
+               out-ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       /* replicator output ports */
+                       port@0 {
+                               reg = <0>;
+                               replicator_out_port0: endpoint {
+                                       remote-endpoint = <&tpiu_in_port>;
+                               };
+                       };
+                       port@1 {
+                               reg = <1>;
+                               replicator_out_port1: endpoint {
+                                       remote-endpoint = <&etb_in_port>;
+                               };
+                       };
+               };
+               in-ports {
+                       /* replicator input port */
+                       port {
+                               replicator_in_port0: endpoint {
+                                       remote-endpoint = <&funnel_out_port>;
+                               };
+                       };
+               };
+       };
+
        amba: amba {
                compatible = "simple-bus";
                #address-cells = <1>;
                        reg = <0xf8005000 0x1000>;
                        timeout-sec = <10>;
                };
+
+               etb@f8801000 {
+                       compatible = "arm,coresight-etb10", "arm,primecell";
+                       reg = <0xf8801000 0x1000>;
+                       clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
+                       clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
+                       in-ports {
+                               port {
+                                       etb_in_port: endpoint {
+                                               remote-endpoint = <&replicator_out_port1>;
+                                       };
+                               };
+                       };
+               };
+
+               tpiu@f8803000 {
+                       compatible = "arm,coresight-tpiu", "arm,primecell";
+                       reg = <0xf8803000 0x1000>;
+                       clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
+                       clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
+                       in-ports {
+                               port {
+                                       tpiu_in_port: endpoint {
+                                               remote-endpoint = <&replicator_out_port0>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@f8804000 {
+                       compatible = "arm,coresight-static-funnel", "arm,primecell";
+                       reg = <0xf8804000 0x1000>;
+                       clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
+                       clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
+
+                       /* funnel output ports */
+                       out-ports {
+                               port {
+                                       funnel_out_port: endpoint {
+                                               remote-endpoint =
+                                                       <&replicator_in_port0>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               /* funnel input ports */
+                               port@0 {
+                                       reg = <0>;
+                                       funnel0_in_port0: endpoint {
+                                               remote-endpoint = <&ptm0_out_port>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       funnel0_in_port1: endpoint {
+                                               remote-endpoint = <&ptm1_out_port>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       funnel0_in_port2: endpoint {
+                                       };
+                               };
+                               /* The other input ports are not connect to anything */
+                       };
+               };
+
+               ptm@f889c000 {
+                       compatible = "arm,coresight-etm3x", "arm,primecell";
+                       reg = <0xf889c000 0x1000>;
+                       clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
+                       clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
+                       cpu = <&cpu0>;
+                       out-ports {
+                               port {
+                                       ptm0_out_port: endpoint {
+                                               remote-endpoint = <&funnel0_in_port0>;
+                                       };
+                               };
+                       };
+               };
+
+               ptm@f889d000 {
+                       compatible = "arm,coresight-etm3x", "arm,primecell";
+                       reg = <0xf889d000 0x1000>;
+                       clocks = <&clkc 27>, <&clkc 46>, <&clkc 47>;
+                       clock-names = "apb_pclk", "dbg_trc", "dbg_apb";
+                       cpu = <&cpu1>;
+                       out-ports {
+                               port {
+                                       ptm1_out_port: endpoint {
+                                               remote-endpoint = <&funnel0_in_port1>;
+                                       };
+                               };
+                       };
+               };
        };
 };
index 3729a6e..f66bb98 100644 (file)
@@ -7,17 +7,13 @@ CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_ARCH_MULTI_V4T=y
 CONFIG_ARCH_MULTI_V5=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_AT91=y
 CONFIG_SOC_AT91RM9200=y
 CONFIG_SOC_AT91SAM9=y
+CONFIG_SOC_SAM9X60=y
 # CONFIG_ATMEL_CLOCKSOURCE_PIT is not set
 CONFIG_AEABI=y
 CONFIG_UACCESS_WITH_MEMCPY=y
@@ -27,6 +23,9 @@ CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="console=ttyS0,115200 initrd=0x21100000,25165824 root=/dev/ram0 rw"
 CONFIG_KEXEC=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_BLK_DEV_BSG is not set
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
@@ -37,13 +36,7 @@ CONFIG_IP_PNP=y
 CONFIG_IP_PNP_DHCP=y
 CONFIG_IP_PNP_BOOTP=y
 CONFIG_IP_PNP_RARP=y
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 # CONFIG_INET_DIAG is not set
-# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET6_XFRM_MODE_BEET is not set
 CONFIG_IPV6_SIT_6RD=y
 CONFIG_CFG80211=y
 CONFIG_MAC80211=y
@@ -57,6 +50,7 @@ CONFIG_MTD_BLOCK=y
 CONFIG_MTD_DATAFLASH=y
 CONFIG_MTD_RAW_NAND=y
 CONFIG_MTD_NAND_ATMEL=y
+CONFIG_MTD_SPI_NOR=y
 CONFIG_MTD_UBI=y
 CONFIG_MTD_UBI_GLUEBI=y
 CONFIG_BLK_DEV_LOOP=y
@@ -69,8 +63,8 @@ CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_LOWLEVEL is not set
 CONFIG_NETDEVICES=y
-CONFIG_MACB=y
 # CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_MACB=y
 CONFIG_DM9000=y
 # CONFIG_NET_VENDOR_FARADAY is not set
 # CONFIG_NET_VENDOR_INTEL is not set
@@ -82,10 +76,12 @@ CONFIG_DM9000=y
 # CONFIG_NET_VENDOR_STMICRO is not set
 CONFIG_DAVICOM_PHY=y
 CONFIG_MICREL_PHY=y
-CONFIG_RTL8187=m
 CONFIG_LIBERTAS=m
 CONFIG_LIBERTAS_SDIO=m
 CONFIG_LIBERTAS_SPI=m
+CONFIG_MWIFIEX=m
+CONFIG_MWIFIEX_SDIO=m
+CONFIG_MWIFIEX_USB=m
 CONFIG_RT2X00=m
 CONFIG_RT2500USB=m
 CONFIG_RT73USB=m
@@ -93,15 +89,10 @@ CONFIG_RT2800USB=m
 CONFIG_RT2800USB_RT53XX=y
 CONFIG_RT2800USB_RT55XX=y
 CONFIG_RT2800USB_UNKNOWN=y
+CONFIG_RTL8187=m
 CONFIG_RTL8192CU=m
 # CONFIG_RTLWIFI_DEBUG is not set
-CONFIG_MWIFIEX=m
-CONFIG_MWIFIEX_SDIO=m
-CONFIG_MWIFIEX_USB=m
 CONFIG_INPUT_POLLDEV=y
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_MOUSEDEV_SCREEN_X=480
-CONFIG_INPUT_MOUSEDEV_SCREEN_Y=272
 CONFIG_INPUT_JOYDEV=y
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_ATKBD is not set
@@ -110,6 +101,7 @@ CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ADS7846=y
+CONFIG_TOUCHSCREEN_ATMEL_MXT=y
 # CONFIG_SERIO is not set
 CONFIG_LEGACY_PTY_COUNT=4
 CONFIG_SERIAL_ATMEL=y
@@ -119,25 +111,25 @@ CONFIG_I2C_AT91=y
 CONFIG_I2C_GPIO=y
 CONFIG_SPI=y
 CONFIG_SPI_ATMEL=y
-CONFIG_POWER_SUPPLY=y
+CONFIG_SPI_ATMEL_QUADSPI=y
 CONFIG_POWER_RESET=y
+# CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC is not set
+CONFIG_POWER_SUPPLY=y
 # CONFIG_HWMON is not set
 CONFIG_WATCHDOG=y
 CONFIG_AT91SAM9X_WATCHDOG=y
+CONFIG_MFD_ATMEL_FLEXCOM=y
 CONFIG_MFD_ATMEL_HLCDC=y
 CONFIG_REGULATOR=y
 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_ATMEL_ISI=y
-CONFIG_SOC_CAMERA_OV2640=m
 CONFIG_DRM=y
 CONFIG_DRM_ATMEL_HLCDC=y
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_FB_ATMEL=y
-# CONFIG_LCD_CLASS_DEVICE is not set
 CONFIG_BACKLIGHT_ATMEL_LCDC=y
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_BACKLIGHT_PWM=y
@@ -150,6 +142,9 @@ CONFIG_SND_ATMEL_SOC=y
 CONFIG_SND_AT91_SOC_SAM9G20_WM8731=y
 CONFIG_SND_ATMEL_SOC_WM8904=y
 CONFIG_SND_AT91_SOC_SAM9X5_WM8731=y
+CONFIG_SND_ATMEL_SOC_CLASSD=y
+CONFIG_SND_SOC_MIKROE_PROTO=m
+CONFIG_SND_MCHP_SOC_I2S_MCC=y
 CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
@@ -165,6 +160,9 @@ CONFIG_USB_AT91=y
 CONFIG_USB_ATMEL_USBA=y
 CONFIG_USB_G_SERIAL=y
 CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_OF_AT91=y
 CONFIG_MMC_ATMELMCI=y
 CONFIG_MMC_SPI=y
 CONFIG_NEW_LEDS=y
@@ -181,9 +179,12 @@ CONFIG_RTC_DRV_AT91RM9200=y
 CONFIG_RTC_DRV_AT91SAM9=y
 CONFIG_DMADEVICES=y
 CONFIG_AT_HDMAC=y
+CONFIG_AT_XDMAC=y
+CONFIG_MICROCHIP_PIT64B=y
 # CONFIG_IOMMU_SUPPORT is not set
 CONFIG_IIO=y
 CONFIG_AT91_ADC=y
+CONFIG_AT91_SAMA5D2_ADC=y
 CONFIG_PWM=y
 CONFIG_PWM_ATMEL=y
 CONFIG_PWM_ATMEL_HLCDC_PWM=y
@@ -200,12 +201,6 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_CODEPAGE_850=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_UTF8=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_DEBUG_FS=y
-# CONFIG_SCHED_DEBUG is not set
-# CONFIG_DEBUG_BUGVERBOSE is not set
-# CONFIG_FTRACE is not set
-CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_ECB=y
 CONFIG_CRYPTO_USER_API_HASH=m
 CONFIG_CRYPTO_USER_API_SKCIPHER=m
@@ -215,3 +210,9 @@ CONFIG_FONTS=y
 CONFIG_FONT_8x8=y
 CONFIG_FONT_ACORN_8x8=y
 CONFIG_FONT_MINI_4x6=y
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_DEBUG_FS=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_FTRACE is not set
+CONFIG_DEBUG_USER=y
index fde84f1..c8e0c14 100644 (file)
@@ -38,6 +38,7 @@ CONFIG_CRYPTO_SHA256_ARM=m
 CONFIG_CRYPTO_SHA512_ARM=m
 CONFIG_CRYPTO_AES_ARM_BS=m
 CONFIG_CRYPTO_CHACHA20_NEON=m
+CONFIG_KALLSYMS_ALL=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_PARTITION_ADVANCED=y
@@ -92,6 +93,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_CRYPTOLOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_SIZE=8192
+CONFIG_SCSI=y
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_SG=y
 CONFIG_ATA=y
@@ -154,6 +156,7 @@ CONFIG_SENSORS_NTC_THERMISTOR=y
 CONFIG_SENSORS_PWM_FAN=y
 CONFIG_SENSORS_INA2XX=y
 CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_WATCHDOG=y
 CONFIG_S3C2410_WATCHDOG=y
@@ -291,6 +294,7 @@ CONFIG_CROS_EC_SPI=y
 CONFIG_COMMON_CLK_MAX77686=y
 CONFIG_COMMON_CLK_S2MPS11=y
 CONFIG_EXYNOS_IOMMU=y
+CONFIG_PM_DEVFREQ=y
 CONFIG_DEVFREQ_GOV_PERFORMANCE=y
 CONFIG_DEVFREQ_GOV_POWERSAVE=y
 CONFIG_DEVFREQ_GOV_USERSPACE=y
@@ -319,6 +323,8 @@ CONFIG_CRAMFS=y
 CONFIG_ROMFS_FS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
@@ -356,4 +362,7 @@ CONFIG_SOFTLOCKUP_DETECTOR=y
 # CONFIG_DETECT_HUNG_TASK is not set
 CONFIG_PROVE_LOCKING=y
 CONFIG_DEBUG_ATOMIC_SLEEP=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_USER=y
index f012e81..d2d5f1c 100644 (file)
@@ -2,28 +2,36 @@
 CONFIG_SYSVIPC=y
 CONFIG_NO_HZ_IDLE=y
 CONFIG_HIGH_RES_TIMERS=y
+CONFIG_PREEMPT=y
 CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_USER_NS=y
 CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_PARTITION_ADVANCED=y
 CONFIG_ARCH_MULTI_V4=y
 # CONFIG_ARCH_MULTI_V7 is not set
 CONFIG_ARCH_GEMINI=y
-CONFIG_PCI=y
-CONFIG_PREEMPT=y
 CONFIG_AEABI=y
 CONFIG_HIGHMEM=y
-CONFIG_CMA=y
 CONFIG_CMDLINE="console=ttyS0,115200n8"
 CONFIG_KEXEC=y
-CONFIG_BINFMT_MISC=y
 CONFIG_PM=y
+CONFIG_PARTITION_ADVANCED=y
+CONFIG_BINFMT_MISC=y
+CONFIG_CMA=y
 CONFIG_NET=y
 CONFIG_UNIX=y
 CONFIG_INET=y
+CONFIG_BRIDGE=y
+CONFIG_BRIDGE_VLAN_FILTERING=y
+CONFIG_NET_DSA=y
+CONFIG_VLAN_8021Q=y
+CONFIG_CFG80211=y
+CONFIG_CFG80211_WEXT=y
+CONFIG_MAC80211=y
+CONFIG_PCI=y
 CONFIG_DEVTMPFS=y
 CONFIG_MTD=y
+CONFIG_MTD_REDBOOT_PARTS=y
 CONFIG_MTD_BLOCK=y
 CONFIG_MTD_CFI=y
 CONFIG_MTD_JEDECPROBE=y
@@ -40,10 +48,12 @@ CONFIG_BLK_DEV_SD=y
 CONFIG_ATA=y
 CONFIG_PATA_FTIDE010=y
 CONFIG_NETDEVICES=y
+CONFIG_TUN=y
+CONFIG_NET_DSA_REALTEK_SMI=y
 CONFIG_GEMINI_ETHERNET=y
 CONFIG_MDIO_BITBANG=y
 CONFIG_MDIO_GPIO=y
-CONFIG_REALTEK_PHY=y
+CONFIG_MARVELL_PHY=y
 CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
@@ -69,7 +79,9 @@ CONFIG_DRM_TVE200=y
 CONFIG_LOGO=y
 CONFIG_USB=y
 CONFIG_USB_MON=y
+CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_FOTG210_HCD=y
+CONFIG_USB_UHCI_HCD=y
 CONFIG_USB_STORAGE=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
index 3608e55..8f216a5 100644 (file)
@@ -182,6 +182,7 @@ CONFIG_TOUCHSCREEN_ADS7846=y
 CONFIG_TOUCHSCREEN_DA9052=y
 CONFIG_TOUCHSCREEN_EGALAX=y
 CONFIG_TOUCHSCREEN_GOODIX=y
+CONFIG_TOUCHSCREEN_ILI210X=y
 CONFIG_TOUCHSCREEN_MAX11801=y
 CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
 CONFIG_TOUCHSCREEN_EDT_FT5X06=y
@@ -282,6 +283,7 @@ CONFIG_DRM_MSM=y
 CONFIG_DRM_PANEL_LVDS=y
 CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_PANEL_SEIKO_43WVF1G=y
+CONFIG_DRM_TI_TFP410=y
 CONFIG_DRM_DW_HDMI_AHB_AUDIO=m
 CONFIG_DRM_DW_HDMI_CEC=y
 CONFIG_DRM_IMX=y
@@ -323,6 +325,7 @@ CONFIG_USB=y
 CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
 CONFIG_USB_EHCI_HCD=y
 CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_ACM=m
 CONFIG_USB_STORAGE=y
 CONFIG_USB_CHIPIDEA=y
 CONFIG_USB_CHIPIDEA_UDC=y
@@ -442,6 +445,8 @@ CONFIG_UBIFS_FS=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_DEFAULT="cp437"
 CONFIG_NLS_CODEPAGE_437=y
index f5d19cc..017d65f 100644 (file)
@@ -492,6 +492,7 @@ CONFIG_SENSORS_PWM_FAN=m
 CONFIG_SENSORS_RASPBERRYPI_HWMON=m
 CONFIG_SENSORS_INA2XX=m
 CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_IMX_THERMAL=y
 CONFIG_ROCKCHIP_THERMAL=y
 CONFIG_RCAR_THERMAL=y
@@ -592,6 +593,7 @@ CONFIG_REGULATOR_S2MPS11=y
 CONFIG_REGULATOR_S5M8767=y
 CONFIG_REGULATOR_STM32_BOOSTER=m
 CONFIG_REGULATOR_STM32_VREFBUF=m
+CONFIG_REGULATOR_STM32_PWR=y
 CONFIG_REGULATOR_STPMIC1=y
 CONFIG_REGULATOR_TI_ABB=y
 CONFIG_REGULATOR_TPS51632=y
@@ -1093,6 +1095,8 @@ CONFIG_PSTORE_RAM=y
 CONFIG_NFS_FS=y
 CONFIG_NFS_V3_ACL=y
 CONFIG_NFS_V4=y
+CONFIG_NFS_V4_1=y
+CONFIG_NFS_V4_2=y
 CONFIG_ROOT_NFS=y
 CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
index 4dd1d8c..cdc75ef 100644 (file)
@@ -148,6 +148,7 @@ CONFIG_MEDIA_SUPPORT=y
 CONFIG_DRM=y
 CONFIG_DRM_MSM=m
 CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_ANALOGIX_ANX78XX=m
 CONFIG_FB=y
 CONFIG_FRAMEBUFFER_CONSOLE=y
 # CONFIG_LCD_CLASS_DEVICE is not set
@@ -251,6 +252,9 @@ CONFIG_PHY_QCOM_IPQ806X_SATA=y
 CONFIG_PHY_QCOM_USB_HS=y
 CONFIG_PHY_QCOM_USB_HSIC=y
 CONFIG_QCOM_QFPROM=y
+CONFIG_INTERCONNECT=y
+CONFIG_INTERCONNECT_QCOM=y
+CONFIG_INTERCONNECT_QCOM_MSM8974=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT3_FS=y
index de38304..64fa849 100644 (file)
@@ -64,6 +64,7 @@ CONFIG_INPUT_EVDEV=y
 CONFIG_KEYBOARD_GPIO=y
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_EDT_FT5X06=y
 CONFIG_TOUCHSCREEN_ST1232=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_ADXL34X=y
@@ -123,7 +124,9 @@ CONFIG_VIDEO_ADV7604=y
 CONFIG_VIDEO_ML86V7667=y
 CONFIG_DRM=y
 CONFIG_DRM_RCAR_DU=y
+CONFIG_DRM_PANEL_SIMPLE=y
 CONFIG_DRM_DUMB_VGA_DAC=y
+CONFIG_DRM_LVDS_CODEC=y
 CONFIG_DRM_SII902X=y
 CONFIG_DRM_I2C_ADV7511=y
 CONFIG_DRM_I2C_ADV7511_AUDIO=y
index 822cddf..4dd5c92 100644 (file)
@@ -12,7 +12,9 @@ CONFIG_ARM_APPENDED_DTB=y
 CONFIG_ARM_ATAG_DTB_COMPAT=y
 CONFIG_CMDLINE="root=/dev/ram0 console=ttyAMA2,115200n8"
 CONFIG_CPU_FREQ=y
-CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_SCHEDUTIL=y
+CONFIG_CPU_FREQ_GOV_ONDEMAND=y
+CONFIG_CPUFREQ_DT=y
 CONFIG_CPU_IDLE=y
 CONFIG_ARM_U8500_CPUIDLE=y
 CONFIG_VFP=y
index b5752f0..c815477 100644 (file)
@@ -326,16 +326,16 @@ static inline u64 __gic_readq_nonatomic(const volatile void __iomem *addr)
 #define gits_write_cwriter(v, c)       __gic_writeq_nonatomic(v, c)
 
 /*
- * GITS_VPROPBASER - hi and lo bits may be accessed independently.
+ * GICR_VPROPBASER - hi and lo bits may be accessed independently.
  */
-#define gits_read_vpropbaser(c)                __gic_readq_nonatomic(c)
-#define gits_write_vpropbaser(v, c)    __gic_writeq_nonatomic(v, c)
+#define gicr_read_vpropbaser(c)                __gic_readq_nonatomic(c)
+#define gicr_write_vpropbaser(v, c)    __gic_writeq_nonatomic(v, c)
 
 /*
- * GITS_VPENDBASER - the Valid bit must be cleared before changing
+ * GICR_VPENDBASER - the Valid bit must be cleared before changing
  * anything else.
  */
-static inline void gits_write_vpendbaser(u64 val, void __iomem *addr)
+static inline void gicr_write_vpendbaser(u64 val, void __iomem *addr)
 {
        u32 tmp;
 
@@ -352,7 +352,7 @@ static inline void gits_write_vpendbaser(u64 val, void __iomem *addr)
        __gic_writeq_nonatomic(val, addr);
 }
 
-#define gits_read_vpendbaser(c)                __gic_readq_nonatomic(c)
+#define gicr_read_vpendbaser(c)                __gic_readq_nonatomic(c)
 
 static inline bool gic_prio_masking_enabled(void)
 {
index 51beec4..0d3ea35 100644 (file)
@@ -189,6 +189,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long addr)
 }
 
 #define pmd_large(pmd)         (pmd_val(pmd) & 2)
+#define pmd_leaf(pmd)          (pmd_val(pmd) & 2)
 #define pmd_bad(pmd)           (pmd_val(pmd) & 2)
 #define pmd_present(pmd)       (pmd_val(pmd))
 
index 5b18295..ad55ab0 100644 (file)
 #define pmd_sect(pmd)          ((pmd_val(pmd) & PMD_TYPE_MASK) == \
                                                 PMD_TYPE_SECT)
 #define pmd_large(pmd)         pmd_sect(pmd)
+#define pmd_leaf(pmd)          pmd_sect(pmd)
 
 #define pud_clear(pudp)                        \
        do {                            \
index 010fa1a..30fb233 100644 (file)
 
 #define swapper_pg_dir ((pgd_t *) 0)
 
-#define __swp_type(x)          (0)
-#define __swp_offset(x)                (0)
-#define __swp_entry(typ,off)   ((swp_entry_t) { ((typ) | ((off) << 7)) })
-#define __pte_to_swp_entry(pte)        ((swp_entry_t) { pte_val(pte) })
-#define __swp_entry_to_pte(x)  ((pte_t) { (x).val })
-
 
 typedef pte_t *pte_addr_t;
 
index 669474a..4d4e7b6 100644 (file)
@@ -37,10 +37,6 @@ static inline void __tlb_remove_table(void *_table)
 
 #include <asm-generic/tlb.h>
 
-#ifndef CONFIG_HAVE_RCU_TABLE_FREE
-#define tlb_remove_table(tlb, entry) tlb_remove_page(tlb, entry)
-#endif
-
 static inline void
 __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, unsigned long addr)
 {
index bf8702e..132a20c 100644 (file)
@@ -31,6 +31,7 @@
 #define UARTA_7268             UARTA_7255
 #define UARTA_7271             UARTA_7268
 #define UARTA_7278             REG_PHYS_ADDR_V7(0x40c000)
+#define UARTA_7216             UARTA_7278
 #define UARTA_7364             REG_PHYS_ADDR(0x40b000)
 #define UARTA_7366             UARTA_7364
 #define UARTA_74371            REG_PHYS_ADDR(0x406b00)
@@ -82,17 +83,18 @@ ARM_BE8(    rev     \rv, \rv )
 
                /* Chip specific detection starts here */
 20:            checkuart(\rp, \rv, 0x33900000, 3390)
-21:            checkuart(\rp, \rv, 0x72500000, 7250)
-22:            checkuart(\rp, \rv, 0x72550000, 7255)
-23:            checkuart(\rp, \rv, 0x72600000, 7260)
-24:            checkuart(\rp, \rv, 0x72680000, 7268)
-25:            checkuart(\rp, \rv, 0x72710000, 7271)
-26:            checkuart(\rp, \rv, 0x72780000, 7278)
-27:            checkuart(\rp, \rv, 0x73640000, 7364)
-28:            checkuart(\rp, \rv, 0x73660000, 7366)
-29:            checkuart(\rp, \rv, 0x07437100, 74371)
-30:            checkuart(\rp, \rv, 0x74390000, 7439)
-31:            checkuart(\rp, \rv, 0x74450000, 7445)
+21:            checkuart(\rp, \rv, 0x72160000, 7216)
+22:            checkuart(\rp, \rv, 0x72500000, 7250)
+23:            checkuart(\rp, \rv, 0x72550000, 7255)
+24:            checkuart(\rp, \rv, 0x72600000, 7260)
+25:            checkuart(\rp, \rv, 0x72680000, 7268)
+26:            checkuart(\rp, \rv, 0x72710000, 7271)
+27:            checkuart(\rp, \rv, 0x72780000, 7278)
+28:            checkuart(\rp, \rv, 0x73640000, 7364)
+29:            checkuart(\rp, \rv, 0x73660000, 7366)
+30:            checkuart(\rp, \rv, 0x07437100, 74371)
+31:            checkuart(\rp, \rv, 0x74390000, 7439)
+32:            checkuart(\rp, \rv, 0x74450000, 7445)
 
                /* No valid UART found */
 90:            mov     \rp, #0
index 312cb89..4247ebf 100644 (file)
@@ -17,9 +17,9 @@ static ssize_t atags_read(struct file *file, char __user *buf,
        return simple_read_from_buffer(buf, count, ppos, b->data, b->size);
 }
 
-static const struct file_operations atags_fops = {
-       .read = atags_read,
-       .llseek = default_llseek,
+static const struct proc_ops atags_proc_ops = {
+       .proc_read      = atags_read,
+       .proc_lseek     = default_llseek,
 };
 
 #define BOOT_PARAMS_SIZE 1536
@@ -61,7 +61,7 @@ static int __init init_atags_procfs(void)
        b->size = size;
        memcpy(b->data, atags_copy, size);
 
-       tags_entry = proc_create_data("atags", 0400, NULL, &atags_fops, b);
+       tags_entry = proc_create_data("atags", 0400, NULL, &atags_proc_ops, b);
        if (!tags_entry)
                goto nomem;
 
index 71778bb..cc726af 100644 (file)
@@ -92,6 +92,8 @@ static int save_trace(struct stackframe *frame, void *d)
                return 0;
 
        regs = (struct pt_regs *)frame->sp;
+       if ((unsigned long)&regs[1] > ALIGN(frame->sp, THREAD_SIZE))
+               return 0;
 
        trace->entries[trace->nr_entries++] = regs->ARM_pc;
 
index abb7dd7..1e70e72 100644 (file)
@@ -64,14 +64,16 @@ static void dump_mem(const char *, const char *, unsigned long, unsigned long);
 
 void dump_backtrace_entry(unsigned long where, unsigned long from, unsigned long frame)
 {
+       unsigned long end = frame + 4 + sizeof(struct pt_regs);
+
 #ifdef CONFIG_KALLSYMS
        printk("[<%08lx>] (%ps) from [<%08lx>] (%pS)\n", where, (void *)where, from, (void *)from);
 #else
        printk("Function entered at [<%08lx>] from [<%08lx>]\n", where, from);
 #endif
 
-       if (in_entry_text(from))
-               dump_mem("", "Exception stack", frame + 4, frame + 4 + sizeof(struct pt_regs));
+       if (in_entry_text(from) && end <= ALIGN(frame, THREAD_SIZE))
+               dump_mem("", "Exception stack", frame + 4, end);
 }
 
 void dump_backtrace_stm(u32 *stack, u32 instruction)
index af41725..7979420 100644 (file)
@@ -105,11 +105,28 @@ config SOC_AT91SAM9
            AT91SAM9X35
            AT91SAM9XE
 
+config SOC_SAM9X60
+       bool "SAM9X60"
+       depends on ARCH_MULTI_V5
+       select ATMEL_AIC5_IRQ
+       select ATMEL_PM if PM
+       select ATMEL_SDRAMC
+       select CPU_ARM926T
+       select HAVE_AT91_USB_CLK
+       select HAVE_AT91_GENERATED_CLK
+       select HAVE_AT91_SAM9X60_PLL
+       select MEMORY
+       select PINCTRL_AT91
+       select SOC_SAM_V4_V5
+       select SRAM if PM
+       help
+         Select this if you are using Microchip's SAM9X60 SoC
+
 comment "Clocksource driver selection"
 
 config ATMEL_CLOCKSOURCE_PIT
        bool "Periodic Interval Timer (PIT) support"
-       depends on SOC_AT91SAM9 || SOC_SAMA5
+       depends on SOC_AT91SAM9 || SOC_SAM9X60 || SOC_SAMA5
        default SOC_AT91SAM9 || SOC_SAMA5
        select ATMEL_PIT
        help
@@ -119,7 +136,7 @@ config ATMEL_CLOCKSOURCE_PIT
 
 config ATMEL_CLOCKSOURCE_TCB
        bool "Timer Counter Blocks (TCB) support"
-       default SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAMA5
+       default SOC_AT91RM9200 || SOC_AT91SAM9 || SOC_SAM9X60 || SOC_SAMA5
        select ATMEL_TCB_CLKSRC
        help
          Select this to get a high precision clocksource based on a
@@ -154,6 +171,9 @@ config HAVE_AT91_AUDIO_PLL
 config HAVE_AT91_I2S_MUX_CLK
        bool
 
+config HAVE_AT91_SAM9X60_PLL
+       bool
+
 config SOC_SAM_V4_V5
        bool
 
index de64301..f565490 100644 (file)
@@ -6,6 +6,7 @@
 # CPU-specific support
 obj-$(CONFIG_SOC_AT91RM9200)   += at91rm9200.o
 obj-$(CONFIG_SOC_AT91SAM9)     += at91sam9.o
+obj-$(CONFIG_SOC_SAM9X60)      += sam9x60.o
 obj-$(CONFIG_SOC_SAMA5)                += sama5.o
 obj-$(CONFIG_SOC_SAMV7)                += samv7.o
 
index bf629c9..7e57218 100644 (file)
@@ -31,21 +31,3 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
        .init_machine   = at91sam9_init,
        .dt_compat      = at91_dt_board_compat,
 MACHINE_END
-
-static void __init sam9x60_init(void)
-{
-       of_platform_default_populate(NULL, NULL, NULL);
-
-       sam9x60_pm_init();
-}
-
-static const char *const sam9x60_dt_board_compat[] __initconst = {
-       "microchip,sam9x60",
-       NULL
-};
-
-DT_MACHINE_START(sam9x60_dt, "Microchip SAM9X60")
-       /* Maintainer: Microchip */
-       .init_machine   = sam9x60_init,
-       .dt_compat      = sam9x60_dt_board_compat,
-MACHINE_END
index d5af6ae..374b9d1 100644 (file)
@@ -691,6 +691,12 @@ static void __init at91_pm_use_default_mode(int pm_mode)
                soc_pm.data.suspend_mode = AT91_PM_ULP0;
 }
 
+static const struct of_device_id atmel_shdwc_ids[] = {
+       { .compatible = "atmel,sama5d2-shdwc" },
+       { .compatible = "microchip,sam9x60-shdwc" },
+       { /* sentinel. */ }
+};
+
 static void __init at91_pm_modes_init(void)
 {
        struct device_node *np;
@@ -700,7 +706,7 @@ static void __init at91_pm_modes_init(void)
            !at91_is_pm_mode_active(AT91_PM_ULP1))
                return;
 
-       np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-shdwc");
+       np = of_find_matching_node(NULL, atmel_shdwc_ids);
        if (!np) {
                pr_warn("%s: failed to find shdwc!\n", __func__);
                goto ulp1_default;
@@ -751,6 +757,7 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = {
        { .compatible = "atmel,sama5d3-pmc", .data = &pmc_infos[1] },
        { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] },
        { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] },
+       { .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[1] },
        { /* sentinel */ },
 };
 
@@ -805,7 +812,7 @@ void __init at91rm9200_pm_init(void)
 
 void __init sam9x60_pm_init(void)
 {
-       if (!IS_ENABLED(CONFIG_SOC_AT91SAM9))
+       if (!IS_ENABLED(CONFIG_SOC_SAM9X60))
                return;
 
        at91_pm_modes_init();
diff --git a/arch/arm/mach-at91/sam9x60.c b/arch/arm/mach-at91/sam9x60.c
new file mode 100644 (file)
index 0000000..d8c739d
--- /dev/null
@@ -0,0 +1,34 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Setup code for SAM9X60.
+ *
+ * Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries
+ *
+ * Author: Claudiu Beznea <claudiu.beznea@microchip.com>
+ */
+
+#include <linux/of.h>
+#include <linux/of_platform.h>
+
+#include <asm/mach/arch.h>
+#include <asm/system_misc.h>
+
+#include "generic.h"
+
+static void __init sam9x60_init(void)
+{
+       of_platform_default_populate(NULL, NULL, NULL);
+
+       sam9x60_pm_init();
+}
+
+static const char *const sam9x60_dt_board_compat[] __initconst = {
+       "microchip,sam9x60",
+       NULL
+};
+
+DT_MACHINE_START(sam9x60_dt, "Microchip SAM9X60")
+       /* Maintainer: Microchip */
+       .init_machine   = sam9x60_init,
+       .dt_compat      = sam9x60_dt_board_compat,
+MACHINE_END
index e4e25f2..fcfe2a0 100644 (file)
@@ -211,6 +211,7 @@ config ARCH_BRCMSTB
        bool "Broadcom BCM7XXX based boards"
        depends on ARCH_MULTI_V7
        select ARCH_HAS_RESET_CONTROLLER
+       select ARM_AMBA
        select ARM_GIC
        select ARM_ERRATA_798181 if SMP
        select HAVE_ARM_ARCH_TIMER
index a03d844..58838a9 100644 (file)
@@ -7,8 +7,7 @@
 ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include
 
 # Common objects
-obj-y                                  := time.o serial.o usb.o \
-                                          common.o sram.o
+obj-y                                  := serial.o usb.o common.o sram.o
 
 obj-$(CONFIG_DAVINCI_MUX)              += mux.o
 
index 150a36f..2328b15 100644 (file)
@@ -30,6 +30,8 @@
 #include <linux/spi/eeprom.h>
 #include <linux/v4l2-dv-timings.h>
 #include <linux/platform_data/ti-aemif.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 
 #include <asm/mach-types.h>
 #include <asm/mach/arch.h>
@@ -245,6 +247,19 @@ static struct davinci_i2c_platform_data i2c_pdata = {
        .bus_delay      = 0     /* usec */,
 };
 
+/* Fixed regulator support */
+static struct regulator_consumer_supply fixed_supplies_3_3v[] = {
+       /* Baseboard 3.3V: 5V -> TPS767D301 -> 3.3V */
+       REGULATOR_SUPPLY("AVDD", "1-0018"),
+       REGULATOR_SUPPLY("DRVDD", "1-0018"),
+       REGULATOR_SUPPLY("IOVDD", "1-0018"),
+};
+
+static struct regulator_consumer_supply fixed_supplies_1_8v[] = {
+       /* Baseboard 1.8V: 5V -> TPS767D301 -> 1.8V */
+       REGULATOR_SUPPLY("DVDD", "1-0018"),
+};
+
 static int dm365evm_keyscan_enable(struct device *dev)
 {
        return davinci_cfg_reg(DM365_KEYSCAN);
@@ -800,6 +815,11 @@ static __init void dm365_evm_init(void)
        if (ret)
                pr_warn("%s: GPIO init failed: %d\n", __func__, ret);
 
+       regulator_register_always_on(0, "fixed-dummy", fixed_supplies_1_8v,
+                                    ARRAY_SIZE(fixed_supplies_1_8v), 1800000);
+       regulator_register_always_on(1, "fixed-dummy", fixed_supplies_3_3v,
+                                    ARRAY_SIZE(fixed_supplies_3_3v), 3300000);
+
        nvmem_add_cell_table(&davinci_nvmem_cell_table);
        nvmem_add_cell_lookups(&davinci_nvmem_cell_lookup, 1);
 
index 040c949..3461d12 100644 (file)
@@ -29,6 +29,8 @@
 #include <linux/v4l2-dv-timings.h>
 #include <linux/export.h>
 #include <linux/leds.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
 
 #include <media/i2c/tvp514x.h>
 
@@ -653,6 +655,19 @@ static struct i2c_board_info __initdata i2c_info[] =  {
        },
 };
 
+/* Fixed regulator support */
+static struct regulator_consumer_supply fixed_supplies_3_3v[] = {
+       /* Baseboard 3.3V: 5V -> TPS54310PWP -> 3.3V */
+       REGULATOR_SUPPLY("AVDD", "1-001b"),
+       REGULATOR_SUPPLY("DRVDD", "1-001b"),
+};
+
+static struct regulator_consumer_supply fixed_supplies_1_8v[] = {
+       /* Baseboard 1.8V: 5V -> TPS54310PWP -> 1.8V */
+       REGULATOR_SUPPLY("IOVDD", "1-001b"),
+       REGULATOR_SUPPLY("DVDD", "1-001b"),
+};
+
 #define DM644X_I2C_SDA_PIN     GPIO_TO_PIN(2, 12)
 #define DM644X_I2C_SCL_PIN     GPIO_TO_PIN(2, 11)
 
@@ -842,6 +857,11 @@ static __init void davinci_evm_init(void)
 
        dm644x_register_clocks();
 
+       regulator_register_always_on(0, "fixed-dummy", fixed_supplies_1_8v,
+                                    ARRAY_SIZE(fixed_supplies_1_8v), 1800000);
+       regulator_register_always_on(1, "fixed-dummy", fixed_supplies_3_3v,
+                                    ARRAY_SIZE(fixed_supplies_3_3v), 3300000);
+
        dm644x_init_devices();
 
        ret = dm644x_gpio_register();
index 2d69e70..feb206b 100644 (file)
@@ -21,7 +21,6 @@
 #include <mach/common.h>
 #include <mach/cputype.h>
 #include <mach/da8xx.h>
-#include <mach/time.h>
 
 #include "asp.h"
 #include "cpuidle.h"
index e650131..849e811 100644 (file)
@@ -17,7 +17,6 @@
 #include <mach/hardware.h>
 #include <mach/cputype.h>
 #include <mach/mux.h>
-#include <mach/time.h>
 
 #include "davinci.h"
 #include "irqs.h"
@@ -303,21 +302,3 @@ int davinci_gpio_register(struct resource *res, int size, void *pdata)
        davinci_gpio_device.dev.platform_data = pdata;
        return platform_device_register(&davinci_gpio_device);
 }
-
-/*-------------------------------------------------------------------------*/
-
-/*-------------------------------------------------------------------------*/
-
-struct davinci_timer_instance davinci_timer_instance[2] = {
-       {
-               .base           = DAVINCI_TIMER0_BASE,
-               .bottom_irq     = DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12),
-               .top_irq        = DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34),
-       },
-       {
-               .base           = DAVINCI_TIMER1_BASE,
-               .bottom_irq     = DAVINCI_INTC_IRQ(IRQ_TINT1_TINT12),
-               .top_irq        = DAVINCI_INTC_IRQ(IRQ_TINT1_TINT34),
-       },
-};
-
index 9fc5c73..c1e0d46 100644 (file)
@@ -35,7 +35,8 @@
 #include <mach/cputype.h>
 #include <mach/mux.h>
 #include <mach/serial.h>
-#include <mach/time.h>
+
+#include <clocksource/timer-davinci.h>
 
 #include "asp.h"
 #include "davinci.h"
@@ -660,10 +661,16 @@ static struct davinci_id dm365_ids[] = {
        },
 };
 
-static struct davinci_timer_info dm365_timer_info = {
-       .timers         = davinci_timer_instance,
-       .clockevent_id  = T0_BOT,
-       .clocksource_id = T0_TOP,
+/*
+ * Bottom half of timer0 is used for clockevent, top half is used for
+ * clocksource.
+ */
+static const struct davinci_timer_cfg dm365_timer_cfg = {
+       .reg = DEFINE_RES_IO(DAVINCI_TIMER0_BASE, SZ_128),
+       .irq = {
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT12)),
+               DEFINE_RES_IRQ(DAVINCI_INTC_IRQ(IRQ_TINT0_TINT34)),
+       },
 };
 
 #define DM365_UART1_BASE       (IO_PHYS + 0x106000)
@@ -723,7 +730,6 @@ static const struct davinci_soc_info davinci_soc_info_dm365 = {
        .pinmux_base            = DAVINCI_SYSTEM_MODULE_BASE,
        .pinmux_pins            = dm365_pins,
        .pinmux_pins_num        = ARRAY_SIZE(dm365_pins),
-       .timer_info             = &dm365_timer_info,
        .emac_pdata             = &dm365_emac_pdata,
        .sram_dma               = 0x00010000,
        .sram_len               = SZ_32K,
@@ -771,6 +777,7 @@ void __init dm365_init_time(void)
 {
        void __iomem *pll1, *pll2, *psc;
        struct clk *clk;
+       int rv;
 
        clk_register_fixed_rate(NULL, "ref_clk", NULL, 0, DM365_REF_FREQ);
 
@@ -789,7 +796,8 @@ void __init dm365_init_time(void)
                return;
        }
 
-       davinci_timer_init(clk);
+       rv = davinci_timer_register(clk, &dm365_timer_cfg);
+       WARN(rv, "Unable to register the timer: %d\n", rv);
 }
 
 void __init dm365_register_clocks(void)
index 9526e5d..139b83d 100644 (file)
 #define DAVINCI_INTC_START             NR_IRQS
 #define DAVINCI_INTC_IRQ(_irqnum)      (DAVINCI_INTC_START + (_irqnum))
 
-void davinci_timer_init(struct clk *clk);
-
-struct davinci_timer_instance {
-       u32             base;
-       u32             bottom_irq;
-       u32             top_irq;
-       unsigned long   cmp_off;
-       unsigned int    cmp_irq;
-};
-
-struct davinci_timer_info {
-       struct davinci_timer_instance   *timers;
-       unsigned int                    clockevent_id;
-       unsigned int                    clocksource_id;
-};
-
 struct davinci_gpio_controller;
 
 /*
@@ -58,7 +42,6 @@ struct davinci_soc_info {
        u32                             pinmux_base;
        const struct mux_config         *pinmux_pins;
        unsigned long                   pinmux_pins_num;
-       struct davinci_timer_info       *timer_info;
        int                             gpio_type;
        u32                             gpio_base;
        unsigned                        gpio_num;
diff --git a/arch/arm/mach-davinci/include/mach/time.h b/arch/arm/mach-davinci/include/mach/time.h
deleted file mode 100644 (file)
index ba91373..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Local header file for DaVinci time code.
- *
- * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#ifndef __ARCH_ARM_MACH_DAVINCI_TIME_H
-#define __ARCH_ARM_MACH_DAVINCI_TIME_H
-
-#define DAVINCI_TIMER1_BASE            (IO_PHYS + 0x21800)
-
-enum {
-       T0_BOT,
-       T0_TOP,
-       T1_BOT,
-       T1_TOP,
-       NUM_TIMERS
-};
-
-#define IS_TIMER1(id)          (id & 0x2)
-#define IS_TIMER0(id)          (!IS_TIMER1(id))
-#define IS_TIMER_TOP(id)       ((id & 0x1))
-#define IS_TIMER_BOT(id)       (!IS_TIMER_TOP(id))
-
-#define ID_TO_TIMER(id)                (IS_TIMER1(id) != 0)
-
-extern struct davinci_timer_instance davinci_timer_instance[];
-
-#endif /* __ARCH_ARM_MACH_DAVINCI_TIME_H */
diff --git a/arch/arm/mach-davinci/time.c b/arch/arm/mach-davinci/time.c
deleted file mode 100644 (file)
index 740410a..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * DaVinci timer subsystem
- *
- * Author: Kevin Hilman, MontaVista Software, Inc. <source@mvista.com>
- *
- * 2007 (c) MontaVista Software, Inc. This file is licensed under
- * the terms of the GNU General Public License version 2. This program
- * is licensed "as is" without any warranty of any kind, whether express
- * or implied.
- */
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/interrupt.h>
-#include <linux/clocksource.h>
-#include <linux/clockchips.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/err.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/sched_clock.h>
-
-#include <asm/mach/irq.h>
-#include <asm/mach/time.h>
-
-#include <mach/cputype.h>
-#include <mach/hardware.h>
-#include <mach/time.h>
-
-static struct clock_event_device clockevent_davinci;
-static unsigned int davinci_clock_tick_rate;
-
-/*
- * This driver configures the 2 64-bit count-up timers as 4 independent
- * 32-bit count-up timers used as follows:
- */
-
-enum {
-       TID_CLOCKEVENT,
-       TID_CLOCKSOURCE,
-};
-
-/* Timer register offsets */
-#define PID12                  0x0
-#define TIM12                  0x10
-#define TIM34                  0x14
-#define PRD12                  0x18
-#define PRD34                  0x1c
-#define TCR                    0x20
-#define TGCR                   0x24
-#define WDTCR                  0x28
-
-/* Offsets of the 8 compare registers */
-#define        CMP12_0                 0x60
-#define        CMP12_1                 0x64
-#define        CMP12_2                 0x68
-#define        CMP12_3                 0x6c
-#define        CMP12_4                 0x70
-#define        CMP12_5                 0x74
-#define        CMP12_6                 0x78
-#define        CMP12_7                 0x7c
-
-/* Timer register bitfields */
-#define TCR_ENAMODE_DISABLE          0x0
-#define TCR_ENAMODE_ONESHOT          0x1
-#define TCR_ENAMODE_PERIODIC         0x2
-#define TCR_ENAMODE_MASK             0x3
-
-#define TGCR_TIMMODE_SHIFT           2
-#define TGCR_TIMMODE_64BIT_GP        0x0
-#define TGCR_TIMMODE_32BIT_UNCHAINED 0x1
-#define TGCR_TIMMODE_64BIT_WDOG      0x2
-#define TGCR_TIMMODE_32BIT_CHAINED   0x3
-
-#define TGCR_TIM12RS_SHIFT           0
-#define TGCR_TIM34RS_SHIFT           1
-#define TGCR_RESET                   0x0
-#define TGCR_UNRESET                 0x1
-#define TGCR_RESET_MASK              0x3
-
-struct timer_s {
-       char *name;
-       unsigned int id;
-       unsigned long period;
-       unsigned long opts;
-       unsigned long flags;
-       void __iomem *base;
-       unsigned long tim_off;
-       unsigned long prd_off;
-       unsigned long enamode_shift;
-       struct irqaction irqaction;
-};
-static struct timer_s timers[];
-
-/* values for 'opts' field of struct timer_s */
-#define TIMER_OPTS_DISABLED            0x01
-#define TIMER_OPTS_ONESHOT             0x02
-#define TIMER_OPTS_PERIODIC            0x04
-#define TIMER_OPTS_STATE_MASK          0x07
-
-#define TIMER_OPTS_USE_COMPARE         0x80000000
-#define USING_COMPARE(t)               ((t)->opts & TIMER_OPTS_USE_COMPARE)
-
-static char *id_to_name[] = {
-       [T0_BOT]        = "timer0_0",
-       [T0_TOP]        = "timer0_1",
-       [T1_BOT]        = "timer1_0",
-       [T1_TOP]        = "timer1_1",
-};
-
-static int timer32_config(struct timer_s *t)
-{
-       u32 tcr;
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-
-       if (USING_COMPARE(t)) {
-               struct davinci_timer_instance *dtip =
-                               soc_info->timer_info->timers;
-               int event_timer = ID_TO_TIMER(timers[TID_CLOCKEVENT].id);
-
-               /*
-                * Next interrupt should be the current time reg value plus
-                * the new period (using 32-bit unsigned addition/wrapping
-                * to 0 on overflow).  This assumes that the clocksource
-                * is setup to count to 2^32-1 before wrapping around to 0.
-                */
-               __raw_writel(__raw_readl(t->base + t->tim_off) + t->period,
-                       t->base + dtip[event_timer].cmp_off);
-       } else {
-               tcr = __raw_readl(t->base + TCR);
-
-               /* disable timer */
-               tcr &= ~(TCR_ENAMODE_MASK << t->enamode_shift);
-               __raw_writel(tcr, t->base + TCR);
-
-               /* reset counter to zero, set new period */
-               __raw_writel(0, t->base + t->tim_off);
-               __raw_writel(t->period, t->base + t->prd_off);
-
-               /* Set enable mode */
-               if (t->opts & TIMER_OPTS_ONESHOT)
-                       tcr |= TCR_ENAMODE_ONESHOT << t->enamode_shift;
-               else if (t->opts & TIMER_OPTS_PERIODIC)
-                       tcr |= TCR_ENAMODE_PERIODIC << t->enamode_shift;
-
-               __raw_writel(tcr, t->base + TCR);
-       }
-       return 0;
-}
-
-static inline u32 timer32_read(struct timer_s *t)
-{
-       return __raw_readl(t->base + t->tim_off);
-}
-
-static irqreturn_t timer_interrupt(int irq, void *dev_id)
-{
-       struct clock_event_device *evt = &clockevent_davinci;
-
-       evt->event_handler(evt);
-       return IRQ_HANDLED;
-}
-
-/* called when 32-bit counter wraps */
-static irqreturn_t freerun_interrupt(int irq, void *dev_id)
-{
-       return IRQ_HANDLED;
-}
-
-static struct timer_s timers[] = {
-       [TID_CLOCKEVENT] = {
-               .name      = "clockevent",
-               .opts      = TIMER_OPTS_DISABLED,
-               .irqaction = {
-                       .flags   = IRQF_TIMER,
-                       .handler = timer_interrupt,
-               }
-       },
-       [TID_CLOCKSOURCE] = {
-               .name       = "free-run counter",
-               .period     = ~0,
-               .opts       = TIMER_OPTS_PERIODIC,
-               .irqaction = {
-                       .flags   = IRQF_TIMER,
-                       .handler = freerun_interrupt,
-               }
-       },
-};
-
-static void __init timer_init(void)
-{
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-       struct davinci_timer_instance *dtip = soc_info->timer_info->timers;
-       void __iomem *base[2];
-       int i;
-
-       /* Global init of each 64-bit timer as a whole */
-       for(i=0; i<2; i++) {
-               u32 tgcr;
-
-               base[i] = ioremap(dtip[i].base, SZ_4K);
-               if (WARN_ON(!base[i]))
-                       continue;
-
-               /* Disabled, Internal clock source */
-               __raw_writel(0, base[i] + TCR);
-
-               /* reset both timers, no pre-scaler for timer34 */
-               tgcr = 0;
-               __raw_writel(tgcr, base[i] + TGCR);
-
-               /* Set both timers to unchained 32-bit */
-               tgcr = TGCR_TIMMODE_32BIT_UNCHAINED << TGCR_TIMMODE_SHIFT;
-               __raw_writel(tgcr, base[i] + TGCR);
-
-               /* Unreset timers */
-               tgcr |= (TGCR_UNRESET << TGCR_TIM12RS_SHIFT) |
-                       (TGCR_UNRESET << TGCR_TIM34RS_SHIFT);
-               __raw_writel(tgcr, base[i] + TGCR);
-
-               /* Init both counters to zero */
-               __raw_writel(0, base[i] + TIM12);
-               __raw_writel(0, base[i] + TIM34);
-       }
-
-       /* Init of each timer as a 32-bit timer */
-       for (i=0; i< ARRAY_SIZE(timers); i++) {
-               struct timer_s *t = &timers[i];
-               int timer = ID_TO_TIMER(t->id);
-               u32 irq;
-
-               t->base = base[timer];
-               if (!t->base)
-                       continue;
-
-               if (IS_TIMER_BOT(t->id)) {
-                       t->enamode_shift = 6;
-                       t->tim_off = TIM12;
-                       t->prd_off = PRD12;
-                       irq = dtip[timer].bottom_irq;
-               } else {
-                       t->enamode_shift = 22;
-                       t->tim_off = TIM34;
-                       t->prd_off = PRD34;
-                       irq = dtip[timer].top_irq;
-               }
-
-               /* Register interrupt */
-               t->irqaction.name = t->name;
-               t->irqaction.dev_id = (void *)t;
-
-               if (t->irqaction.handler != NULL) {
-                       irq = USING_COMPARE(t) ? dtip[i].cmp_irq : irq;
-                       setup_irq(irq, &t->irqaction);
-               }
-       }
-}
-
-/*
- * clocksource
- */
-static u64 read_cycles(struct clocksource *cs)
-{
-       struct timer_s *t = &timers[TID_CLOCKSOURCE];
-
-       return (cycles_t)timer32_read(t);
-}
-
-static struct clocksource clocksource_davinci = {
-       .rating         = 300,
-       .read           = read_cycles,
-       .mask           = CLOCKSOURCE_MASK(32),
-       .flags          = CLOCK_SOURCE_IS_CONTINUOUS,
-};
-
-/*
- * Overwrite weak default sched_clock with something more precise
- */
-static u64 notrace davinci_read_sched_clock(void)
-{
-       return timer32_read(&timers[TID_CLOCKSOURCE]);
-}
-
-/*
- * clockevent
- */
-static int davinci_set_next_event(unsigned long cycles,
-                                 struct clock_event_device *evt)
-{
-       struct timer_s *t = &timers[TID_CLOCKEVENT];
-
-       t->period = cycles;
-       timer32_config(t);
-       return 0;
-}
-
-static int davinci_shutdown(struct clock_event_device *evt)
-{
-       struct timer_s *t = &timers[TID_CLOCKEVENT];
-
-       t->opts &= ~TIMER_OPTS_STATE_MASK;
-       t->opts |= TIMER_OPTS_DISABLED;
-       return 0;
-}
-
-static int davinci_set_oneshot(struct clock_event_device *evt)
-{
-       struct timer_s *t = &timers[TID_CLOCKEVENT];
-
-       t->opts &= ~TIMER_OPTS_STATE_MASK;
-       t->opts |= TIMER_OPTS_ONESHOT;
-       return 0;
-}
-
-static int davinci_set_periodic(struct clock_event_device *evt)
-{
-       struct timer_s *t = &timers[TID_CLOCKEVENT];
-
-       t->period = davinci_clock_tick_rate / (HZ);
-       t->opts &= ~TIMER_OPTS_STATE_MASK;
-       t->opts |= TIMER_OPTS_PERIODIC;
-       timer32_config(t);
-       return 0;
-}
-
-static struct clock_event_device clockevent_davinci = {
-       .features               = CLOCK_EVT_FEAT_PERIODIC |
-                                 CLOCK_EVT_FEAT_ONESHOT,
-       .set_next_event         = davinci_set_next_event,
-       .set_state_shutdown     = davinci_shutdown,
-       .set_state_periodic     = davinci_set_periodic,
-       .set_state_oneshot      = davinci_set_oneshot,
-};
-
-void __init davinci_timer_init(struct clk *timer_clk)
-{
-       struct davinci_soc_info *soc_info = &davinci_soc_info;
-       unsigned int clockevent_id;
-       unsigned int clocksource_id;
-       int i;
-
-       clockevent_id = soc_info->timer_info->clockevent_id;
-       clocksource_id = soc_info->timer_info->clocksource_id;
-
-       timers[TID_CLOCKEVENT].id = clockevent_id;
-       timers[TID_CLOCKSOURCE].id = clocksource_id;
-
-       /*
-        * If using same timer for both clock events & clocksource,
-        * a compare register must be used to generate an event interrupt.
-        * This is equivalent to a oneshot timer only (not periodic).
-        */
-       if (clockevent_id == clocksource_id) {
-               struct davinci_timer_instance *dtip =
-                               soc_info->timer_info->timers;
-               int event_timer = ID_TO_TIMER(clockevent_id);
-
-               /* Only bottom timers can use compare regs */
-               if (IS_TIMER_TOP(clockevent_id))
-                       pr_warn("%s: Invalid use of system timers.  Results unpredictable.\n",
-                               __func__);
-               else if ((dtip[event_timer].cmp_off == 0)
-                               || (dtip[event_timer].cmp_irq == 0))
-                       pr_warn("%s: Invalid timer instance setup.  Results unpredictable.\n",
-                               __func__);
-               else {
-                       timers[TID_CLOCKEVENT].opts |= TIMER_OPTS_USE_COMPARE;
-                       clockevent_davinci.features = CLOCK_EVT_FEAT_ONESHOT;
-               }
-       }
-
-       BUG_ON(IS_ERR(timer_clk));
-       clk_prepare_enable(timer_clk);
-
-       /* init timer hw */
-       timer_init();
-
-       davinci_clock_tick_rate = clk_get_rate(timer_clk);
-
-       /* setup clocksource */
-       clocksource_davinci.name = id_to_name[clocksource_id];
-       if (clocksource_register_hz(&clocksource_davinci,
-                                   davinci_clock_tick_rate))
-               pr_err("%s: can't register clocksource!\n",
-                      clocksource_davinci.name);
-
-       sched_clock_register(davinci_read_sched_clock, 32,
-                         davinci_clock_tick_rate);
-
-       /* setup clockevent */
-       clockevent_davinci.name = id_to_name[timers[TID_CLOCKEVENT].id];
-
-       clockevent_davinci.cpumask = cpumask_of(0);
-       clockevents_config_and_register(&clockevent_davinci,
-                                       davinci_clock_tick_rate, 1, 0xfffffffe);
-
-       for (i=0; i< ARRAY_SIZE(timers); i++)
-               timer32_config(&timers[i]);
-}
index 6e7f10c..cbbe03e 100644 (file)
@@ -3,10 +3,10 @@
 # Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
 #              http://www.samsung.com/
 
-# Configuration options for the EXYNOS
+# Configuration options for the Samsung Exynos
 
 menuconfig ARCH_EXYNOS
-       bool "Samsung EXYNOS"
+       bool "Samsung Exynos"
        depends on ARCH_MULTI_V7
        select ARCH_HAS_HOLES_MEMORYMODEL
        select ARCH_SUPPORTS_BIG_ENDIAN
@@ -42,7 +42,7 @@ menuconfig ARCH_EXYNOS
        select POWER_RESET_SYSCON
        select POWER_RESET_SYSCON_POWEROFF
        help
-         Support for SAMSUNG EXYNOS SoCs (EXYNOS4/5)
+         Support for Samsung Exynos SoCs
 
 if ARCH_EXYNOS
 
@@ -52,63 +52,62 @@ config S5P_DEV_MFC
          Compile in setup memory (init) code for MFC
 
 config ARCH_EXYNOS3
-       bool "SAMSUNG EXYNOS3"
+       bool "Samsung Exynos3"
        default y
        select ARM_CPU_SUSPEND if PM
        help
-         Samsung EXYNOS3 (Cortex-A7) SoC based systems
+         Samsung Exynos3 (Cortex-A7) SoC based systems
 
 config ARCH_EXYNOS4
-       bool "SAMSUNG EXYNOS4"
+       bool "Samsung Exynos4"
        default y
        select ARM_CPU_SUSPEND if PM_SLEEP
        select CLKSRC_SAMSUNG_PWM if CPU_EXYNOS4210
        select CPU_EXYNOS4210
        select GIC_NON_BANKED
-       select MIGHT_HAVE_CACHE_L2X0
        help
-         Samsung EXYNOS4 (Cortex-A9) SoC based systems
+         Samsung Exynos4 (Cortex-A9) SoC based systems
 
 config ARCH_EXYNOS5
-       bool "SAMSUNG EXYNOS5"
+       bool "Samsung Exynos5"
        default y
        help
-         Samsung EXYNOS5 (Cortex-A15/A7) SoC based systems
+         Samsung Exynos5 (Cortex-A15/A7) SoC based systems
 
-comment "EXYNOS SoCs"
+comment "Exynos SoCs"
 
 config SOC_EXYNOS3250
-       bool "SAMSUNG EXYNOS3250"
+       bool "Samsung Exynos3250"
        default y
        depends on ARCH_EXYNOS3
 
 config CPU_EXYNOS4210
-       bool "SAMSUNG EXYNOS4210"
+       bool "Samsung Exynos4210"
        default y
        depends on ARCH_EXYNOS4
 
 config SOC_EXYNOS4412
-       bool "SAMSUNG EXYNOS4412"
+       bool "Samsung Exynos4412"
        default y
        depends on ARCH_EXYNOS4
 
 config SOC_EXYNOS5250
-       bool "SAMSUNG EXYNOS5250"
+       bool "Samsung Exynos5250"
        default y
        depends on ARCH_EXYNOS5
 
 config SOC_EXYNOS5260
-       bool "SAMSUNG EXYNOS5260"
+       bool "Samsung Exynos5260"
        default y
        depends on ARCH_EXYNOS5
 
 config SOC_EXYNOS5410
-       bool "SAMSUNG EXYNOS5410"
+       bool "Samsung Exynos5410"
        default y
        depends on ARCH_EXYNOS5
 
 config SOC_EXYNOS5420
-       bool "SAMSUNG EXYNOS5420"
+       bool "Samsung Exynos5420"
        default y
        depends on ARCH_EXYNOS5
        select EXYNOS_MCPM if SMP
@@ -116,7 +115,7 @@ config SOC_EXYNOS5420
        select ARM_CPU_SUSPEND
 
 config SOC_EXYNOS5800
-       bool "SAMSUNG EXYNOS5800"
+       bool "Samsung EXYNOS5800"
        default y
        depends on SOC_EXYNOS5420
 
index 56411bb..afd988a 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2011 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * Common Header for EXYNOS machines
+ * Common Header for Exynos machines
  */
 
 #ifndef __ARCH_ARM_MACH_EXYNOS_COMMON_H
index 9aa4833..7a8d155 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 //
-// SAMSUNG EXYNOS Flattened Device Tree enabled machine
+// Samsung Exynos Flattened Device Tree enabled machine
 //
 // Copyright (c) 2010-2014 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com
@@ -192,7 +192,7 @@ static void __init exynos_dt_fixup(void)
        of_fdt_limit_memory(8);
 }
 
-DT_MACHINE_START(EXYNOS_DT, "SAMSUNG EXYNOS (Flattened Device Tree)")
+DT_MACHINE_START(EXYNOS_DT, "Samsung Exynos (Flattened Device Tree)")
        .l2c_aux_val    = 0x3c400001,
        .l2c_aux_mask   = 0xc20fffff,
        .smp            = smp_ops(exynos_smp_ops),
index 22ebe36..8d58faa 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2010-2011 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com/
  *
- * EXYNOS - Memory map definitions
+ * Exynos - Memory map definitions
  */
 
 #ifndef __ASM_ARCH_MAP_H
index 48e7fb3..78af34c 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com
 //
-// EXYNOS - Power Management support
+// Exynos - Power Management support
 //
 // Based on arch/arm/mach-s3c2410/pm.c
 // Copyright (c) 2006 Simtec Electronics
index 98832e5..5c30feb 100644 (file)
@@ -2,7 +2,7 @@
 /*
  *  Copyright (c) 2012 Samsung Electronics.
  *
- * EXYNOS - SMC Call
+ * Exynos - SMC Call
  */
 
 #ifndef __ASM_ARCH_EXYNOS_SMC_H
index 6a0d344..3bf14ca 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com
 //
-// EXYNOS - Suspend support
+// Exynos - Suspend support
 //
 // Based on arch/arm/mach-s3c2410/pm.c
 // Copyright (c) 2006 Simtec Electronics
index 593bf15..95584ee 100644 (file)
@@ -520,6 +520,7 @@ config SOC_IMX6UL
        bool "i.MX6 UltraLite support"
        select PINCTRL_IMX6UL
        select SOC_IMX6
+       select ARM_ERRATA_814220
 
        help
          This enables support for Freescale i.MX6 UltraLite processor.
@@ -556,6 +557,7 @@ config SOC_IMX7D
        select PINCTRL_IMX7D
        select SOC_IMX7D_CA7 if ARCH_MULTI_V7
        select SOC_IMX7D_CM4 if ARM_SINGLE_ARMV7M
+       select ARM_ERRATA_814220 if ARCH_MULTI_V7
        help
                This enables support for Freescale i.MX7 Dual processor.
 
index 871f983..06f8d64 100644 (file)
 #define OCOTP_UID_H    0x420
 #define OCOTP_UID_L    0x410
 
+#define OCOTP_ULP_UID_1                0x4b0
+#define OCOTP_ULP_UID_2                0x4c0
+#define OCOTP_ULP_UID_3                0x4d0
+#define OCOTP_ULP_UID_4                0x4e0
+
 unsigned int __mxc_cpu_type;
 static unsigned int imx_soc_revision;
 
@@ -164,6 +169,7 @@ struct device * __init imx_soc_device_init(void)
                soc_id = "i.MX7D";
                break;
        case MXC_CPU_IMX7ULP:
+               ocotp_compat = "fsl,imx7ulp-ocotp";
                soc_id = "i.MX7ULP";
                break;
        default:
@@ -178,11 +184,25 @@ struct device * __init imx_soc_device_init(void)
        }
 
        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;
+               if (__mxc_cpu_type == MXC_CPU_IMX7ULP) {
+                       regmap_read(ocotp, OCOTP_ULP_UID_4, &val);
+                       soc_uid = val & 0xffff;
+                       regmap_read(ocotp, OCOTP_ULP_UID_3, &val);
+                       soc_uid <<= 16;
+                       soc_uid |= val & 0xffff;
+                       regmap_read(ocotp, OCOTP_ULP_UID_2, &val);
+                       soc_uid <<= 16;
+                       soc_uid |= val & 0xffff;
+                       regmap_read(ocotp, OCOTP_ULP_UID_1, &val);
+                       soc_uid <<= 16;
+                       soc_uid |= val & 0xffff;
+               } else {
+                       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",
index f07cfda..e1135b9 100644 (file)
@@ -16,11 +16,11 @@ hwmod-common                                = omap_hwmod.o omap_hwmod_reset.o \
 clock-common                           = clock.o
 secure-common                          = omap-smc.o omap-secure.o
 
-obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common)
+obj-$(CONFIG_ARCH_OMAP2) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
 obj-$(CONFIG_ARCH_OMAP3) += $(omap-2-3-common) $(hwmod-common) $(secure-common)
 obj-$(CONFIG_ARCH_OMAP4) += $(hwmod-common) $(secure-common)
-obj-$(CONFIG_SOC_AM33XX) += $(hwmod-common)
-obj-$(CONFIG_SOC_OMAP5)         += $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_AM33XX) += $(hwmod-common) $(secure-common)
+obj-$(CONFIG_SOC_OMAP5)  += $(hwmod-common) $(secure-common)
 obj-$(CONFIG_SOC_AM43XX) += $(hwmod-common) $(secure-common)
 obj-$(CONFIG_SOC_DRA7XX) += $(hwmod-common) $(secure-common)
 
index 751708d..c96a2b1 100644 (file)
@@ -84,6 +84,15 @@ static struct clockdomain l3s_tsc_43xx_clkdm = {
        .flags            = CLKDM_CAN_SWSUP,
 };
 
+static struct clockdomain lcdc_43xx_clkdm = {
+       .name             = "lcdc_clkdm",
+       .pwrdm            = { .name = "per_pwrdm" },
+       .prcm_partition   = AM43XX_CM_PARTITION,
+       .cm_inst          = AM43XX_CM_PER_INST,
+       .clkdm_offs       = AM43XX_CM_PER_LCDC_CDOFFS,
+       .flags            = CLKDM_CAN_SWSUP,
+};
+
 static struct clockdomain dss_43xx_clkdm = {
        .name             = "dss_clkdm",
        .pwrdm            = { .name = "per_pwrdm" },
@@ -173,6 +182,7 @@ static struct clockdomain *clockdomains_am43xx[] __initdata = {
        &pruss_ocp_43xx_clkdm,
        &ocpwp_l3_43xx_clkdm,
        &l3s_tsc_43xx_clkdm,
+       &lcdc_43xx_clkdm,
        &dss_43xx_clkdm,
        &l3_aon_43xx_clkdm,
        &emif_43xx_clkdm,
index 3068802..27835c4 100644 (file)
@@ -606,7 +606,7 @@ static struct clockdomain cam_7xx_clkdm = {
        .dep_bit          = DRA7XX_CAM_STATDEP_SHIFT,
        .wkdep_srcs       = cam_wkup_sleep_deps,
        .sleepdep_srcs    = cam_wkup_sleep_deps,
-       .flags            = CLKDM_CAN_HWSUP_SWSUP,
+       .flags            = CLKDM_CAN_SWSUP,
 };
 
 static struct clockdomain l4per_7xx_clkdm = {
index 223b37c..75d7299 100644 (file)
@@ -255,7 +255,7 @@ extern void gic_dist_disable(void);
 extern void gic_dist_enable(void);
 extern bool gic_dist_disabled(void);
 extern void gic_timer_retrigger(void);
-extern void omap_smc1(u32 fn, u32 arg);
+extern void _omap_smc1(u32 fn, u32 arg);
 extern void omap4_sar_ram_init(void);
 extern void __iomem *omap4_get_sar_ram_base(void);
 extern void omap4_mpuss_early_init(void);
@@ -345,9 +345,12 @@ static inline int dra7xx_pciess_reset(struct omap_hwmod *oh)
 }
 #endif
 
+struct omap_system_dma_plat_info;
+
 void pdata_quirks_init(const struct of_device_id *);
 void omap_auxdata_legacy_init(struct device *dev);
 void omap_pcs_legacy_init(int irq, void (*rearm)(void));
+extern struct omap_system_dma_plat_info dma_plat_info;
 
 struct omap_sdrc_params;
 extern void omap_sdrc_init(struct omap_sdrc_params *sdrc_cs0,
index 0c105ba..8cc109c 100644 (file)
 #include <linux/omap-dma.h>
 
 #include "soc.h"
-#include "omap_hwmod.h"
-#include "omap_device.h"
-
-static enum omap_reg_offsets dma_common_ch_end;
 
 static const struct omap_dma_reg reg_map[] = {
        [REVISION]      = { 0x0000, 0x00, OMAP_DMA_REG_32BIT },
@@ -81,42 +77,6 @@ static const struct omap_dma_reg reg_map[] = {
        [CCDN]          = { 0x00d8, 0x60, OMAP_DMA_REG_32BIT },
 };
 
-static void __iomem *dma_base;
-static inline void dma_write(u32 val, int reg, int lch)
-{
-       void __iomem *addr = dma_base;
-
-       addr += reg_map[reg].offset;
-       addr += reg_map[reg].stride * lch;
-
-       writel_relaxed(val, addr);
-}
-
-static inline u32 dma_read(int reg, int lch)
-{
-       void __iomem *addr = dma_base;
-
-       addr += reg_map[reg].offset;
-       addr += reg_map[reg].stride * lch;
-
-       return readl_relaxed(addr);
-}
-
-static void omap2_clear_dma(int lch)
-{
-       int i;
-
-       for (i = CSDP; i <= dma_common_ch_end; i += 1)
-               dma_write(0, i, lch);
-}
-
-static void omap2_show_dma_caps(void)
-{
-       u8 revision = dma_read(REVISION, 0) & 0xff;
-       printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
-                               revision >> 4, revision & 0xf);
-}
-
 static unsigned configure_dma_errata(void)
 {
        unsigned errata = 0;
@@ -211,82 +171,35 @@ static const struct dma_slave_map omap24xx_sdma_dt_map[] = {
        { "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
 };
 
-static struct omap_system_dma_plat_info dma_plat_info __initdata = {
-       .reg_map        = reg_map,
-       .channel_stride = 0x60,
-       .show_dma_caps  = omap2_show_dma_caps,
-       .clear_dma      = omap2_clear_dma,
-       .dma_write      = dma_write,
-       .dma_read       = dma_read,
+static struct omap_dma_dev_attr dma_attr = {
+       .dev_caps = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
+                   IS_CSSA_32 | IS_CDSA_32,
+       .lch_count = 32,
 };
 
-static struct platform_device_info omap_dma_dev_info __initdata = {
-       .name = "omap-dma-engine",
-       .id = -1,
-       .dma_mask = DMA_BIT_MASK(32),
+struct omap_system_dma_plat_info dma_plat_info = {
+       .reg_map        = reg_map,
+       .channel_stride = 0x60,
+       .dma_attr       = &dma_attr,
 };
 
 /* One time initializations */
-static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
+static int __init omap2_system_dma_init(void)
 {
-       struct platform_device                  *pdev;
-       struct omap_system_dma_plat_info        p;
-       struct omap_dma_dev_attr                *d;
-       struct resource                         *mem;
-       char                                    *name = "omap_dma_system";
-
-       p = dma_plat_info;
-       p.dma_attr = (struct omap_dma_dev_attr *)oh->dev_attr;
-       p.errata = configure_dma_errata();
+       dma_plat_info.errata = configure_dma_errata();
 
        if (soc_is_omap24xx()) {
                /* DMA slave map for drivers not yet converted to DT */
-               p.slave_map = omap24xx_sdma_dt_map;
-               p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map);
+               dma_plat_info.slave_map = omap24xx_sdma_dt_map;
+               dma_plat_info.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map);
        }
 
-       pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
-       if (IS_ERR(pdev)) {
-               pr_err("%s: Can't build omap_device for %s:%s.\n",
-                       __func__, name, oh->name);
-               return PTR_ERR(pdev);
-       }
-
-       omap_dma_dev_info.res = pdev->resource;
-       omap_dma_dev_info.num_res = pdev->num_resources;
+       if (!soc_is_omap242x())
+               dma_attr.dev_caps |= IS_RW_PRIORITY;
 
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem) {
-               dev_err(&pdev->dev, "%s: no mem resource\n", __func__);
-               return -EINVAL;
-       }
-
-       dma_base = ioremap(mem->start, resource_size(mem));
-       if (!dma_base) {
-               dev_err(&pdev->dev, "%s: ioremap fail\n", __func__);
-               return -ENOMEM;
-       }
-
-       d = oh->dev_attr;
-
-       if (cpu_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
-               d->dev_caps |= HS_CHANNELS_RESERVED;
-
-       if (platform_get_irq_byname(pdev, "0") < 0)
-               d->dev_caps |= DMA_ENGINE_HANDLE_IRQ;
-
-       /* Check the capabilities register for descriptor loading feature */
-       if (dma_read(CAPS_0, 0) & DMA_HAS_DESCRIPTOR_CAPS)
-               dma_common_ch_end = CCDN;
-       else
-               dma_common_ch_end = CCFN;
+       if (soc_is_omap34xx() && (omap_type() != OMAP2_DEVICE_TYPE_GP))
+               dma_attr.dev_caps |= HS_CHANNELS_RESERVED;
 
        return 0;
 }
-
-static int __init omap2_system_dma_init(void)
-{
-       return omap_hwmod_for_each_by_class("dma",
-                       omap2_system_dma_init_dev, NULL);
-}
 omap_arch_initcall(omap2_system_dma_init);
index 349e480..f280472 100644 (file)
@@ -51,6 +51,7 @@
 #include "prm33xx.h"
 #include "prm44xx.h"
 #include "opp2xxx.h"
+#include "omap-secure.h"
 
 /*
  * omap_clk_soc_init: points to a function that does the SoC-specific
@@ -430,6 +431,7 @@ void __init omap2420_init_early(void)
        omap_hwmod_init_postsetup();
        omap_clk_soc_init = omap2420_dt_clk_init;
        rate_table = omap2420_rate_table;
+       omap_secure_init();
 }
 
 void __init omap2420_init_late(void)
@@ -454,6 +456,7 @@ void __init omap2430_init_early(void)
        omap_hwmod_init_postsetup();
        omap_clk_soc_init = omap2430_dt_clk_init;
        rate_table = omap2430_rate_table;
+       omap_secure_init();
 }
 
 void __init omap2430_init_late(void)
@@ -481,6 +484,7 @@ void __init omap3_init_early(void)
        omap3xxx_clockdomains_init();
        omap3xxx_hwmod_init();
        omap_hwmod_init_postsetup();
+       omap_secure_init();
 }
 
 void __init omap3430_init_early(void)
@@ -533,6 +537,7 @@ void __init ti814x_init_early(void)
        dm814x_hwmod_init();
        omap_hwmod_init_postsetup();
        omap_clk_soc_init = dm814x_dt_clk_init;
+       omap_secure_init();
 }
 
 void __init ti816x_init_early(void)
@@ -549,6 +554,7 @@ void __init ti816x_init_early(void)
        dm816x_hwmod_init();
        omap_hwmod_init_postsetup();
        omap_clk_soc_init = dm816x_dt_clk_init;
+       omap_secure_init();
 }
 #endif
 
@@ -566,6 +572,7 @@ void __init am33xx_init_early(void)
        am33xx_hwmod_init();
        omap_hwmod_init_postsetup();
        omap_clk_soc_init = am33xx_dt_clk_init;
+       omap_secure_init();
 }
 
 void __init am33xx_init_late(void)
@@ -589,6 +596,7 @@ void __init am43xx_init_early(void)
        omap_hwmod_init_postsetup();
        omap_l2_cache_init();
        omap_clk_soc_init = am43xx_dt_clk_init;
+       omap_secure_init();
 }
 
 void __init am43xx_init_late(void)
@@ -617,6 +625,7 @@ void __init omap4430_init_early(void)
        omap_hwmod_init_postsetup();
        omap_l2_cache_init();
        omap_clk_soc_init = omap4xxx_dt_clk_init;
+       omap_secure_init();
 }
 
 void __init omap4430_init_late(void)
@@ -643,6 +652,7 @@ void __init omap5_init_early(void)
        omap54xx_hwmod_init();
        omap_hwmod_init_postsetup();
        omap_clk_soc_init = omap5xxx_dt_clk_init;
+       omap_secure_init();
 }
 
 void __init omap5_init_late(void)
@@ -666,6 +676,7 @@ void __init dra7xx_init_early(void)
        dra7xx_hwmod_init();
        omap_hwmod_init_postsetup();
        omap_clk_soc_init = dra7xx_dt_clk_init;
+       omap_secure_init();
 }
 
 void __init dra7xx_init_late(void)
index f1a6ece..54aff33 100644 (file)
 
 #include <linux/platform_device.h>
 #include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/list.h>
 
-#include "omap_hwmod.h"
-#include "omap_device.h"
+#include "clockdomain.h"
 #include "powerdomain.h"
 
+struct pwrdm_link {
+       struct device *dev;
+       struct powerdomain *pwrdm;
+       struct list_head node;
+};
+
+static DEFINE_SPINLOCK(iommu_lock);
+static struct clockdomain *emu_clkdm;
+static atomic_t emu_count;
+
+static void omap_iommu_dra7_emu_swsup_config(struct platform_device *pdev,
+                                            bool enable)
+{
+       struct device_node *np = pdev->dev.of_node;
+       unsigned long flags;
+
+       if (!of_device_is_compatible(np, "ti,dra7-dsp-iommu"))
+               return;
+
+       if (!emu_clkdm) {
+               emu_clkdm = clkdm_lookup("emu_clkdm");
+               if (WARN_ON_ONCE(!emu_clkdm))
+                       return;
+       }
+
+       spin_lock_irqsave(&iommu_lock, flags);
+
+       if (enable && (atomic_inc_return(&emu_count) == 1))
+               clkdm_deny_idle(emu_clkdm);
+       else if (!enable && (atomic_dec_return(&emu_count) == 0))
+               clkdm_allow_idle(emu_clkdm);
+
+       spin_unlock_irqrestore(&iommu_lock, flags);
+}
+
+static struct powerdomain *_get_pwrdm(struct device *dev)
+{
+       struct clk *clk;
+       struct clk_hw_omap *hwclk;
+       struct clockdomain *clkdm;
+       struct powerdomain *pwrdm = NULL;
+       struct pwrdm_link *entry;
+       unsigned long flags;
+       static LIST_HEAD(cache);
+
+       spin_lock_irqsave(&iommu_lock, flags);
+
+       list_for_each_entry(entry, &cache, node) {
+               if (entry->dev == dev) {
+                       pwrdm = entry->pwrdm;
+                       break;
+               }
+       }
+
+       spin_unlock_irqrestore(&iommu_lock, flags);
+
+       if (pwrdm)
+               return pwrdm;
+
+       clk = of_clk_get(dev->of_node->parent, 0);
+       if (!clk) {
+               dev_err(dev, "no fck found\n");
+               return NULL;
+       }
+
+       hwclk = to_clk_hw_omap(__clk_get_hw(clk));
+       clk_put(clk);
+       if (!hwclk || !hwclk->clkdm_name) {
+               dev_err(dev, "no hwclk data\n");
+               return NULL;
+       }
+
+       clkdm = clkdm_lookup(hwclk->clkdm_name);
+       if (!clkdm) {
+               dev_err(dev, "clkdm not found: %s\n", hwclk->clkdm_name);
+               return NULL;
+       }
+
+       pwrdm = clkdm_get_pwrdm(clkdm);
+       if (!pwrdm) {
+               dev_err(dev, "pwrdm not found: %s\n", clkdm->name);
+               return NULL;
+       }
+
+       entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+       if (entry) {
+               entry->dev = dev;
+               entry->pwrdm = pwrdm;
+               spin_lock_irqsave(&iommu_lock, flags);
+               list_add(&entry->node, &cache);
+               spin_unlock_irqrestore(&iommu_lock, flags);
+       }
+
+       return pwrdm;
+}
+
 int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
                                    u8 *pwrst)
 {
        struct powerdomain *pwrdm;
-       struct omap_device *od;
        u8 next_pwrst;
+       int ret = 0;
 
-       od = to_omap_device(pdev);
-       if (!od)
-               return -ENODEV;
-
-       if (od->hwmods_cnt != 1)
-               return -EINVAL;
-
-       pwrdm = omap_hwmod_get_pwrdm(od->hwmods[0]);
+       pwrdm = _get_pwrdm(&pdev->dev);
        if (!pwrdm)
-               return -EINVAL;
+               return -ENODEV;
 
-       if (request)
+       if (request) {
                *pwrst = pwrdm_read_next_pwrst(pwrdm);
+               omap_iommu_dra7_emu_swsup_config(pdev, true);
+       }
 
        if (*pwrst > PWRDM_POWER_RET)
-               return 0;
+               goto out;
 
        next_pwrst = request ? PWRDM_POWER_ON : *pwrst;
 
-       return pwrdm_set_next_pwrst(pwrdm, next_pwrst);
+       ret = pwrdm_set_next_pwrst(pwrdm, next_pwrst);
+
+out:
+       if (!request)
+               omap_iommu_dra7_emu_swsup_config(pdev, false);
+
+       return ret;
 }
index 24298e4..d00e3c7 100644 (file)
@@ -8,18 +8,42 @@
  * Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
  */
 
+#include <linux/arm-smccc.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/memblock.h>
+#include <linux/of.h>
 
 #include <asm/cacheflush.h>
 #include <asm/memblock.h>
 
+#include "common.h"
 #include "omap-secure.h"
 
 static phys_addr_t omap_secure_memblock_base;
 
+bool optee_available;
+
+#define OMAP_SIP_SMC_STD_CALL_VAL(func_num) \
+       ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_32, \
+       ARM_SMCCC_OWNER_SIP, (func_num))
+
+static void __init omap_optee_init_check(void)
+{
+       struct device_node *np;
+
+       /*
+        * We only check that the OP-TEE node is present and available. The
+        * OP-TEE kernel driver is not needed for the type of interaction made
+        * with OP-TEE here so the driver's status is not checked.
+        */
+       np = of_find_node_by_path("/firmware/optee");
+       if (np && of_device_is_available(np))
+               optee_available = true;
+       of_node_put(np);
+}
+
 /**
  * omap_sec_dispatcher: Routine to dispatch low power secure
  * service routines
@@ -53,6 +77,27 @@ u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
        return ret;
 }
 
+void omap_smccc_smc(u32 fn, u32 arg)
+{
+       struct arm_smccc_res res;
+
+       arm_smccc_smc(OMAP_SIP_SMC_STD_CALL_VAL(fn), arg,
+                     0, 0, 0, 0, 0, 0, &res);
+       WARN(res.a0, "Secure function call 0x%08x failed\n", fn);
+}
+
+void omap_smc1(u32 fn, u32 arg)
+{
+       /*
+        * If this platform has OP-TEE installed we use ARM SMC calls
+        * otherwise fall back to the OMAP ROM style calls.
+        */
+       if (optee_available)
+               omap_smccc_smc(fn, arg);
+       else
+               _omap_smc1(fn, arg);
+}
+
 /* Allocate the memory to save secure ram */
 int __init omap_secure_ram_reserve_memblock(void)
 {
@@ -163,3 +208,8 @@ u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag)
                                      NO_FLAG,
                                      3, ptr, count, flag, 0);
 }
+
+void __init omap_secure_init(void)
+{
+       omap_optee_init_check();
+}
index 20046e8..ba8c486 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef OMAP_ARCH_OMAP_SECURE_H
 #define OMAP_ARCH_OMAP_SECURE_H
 
+#include <linux/types.h>
+
 /* Monitor error code */
 #define  API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR       0xFFFFFFFE
 #define  API_HAL_RET_VALUE_SERVICE_UNKNWON             0xFFFFFFFF
@@ -51,6 +53,9 @@
 #define OMAP4_PPA_L2_POR_INDEX         0x23
 #define OMAP4_PPA_CPU_ACTRL_SMP_INDEX  0x25
 
+#define AM43xx_PPA_SVC_PM_SUSPEND      0x71
+#define AM43xx_PPA_SVC_PM_RESUME       0x72
+
 /* Secure RX-51 PPA (Primary Protected Application) APIs */
 #define RX51_PPA_HWRNG                 29
 #define RX51_PPA_L2_INVAL              40
@@ -60,6 +65,8 @@
 
 extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
                                u32 arg1, u32 arg2, u32 arg3, u32 arg4);
+extern void omap_smccc_smc(u32 fn, u32 arg);
+extern void omap_smc1(u32 fn, u32 arg);
 extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
 extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs);
 extern phys_addr_t omap_secure_ram_mempool_base(void);
@@ -72,6 +79,9 @@ extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
 extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits);
 extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag);
 
+extern bool optee_available;
+void omap_secure_init(void);
+
 #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
 void set_cntfreq(void);
 #else
index fd2bcd9..d483284 100644 (file)
  * the monitor API number. It uses few CPU registers
  * internally and hence they need be backed up including
  * link register "lr".
- * Function signature : void omap_smc1(u32 fn, u32 arg)
+ * Function signature : void _omap_smc1(u32 fn, u32 arg)
  */
        .arch armv7-a
        .arch_extension sec
-ENTRY(omap_smc1)
+ENTRY(_omap_smc1)
        stmfd   sp!, {r2-r12, lr}
        mov     r12, r0
        mov     r0, r1
        dsb
        smc     #0
        ldmfd   sp!, {r2-r12, pc}
-ENDPROC(omap_smc1)
+ENDPROC(_omap_smc1)
 
 /**
  * u32 omap_smc2(u32 id, u32 falg, u32 pargs)
index 1d55602..6b4548f 100644 (file)
@@ -373,176 +373,6 @@ void omap_device_delete(struct omap_device *od)
        kfree(od);
 }
 
-/**
- * omap_device_copy_resources - Add legacy IO and IRQ resources
- * @oh: interconnect target module
- * @pdev: platform device to copy resources to
- *
- * We still have legacy DMA and smartreflex needing resources.
- * Let's populate what they need until we can eventually just
- * remove this function. Note that there should be no need to
- * call this from omap_device_build_from_dt(), nor should there
- * be any need to call it for other devices.
- */
-static int
-omap_device_copy_resources(struct omap_hwmod *oh,
-                          struct platform_device *pdev)
-{
-       struct device_node *np, *child;
-       struct property *prop;
-       struct resource *res;
-       const char *name;
-       int error, irq = 0;
-
-       if (!oh || !oh->od || !oh->od->pdev)
-               return -EINVAL;
-
-       np = oh->od->pdev->dev.of_node;
-       if (!np) {
-               error = -ENODEV;
-               goto error;
-       }
-
-       res = kcalloc(2, sizeof(*res), GFP_KERNEL);
-       if (!res)
-               return -ENOMEM;
-
-       /* Do we have a dts range for the interconnect target module? */
-       error = omap_hwmod_parse_module_range(oh, np, res);
-
-       /* No ranges, rely on device reg entry */
-       if (error)
-               error = of_address_to_resource(np, 0, res);
-       if (error)
-               goto free;
-
-       /* SmartReflex needs first IO resource name to be "mpu" */
-       res[0].name = "mpu";
-
-       /*
-        * We may have a configured "ti,sysc" interconnect target with a
-        * dts child with the interrupt. If so use the first child's
-        * first interrupt for "ti-hwmods" legacy support.
-        */
-       of_property_for_each_string(np, "compatible", prop, name)
-               if (!strncmp("ti,sysc-", name, 8))
-                       break;
-
-       child = of_get_next_available_child(np, NULL);
-
-       if (name)
-               irq = irq_of_parse_and_map(child, 0);
-       if (!irq)
-               irq = irq_of_parse_and_map(np, 0);
-       if (!irq) {
-               error = -EINVAL;
-               goto free;
-       }
-
-       /* Legacy DMA code needs interrupt name to be "0" */
-       res[1].start = irq;
-       res[1].end = irq;
-       res[1].flags = IORESOURCE_IRQ;
-       res[1].name = "0";
-
-       error = platform_device_add_resources(pdev, res, 2);
-
-free:
-       kfree(res);
-
-error:
-       WARN(error, "%s: %s device %s failed: %i\n",
-            __func__, oh->name, dev_name(&pdev->dev),
-            error);
-
-       return error;
-}
-
-/**
- * omap_device_build - build and register an omap_device with one omap_hwmod
- * @pdev_name: name of the platform_device driver to use
- * @pdev_id: this platform_device's connection ID
- * @oh: ptr to the single omap_hwmod that backs this omap_device
- * @pdata: platform_data ptr to associate with the platform_device
- * @pdata_len: amount of memory pointed to by @pdata
- *
- * Convenience function for building and registering a single
- * omap_device record, which in turn builds and registers a
- * platform_device record.  See omap_device_build_ss() for more
- * information.  Returns ERR_PTR(-EINVAL) if @oh is NULL; otherwise,
- * passes along the return value of omap_device_build_ss().
- */
-struct platform_device __init *omap_device_build(const char *pdev_name,
-                                                int pdev_id,
-                                                struct omap_hwmod *oh,
-                                                void *pdata, int pdata_len)
-{
-       int ret = -ENOMEM;
-       struct platform_device *pdev;
-       struct omap_device *od;
-
-       if (!oh || !pdev_name)
-               return ERR_PTR(-EINVAL);
-
-       if (!pdata && pdata_len > 0)
-               return ERR_PTR(-EINVAL);
-
-       if (strncmp(oh->name, "smartreflex", 11) &&
-           strncmp(oh->name, "dma", 3)) {
-               pr_warn("%s need to update %s to probe with dt\na",
-                       __func__, pdev_name);
-               ret = -ENODEV;
-               goto odbs_exit;
-       }
-
-       pdev = platform_device_alloc(pdev_name, pdev_id);
-       if (!pdev) {
-               ret = -ENOMEM;
-               goto odbs_exit;
-       }
-
-       /* Set the dev_name early to allow dev_xxx in omap_device_alloc */
-       if (pdev->id != -1)
-               dev_set_name(&pdev->dev, "%s.%d", pdev->name,  pdev->id);
-       else
-               dev_set_name(&pdev->dev, "%s", pdev->name);
-
-       /*
-        * Must be called before omap_device_alloc() as oh->od
-        * only contains the currently registered omap_device
-        * and will get overwritten by omap_device_alloc().
-        */
-       ret = omap_device_copy_resources(oh, pdev);
-       if (ret)
-               goto odbs_exit1;
-
-       od = omap_device_alloc(pdev, &oh, 1);
-       if (IS_ERR(od)) {
-               ret = PTR_ERR(od);
-               goto odbs_exit1;
-       }
-
-       ret = platform_device_add_data(pdev, pdata, pdata_len);
-       if (ret)
-               goto odbs_exit2;
-
-       ret = omap_device_register(pdev);
-       if (ret)
-               goto odbs_exit2;
-
-       return pdev;
-
-odbs_exit2:
-       omap_device_delete(od);
-odbs_exit1:
-       platform_device_put(pdev);
-odbs_exit:
-
-       pr_err("omap_device: %s: build failed (%d)\n", pdev_name, ret);
-
-       return ERR_PTR(ret);
-}
-
 #ifdef CONFIG_PM
 static int _od_runtime_suspend(struct device *dev)
 {
index ced775e..f77e76a 100644 (file)
@@ -68,10 +68,6 @@ int omap_device_idle(struct platform_device *pdev);
 
 /* Core code interface */
 
-struct platform_device *omap_device_build(const char *pdev_name, int pdev_id,
-                                         struct omap_hwmod *oh, void *pdata,
-                                         int pdata_len);
-
 struct omap_device *omap_device_alloc(struct platform_device *pdev,
                                      struct omap_hwmod **ohs, int oh_cnt);
 void omap_device_delete(struct omap_device *od);
index a136788..17d337e 100644 (file)
@@ -1853,23 +1853,6 @@ static int _omap4_get_context_lost(struct omap_hwmod *oh)
 }
 
 /**
- * _enable_preprogram - Pre-program an IP block during the _enable() process
- * @oh: struct omap_hwmod *
- *
- * Some IP blocks (such as AESS) require some additional programming
- * after enable before they can enter idle.  If a function pointer to
- * do so is present in the hwmod data, then call it and pass along the
- * return value; otherwise, return 0.
- */
-static int _enable_preprogram(struct omap_hwmod *oh)
-{
-       if (!oh->class->enable_preprogram)
-               return 0;
-
-       return oh->class->enable_preprogram(oh);
-}
-
-/**
  * _enable - enable an omap_hwmod
  * @oh: struct omap_hwmod *
  *
@@ -1952,7 +1935,6 @@ static int _enable(struct omap_hwmod *oh)
                                _update_sysc_cache(oh);
                        _enable_sysc(oh);
                }
-               r = _enable_preprogram(oh);
        } else {
                if (soc_ops.disable_module)
                        soc_ops.disable_module(oh);
index 2d0fd99..eebf2fd 100644 (file)
@@ -501,7 +501,6 @@ struct omap_hwmod_omap4_prcm {
  * @sysc: device SYSCONFIG/SYSSTATUS register data
  * @pre_shutdown: ptr to fn to be executed immediately prior to device shutdown
  * @reset: ptr to fn to be executed in place of the standard hwmod reset fn
- * @enable_preprogram:  ptr to fn to be executed during device enable
  * @lock: ptr to fn to be executed to lock IP registers
  * @unlock: ptr to fn to be executed to unlock IP registers
  *
@@ -526,7 +525,6 @@ struct omap_hwmod_class {
        struct omap_hwmod_class_sysconfig       *sysc;
        int                                     (*pre_shutdown)(struct omap_hwmod *oh);
        int                                     (*reset)(struct omap_hwmod *oh);
-       int                                     (*enable_preprogram)(struct omap_hwmod *oh);
        void                                    (*lock)(struct omap_hwmod *oh);
        void                                    (*unlock)(struct omap_hwmod *oh);
 };
@@ -662,7 +660,6 @@ const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
  *
  */
 
-extern int omap_hwmod_aess_preprogram(struct omap_hwmod *oh);
 void omap_hwmod_rtc_unlock(struct omap_hwmod *oh);
 void omap_hwmod_rtc_lock(struct omap_hwmod *oh);
 
index d49df96..b14442c 100644 (file)
@@ -11,7 +11,6 @@
  */
 
 #include <linux/platform_data/i2c-omap.h>
-#include <linux/omap-dma.h>
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
@@ -126,21 +125,6 @@ static struct omap_hwmod omap2420_i2c2_hwmod = {
        .flags          = HWMOD_16BIT_REG,
 };
 
-/* dma attributes */
-static struct omap_dma_dev_attr dma_dev_attr = {
-       .dev_caps  = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
-                                               IS_CSSA_32 | IS_CDSA_32,
-       .lch_count = 32,
-};
-
-static struct omap_hwmod omap2420_dma_system_hwmod = {
-       .name           = "dma",
-       .class          = &omap2xxx_dma_hwmod_class,
-       .main_clk       = "core_l3_ck",
-       .dev_attr       = &dma_dev_attr,
-       .flags          = HWMOD_NO_IDLEST,
-};
-
 /* mailbox */
 static struct omap_hwmod omap2420_mailbox_hwmod = {
        .name           = "mailbox",
@@ -328,22 +312,6 @@ static struct omap_hwmod_ocp_if omap2420_l4_wkup__gpio4 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* dma_system -> L3 */
-static struct omap_hwmod_ocp_if omap2420_dma_system__l3 = {
-       .master         = &omap2420_dma_system_hwmod,
-       .slave          = &omap2xxx_l3_main_hwmod,
-       .clk            = "core_l3_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_core -> dma_system */
-static struct omap_hwmod_ocp_if omap2420_l4_core__dma_system = {
-       .master         = &omap2xxx_l4_core_hwmod,
-       .slave          = &omap2420_dma_system_hwmod,
-       .clk            = "sdma_ick",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_core -> mailbox */
 static struct omap_hwmod_ocp_if omap2420_l4_core__mailbox = {
        .master         = &omap2xxx_l4_core_hwmod,
@@ -435,8 +403,6 @@ static struct omap_hwmod_ocp_if *omap2420_hwmod_ocp_ifs[] __initdata = {
        &omap2420_l4_wkup__gpio2,
        &omap2420_l4_wkup__gpio3,
        &omap2420_l4_wkup__gpio4,
-       &omap2420_dma_system__l3,
-       &omap2420_l4_core__dma_system,
        &omap2420_l4_core__mailbox,
        &omap2420_l4_core__mcbsp1,
        &omap2420_l4_core__mcbsp2,
index c51ef84..41a37c7 100644 (file)
@@ -12,7 +12,6 @@
 
 #include <linux/platform_data/i2c-omap.h>
 #include <linux/platform_data/hsmmc-omap.h>
-#include <linux/omap-dma.h>
 
 #include "omap_hwmod.h"
 #include "l3_2xxx.h"
@@ -121,21 +120,6 @@ static struct omap_hwmod omap2430_gpio5_hwmod = {
        .class          = &omap2xxx_gpio_hwmod_class,
 };
 
-/* dma attributes */
-static struct omap_dma_dev_attr dma_dev_attr = {
-       .dev_caps  = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
-                               IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
-       .lch_count = 32,
-};
-
-static struct omap_hwmod omap2430_dma_system_hwmod = {
-       .name           = "dma",
-       .class          = &omap2xxx_dma_hwmod_class,
-       .main_clk       = "core_l3_ck",
-       .dev_attr       = &dma_dev_attr,
-       .flags          = HWMOD_NO_IDLEST,
-};
-
 /* mailbox */
 static struct omap_hwmod omap2430_mailbox_hwmod = {
        .name           = "mailbox",
@@ -508,22 +492,6 @@ static struct omap_hwmod_ocp_if omap2430_l4_core__gpio5 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* dma_system -> L3 */
-static struct omap_hwmod_ocp_if omap2430_dma_system__l3 = {
-       .master         = &omap2430_dma_system_hwmod,
-       .slave          = &omap2xxx_l3_main_hwmod,
-       .clk            = "core_l3_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_core -> dma_system */
-static struct omap_hwmod_ocp_if omap2430_l4_core__dma_system = {
-       .master         = &omap2xxx_l4_core_hwmod,
-       .slave          = &omap2430_dma_system_hwmod,
-       .clk            = "sdma_ick",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_core -> mailbox */
 static struct omap_hwmod_ocp_if omap2430_l4_core__mailbox = {
        .master         = &omap2xxx_l4_core_hwmod,
@@ -635,8 +603,6 @@ static struct omap_hwmod_ocp_if *omap2430_hwmod_ocp_ifs[] __initdata = {
        &omap2430_l4_wkup__gpio3,
        &omap2430_l4_wkup__gpio4,
        &omap2430_l4_core__gpio5,
-       &omap2430_dma_system__l3,
-       &omap2430_l4_core__dma_system,
        &omap2430_l4_core__mailbox,
        &omap2430_l4_core__mcbsp1,
        &omap2430_l4_core__mcbsp2,
index f767524..a445704 100644 (file)
@@ -7,7 +7,6 @@
  */
 
 #include <linux/types.h>
-#include <linux/omap-dma.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
@@ -95,23 +94,6 @@ struct omap_hwmod_class omap2xxx_gpio_hwmod_class = {
        .sysc = &omap2xxx_gpio_sysc,
 };
 
-/* system dma */
-static struct omap_hwmod_class_sysconfig omap2xxx_dma_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x002c,
-       .syss_offs      = 0x0028,
-       .sysc_flags     = (SYSC_HAS_SOFTRESET | SYSC_HAS_MIDLEMODE |
-                          SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_EMUFREE |
-                          SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-struct omap_hwmod_class omap2xxx_dma_hwmod_class = {
-       .name   = "dma",
-       .sysc   = &omap2xxx_dma_sysc,
-};
-
 /*
  * 'mailbox' class
  * mailbox module allowing communication between the on-chip processors
index 26e13d4..5ef76fe 100644 (file)
@@ -28,29 +28,13 @@ extern struct omap_hwmod_ocp_if am33xx_pruss__l3_main;
 extern struct omap_hwmod_ocp_if am33xx_gfx__l3_main;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__gfx;
 extern struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc;
-extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan0;
-extern struct omap_hwmod_ocp_if am33xx_l4_per__dcan1;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__elm;
-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_ls__spinlock;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1;
 extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer2;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer3;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer4;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer5;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer6;
-extern struct omap_hwmod_ocp_if am33xx_l4_ls__timer7;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__tpcc;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc0;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc1;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__tptc2;
 extern struct omap_hwmod_ocp_if am33xx_l3_main__ocmc;
-extern struct omap_hwmod_ocp_if am33xx_l3_main__sha0;
-extern struct omap_hwmod_ocp_if am33xx_l3_main__aes0;
 
 extern struct omap_hwmod am33xx_l3_main_hwmod;
 extern struct omap_hwmod am33xx_l3_s_hwmod;
@@ -61,29 +45,13 @@ extern struct omap_hwmod am33xx_mpu_hwmod;
 extern struct omap_hwmod am33xx_pruss_hwmod;
 extern struct omap_hwmod am33xx_gfx_hwmod;
 extern struct omap_hwmod am33xx_prcm_hwmod;
-extern struct omap_hwmod am33xx_aes0_hwmod;
-extern struct omap_hwmod am33xx_sha0_hwmod;
 extern struct omap_hwmod am33xx_ocmcram_hwmod;
 extern struct omap_hwmod am33xx_smartreflex0_hwmod;
 extern struct omap_hwmod am33xx_smartreflex1_hwmod;
-extern struct omap_hwmod am33xx_dcan0_hwmod;
-extern struct omap_hwmod am33xx_dcan1_hwmod;
-extern struct omap_hwmod am33xx_elm_hwmod;
-extern struct omap_hwmod am33xx_epwmss0_hwmod;
-extern struct omap_hwmod am33xx_epwmss1_hwmod;
-extern struct omap_hwmod am33xx_epwmss2_hwmod;
 extern struct omap_hwmod am33xx_gpmc_hwmod;
 extern struct omap_hwmod am33xx_rtc_hwmod;
-extern struct omap_hwmod am33xx_spi0_hwmod;
-extern struct omap_hwmod am33xx_spi1_hwmod;
-extern struct omap_hwmod am33xx_spinlock_hwmod;
 extern struct omap_hwmod am33xx_timer1_hwmod;
 extern struct omap_hwmod am33xx_timer2_hwmod;
-extern struct omap_hwmod am33xx_timer3_hwmod;
-extern struct omap_hwmod am33xx_timer4_hwmod;
-extern struct omap_hwmod am33xx_timer5_hwmod;
-extern struct omap_hwmod am33xx_timer6_hwmod;
-extern struct omap_hwmod am33xx_timer7_hwmod;
 extern struct omap_hwmod am33xx_tpcc_hwmod;
 extern struct omap_hwmod am33xx_tptc0_hwmod;
 extern struct omap_hwmod am33xx_tptc1_hwmod;
@@ -94,7 +62,6 @@ extern struct omap_hwmod_class am33xx_l4_hwmod_class;
 extern struct omap_hwmod_class am33xx_wkup_m3_hwmod_class;
 extern struct omap_hwmod_class am33xx_control_hwmod_class;
 extern struct omap_hwmod_class am33xx_timer_hwmod_class;
-extern struct omap_hwmod_class am33xx_epwmss_hwmod_class;
 extern struct omap_hwmod_class am33xx_ehrpwm_hwmod_class;
 extern struct omap_hwmod_class am33xx_spi_hwmod_class;
 
index 7123c45..ac7d5bb 100644 (file)
@@ -106,50 +106,6 @@ struct omap_hwmod_ocp_if am33xx_l4_wkup__rtc = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4 per/ls -> DCAN0 */
-struct omap_hwmod_ocp_if am33xx_l4_per__dcan0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_dcan0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4 per/ls -> DCAN1 */
-struct omap_hwmod_ocp_if am33xx_l4_per__dcan1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_dcan1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-struct omap_hwmod_ocp_if am33xx_l4_ls__elm = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_elm_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_epwmss0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_epwmss1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-struct omap_hwmod_ocp_if am33xx_l4_ls__epwmss2 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_epwmss2_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l3s cfg -> gpmc */
 struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = {
        .master         = &am33xx_l3_s_hwmod,
@@ -158,30 +114,6 @@ struct omap_hwmod_ocp_if am33xx_l3_s__gpmc = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4 ls -> spinlock */
-struct omap_hwmod_ocp_if am33xx_l4_ls__spinlock = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_spinlock_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mcspi0 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_spi0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 ls -> mcspi1 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__mcspi1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_spi1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l4 per -> timer2 */
 struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = {
        .master         = &am33xx_l4_ls_hwmod,
@@ -190,46 +122,6 @@ struct omap_hwmod_ocp_if am33xx_l4_ls__timer2 = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4 per -> timer3 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__timer3 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer3_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer4 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__timer4 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer4_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer5 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__timer5 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer5_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer6 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__timer6 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer6_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4 per -> timer7 */
-struct omap_hwmod_ocp_if am33xx_l4_ls__timer7 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am33xx_timer7_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l3 main -> tpcc */
 struct omap_hwmod_ocp_if am33xx_l3_main__tpcc = {
        .master         = &am33xx_l3_main_hwmod,
@@ -268,19 +160,3 @@ struct omap_hwmod_ocp_if am33xx_l3_main__ocmc = {
        .slave          = &am33xx_ocmcram_hwmod,
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
-
-/* l3 main -> sha0 HIB2 */
-struct omap_hwmod_ocp_if am33xx_l3_main__sha0 = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_sha0_hwmod,
-       .clk            = "sha0_fck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3 main -> AES0 HIB2 */
-struct omap_hwmod_ocp_if am33xx_l3_main__aes0 = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_aes0_hwmod,
-       .clk            = "aes0_fck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
index 2df8659..78ec1bc 100644 (file)
@@ -213,57 +213,7 @@ struct omap_hwmod_class am33xx_emif_hwmod_class = {
        .sysc           = &am33xx_emif_sysc,
 };
 
-/*
- * 'aes0' class
- */
-static struct omap_hwmod_class_sysconfig am33xx_aes0_sysc = {
-       .rev_offs       = 0x80,
-       .sysc_offs      = 0x84,
-       .syss_offs      = 0x88,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class am33xx_aes0_hwmod_class = {
-       .name           = "aes0",
-       .sysc           = &am33xx_aes0_sysc,
-};
-
-struct omap_hwmod am33xx_aes0_hwmod = {
-       .name           = "aes",
-       .class          = &am33xx_aes0_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .main_clk       = "aes0_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* sha0 HIB2 (the 'P' (public) device) */
-static struct omap_hwmod_class_sysconfig am33xx_sha0_sysc = {
-       .rev_offs       = 0x100,
-       .sysc_offs      = 0x110,
-       .syss_offs      = 0x114,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
 
-static struct omap_hwmod_class am33xx_sha0_hwmod_class = {
-       .name           = "sha0",
-       .sysc           = &am33xx_sha0_sysc,
-};
-
-struct omap_hwmod am33xx_sha0_hwmod = {
-       .name           = "sham",
-       .class          = &am33xx_sha0_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 /* ocmcram */
 static struct omap_hwmod_class am33xx_ocmcram_hwmod_class = {
@@ -321,122 +271,6 @@ struct omap_hwmod_class am33xx_control_hwmod_class = {
        .name           = "control",
 };
 
-/*
- * dcan class
- */
-static struct omap_hwmod_class am33xx_dcan_hwmod_class = {
-       .name = "d_can",
-};
-
-/* dcan0 */
-struct omap_hwmod am33xx_dcan0_hwmod = {
-       .name           = "d_can0",
-       .class          = &am33xx_dcan_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dcan0_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* dcan1 */
-struct omap_hwmod am33xx_dcan1_hwmod = {
-       .name           = "d_can1",
-       .class          = &am33xx_dcan_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dcan1_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* elm */
-static struct omap_hwmod_class_sysconfig am33xx_elm_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
-                       SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
-                       SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_elm_hwmod_class = {
-       .name           = "elm",
-       .sysc           = &am33xx_elm_sysc,
-};
-
-struct omap_hwmod am33xx_elm_hwmod = {
-       .name           = "elm",
-       .class          = &am33xx_elm_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* pwmss  */
-static struct omap_hwmod_class_sysconfig am33xx_epwmss_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x4,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                       SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
-                       MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-struct omap_hwmod_class am33xx_epwmss_hwmod_class = {
-       .name           = "epwmss",
-       .sysc           = &am33xx_epwmss_sysc,
-};
-
-/* epwmss0 */
-struct omap_hwmod am33xx_epwmss0_hwmod = {
-       .name           = "epwmss0",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* epwmss1 */
-struct omap_hwmod am33xx_epwmss1_hwmod = {
-       .name           = "epwmss1",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* epwmss2 */
-struct omap_hwmod am33xx_epwmss2_hwmod = {
-       .name           = "epwmss2",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 /* gpmc */
 static struct omap_hwmod_class_sysconfig gpmc_sysc = {
@@ -501,83 +335,6 @@ struct omap_hwmod am33xx_rtc_hwmod = {
        },
 };
 
-/* 'spi' class */
-static struct omap_hwmod_class_sysconfig am33xx_mcspi_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0110,
-       .syss_offs      = 0x0114,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
-                         SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
-                         SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-struct omap_hwmod_class am33xx_spi_hwmod_class = {
-       .name           = "mcspi",
-       .sysc           = &am33xx_mcspi_sysc,
-};
-
-/* spi0 */
-struct omap_hwmod am33xx_spi0_hwmod = {
-       .name           = "spi0",
-       .class          = &am33xx_spi_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* spi1 */
-struct omap_hwmod am33xx_spi1_hwmod = {
-       .name           = "spi1",
-       .class          = &am33xx_spi_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'spinlock' class
- * spinlock provides hardware assistance for synchronizing the
- * processes running on multiple processors
- */
-
-static struct omap_hwmod_class_sysconfig am33xx_spinlock_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class am33xx_spinlock_hwmod_class = {
-       .name           = "spinlock",
-       .sysc           = &am33xx_spinlock_sysc,
-};
-
-struct omap_hwmod am33xx_spinlock_hwmod = {
-       .name           = "spinlock",
-       .class          = &am33xx_spinlock_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 /* 'timer 2-7' class */
 static struct omap_hwmod_class_sysconfig am33xx_timer_sysc = {
        .rev_offs       = 0x0000,
@@ -636,66 +393,6 @@ struct omap_hwmod am33xx_timer2_hwmod = {
        },
 };
 
-struct omap_hwmod am33xx_timer3_hwmod = {
-       .name           = "timer3",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer3_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-struct omap_hwmod am33xx_timer4_hwmod = {
-       .name           = "timer4",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer4_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-struct omap_hwmod am33xx_timer5_hwmod = {
-       .name           = "timer5",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer5_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-struct omap_hwmod am33xx_timer6_hwmod = {
-       .name           = "timer6",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer6_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-struct omap_hwmod am33xx_timer7_hwmod = {
-       .name           = "timer7",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer7_fck",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 /* tpcc */
 static struct omap_hwmod_class am33xx_tpcc_hwmod_class = {
        .name           = "tpcc",
@@ -772,21 +469,7 @@ struct omap_hwmod am33xx_tptc2_hwmod = {
 
 static void omap_hwmod_am33xx_clkctrl(void)
 {
-       CLKCTRL(am33xx_dcan0_hwmod, AM33XX_CM_PER_DCAN0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_dcan1_hwmod, AM33XX_CM_PER_DCAN1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_elm_hwmod, AM33XX_CM_PER_ELM_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_epwmss0_hwmod, AM33XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_epwmss1_hwmod, AM33XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_epwmss2_hwmod, AM33XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_spi0_hwmod, AM33XX_CM_PER_SPI0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_spi1_hwmod, AM33XX_CM_PER_SPI1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_spinlock_hwmod, AM33XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_timer2_hwmod, AM33XX_CM_PER_TIMER2_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer3_hwmod, AM33XX_CM_PER_TIMER3_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer4_hwmod, AM33XX_CM_PER_TIMER4_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer5_hwmod, AM33XX_CM_PER_TIMER5_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer6_hwmod, AM33XX_CM_PER_TIMER6_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer7_hwmod, AM33XX_CM_PER_TIMER7_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_smartreflex0_hwmod,
                AM33XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_smartreflex1_hwmod,
@@ -807,8 +490,6 @@ static void omap_hwmod_am33xx_clkctrl(void)
        CLKCTRL(am33xx_mpu_hwmod , AM33XX_CM_MPU_MPU_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_l3_instr_hwmod , AM33XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_ocmcram_hwmod , AM33XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_sha0_hwmod , AM33XX_CM_PER_SHA0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_aes0_hwmod , AM33XX_CM_PER_AES0_CLKCTRL_OFFSET);
 }
 
 static void omap_hwmod_am33xx_rst(void)
@@ -826,21 +507,7 @@ void omap_hwmod_am33xx_reg(void)
 
 static void omap_hwmod_am43xx_clkctrl(void)
 {
-       CLKCTRL(am33xx_dcan0_hwmod, AM43XX_CM_PER_DCAN0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_dcan1_hwmod, AM43XX_CM_PER_DCAN1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_elm_hwmod, AM43XX_CM_PER_ELM_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_epwmss0_hwmod, AM43XX_CM_PER_EPWMSS0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_epwmss1_hwmod, AM43XX_CM_PER_EPWMSS1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_epwmss2_hwmod, AM43XX_CM_PER_EPWMSS2_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_spi0_hwmod, AM43XX_CM_PER_SPI0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_spi1_hwmod, AM43XX_CM_PER_SPI1_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_spinlock_hwmod, AM43XX_CM_PER_SPINLOCK_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_timer2_hwmod, AM43XX_CM_PER_TIMER2_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer3_hwmod, AM43XX_CM_PER_TIMER3_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer4_hwmod, AM43XX_CM_PER_TIMER4_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer5_hwmod, AM43XX_CM_PER_TIMER5_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer6_hwmod, AM43XX_CM_PER_TIMER6_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_timer7_hwmod, AM43XX_CM_PER_TIMER7_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_smartreflex0_hwmod,
                AM43XX_CM_WKUP_SMARTREFLEX0_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_smartreflex1_hwmod,
@@ -860,8 +527,6 @@ static void omap_hwmod_am43xx_clkctrl(void)
        CLKCTRL(am33xx_mpu_hwmod , AM43XX_CM_MPU_MPU_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_l3_instr_hwmod , AM43XX_CM_PER_L3_INSTR_CLKCTRL_OFFSET);
        CLKCTRL(am33xx_ocmcram_hwmod , AM43XX_CM_PER_OCMCRAM_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_sha0_hwmod , AM43XX_CM_PER_SHA0_CLKCTRL_OFFSET);
-       CLKCTRL(am33xx_aes0_hwmod , AM43XX_CM_PER_AES0_CLKCTRL_OFFSET);
 }
 
 static void omap_hwmod_am43xx_rst(void)
index c63f664..f1ea8c6 100644 (file)
@@ -81,36 +81,6 @@ static struct omap_hwmod am33xx_wkup_m3_hwmod = {
        .rst_lines_cnt  = ARRAY_SIZE(am33xx_wkup_m3_resets),
 };
 
-/*
- * 'adc/tsc' class
- * TouchScreen Controller (Anolog-To-Digital Converter)
- */
-static struct omap_hwmod_class_sysconfig am33xx_adc_tsc_sysc = {
-       .rev_offs       = 0x00,
-       .sysc_offs      = 0x10,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                       SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_adc_tsc_hwmod_class = {
-       .name           = "adc_tsc",
-       .sysc           = &am33xx_adc_tsc_sysc,
-};
-
-static struct omap_hwmod am33xx_adc_tsc_hwmod = {
-       .name           = "adc_tsc",
-       .class          = &am33xx_adc_tsc_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .main_clk       = "adc_tsc_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 /*
  * Modules omap_hwmod structures
@@ -226,34 +196,6 @@ static struct omap_hwmod am33xx_control_hwmod = {
        },
 };
 
-/* lcdc */
-static struct omap_hwmod_class_sysconfig lcdc_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x54,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE,
-       .idlemodes      = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART,
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am33xx_lcdc_hwmod_class = {
-       .name           = "lcdc",
-       .sysc           = &lcdc_sysc,
-};
-
-static struct omap_hwmod am33xx_lcdc_hwmod = {
-       .name           = "lcdc",
-       .class          = &am33xx_lcdc_hwmod_class,
-       .clkdm_name     = "lcdc_clkdm",
-       .flags          = HWMOD_SWSUP_SIDLE | HWMOD_SWSUP_MSTANDBY,
-       .main_clk       = "lcd_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM33XX_CM_PER_LCDC_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 /*
  * Interfaces
@@ -331,21 +273,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__control = {
        .user           = OCP_USER_MPU,
 };
 
-/* L4 WKUP -> ADC_TSC */
-static struct omap_hwmod_ocp_if am33xx_l4_wkup__adc_tsc = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am33xx_adc_tsc_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am33xx_l3_main__lcdc = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am33xx_lcdc_hwmod,
-       .clk            = "dpll_core_m4_ck",
-       .user           = OCP_USER_MPU,
-};
-
 /* l4 wkup -> timer1 */
 static struct omap_hwmod_ocp_if am33xx_l4_wkup__timer1 = {
        .master         = &am33xx_l4_wkup_hwmod,
@@ -375,32 +302,14 @@ static struct omap_hwmod_ocp_if *am33xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_l4_wkup__smartreflex1,
        &am33xx_l4_wkup__timer1,
        &am33xx_l4_wkup__rtc,
-       &am33xx_l4_wkup__adc_tsc,
        &am33xx_l4_hs__pruss,
-       &am33xx_l4_per__dcan0,
-       &am33xx_l4_per__dcan1,
        &am33xx_l4_ls__timer2,
-       &am33xx_l4_ls__timer3,
-       &am33xx_l4_ls__timer4,
-       &am33xx_l4_ls__timer5,
-       &am33xx_l4_ls__timer6,
-       &am33xx_l4_ls__timer7,
        &am33xx_l3_main__tpcc,
-       &am33xx_l4_ls__spinlock,
-       &am33xx_l4_ls__elm,
-       &am33xx_l4_ls__epwmss0,
-       &am33xx_l4_ls__epwmss1,
-       &am33xx_l4_ls__epwmss2,
        &am33xx_l3_s__gpmc,
-       &am33xx_l3_main__lcdc,
-       &am33xx_l4_ls__mcspi0,
-       &am33xx_l4_ls__mcspi1,
        &am33xx_l3_main__tptc0,
        &am33xx_l3_main__tptc1,
        &am33xx_l3_main__tptc2,
        &am33xx_l3_main__ocmc,
-       &am33xx_l3_main__sha0,
-       &am33xx_l3_main__aes0,
        NULL,
 };
 
index f52438b..3c8d2b6 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/power/smartreflex.h>
 #include <linux/platform_data/hsmmc-omap.h>
 
-#include <linux/omap-dma.h>
 #include "l3_3xxx.h"
 #include "l4_3xxx.h"
 
@@ -833,47 +832,6 @@ static struct omap_hwmod omap3xxx_gpio6_hwmod = {
        .class          = &omap3xxx_gpio_hwmod_class,
 };
 
-/* dma attributes */
-static struct omap_dma_dev_attr dma_dev_attr = {
-       .dev_caps  = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
-                               IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
-       .lch_count = 32,
-};
-
-static struct omap_hwmod_class_sysconfig omap3xxx_dma_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x002c,
-       .syss_offs      = 0x0028,
-       .sysc_flags     = (SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSC_HAS_MIDLEMODE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_EMUFREE | SYSC_HAS_AUTOIDLE |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap3xxx_dma_hwmod_class = {
-       .name = "dma",
-       .sysc = &omap3xxx_dma_sysc,
-};
-
-/* dma_system */
-static struct omap_hwmod omap3xxx_dma_system_hwmod = {
-       .name           = "dma",
-       .class          = &omap3xxx_dma_hwmod_class,
-       .main_clk       = "core_l3_ick",
-       .prcm = {
-               .omap2 = {
-                       .module_offs            = CORE_MOD,
-                       .idlest_reg_id          = 1,
-                       .idlest_idle_bit        = OMAP3430_ST_SDMA_SHIFT,
-               },
-       },
-       .dev_attr       = &dma_dev_attr,
-       .flags          = HWMOD_NO_IDLEST,
-};
-
 /*
  * 'mcbsp' class
  * multi channel buffered serial port controller
@@ -2233,23 +2191,6 @@ static struct omap_hwmod_ocp_if omap3xxx_l4_per__gpio6 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* dma_system -> L3 */
-static struct omap_hwmod_ocp_if omap3xxx_dma_system__l3 = {
-       .master         = &omap3xxx_dma_system_hwmod,
-       .slave          = &omap3xxx_l3_main_hwmod,
-       .clk            = "core_l3_ick",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> dma_system */
-static struct omap_hwmod_ocp_if omap3xxx_l4_core__dma_system = {
-       .master         = &omap3xxx_l4_core_hwmod,
-       .slave          = &omap3xxx_dma_system_hwmod,
-       .clk            = "core_l4_ick",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-
 /* l4_core -> mcbsp1 */
 static struct omap_hwmod_ocp_if omap3xxx_l4_core__mcbsp1 = {
        .master         = &omap3xxx_l4_core_hwmod,
@@ -2628,8 +2569,6 @@ static struct omap_hwmod_ocp_if *omap3xxx_hwmod_ocp_ifs[] __initdata = {
        &omap3xxx_l4_per__gpio4,
        &omap3xxx_l4_per__gpio5,
        &omap3xxx_l4_per__gpio6,
-       &omap3xxx_dma_system__l3,
-       &omap3xxx_l4_core__dma_system,
        &omap3xxx_l4_core__mcbsp1,
        &omap3xxx_l4_per__mcbsp2,
        &omap3xxx_l4_per__mcbsp3,
index b81f834..d0867db 100644 (file)
@@ -112,165 +112,6 @@ static struct omap_hwmod am43xx_synctimer_hwmod = {
        },
 };
 
-static struct omap_hwmod am43xx_timer8_hwmod = {
-       .name           = "timer8",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer8_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM43XX_CM_PER_TIMER8_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_timer9_hwmod = {
-       .name           = "timer9",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer9_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM43XX_CM_PER_TIMER9_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_timer10_hwmod = {
-       .name           = "timer10",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer10_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM43XX_CM_PER_TIMER10_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_timer11_hwmod = {
-       .name           = "timer11",
-       .class          = &am33xx_timer_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "timer11_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM43XX_CM_PER_TIMER11_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_epwmss3_hwmod = {
-       .name           = "epwmss3",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs = AM43XX_CM_PER_EPWMSS3_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_epwmss4_hwmod = {
-       .name           = "epwmss4",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs = AM43XX_CM_PER_EPWMSS4_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_epwmss5_hwmod = {
-       .name           = "epwmss5",
-       .class          = &am33xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs = AM43XX_CM_PER_EPWMSS5_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_spi2_hwmod = {
-       .name           = "spi2",
-       .class          = &am33xx_spi_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs = AM43XX_CM_PER_SPI2_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_spi3_hwmod = {
-       .name           = "spi3",
-       .class          = &am33xx_spi_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs = AM43XX_CM_PER_SPI3_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_spi4_hwmod = {
-       .name           = "spi4",
-       .class          = &am33xx_spi_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "dpll_per_m2_div4_ck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs = AM43XX_CM_PER_SPI4_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod_class am43xx_ocp2scp_hwmod_class = {
-       .name   = "ocp2scp",
-};
-
-static struct omap_hwmod am43xx_ocp2scp0_hwmod = {
-       .name           = "ocp2scp0",
-       .class          = &am43xx_ocp2scp_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = AM43XX_CM_PER_USBPHYOCP2SCP0_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_ocp2scp1_hwmod = {
-       .name           = "ocp2scp1",
-       .class          = &am43xx_ocp2scp_hwmod_class,
-       .clkdm_name     = "l4ls_clkdm",
-       .main_clk       = "l4ls_gclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs   = AM43XX_CM_PER_USBPHYOCP2SCP1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
 
 static struct omap_hwmod_class_sysconfig am43xx_usb_otg_ss_sysc = {
        .rev_offs       = 0x0000,
@@ -315,89 +156,6 @@ static struct omap_hwmod am43xx_usb_otg_ss1_hwmod = {
        },
 };
 
-static struct omap_hwmod_class_sysconfig am43xx_qspi_sysc = {
-       .rev_offs       = 0,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                               SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am43xx_qspi_hwmod_class = {
-       .name   = "qspi",
-       .sysc   = &am43xx_qspi_sysc,
-};
-
-static struct omap_hwmod am43xx_qspi_hwmod = {
-       .name           = "qspi",
-       .class          = &am43xx_qspi_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .main_clk       = "l3s_gclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = AM43XX_CM_PER_QSPI_CLKCTRL_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'adc/tsc' class
- * TouchScreen Controller (Analog-To-Digital Converter)
- */
-static struct omap_hwmod_class_sysconfig am43xx_adc_tsc_sysc = {
-       .rev_offs       = 0x00,
-       .sysc_offs      = 0x10,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                         SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am43xx_adc_tsc_hwmod_class = {
-       .name           = "adc_tsc",
-       .sysc           = &am43xx_adc_tsc_sysc,
-};
-
-static struct omap_hwmod am43xx_adc_tsc_hwmod = {
-       .name           = "adc_tsc",
-       .class          = &am43xx_adc_tsc_hwmod_class,
-       .clkdm_name     = "l3s_tsc_clkdm",
-       .main_clk       = "adc_tsc_fck",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM43XX_CM_WKUP_ADC_TSC_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod_class_sysconfig am43xx_des_sysc = {
-       .rev_offs       = 0x30,
-       .sysc_offs      = 0x34,
-       .syss_offs      = 0x38,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class am43xx_des_hwmod_class = {
-       .name           = "des",
-       .sysc           = &am43xx_des_sysc,
-};
-
-static struct omap_hwmod am43xx_des_hwmod = {
-       .name           = "des",
-       .class          = &am43xx_des_hwmod_class,
-       .clkdm_name     = "l3_clkdm",
-       .main_clk       = "l3_gclk",
-       .prcm           = {
-               .omap4  = {
-                       .clkctrl_offs   = AM43XX_CM_PER_DES_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 /* dss */
 
 static struct omap_hwmod am43xx_dss_core_hwmod = {
@@ -467,44 +225,6 @@ static struct omap_hwmod am43xx_dss_rfbi_hwmod = {
 };
 
 
-static struct omap_hwmod_class_sysconfig am43xx_vpfe_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x104,
-       .sysc_flags     = SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                               MSTANDBY_FORCE | MSTANDBY_SMART | MSTANDBY_NO),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class am43xx_vpfe_hwmod_class = {
-       .name           = "vpfe",
-       .sysc           = &am43xx_vpfe_sysc,
-};
-
-static struct omap_hwmod am43xx_vpfe0_hwmod = {
-       .name           = "vpfe0",
-       .class          = &am43xx_vpfe_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-                       .clkctrl_offs   = AM43XX_CM_PER_VPFE0_CLKCTRL_OFFSET,
-               },
-       },
-};
-
-static struct omap_hwmod am43xx_vpfe1_hwmod = {
-       .name           = "vpfe1",
-       .class          = &am43xx_vpfe_hwmod_class,
-       .clkdm_name     = "l3s_clkdm",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-                       .clkctrl_offs   = AM43XX_CM_PER_VPFE1_CLKCTRL_OFFSET,
-               },
-       },
-};
-
 /* Interfaces */
 static struct omap_hwmod_ocp_if am43xx_l3_main__emif = {
        .master         = &am33xx_l3_main_hwmod,
@@ -562,13 +282,6 @@ static struct omap_hwmod_ocp_if am43xx_l4_wkup__control = {
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_ocp_if am43xx_l4_wkup__adc_tsc = {
-       .master         = &am33xx_l4_wkup_hwmod,
-       .slave          = &am43xx_adc_tsc_hwmod,
-       .clk            = "dpll_core_m4_div2_ck",
-       .user           = OCP_USER_MPU,
-};
-
 static struct omap_hwmod_ocp_if am43xx_l4_wkup__timer1 = {
        .master         = &am33xx_l4_wkup_hwmod,
        .slave          = &am33xx_timer1_hwmod,
@@ -583,90 +296,6 @@ static struct omap_hwmod_ocp_if am33xx_l4_wkup__synctimer = {
        .user           = OCP_USER_MPU,
 };
 
-static struct omap_hwmod_ocp_if am43xx_l4_ls__timer8 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_timer8_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__timer9 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_timer9_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__timer10 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_timer10_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__timer11 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_timer11_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss3 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_epwmss3_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss4 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_epwmss4_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__epwmss5 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_epwmss5_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi2 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_spi2_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi3 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_spi3_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__mcspi4 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_spi4_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_ocp2scp0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__ocp2scp1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_ocp2scp1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss0 = {
        .master         = &am33xx_l3_s_hwmod,
        .slave          = &am43xx_usb_otg_ss0_hwmod,
@@ -681,13 +310,6 @@ static struct omap_hwmod_ocp_if am43xx_l3_s__usbotgss1 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-static struct omap_hwmod_ocp_if am43xx_l3_s__qspi = {
-       .master         = &am33xx_l3_s_hwmod,
-       .slave          = &am43xx_qspi_hwmod,
-       .clk            = "l3s_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 static struct omap_hwmod_ocp_if am43xx_dss__l3_main = {
        .master         = &am43xx_dss_core_hwmod,
        .slave          = &am33xx_l3_main_hwmod,
@@ -716,53 +338,8 @@ 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_l3__vpfe0 = {
-       .master         = &am43xx_vpfe0_hwmod,
-       .slave          = &am33xx_l3_main_hwmod,
-       .clk            = "l3_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l3__vpfe1 = {
-       .master         = &am43xx_vpfe1_hwmod,
-       .slave          = &am33xx_l3_main_hwmod,
-       .clk            = "l3_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe0 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_vpfe0_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l4_ls__vpfe1 = {
-       .master         = &am33xx_l4_ls_hwmod,
-       .slave          = &am43xx_vpfe1_hwmod,
-       .clk            = "l4ls_gclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod_ocp_if am43xx_l3_main__des = {
-       .master         = &am33xx_l3_main_hwmod,
-       .slave          = &am43xx_des_hwmod,
-       .clk            = "l3_gclk",
-       .user           = OCP_USER_MPU,
-};
-
 static struct omap_hwmod_ocp_if *am43xx_hwmod_ocp_ifs[] __initdata = {
        &am33xx_l4_wkup__synctimer,
-       &am43xx_l4_ls__timer8,
-       &am43xx_l4_ls__timer9,
-       &am43xx_l4_ls__timer10,
-       &am43xx_l4_ls__timer11,
-       &am43xx_l4_ls__epwmss3,
-       &am43xx_l4_ls__epwmss4,
-       &am43xx_l4_ls__epwmss5,
-       &am43xx_l4_ls__mcspi2,
-       &am43xx_l4_ls__mcspi3,
-       &am43xx_l4_ls__mcspi4,
        &am43xx_l3_main__pruss,
        &am33xx_mpu__l3_main,
        &am33xx_mpu__prcm,
@@ -782,44 +359,19 @@ 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__adc_tsc,
-       &am43xx_l3_s__qspi,
-       &am33xx_l4_per__dcan0,
-       &am33xx_l4_per__dcan1,
        &am33xx_l4_ls__timer2,
-       &am33xx_l4_ls__timer3,
-       &am33xx_l4_ls__timer4,
-       &am33xx_l4_ls__timer5,
-       &am33xx_l4_ls__timer6,
-       &am33xx_l4_ls__timer7,
        &am33xx_l3_main__tpcc,
-       &am33xx_l4_ls__spinlock,
-       &am33xx_l4_ls__elm,
-       &am33xx_l4_ls__epwmss0,
-       &am33xx_l4_ls__epwmss1,
-       &am33xx_l4_ls__epwmss2,
        &am33xx_l3_s__gpmc,
-       &am33xx_l4_ls__mcspi0,
-       &am33xx_l4_ls__mcspi1,
        &am33xx_l3_main__tptc0,
        &am33xx_l3_main__tptc1,
        &am33xx_l3_main__tptc2,
        &am33xx_l3_main__ocmc,
-       &am33xx_l3_main__sha0,
-       &am33xx_l3_main__aes0,
-       &am43xx_l3_main__des,
-       &am43xx_l4_ls__ocp2scp0,
-       &am43xx_l4_ls__ocp2scp1,
        &am43xx_l3_s__usbotgss0,
        &am43xx_l3_s__usbotgss1,
        &am43xx_dss__l3_main,
        &am43xx_l4_ls__dss,
        &am43xx_l4_ls__dss_dispc,
        &am43xx_l4_ls__dss_rfbi,
-       &am43xx_l3__vpfe0,
-       &am43xx_l3__vpfe1,
-       &am43xx_l4_ls__vpfe0,
-       &am43xx_l4_ls__vpfe1,
        NULL,
 };
 
index 292f544..b7c51ea 100644 (file)
@@ -18,9 +18,6 @@
  */
 
 #include <linux/io.h>
-#include <linux/power/smartreflex.h>
-
-#include <linux/omap-dma.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
@@ -32,9 +29,6 @@
 /* Base offset for all OMAP4 interrupts external to MPUSS */
 #define OMAP44XX_IRQ_GIC_START 32
 
-/* Base offset for all OMAP4 dma requests */
-#define OMAP44XX_DMA_REQ_START 1
-
 /*
  * IP blocks
  */
@@ -238,43 +232,6 @@ static struct omap_hwmod omap44xx_ocp_wp_noc_hwmod = {
  */
 
 /*
- * 'aess' class
- * audio engine sub system
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_aess_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART |
-                          MSTANDBY_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap44xx_aess_hwmod_class = {
-       .name   = "aess",
-       .sysc   = &omap44xx_aess_sysc,
-       .enable_preprogram = omap_hwmod_aess_preprogram,
-};
-
-/* aess */
-static struct omap_hwmod omap44xx_aess_hwmod = {
-       .name           = "aess",
-       .class          = &omap44xx_aess_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "aess_fclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_AESS_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_AESS_CONTEXT_OFFSET,
-                       .lostcontext_mask = OMAP4430_LOSTCONTEXT_DFF_MASK,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
  * 'counter' class
  * 32-bit ordinary counter, clocked by the falling edge of the 32 khz clock
  */
@@ -399,87 +356,6 @@ static struct omap_hwmod omap44xx_debugss_hwmod = {
 };
 
 /*
- * 'dma' class
- * dma controller for data exchange between memory to memory (i.e. internal or
- * external memory) and gp peripherals to memory or memory to gp peripherals
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_dma_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x002c,
-       .syss_offs      = 0x0028,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_dma_hwmod_class = {
-       .name   = "dma",
-       .sysc   = &omap44xx_dma_sysc,
-};
-
-/* dma dev_attr */
-static struct omap_dma_dev_attr dma_dev_attr = {
-       .dev_caps       = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
-                         IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
-       .lch_count      = 32,
-};
-
-/* dma_system */
-static struct omap_hwmod omap44xx_dma_system_hwmod = {
-       .name           = "dma_system",
-       .class          = &omap44xx_dma_hwmod_class,
-       .clkdm_name     = "l3_dma_clkdm",
-       .main_clk       = "l3_div_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_SDMA_SDMA_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_SDMA_SDMA_CONTEXT_OFFSET,
-               },
-       },
-       .dev_attr       = &dma_dev_attr,
-};
-
-/*
- * 'dmic' class
- * digital microphone controller
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_dmic_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap44xx_dmic_hwmod_class = {
-       .name   = "dmic",
-       .sysc   = &omap44xx_dmic_sysc,
-};
-
-/* dmic */
-static struct omap_hwmod omap44xx_dmic_hwmod = {
-       .name           = "dmic",
-       .class          = &omap44xx_dmic_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "func_dmic_abe_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_DMIC_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_DMIC_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
  * 'dsp' class
  * dsp sub-system
  */
@@ -777,66 +653,7 @@ static struct omap_hwmod omap44xx_dss_venc_hwmod = {
        .opt_clks_cnt   = ARRAY_SIZE(dss_venc_opt_clks),
 };
 
-/* sha0 HIB2 (the 'P' (public) device) */
-static struct omap_hwmod_class_sysconfig omap44xx_sha0_sysc = {
-       .rev_offs       = 0x100,
-       .sysc_offs      = 0x110,
-       .syss_offs      = 0x114,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class omap44xx_sha0_hwmod_class = {
-       .name           = "sham",
-       .sysc           = &omap44xx_sha0_sysc,
-};
-
-static struct omap_hwmod omap44xx_sha0_hwmod = {
-       .name           = "sham",
-       .class          = &omap44xx_sha0_hwmod_class,
-       .clkdm_name     = "l4_secure_clkdm",
-       .main_clk       = "l3_div_ck",
-       .prcm           = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'elm' class
- * bch error location module
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_elm_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_elm_hwmod_class = {
-       .name   = "elm",
-       .sysc   = &omap44xx_elm_sysc,
-};
 
-/* elm */
-static struct omap_hwmod omap44xx_elm_hwmod = {
-       .name           = "elm",
-       .class          = &omap44xx_elm_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_ELM_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_ELM_CONTEXT_OFFSET,
-               },
-       },
-};
 
 /*
  * 'emif' class
@@ -885,147 +702,6 @@ static struct omap_hwmod omap44xx_emif2_hwmod = {
 };
 
 /*
-    Crypto modules AES0/1 belong to:
-       PD_L4_PER power domain
-       CD_L4_SEC clock domain
-       On the L3, the AES modules are mapped to
-       L3_CLK2: Peripherals and multimedia sub clock domain
-*/
-static struct omap_hwmod_class_sysconfig omap44xx_aes_sysc = {
-       .rev_offs       = 0x80,
-       .sysc_offs      = 0x84,
-       .syss_offs      = 0x88,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class omap44xx_aes_hwmod_class = {
-       .name           = "aes",
-       .sysc           = &omap44xx_aes_sysc,
-};
-
-static struct omap_hwmod omap44xx_aes1_hwmod = {
-       .name           = "aes1",
-       .class          = &omap44xx_aes_hwmod_class,
-       .clkdm_name     = "l4_secure_clkdm",
-       .main_clk       = "l3_div_ck",
-       .prcm           = {
-               .omap4  = {
-                       .context_offs   = OMAP4_RM_L4SEC_AES1_CONTEXT_OFFSET,
-                       .clkctrl_offs   = OMAP4_CM_L4SEC_AES1_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes1 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_aes1_hwmod,
-       .clk            = "l3_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod omap44xx_aes2_hwmod = {
-       .name           = "aes2",
-       .class          = &omap44xx_aes_hwmod_class,
-       .clkdm_name     = "l4_secure_clkdm",
-       .main_clk       = "l3_div_ck",
-       .prcm           = {
-               .omap4  = {
-                       .context_offs   = OMAP4_RM_L4SEC_AES2_CONTEXT_OFFSET,
-                       .clkctrl_offs   = OMAP4_CM_L4SEC_AES2_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-static struct omap_hwmod_ocp_if omap44xx_l3_main_2__aes2 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_aes2_hwmod,
-       .clk            = "l3_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/*
- * 'des' class for DES3DES module
- */
-static struct omap_hwmod_class_sysconfig omap44xx_des_sysc = {
-       .rev_offs       = 0x30,
-       .sysc_offs      = 0x34,
-       .syss_offs      = 0x38,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class omap44xx_des_hwmod_class = {
-       .name           = "des",
-       .sysc           = &omap44xx_des_sysc,
-};
-
-static struct omap_hwmod omap44xx_des_hwmod = {
-       .name           = "des",
-       .class          = &omap44xx_des_hwmod_class,
-       .clkdm_name     = "l4_secure_clkdm",
-       .main_clk       = "l3_div_ck",
-       .prcm           = {
-               .omap4  = {
-                       .context_offs   = OMAP4_RM_L4SEC_DES3DES_CONTEXT_OFFSET,
-                       .clkctrl_offs   = OMAP4_CM_L4SEC_DES3DES_CLKCTRL_OFFSET,
-                       .modulemode     = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-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",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/*
- * 'fdif' class
- * face detection hw accelerator module
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_fdif_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       /*
-        * FDIF needs 100 OCP clk cycles delay after a softreset before
-        * accessing sysconfig again.
-        * The lowest frequency at the moment for L3 bus is 100 MHz, so
-        * 1usec delay is needed. Add an x2 margin to be safe (2 usecs).
-        *
-        * TODO: Indicate errata when available.
-        */
-       .srst_udelay    = 2,
-       .sysc_flags     = (SYSC_HAS_MIDLEMODE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap44xx_fdif_hwmod_class = {
-       .name   = "fdif",
-       .sysc   = &omap44xx_fdif_sysc,
-};
-
-/* fdif */
-static struct omap_hwmod omap44xx_fdif_hwmod = {
-       .name           = "fdif",
-       .class          = &omap44xx_fdif_hwmod_class,
-       .clkdm_name     = "iss_clkdm",
-       .main_clk       = "fdif_fck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_CAM_FDIF_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_CAM_FDIF_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
  * 'gpmc' class
  * general purpose memory controller
  */
@@ -1063,45 +739,6 @@ static struct omap_hwmod omap44xx_gpmc_hwmod = {
 
 
 /*
- * 'hsi' class
- * mipi high-speed synchronous serial interface (multichannel and full-duplex
- * serial if)
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_hsi_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_EMUFREE |
-                          SYSC_HAS_MIDLEMODE | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
-                          MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_hsi_hwmod_class = {
-       .name   = "hsi",
-       .sysc   = &omap44xx_hsi_sysc,
-};
-
-/* hsi */
-static struct omap_hwmod omap44xx_hsi_hwmod = {
-       .name           = "hsi",
-       .class          = &omap44xx_hsi_hwmod_class,
-       .clkdm_name     = "l3_init_clkdm",
-       .main_clk       = "hsi_fck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L3INIT_HSI_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L3INIT_HSI_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/*
  * 'ipu' class
  * imaging processor unit
  */
@@ -1218,276 +855,60 @@ static struct omap_hwmod omap44xx_iva_hwmod = {
 };
 
 /*
- * 'kbd' class
- * keyboard controller
+ * 'mpu' class
+ * mpu sub-system
  */
 
-static struct omap_hwmod_class_sysconfig omap44xx_kbd_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_EMUFREE | SYSC_HAS_ENAWAKEUP |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_kbd_hwmod_class = {
-       .name   = "kbd",
-       .sysc   = &omap44xx_kbd_sysc,
+static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
+       .name   = "mpu",
 };
 
-/* kbd */
-static struct omap_hwmod omap44xx_kbd_hwmod = {
-       .name           = "kbd",
-       .class          = &omap44xx_kbd_hwmod_class,
-       .clkdm_name     = "l4_wkup_clkdm",
-       .main_clk       = "sys_32k_ck",
+/* mpu */
+static struct omap_hwmod omap44xx_mpu_hwmod = {
+       .name           = "mpu",
+       .class          = &omap44xx_mpu_hwmod_class,
+       .clkdm_name     = "mpuss_clkdm",
+       .flags          = HWMOD_INIT_NO_IDLE,
+       .main_clk       = "dpll_mpu_m2_ck",
        .prcm = {
                .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_WKUP_KEYBOARD_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_WKUP_KEYBOARD_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
+                       .clkctrl_offs = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET,
+                       .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET,
                },
        },
 };
 
-
 /*
- * 'mcpdm' class
- * multi channel pdm controller (proprietary interface with phoenix power
- * ic)
+ * 'ocmc_ram' class
+ * top-level core on-chip ram
  */
 
-static struct omap_hwmod_class_sysconfig omap44xx_mcpdm_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap44xx_mcpdm_hwmod_class = {
-       .name   = "mcpdm",
-       .sysc   = &omap44xx_mcpdm_sysc,
+static struct omap_hwmod_class omap44xx_ocmc_ram_hwmod_class = {
+       .name   = "ocmc_ram",
 };
 
-/* mcpdm */
-static struct omap_hwmod omap44xx_mcpdm_hwmod = {
-       .name           = "mcpdm",
-       .class          = &omap44xx_mcpdm_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       /*
-        * It's suspected that the McPDM requires an off-chip main
-        * functional clock, controlled via I2C.  This IP block is
-        * currently reset very early during boot, before I2C is
-        * available, so it doesn't seem that we have any choice in
-        * the kernel other than to avoid resetting it.
-        *
-        * Also, McPDM needs to be configured to NO_IDLE mode when it
-        * is in used otherwise vital clocks will be gated which
-        * results 'slow motion' audio playback.
-        */
-       .flags          = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE,
-       .main_clk       = "pad_clks_ck",
+/* ocmc_ram */
+static struct omap_hwmod omap44xx_ocmc_ram_hwmod = {
+       .name           = "ocmc_ram",
+       .class          = &omap44xx_ocmc_ram_hwmod_class,
+       .clkdm_name     = "l3_2_clkdm",
        .prcm = {
                .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_PDM_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_PDM_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
+                       .clkctrl_offs = OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET,
+                       .context_offs = OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET,
                },
        },
 };
 
+
 /*
- * 'mmu' class
- * The memory management unit performs virtual to physical address translation
- * for its requestors.
+ * 'prcm' class
+ * power and reset manager (part of the prcm infrastructure) + clock manager 2
+ * + clock manager 1 (in always on power domain) + local prm in mpu
  */
 
-static struct omap_hwmod_class_sysconfig mmu_sysc = {
-       .rev_offs       = 0x000,
-       .sysc_offs      = 0x010,
-       .syss_offs      = 0x014,
-       .sysc_flags     = (SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_mmu_hwmod_class = {
-       .name = "mmu",
-       .sysc = &mmu_sysc,
-};
-
-/* mmu ipu */
-
-static struct omap_hwmod omap44xx_mmu_ipu_hwmod;
-static struct omap_hwmod_rst_info omap44xx_mmu_ipu_resets[] = {
-       { .name = "mmu_cache", .rst_shift = 2 },
-};
-
-/* l3_main_2 -> mmu_ipu */
-static struct omap_hwmod_ocp_if omap44xx_l3_main_2__mmu_ipu = {
-       .master         = &omap44xx_l3_main_2_hwmod,
-       .slave          = &omap44xx_mmu_ipu_hwmod,
-       .clk            = "l3_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod omap44xx_mmu_ipu_hwmod = {
-       .name           = "mmu_ipu",
-       .class          = &omap44xx_mmu_hwmod_class,
-       .clkdm_name     = "ducati_clkdm",
-       .rst_lines      = omap44xx_mmu_ipu_resets,
-       .rst_lines_cnt  = ARRAY_SIZE(omap44xx_mmu_ipu_resets),
-       .main_clk       = "ducati_clk_mux_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_DUCATI_DUCATI_CLKCTRL_OFFSET,
-                       .rstctrl_offs = OMAP4_RM_DUCATI_RSTCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_DUCATI_DUCATI_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/* mmu dsp */
-
-static struct omap_hwmod omap44xx_mmu_dsp_hwmod;
-static struct omap_hwmod_rst_info omap44xx_mmu_dsp_resets[] = {
-       { .name = "mmu_cache", .rst_shift = 1 },
-};
-
-/* l4_cfg -> dsp */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__mmu_dsp = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_mmu_dsp_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod omap44xx_mmu_dsp_hwmod = {
-       .name           = "mmu_dsp",
-       .class          = &omap44xx_mmu_hwmod_class,
-       .clkdm_name     = "tesla_clkdm",
-       .rst_lines      = omap44xx_mmu_dsp_resets,
-       .rst_lines_cnt  = ARRAY_SIZE(omap44xx_mmu_dsp_resets),
-       .main_clk       = "dpll_iva_m4x2_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_TESLA_TESLA_CLKCTRL_OFFSET,
-                       .rstctrl_offs = OMAP4_RM_TESLA_RSTCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_TESLA_TESLA_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/*
- * 'mpu' class
- * mpu sub-system
- */
-
-static struct omap_hwmod_class omap44xx_mpu_hwmod_class = {
-       .name   = "mpu",
-};
-
-/* mpu */
-static struct omap_hwmod omap44xx_mpu_hwmod = {
-       .name           = "mpu",
-       .class          = &omap44xx_mpu_hwmod_class,
-       .clkdm_name     = "mpuss_clkdm",
-       .flags          = HWMOD_INIT_NO_IDLE,
-       .main_clk       = "dpll_mpu_m2_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_MPU_MPU_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_MPU_MPU_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/*
- * 'ocmc_ram' class
- * top-level core on-chip ram
- */
-
-static struct omap_hwmod_class omap44xx_ocmc_ram_hwmod_class = {
-       .name   = "ocmc_ram",
-};
-
-/* ocmc_ram */
-static struct omap_hwmod omap44xx_ocmc_ram_hwmod = {
-       .name           = "ocmc_ram",
-       .class          = &omap44xx_ocmc_ram_hwmod_class,
-       .clkdm_name     = "l3_2_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L3_2_OCMC_RAM_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L3_2_OCMC_RAM_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/*
- * 'ocp2scp' class
- * bridge to transform ocp interface protocol to scp (serial control port)
- * protocol
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_ocp2scp_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_ocp2scp_hwmod_class = {
-       .name   = "ocp2scp",
-       .sysc   = &omap44xx_ocp2scp_sysc,
-};
-
-/* ocp2scp_usb_phy */
-static struct omap_hwmod omap44xx_ocp2scp_usb_phy_hwmod = {
-       .name           = "ocp2scp_usb_phy",
-       .class          = &omap44xx_ocp2scp_hwmod_class,
-       .clkdm_name     = "l3_init_clkdm",
-       /*
-        * ocp2scp_usb_phy_phy_48m is provided by the OMAP4 PRCM IP
-        * block as an "optional clock," and normally should never be
-        * specified as the main_clk for an OMAP IP block.  However it
-        * turns out that this clock is actually the main clock for
-        * the ocp2scp_usb_phy IP block:
-        * http://lists.infradead.org/pipermail/linux-arm-kernel/2012-September/119943.html
-        * So listing ocp2scp_usb_phy_phy_48m as a main_clk here seems
-        * to be the best workaround.
-        */
-       .main_clk       = "ocp2scp_usb_phy_phy_48m",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L3INIT_USBPHYOCP2SCP_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L3INIT_USBPHYOCP2SCP_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/*
- * 'prcm' class
- * power and reset manager (part of the prcm infrastructure) + clock manager 2
- * + clock manager 1 (in always on power domain) + local prm in mpu
- */
-
-static struct omap_hwmod_class omap44xx_prcm_hwmod_class = {
-       .name   = "prcm",
+static struct omap_hwmod_class omap44xx_prcm_hwmod_class = {
+       .name   = "prcm",
 };
 
 /* prcm_mpu */
@@ -1585,189 +1006,6 @@ static struct omap_hwmod omap44xx_sl2if_hwmod = {
 };
 
 /*
- * 'slimbus' class
- * bidirectional, multi-drop, multi-channel two-line serial interface between
- * the device and external components
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_slimbus_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_RESET_STATUS | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap44xx_slimbus_hwmod_class = {
-       .name   = "slimbus",
-       .sysc   = &omap44xx_slimbus_sysc,
-};
-
-/* slimbus1 */
-static struct omap_hwmod_opt_clk slimbus1_opt_clks[] = {
-       { .role = "fclk_1", .clk = "slimbus1_fclk_1" },
-       { .role = "fclk_0", .clk = "slimbus1_fclk_0" },
-       { .role = "fclk_2", .clk = "slimbus1_fclk_2" },
-       { .role = "slimbus_clk", .clk = "slimbus1_slimbus_clk" },
-};
-
-static struct omap_hwmod omap44xx_slimbus1_hwmod = {
-       .name           = "slimbus1",
-       .class          = &omap44xx_slimbus_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_SLIMBUS_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_SLIMBUS_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = slimbus1_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(slimbus1_opt_clks),
-};
-
-/* slimbus2 */
-static struct omap_hwmod_opt_clk slimbus2_opt_clks[] = {
-       { .role = "fclk_1", .clk = "slimbus2_fclk_1" },
-       { .role = "fclk_0", .clk = "slimbus2_fclk_0" },
-       { .role = "slimbus_clk", .clk = "slimbus2_slimbus_clk" },
-};
-
-static struct omap_hwmod omap44xx_slimbus2_hwmod = {
-       .name           = "slimbus2",
-       .class          = &omap44xx_slimbus_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_SLIMBUS2_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_SLIMBUS2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .opt_clks       = slimbus2_opt_clks,
-       .opt_clks_cnt   = ARRAY_SIZE(slimbus2_opt_clks),
-};
-
-/*
- * 'smartreflex' class
- * smartreflex module (monitor silicon performance and outputs a measure of
- * performance error)
- */
-
-/* The IP is not compliant to type1 / type2 scheme */
-static struct omap_hwmod_class_sysconfig omap44xx_smartreflex_sysc = {
-       .rev_offs       = -ENODEV,
-       .sysc_offs      = 0x0038,
-       .sysc_flags     = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap36xx_sr_sysc_fields,
-};
-
-static struct omap_hwmod_class omap44xx_smartreflex_hwmod_class = {
-       .name   = "smartreflex",
-       .sysc   = &omap44xx_smartreflex_sysc,
-};
-
-/* smartreflex_core */
-static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = {
-       .sensor_voltdm_name   = "core",
-};
-
-static struct omap_hwmod omap44xx_smartreflex_core_hwmod = {
-       .name           = "smartreflex_core",
-       .class          = &omap44xx_smartreflex_hwmod_class,
-       .clkdm_name     = "l4_ao_clkdm",
-
-       .main_clk       = "smartreflex_core_fck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_ALWON_SR_CORE_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ALWON_SR_CORE_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &smartreflex_core_dev_attr,
-};
-
-/* smartreflex_iva */
-static struct omap_smartreflex_dev_attr smartreflex_iva_dev_attr = {
-       .sensor_voltdm_name     = "iva",
-};
-
-static struct omap_hwmod omap44xx_smartreflex_iva_hwmod = {
-       .name           = "smartreflex_iva",
-       .class          = &omap44xx_smartreflex_hwmod_class,
-       .clkdm_name     = "l4_ao_clkdm",
-       .main_clk       = "smartreflex_iva_fck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_ALWON_SR_IVA_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ALWON_SR_IVA_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &smartreflex_iva_dev_attr,
-};
-
-/* smartreflex_mpu */
-static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = {
-       .sensor_voltdm_name     = "mpu",
-};
-
-static struct omap_hwmod omap44xx_smartreflex_mpu_hwmod = {
-       .name           = "smartreflex_mpu",
-       .class          = &omap44xx_smartreflex_hwmod_class,
-       .clkdm_name     = "l4_ao_clkdm",
-       .main_clk       = "smartreflex_mpu_fck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_ALWON_SR_MPU_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ALWON_SR_MPU_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &smartreflex_mpu_dev_attr,
-};
-
-/*
- * 'spinlock' class
- * spinlock provides hardware assistance for synchronizing the processes
- * running on multiple processors
- */
-
-static struct omap_hwmod_class_sysconfig omap44xx_spinlock_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap44xx_spinlock_hwmod_class = {
-       .name   = "spinlock",
-       .sysc   = &omap44xx_spinlock_sysc,
-};
-
-/* spinlock */
-static struct omap_hwmod omap44xx_spinlock_hwmod = {
-       .name           = "spinlock",
-       .class          = &omap44xx_spinlock_hwmod_class,
-       .clkdm_name     = "l4_cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4CFG_HW_SEM_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4CFG_HW_SEM_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/*
  * 'timer' class
  * general purpose timer module with accurate 1ms tick
  * This class contains several variants: ['timer_1ms', 'timer']
@@ -1790,21 +1028,6 @@ static struct omap_hwmod_class omap44xx_timer_1ms_hwmod_class = {
        .sysc   = &omap44xx_timer_1ms_sysc,
 };
 
-static struct omap_hwmod_class_sysconfig omap44xx_timer_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap44xx_timer_hwmod_class = {
-       .name   = "timer",
-       .sysc   = &omap44xx_timer_sysc,
-};
-
 /* timer1 */
 static struct omap_hwmod omap44xx_timer1_hwmod = {
        .name           = "timer1",
@@ -1821,158 +1044,6 @@ static struct omap_hwmod omap44xx_timer1_hwmod = {
        },
 };
 
-/* timer2 */
-static struct omap_hwmod omap44xx_timer2_hwmod = {
-       .name           = "timer2",
-       .class          = &omap44xx_timer_1ms_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .flags          = HWMOD_SET_DEFAULT_CLOCKACT,
-       .main_clk       = "cm2_dm2_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER2_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_DMTIMER2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer3 */
-static struct omap_hwmod omap44xx_timer3_hwmod = {
-       .name           = "timer3",
-       .class          = &omap44xx_timer_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .main_clk       = "cm2_dm3_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER3_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_DMTIMER3_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer4 */
-static struct omap_hwmod omap44xx_timer4_hwmod = {
-       .name           = "timer4",
-       .class          = &omap44xx_timer_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .main_clk       = "cm2_dm4_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER4_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_DMTIMER4_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer5 */
-static struct omap_hwmod omap44xx_timer5_hwmod = {
-       .name           = "timer5",
-       .class          = &omap44xx_timer_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "timer5_sync_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_TIMER5_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_TIMER5_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer6 */
-static struct omap_hwmod omap44xx_timer6_hwmod = {
-       .name           = "timer6",
-       .class          = &omap44xx_timer_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "timer6_sync_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_TIMER6_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_TIMER6_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer7 */
-static struct omap_hwmod omap44xx_timer7_hwmod = {
-       .name           = "timer7",
-       .class          = &omap44xx_timer_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "timer7_sync_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_TIMER7_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_TIMER7_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer8 */
-static struct omap_hwmod omap44xx_timer8_hwmod = {
-       .name           = "timer8",
-       .class          = &omap44xx_timer_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "timer8_sync_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM1_ABE_TIMER8_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_ABE_TIMER8_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer9 */
-static struct omap_hwmod omap44xx_timer9_hwmod = {
-       .name           = "timer9",
-       .class          = &omap44xx_timer_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .main_clk       = "cm2_dm9_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER9_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_DMTIMER9_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer10 */
-static struct omap_hwmod omap44xx_timer10_hwmod = {
-       .name           = "timer10",
-       .class          = &omap44xx_timer_1ms_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .flags          = HWMOD_SET_DEFAULT_CLOCKACT,
-       .main_clk       = "cm2_dm10_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER10_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_DMTIMER10_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer11 */
-static struct omap_hwmod omap44xx_timer11_hwmod = {
-       .name           = "timer11",
-       .class          = &omap44xx_timer_hwmod_class,
-       .clkdm_name     = "l4_per_clkdm",
-       .main_clk       = "cm2_dm11_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP4_CM_L4PER_DMTIMER11_CLKCTRL_OFFSET,
-                       .context_offs = OMAP4_RM_L4PER_DMTIMER11_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 /*
  * 'usb_host_fs' class
  * full-speed usb host controller
@@ -2213,30 +1284,6 @@ static struct omap_hwmod_ocp_if omap44xx_debugss__l3_main_2 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* dma_system -> l3_main_2 */
-static struct omap_hwmod_ocp_if omap44xx_dma_system__l3_main_2 = {
-       .master         = &omap44xx_dma_system_hwmod,
-       .slave          = &omap44xx_l3_main_2_hwmod,
-       .clk            = "l3_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* fdif -> l3_main_2 */
-static struct omap_hwmod_ocp_if omap44xx_fdif__l3_main_2 = {
-       .master         = &omap44xx_fdif_hwmod,
-       .slave          = &omap44xx_l3_main_2_hwmod,
-       .clk            = "l3_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* hsi -> l3_main_2 */
-static struct omap_hwmod_ocp_if omap44xx_hsi__l3_main_2 = {
-       .master         = &omap44xx_hsi_hwmod,
-       .slave          = &omap44xx_l3_main_2_hwmod,
-       .clk            = "l3_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* ipu -> l3_main_2 */
 static struct omap_hwmod_ocp_if omap44xx_ipu__l3_main_2 = {
        .master         = &omap44xx_ipu_hwmod,
@@ -2317,14 +1364,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__l3_main_3 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* aess -> l4_abe */
-static struct omap_hwmod_ocp_if __maybe_unused omap44xx_aess__l4_abe = {
-       .master         = &omap44xx_aess_hwmod,
-       .slave          = &omap44xx_l4_abe_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* dsp -> l4_abe */
 static struct omap_hwmod_ocp_if omap44xx_dsp__l4_abe = {
        .master         = &omap44xx_dsp_hwmod,
@@ -2389,22 +1428,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp_wp_noc = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_abe -> aess */
-static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_aess_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_abe -> aess (dma) */
-static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_abe__aess_dma = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_aess_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_SDMA,
-};
-
 /* l4_wkup -> counter_32k */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__counter_32k = {
        .master         = &omap44xx_l4_wkup_hwmod,
@@ -2453,22 +1476,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_instr__debugss = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> dma_system */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__dma_system = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_dma_system_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> dmic */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__dmic = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_dmic_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* dsp -> iva */
 static struct omap_hwmod_ocp_if omap44xx_dsp__iva = {
        .master         = &omap44xx_dsp_hwmod,
@@ -2605,30 +1612,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_per__dss_venc = {
        .user           = OCP_USER_MPU,
 };
 
-/* l3_main_2 -> sham */
-static struct omap_hwmod_ocp_if omap44xx_l3_main_2__sha0 = {
-       .master         = &omap44xx_l3_main_2_hwmod,
-       .slave          = &omap44xx_sha0_hwmod,
-       .clk            = "l3_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> elm */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__elm = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_elm_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> fdif */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__fdif = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_fdif_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_2 -> gpmc */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = {
        .master         = &omap44xx_l3_main_2_hwmod,
@@ -2637,14 +1620,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__gpmc = {
        .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,
-       .slave          = &omap44xx_hsi_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_2 -> ipu */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ipu = {
        .master         = &omap44xx_l3_main_2_hwmod,
@@ -2677,22 +1652,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__iva = {
        .user           = OCP_USER_MPU,
 };
 
-/* l4_wkup -> kbd */
-static struct omap_hwmod_ocp_if omap44xx_l4_wkup__kbd = {
-       .master         = &omap44xx_l4_wkup_hwmod,
-       .slave          = &omap44xx_kbd_hwmod,
-       .clk            = "l4_wkup_clk_mux_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> mcpdm */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__mcpdm = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_mcpdm_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_2 -> ocmc_ram */
 static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ocmc_ram = {
        .master         = &omap44xx_l3_main_2_hwmod,
@@ -2701,14 +1660,6 @@ static struct omap_hwmod_ocp_if omap44xx_l3_main_2__ocmc_ram = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> ocp2scp_usb_phy */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__ocp2scp_usb_phy = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_ocp2scp_usb_phy_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* mpu_private -> prcm_mpu */
 static struct omap_hwmod_ocp_if omap44xx_mpu_private__prcm_mpu = {
        .master         = &omap44xx_mpu_private_hwmod,
@@ -2757,62 +1708,6 @@ static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l3_main_2__sl2if = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_abe -> slimbus1 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__slimbus1 = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_slimbus1_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_abe -> slimbus1 (dma) */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__slimbus1_dma = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_slimbus1_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_SDMA,
-};
-
-/* l4_per -> slimbus2 */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__slimbus2 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_slimbus2_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> smartreflex_core */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_core = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_smartreflex_core_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> smartreflex_iva */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_iva = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_smartreflex_iva_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> smartreflex_mpu */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__smartreflex_mpu = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_smartreflex_mpu_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> spinlock */
-static struct omap_hwmod_ocp_if omap44xx_l4_cfg__spinlock = {
-       .master         = &omap44xx_l4_cfg_hwmod,
-       .slave          = &omap44xx_spinlock_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_wkup -> timer1 */
 static struct omap_hwmod_ocp_if omap44xx_l4_wkup__timer1 = {
        .master         = &omap44xx_l4_wkup_hwmod,
@@ -2821,86 +1716,6 @@ static struct omap_hwmod_ocp_if omap44xx_l4_wkup__timer1 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_per -> timer2 */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__timer2 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_timer2_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer3 */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__timer3 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_timer3_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer4 */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__timer4 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_timer4_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> timer5 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer5 = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_timer5_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> timer6 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer6 = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_timer6_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> timer7 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer7 = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_timer7_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> timer8 */
-static struct omap_hwmod_ocp_if omap44xx_l4_abe__timer8 = {
-       .master         = &omap44xx_l4_abe_hwmod,
-       .slave          = &omap44xx_timer8_hwmod,
-       .clk            = "ocp_abe_iclk",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer9 */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__timer9 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_timer9_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer10 */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__timer10 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_timer10_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer11 */
-static struct omap_hwmod_ocp_if omap44xx_l4_per__timer11 = {
-       .master         = &omap44xx_l4_per_hwmod,
-       .slave          = &omap44xx_timer11_hwmod,
-       .clk            = "l4_div_ck",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_cfg -> usb_host_fs */
 static struct omap_hwmod_ocp_if __maybe_unused omap44xx_l4_cfg__usb_host_fs = {
        .master         = &omap44xx_l4_cfg_hwmod,
@@ -2953,9 +1768,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
        &omap44xx_l4_cfg__l3_main_1,
        &omap44xx_mpu__l3_main_1,
        &omap44xx_debugss__l3_main_2,
-       &omap44xx_dma_system__l3_main_2,
-       &omap44xx_fdif__l3_main_2,
-       &omap44xx_hsi__l3_main_2,
        &omap44xx_ipu__l3_main_2,
        &omap44xx_iss__l3_main_2,
        &omap44xx_iva__l3_main_2,
@@ -2966,7 +1778,6 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
        &omap44xx_l3_main_1__l3_main_3,
        &omap44xx_l3_main_2__l3_main_3,
        &omap44xx_l4_cfg__l3_main_3,
-       &omap44xx_aess__l4_abe,
        &omap44xx_dsp__l4_abe,
        &omap44xx_l3_main_1__l4_abe,
        &omap44xx_mpu__l4_abe,
@@ -2975,16 +1786,12 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
        &omap44xx_l4_cfg__l4_wkup,
        &omap44xx_mpu__mpu_private,
        &omap44xx_l4_cfg__ocp_wp_noc,
-       &omap44xx_l4_abe__aess,
-       &omap44xx_l4_abe__aess_dma,
        &omap44xx_l4_wkup__counter_32k,
        &omap44xx_l4_cfg__ctrl_module_core,
        &omap44xx_l4_cfg__ctrl_module_pad_core,
        &omap44xx_l4_wkup__ctrl_module_wkup,
        &omap44xx_l4_wkup__ctrl_module_pad_wkup,
        &omap44xx_l3_instr__debugss,
-       &omap44xx_l4_cfg__dma_system,
-       &omap44xx_l4_abe__dmic,
        &omap44xx_dsp__iva,
        /* &omap44xx_dsp__sl2if, */
        &omap44xx_l4_cfg__dsp,
@@ -3002,53 +1809,24 @@ static struct omap_hwmod_ocp_if *omap44xx_hwmod_ocp_ifs[] __initdata = {
        &omap44xx_l4_per__dss_rfbi,
        &omap44xx_l3_main_2__dss_venc,
        &omap44xx_l4_per__dss_venc,
-       &omap44xx_l4_per__elm,
-       &omap44xx_l4_cfg__fdif,
        &omap44xx_l3_main_2__gpmc,
-       &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_abe__mcpdm,
-       &omap44xx_l3_main_2__mmu_ipu,
-       &omap44xx_l4_cfg__mmu_dsp,
        &omap44xx_l3_main_2__ocmc_ram,
-       &omap44xx_l4_cfg__ocp2scp_usb_phy,
        &omap44xx_mpu_private__prcm_mpu,
        &omap44xx_l4_wkup__cm_core_aon,
        &omap44xx_l4_cfg__cm_core,
        &omap44xx_l4_wkup__prm,
        &omap44xx_l4_wkup__scrm,
        /* &omap44xx_l3_main_2__sl2if, */
-       &omap44xx_l4_abe__slimbus1,
-       &omap44xx_l4_abe__slimbus1_dma,
-       &omap44xx_l4_per__slimbus2,
-       &omap44xx_l4_cfg__smartreflex_core,
-       &omap44xx_l4_cfg__smartreflex_iva,
-       &omap44xx_l4_cfg__smartreflex_mpu,
-       &omap44xx_l4_cfg__spinlock,
        &omap44xx_l4_wkup__timer1,
-       &omap44xx_l4_per__timer2,
-       &omap44xx_l4_per__timer3,
-       &omap44xx_l4_per__timer4,
-       &omap44xx_l4_abe__timer5,
-       &omap44xx_l4_abe__timer6,
-       &omap44xx_l4_abe__timer7,
-       &omap44xx_l4_abe__timer8,
-       &omap44xx_l4_per__timer9,
-       &omap44xx_l4_per__timer10,
-       &omap44xx_l4_per__timer11,
        /* &omap44xx_l4_cfg__usb_host_fs, */
        &omap44xx_l4_cfg__usb_host_hs,
        &omap44xx_l4_cfg__usb_tll_hs,
        &omap44xx_mpu__emif1,
        &omap44xx_mpu__emif2,
-       &omap44xx_l3_main_2__aes1,
-       &omap44xx_l3_main_2__aes2,
-       &omap44xx_l3_main_2__des,
-       &omap44xx_l3_main_2__sha0,
        NULL,
 };
 
index cc5ad6a..ad398f6 100644 (file)
@@ -17,8 +17,6 @@
 #include <linux/io.h>
 #include <linux/power/smartreflex.h>
 
-#include <linux/omap-dma.h>
-
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
 #include "cm1_54xx.h"
 /* Base offset for all OMAP5 interrupts external to MPUSS */
 #define OMAP54XX_IRQ_GIC_START 32
 
-/* Base offset for all OMAP5 dma requests */
-#define OMAP54XX_DMA_REQ_START 1
-
-
 /*
  * IP blocks
  */
@@ -233,87 +227,6 @@ static struct omap_hwmod omap54xx_counter_32k_hwmod = {
 };
 
 /*
- * 'dma' class
- * dma controller for data exchange between memory to memory (i.e. internal or
- * external memory) and gp peripherals to memory or memory to gp peripherals
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_dma_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x002c,
-       .syss_offs      = 0x0028,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          MSTANDBY_FORCE | MSTANDBY_NO | MSTANDBY_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap54xx_dma_hwmod_class = {
-       .name   = "dma",
-       .sysc   = &omap54xx_dma_sysc,
-};
-
-/* dma dev_attr */
-static struct omap_dma_dev_attr dma_dev_attr = {
-       .dev_caps       = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
-                         IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
-       .lch_count      = 32,
-};
-
-/* dma_system */
-static struct omap_hwmod omap54xx_dma_system_hwmod = {
-       .name           = "dma_system",
-       .class          = &omap54xx_dma_hwmod_class,
-       .clkdm_name     = "dma_clkdm",
-       .main_clk       = "l3_iclk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET,
-               },
-       },
-       .dev_attr       = &dma_dev_attr,
-};
-
-/*
- * 'dmic' class
- * digital microphone controller
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_dmic_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap54xx_dmic_hwmod_class = {
-       .name   = "dmic",
-       .sysc   = &omap54xx_dmic_sysc,
-};
-
-/* dmic */
-static struct omap_hwmod omap54xx_dmic_hwmod = {
-       .name           = "dmic",
-       .class          = &omap54xx_dmic_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "dmic_gfclk",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_DMIC_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_DMIC_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
  * 'dss' class
  * display sub-system
  */
@@ -593,154 +506,8 @@ static struct omap_hwmod omap54xx_emif2_hwmod = {
        },
 };
 
-/*
- * 'kbd' class
- * keyboard controller
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_kbd_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap54xx_kbd_hwmod_class = {
-       .name   = "kbd",
-       .sysc   = &omap54xx_kbd_sysc,
-};
-
-/* kbd */
-static struct omap_hwmod omap54xx_kbd_hwmod = {
-       .name           = "kbd",
-       .class          = &omap54xx_kbd_hwmod_class,
-       .clkdm_name     = "wkupaon_clkdm",
-       .main_clk       = "sys_32k_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_WKUPAON_KBD_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_WKUPAON_KBD_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/*
- * 'mcpdm' class
- * multi channel pdm controller (proprietary interface with phoenix power
- * ic)
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_mcpdm_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap54xx_mcpdm_hwmod_class = {
-       .name   = "mcpdm",
-       .sysc   = &omap54xx_mcpdm_sysc,
-};
-
-/* mcpdm */
-static struct omap_hwmod omap54xx_mcpdm_hwmod = {
-       .name           = "mcpdm",
-       .class          = &omap54xx_mcpdm_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       /*
-        * It's suspected that the McPDM requires an off-chip main
-        * functional clock, controlled via I2C.  This IP block is
-        * currently reset very early during boot, before I2C is
-        * available, so it doesn't seem that we have any choice in
-        * the kernel other than to avoid resetting it.  XXX This is
-        * really a hardware issue workaround: every IP block should
-        * be able to source its main functional clock from either
-        * on-chip or off-chip sources.  McPDM seems to be the only
-        * current exception.
-        */
-
-       .flags          = HWMOD_EXT_OPT_MAIN_CLK | HWMOD_SWSUP_SIDLE,
-       .main_clk       = "pad_clks_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_MCPDM_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_MCPDM_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 
-/*
- * 'mmu' class
- * The memory management unit performs virtual to physical address translation
- * for its requestors.
- */
 
-static struct omap_hwmod_class_sysconfig omap54xx_mmu_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap54xx_mmu_hwmod_class = {
-       .name = "mmu",
-       .sysc = &omap54xx_mmu_sysc,
-};
-
-static struct omap_hwmod_rst_info omap54xx_mmu_dsp_resets[] = {
-       { .name = "mmu_cache", .rst_shift = 1 },
-};
-
-static struct omap_hwmod omap54xx_mmu_dsp_hwmod = {
-       .name           = "mmu_dsp",
-       .class          = &omap54xx_mmu_hwmod_class,
-       .clkdm_name     = "dsp_clkdm",
-       .rst_lines      = omap54xx_mmu_dsp_resets,
-       .rst_lines_cnt  = ARRAY_SIZE(omap54xx_mmu_dsp_resets),
-       .main_clk       = "dpll_iva_h11x2_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_DSP_DSP_CLKCTRL_OFFSET,
-                       .rstctrl_offs = OMAP54XX_RM_DSP_RSTCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_DSP_DSP_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/* mmu ipu */
-static struct omap_hwmod_rst_info omap54xx_mmu_ipu_resets[] = {
-       { .name = "mmu_cache", .rst_shift = 2 },
-};
-
-static struct omap_hwmod omap54xx_mmu_ipu_hwmod = {
-       .name           = "mmu_ipu",
-       .class          = &omap54xx_mmu_hwmod_class,
-       .clkdm_name     = "ipu_clkdm",
-       .rst_lines      = omap54xx_mmu_ipu_resets,
-       .rst_lines_cnt  = ARRAY_SIZE(omap54xx_mmu_ipu_resets),
-       .main_clk       = "dpll_core_h22x2_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_IPU_IPU_CLKCTRL_OFFSET,
-                       .rstctrl_offs = OMAP54XX_RM_IPU_RSTCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_IPU_IPU_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
 
 /*
  * 'mpu' class
@@ -766,76 +533,6 @@ static struct omap_hwmod omap54xx_mpu_hwmod = {
        },
 };
 
-/*
- * 'spinlock' class
- * spinlock provides hardware assistance for synchronizing the processes
- * running on multiple processors
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_spinlock_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap54xx_spinlock_hwmod_class = {
-       .name   = "spinlock",
-       .sysc   = &omap54xx_spinlock_sysc,
-};
-
-/* spinlock */
-static struct omap_hwmod omap54xx_spinlock_hwmod = {
-       .name           = "spinlock",
-       .class          = &omap54xx_spinlock_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/*
- * 'ocp2scp' class
- * bridge to transform ocp interface protocol to scp (serial control port)
- * protocol
- */
-
-static struct omap_hwmod_class_sysconfig omap54xx_ocp2scp_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
-                       SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class omap54xx_ocp2scp_hwmod_class = {
-       .name   = "ocp2scp",
-       .sysc   = &omap54xx_ocp2scp_sysc,
-};
-
-/* ocp2scp1 */
-static struct omap_hwmod omap54xx_ocp2scp1_hwmod = {
-       .name           = "ocp2scp1",
-       .class          = &omap54xx_ocp2scp_hwmod_class,
-       .clkdm_name     = "l3init_clkdm",
-       .main_clk       = "l4_root_clk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
 
 /*
  * 'timer' class
@@ -858,21 +555,6 @@ static struct omap_hwmod_class omap54xx_timer_1ms_hwmod_class = {
        .sysc   = &omap54xx_timer_1ms_sysc,
 };
 
-static struct omap_hwmod_class_sysconfig omap54xx_timer_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .sysc_flags     = (SYSC_HAS_EMUFREE | SYSC_HAS_RESET_STATUS |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-static struct omap_hwmod_class omap54xx_timer_hwmod_class = {
-       .name   = "timer",
-       .sysc   = &omap54xx_timer_sysc,
-};
-
 /* timer1 */
 static struct omap_hwmod omap54xx_timer1_hwmod = {
        .name           = "timer1",
@@ -889,158 +571,6 @@ static struct omap_hwmod omap54xx_timer1_hwmod = {
        },
 };
 
-/* timer2 */
-static struct omap_hwmod omap54xx_timer2_hwmod = {
-       .name           = "timer2",
-       .class          = &omap54xx_timer_1ms_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer2_gfclk_mux",
-       .flags          = HWMOD_SET_DEFAULT_CLOCKACT,
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER2_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_TIMER2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer3 */
-static struct omap_hwmod omap54xx_timer3_hwmod = {
-       .name           = "timer3",
-       .class          = &omap54xx_timer_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer3_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER3_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_TIMER3_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer4 */
-static struct omap_hwmod omap54xx_timer4_hwmod = {
-       .name           = "timer4",
-       .class          = &omap54xx_timer_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer4_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER4_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_TIMER4_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer5 */
-static struct omap_hwmod omap54xx_timer5_hwmod = {
-       .name           = "timer5",
-       .class          = &omap54xx_timer_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "timer5_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_TIMER5_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_TIMER5_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer6 */
-static struct omap_hwmod omap54xx_timer6_hwmod = {
-       .name           = "timer6",
-       .class          = &omap54xx_timer_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "timer6_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_TIMER6_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_TIMER6_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer7 */
-static struct omap_hwmod omap54xx_timer7_hwmod = {
-       .name           = "timer7",
-       .class          = &omap54xx_timer_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "timer7_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_TIMER7_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_TIMER7_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer8 */
-static struct omap_hwmod omap54xx_timer8_hwmod = {
-       .name           = "timer8",
-       .class          = &omap54xx_timer_hwmod_class,
-       .clkdm_name     = "abe_clkdm",
-       .main_clk       = "timer8_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_ABE_TIMER8_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_ABE_TIMER8_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer9 */
-static struct omap_hwmod omap54xx_timer9_hwmod = {
-       .name           = "timer9",
-       .class          = &omap54xx_timer_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer9_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_TIMER9_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer10 */
-static struct omap_hwmod omap54xx_timer10_hwmod = {
-       .name           = "timer10",
-       .class          = &omap54xx_timer_1ms_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer10_gfclk_mux",
-       .flags          = HWMOD_SET_DEFAULT_CLOCKACT,
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_TIMER10_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer11 */
-static struct omap_hwmod omap54xx_timer11_hwmod = {
-       .name           = "timer11",
-       .class          = &omap54xx_timer_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer11_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L4PER_TIMER11_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
 /*
  * 'usb_host_hs' class
  * high-speed multi-port usb host controller
@@ -1193,35 +723,6 @@ static struct omap_hwmod omap54xx_usb_otg_ss_hwmod = {
        .opt_clks_cnt   = ARRAY_SIZE(usb_otg_ss_opt_clks),
 };
 
-
-/*
- * 'ocp2scp' class
- * bridge to transform ocp interface protocol to scp (serial control port)
- * protocol
- */
-/* ocp2scp3 */
-static struct omap_hwmod omap54xx_ocp2scp3_hwmod;
-/* l4_cfg -> ocp2scp3 */
-static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp3 = {
-       .master         = &omap54xx_l4_cfg_hwmod,
-       .slave          = &omap54xx_ocp2scp3_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-static struct omap_hwmod omap54xx_ocp2scp3_hwmod = {
-       .name           = "ocp2scp3",
-       .class          = &omap54xx_ocp2scp_hwmod_class,
-       .clkdm_name     = "l3init_clkdm",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = OMAP54XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET,
-                       .context_offs = OMAP54XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
 /*
  * 'sata' class
  * sata:  serial ata interface  gen2 compliant   ( 1 rx/ 1 tx)
@@ -1303,14 +804,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_1 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> mmu_dsp */
-static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mmu_dsp = {
-       .master         = &omap54xx_l4_cfg_hwmod,
-       .slave          = &omap54xx_mmu_dsp_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* mpu -> l3_main_1 */
 static struct omap_hwmod_ocp_if omap54xx_mpu__l3_main_1 = {
        .master         = &omap54xx_mpu_hwmod,
@@ -1335,14 +828,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__l3_main_2 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l3_main_2 -> mmu_ipu */
-static struct omap_hwmod_ocp_if omap54xx_l3_main_2__mmu_ipu = {
-       .master         = &omap54xx_l3_main_2_hwmod,
-       .slave          = &omap54xx_mmu_ipu_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_1 -> l3_main_3 */
 static struct omap_hwmod_ocp_if omap54xx_l3_main_1__l3_main_3 = {
        .master         = &omap54xx_l3_main_1_hwmod,
@@ -1423,22 +908,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_wkup__counter_32k = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> dma_system */
-static struct omap_hwmod_ocp_if omap54xx_l4_cfg__dma_system = {
-       .master         = &omap54xx_l4_cfg_hwmod,
-       .slave          = &omap54xx_dma_system_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> dmic */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__dmic = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_dmic_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l3_main_2 -> dss */
 static struct omap_hwmod_ocp_if omap54xx_l3_main_2__dss = {
        .master         = &omap54xx_l3_main_2_hwmod,
@@ -1503,22 +972,6 @@ static struct omap_hwmod_ocp_if omap54xx_mpu__emif2 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_wkup -> kbd */
-static struct omap_hwmod_ocp_if omap54xx_l4_wkup__kbd = {
-       .master         = &omap54xx_l4_wkup_hwmod,
-       .slave          = &omap54xx_kbd_hwmod,
-       .clk            = "wkupaon_iclk_mux",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> mcpdm */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__mcpdm = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_mcpdm_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
 /* l4_cfg -> mpu */
 static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = {
        .master         = &omap54xx_l4_cfg_hwmod,
@@ -1527,22 +980,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_cfg__mpu = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> spinlock */
-static struct omap_hwmod_ocp_if omap54xx_l4_cfg__spinlock = {
-       .master         = &omap54xx_l4_cfg_hwmod,
-       .slave          = &omap54xx_spinlock_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> ocp2scp1 */
-static struct omap_hwmod_ocp_if omap54xx_l4_cfg__ocp2scp1 = {
-       .master         = &omap54xx_l4_cfg_hwmod,
-       .slave          = &omap54xx_ocp2scp1_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_wkup -> timer1 */
 static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = {
        .master         = &omap54xx_l4_wkup_hwmod,
@@ -1551,86 +988,6 @@ static struct omap_hwmod_ocp_if omap54xx_l4_wkup__timer1 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_per -> timer2 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__timer2 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_timer2_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer3 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__timer3 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_timer3_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer4 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__timer4 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_timer4_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_abe -> timer5 */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer5 = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_timer5_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_abe -> timer6 */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer6 = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_timer6_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_abe -> timer7 */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer7 = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_timer7_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_abe -> timer8 */
-static struct omap_hwmod_ocp_if omap54xx_l4_abe__timer8 = {
-       .master         = &omap54xx_l4_abe_hwmod,
-       .slave          = &omap54xx_timer8_hwmod,
-       .clk            = "abe_iclk",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_per -> timer9 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__timer9 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_timer9_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer10 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__timer10 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_timer10_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per -> timer11 */
-static struct omap_hwmod_ocp_if omap54xx_l4_per__timer11 = {
-       .master         = &omap54xx_l4_per_hwmod,
-       .slave          = &omap54xx_timer11_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_cfg -> usb_host_hs */
 static struct omap_hwmod_ocp_if omap54xx_l4_cfg__usb_host_hs = {
        .master         = &omap54xx_l4_cfg_hwmod,
@@ -1673,9 +1030,6 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_l3_main_1__l4_wkup,
        &omap54xx_mpu__mpu_private,
        &omap54xx_l4_wkup__counter_32k,
-       &omap54xx_l4_cfg__dma_system,
-       &omap54xx_l4_abe__dmic,
-       &omap54xx_l4_cfg__mmu_dsp,
        &omap54xx_l3_main_2__dss,
        &omap54xx_l3_main_2__dss_dispc,
        &omap54xx_l3_main_2__dss_dsi1_a,
@@ -1684,27 +1038,11 @@ static struct omap_hwmod_ocp_if *omap54xx_hwmod_ocp_ifs[] __initdata = {
        &omap54xx_l3_main_2__dss_rfbi,
        &omap54xx_mpu__emif1,
        &omap54xx_mpu__emif2,
-       &omap54xx_l3_main_2__mmu_ipu,
-       &omap54xx_l4_wkup__kbd,
-       &omap54xx_l4_abe__mcpdm,
        &omap54xx_l4_cfg__mpu,
-       &omap54xx_l4_cfg__spinlock,
-       &omap54xx_l4_cfg__ocp2scp1,
        &omap54xx_l4_wkup__timer1,
-       &omap54xx_l4_per__timer2,
-       &omap54xx_l4_per__timer3,
-       &omap54xx_l4_per__timer4,
-       &omap54xx_l4_abe__timer5,
-       &omap54xx_l4_abe__timer6,
-       &omap54xx_l4_abe__timer7,
-       &omap54xx_l4_abe__timer8,
-       &omap54xx_l4_per__timer9,
-       &omap54xx_l4_per__timer10,
-       &omap54xx_l4_per__timer11,
        &omap54xx_l4_cfg__usb_host_hs,
        &omap54xx_l4_cfg__usb_tll_hs,
        &omap54xx_l4_cfg__usb_otg_ss,
-       &omap54xx_l4_cfg__ocp2scp3,
        &omap54xx_l4_cfg__sata,
        NULL,
 };
index f8715bd..acef373 100644 (file)
@@ -15,9 +15,6 @@
  */
 
 #include <linux/io.h>
-#include <linux/power/smartreflex.h>
-
-#include <linux/omap-dma.h>
 
 #include "omap_hwmod.h"
 #include "omap_hwmod_common_data.h"
 /* Base offset for all DRA7XX interrupts external to MPUSS */
 #define DRA7XX_IRQ_GIC_START   32
 
-/* Base offset for all DRA7XX dma requests */
-#define DRA7XX_DMA_REQ_START   1
-
-
 /*
  * IP blocks
  */
@@ -284,156 +277,6 @@ static struct omap_hwmod dra7xx_ctrl_module_wkup_hwmod = {
 };
 
 /*
- * 'dcan' class
- *
- */
-
-static struct omap_hwmod_class dra7xx_dcan_hwmod_class = {
-       .name   = "dcan",
-};
-
-/* dcan1 */
-static struct omap_hwmod dra7xx_dcan1_hwmod = {
-       .name           = "dcan1",
-       .class          = &dra7xx_dcan_hwmod_class,
-       .clkdm_name     = "wkupaon_clkdm",
-       .main_clk       = "dcan1_sys_clk_mux",
-       .flags          = HWMOD_CLKDM_NOAUTO,
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_WKUPAON_DCAN1_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_WKUPAON_DCAN1_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* dcan2 */
-static struct omap_hwmod dra7xx_dcan2_hwmod = {
-       .name           = "dcan2",
-       .class          = &dra7xx_dcan_hwmod_class,
-       .clkdm_name     = "l4per2_clkdm",
-       .main_clk       = "sys_clkin1",
-       .flags          = HWMOD_CLKDM_NOAUTO,
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER2_DCAN2_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER2_DCAN2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* pwmss  */
-static struct omap_hwmod_class_sysconfig dra7xx_epwmss_sysc = {
-       .rev_offs       = 0x0,
-       .sysc_offs      = 0x4,
-       .sysc_flags     = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                         SYSC_HAS_RESET_STATUS,
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type2,
-};
-
-/*
- * epwmss class
- */
-static struct omap_hwmod_class dra7xx_epwmss_hwmod_class = {
-       .name           = "epwmss",
-       .sysc           = &dra7xx_epwmss_sysc,
-};
-
-/* epwmss0 */
-static struct omap_hwmod dra7xx_epwmss0_hwmod = {
-       .name           = "epwmss0",
-       .class          = &dra7xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4per2_clkdm",
-       .main_clk       = "l4_root_clk_div",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-                       .clkctrl_offs   = DRA7XX_CM_L4PER2_PWMSS1_CLKCTRL_OFFSET,
-                       .context_offs   = DRA7XX_RM_L4PER2_PWMSS1_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* epwmss1 */
-static struct omap_hwmod dra7xx_epwmss1_hwmod = {
-       .name           = "epwmss1",
-       .class          = &dra7xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4per2_clkdm",
-       .main_clk       = "l4_root_clk_div",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-                       .clkctrl_offs   = DRA7XX_CM_L4PER2_PWMSS2_CLKCTRL_OFFSET,
-                       .context_offs   = DRA7XX_RM_L4PER2_PWMSS2_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* epwmss2 */
-static struct omap_hwmod dra7xx_epwmss2_hwmod = {
-       .name           = "epwmss2",
-       .class          = &dra7xx_epwmss_hwmod_class,
-       .clkdm_name     = "l4per2_clkdm",
-       .main_clk       = "l4_root_clk_div",
-       .prcm           = {
-               .omap4  = {
-                       .modulemode     = MODULEMODE_SWCTRL,
-                       .clkctrl_offs   = DRA7XX_CM_L4PER2_PWMSS3_CLKCTRL_OFFSET,
-                       .context_offs   = DRA7XX_RM_L4PER2_PWMSS3_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/*
- * 'dma' class
- *
- */
-
-static struct omap_hwmod_class_sysconfig dra7xx_dma_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x002c,
-       .syss_offs      = 0x0028,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_EMUFREE | SYSC_HAS_MIDLEMODE |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP | MSTANDBY_FORCE | MSTANDBY_NO |
-                          MSTANDBY_SMART | MSTANDBY_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class dra7xx_dma_hwmod_class = {
-       .name   = "dma",
-       .sysc   = &dra7xx_dma_sysc,
-};
-
-/* dma dev_attr */
-static struct omap_dma_dev_attr dma_dev_attr = {
-       .dev_caps       = RESERVE_CHANNEL | DMA_LINKED_LCH | GLOBAL_PRIORITY |
-                         IS_CSSA_32 | IS_CDSA_32 | IS_RW_PRIORITY,
-       .lch_count      = 32,
-};
-
-/* dma_system */
-static struct omap_hwmod dra7xx_dma_system_hwmod = {
-       .name           = "dma_system",
-       .class          = &dra7xx_dma_hwmod_class,
-       .clkdm_name     = "dma_clkdm",
-       .main_clk       = "l3_iclk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_DMA_DMA_SYSTEM_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_DMA_DMA_SYSTEM_CONTEXT_OFFSET,
-               },
-       },
-       .dev_attr       = &dma_dev_attr,
-};
-
-/*
  * 'tpcc' class
  *
  */
@@ -626,112 +469,9 @@ static struct omap_hwmod dra7xx_dss_hdmi_hwmod = {
        .parent_hwmod   = &dra7xx_dss_hwmod,
 };
 
-/* AES (the 'P' (public) device) */
-static struct omap_hwmod_class_sysconfig dra7xx_aes_sysc = {
-       .rev_offs       = 0x0080,
-       .sysc_offs      = 0x0084,
-       .syss_offs      = 0x0088,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
 
-static struct omap_hwmod_class dra7xx_aes_hwmod_class = {
-       .name   = "aes",
-       .sysc   = &dra7xx_aes_sysc,
-};
 
-/* AES1 */
-static struct omap_hwmod dra7xx_aes1_hwmod = {
-       .name           = "aes1",
-       .class          = &dra7xx_aes_hwmod_class,
-       .clkdm_name     = "l4sec_clkdm",
-       .main_clk       = "l3_iclk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4SEC_AES1_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4SEC_AES1_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/* AES2 */
-static struct omap_hwmod dra7xx_aes2_hwmod = {
-       .name           = "aes2",
-       .class          = &dra7xx_aes_hwmod_class,
-       .clkdm_name     = "l4sec_clkdm",
-       .main_clk       = "l3_iclk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4SEC_AES2_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4SEC_AES2_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/* sha0 HIB2 (the 'P' (public) device) */
-static struct omap_hwmod_class_sysconfig dra7xx_sha0_sysc = {
-       .rev_offs       = 0x100,
-       .sysc_offs      = 0x110,
-       .syss_offs      = 0x114,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class dra7xx_sha0_hwmod_class = {
-       .name           = "sham",
-       .sysc           = &dra7xx_sha0_sysc,
-};
 
-static struct omap_hwmod dra7xx_sha0_hwmod = {
-       .name           = "sham",
-       .class          = &dra7xx_sha0_hwmod_class,
-       .clkdm_name     = "l4sec_clkdm",
-       .main_clk       = "l3_iclk_div",
-       .prcm           = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4SEC_SHA2MD51_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4SEC_SHA2MD51_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/*
- * 'elm' class
- *
- */
-
-static struct omap_hwmod_class_sysconfig dra7xx_elm_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_CLOCKACTIVITY |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class dra7xx_elm_hwmod_class = {
-       .name   = "elm",
-       .sysc   = &dra7xx_elm_sysc,
-};
-
-/* elm */
-
-static struct omap_hwmod dra7xx_elm_hwmod = {
-       .name           = "elm",
-       .class          = &dra7xx_elm_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "l3_iclk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER_ELM_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER_ELM_CONTEXT_OFFSET,
-               },
-       },
-};
 
 /*
  * 'gpmc' class
@@ -797,55 +537,6 @@ static struct omap_hwmod dra7xx_mpu_hwmod = {
        },
 };
 
-/*
- * 'ocp2scp' class
- *
- */
-
-static struct omap_hwmod_class_sysconfig dra7xx_ocp2scp_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_SIDLEMODE |
-                          SYSC_HAS_SOFTRESET | SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class dra7xx_ocp2scp_hwmod_class = {
-       .name   = "ocp2scp",
-       .sysc   = &dra7xx_ocp2scp_sysc,
-};
-
-/* ocp2scp1 */
-static struct omap_hwmod dra7xx_ocp2scp1_hwmod = {
-       .name           = "ocp2scp1",
-       .class          = &dra7xx_ocp2scp_hwmod_class,
-       .clkdm_name     = "l3init_clkdm",
-       .main_clk       = "l4_root_clk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L3INIT_OCP2SCP1_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L3INIT_OCP2SCP1_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
-/* ocp2scp3 */
-static struct omap_hwmod dra7xx_ocp2scp3_hwmod = {
-       .name           = "ocp2scp3",
-       .class          = &dra7xx_ocp2scp_hwmod_class,
-       .clkdm_name     = "l3init_clkdm",
-       .main_clk       = "l4_root_clk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L3INIT_OCP2SCP3_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L3INIT_OCP2SCP3_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
 
 /*
  * 'PCIE' class
@@ -1032,103 +723,6 @@ static struct omap_hwmod dra7xx_sata_hwmod = {
 };
 
 /*
- * 'smartreflex' class
- *
- */
-
-/* The IP is not compliant to type1 / type2 scheme */
-static struct omap_hwmod_class_sysconfig dra7xx_smartreflex_sysc = {
-       .rev_offs       = -ENODEV,
-       .sysc_offs      = 0x0038,
-       .sysc_flags     = (SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
-                          SIDLE_SMART_WKUP),
-       .sysc_fields    = &omap36xx_sr_sysc_fields,
-};
-
-static struct omap_hwmod_class dra7xx_smartreflex_hwmod_class = {
-       .name   = "smartreflex",
-       .sysc   = &dra7xx_smartreflex_sysc,
-};
-
-/* smartreflex_core */
-/* smartreflex_core dev_attr */
-static struct omap_smartreflex_dev_attr smartreflex_core_dev_attr = {
-       .sensor_voltdm_name     = "core",
-};
-
-static struct omap_hwmod dra7xx_smartreflex_core_hwmod = {
-       .name           = "smartreflex_core",
-       .class          = &dra7xx_smartreflex_hwmod_class,
-       .clkdm_name     = "coreaon_clkdm",
-       .main_clk       = "wkupaon_iclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_COREAON_SMARTREFLEX_CORE_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_COREAON_SMARTREFLEX_CORE_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &smartreflex_core_dev_attr,
-};
-
-/* smartreflex_mpu */
-/* smartreflex_mpu dev_attr */
-static struct omap_smartreflex_dev_attr smartreflex_mpu_dev_attr = {
-       .sensor_voltdm_name     = "mpu",
-};
-
-static struct omap_hwmod dra7xx_smartreflex_mpu_hwmod = {
-       .name           = "smartreflex_mpu",
-       .class          = &dra7xx_smartreflex_hwmod_class,
-       .clkdm_name     = "coreaon_clkdm",
-       .main_clk       = "wkupaon_iclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_COREAON_SMARTREFLEX_MPU_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_COREAON_SMARTREFLEX_MPU_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-       .dev_attr       = &smartreflex_mpu_dev_attr,
-};
-
-/*
- * 'spinlock' class
- *
- */
-
-static struct omap_hwmod_class_sysconfig dra7xx_spinlock_sysc = {
-       .rev_offs       = 0x0000,
-       .sysc_offs      = 0x0010,
-       .syss_offs      = 0x0014,
-       .sysc_flags     = (SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
-                          SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
-                          SYSS_HAS_RESET_STATUS),
-       .idlemodes      = (SIDLE_FORCE | SIDLE_NO | SIDLE_SMART),
-       .sysc_fields    = &omap_hwmod_sysc_type1,
-};
-
-static struct omap_hwmod_class dra7xx_spinlock_hwmod_class = {
-       .name   = "spinlock",
-       .sysc   = &dra7xx_spinlock_sysc,
-};
-
-/* spinlock */
-static struct omap_hwmod dra7xx_spinlock_hwmod = {
-       .name           = "spinlock",
-       .class          = &dra7xx_spinlock_hwmod_class,
-       .clkdm_name     = "l4cfg_clkdm",
-       .main_clk       = "l3_iclk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4CFG_SPINLOCK_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4CFG_SPINLOCK_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/*
  * 'timer' class
  *
  * This class contains several variants: ['timer_1ms', 'timer_secure',
@@ -1225,213 +819,6 @@ static struct omap_hwmod dra7xx_timer4_hwmod = {
        },
 };
 
-/* timer5 */
-static struct omap_hwmod dra7xx_timer5_hwmod = {
-       .name           = "timer5",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "ipu_clkdm",
-       .main_clk       = "timer5_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_IPU_TIMER5_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_IPU_TIMER5_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer6 */
-static struct omap_hwmod dra7xx_timer6_hwmod = {
-       .name           = "timer6",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "ipu_clkdm",
-       .main_clk       = "timer6_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_IPU_TIMER6_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_IPU_TIMER6_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer7 */
-static struct omap_hwmod dra7xx_timer7_hwmod = {
-       .name           = "timer7",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "ipu_clkdm",
-       .main_clk       = "timer7_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_IPU_TIMER7_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_IPU_TIMER7_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer8 */
-static struct omap_hwmod dra7xx_timer8_hwmod = {
-       .name           = "timer8",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "ipu_clkdm",
-       .main_clk       = "timer8_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_IPU_TIMER8_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_IPU_TIMER8_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer9 */
-static struct omap_hwmod dra7xx_timer9_hwmod = {
-       .name           = "timer9",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer9_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER_TIMER9_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER_TIMER9_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer10 */
-static struct omap_hwmod dra7xx_timer10_hwmod = {
-       .name           = "timer10",
-       .class          = &dra7xx_timer_1ms_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer10_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER_TIMER10_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER_TIMER10_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer11 */
-static struct omap_hwmod dra7xx_timer11_hwmod = {
-       .name           = "timer11",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "l4per_clkdm",
-       .main_clk       = "timer11_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER_TIMER11_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER_TIMER11_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer12 */
-static struct omap_hwmod dra7xx_timer12_hwmod = {
-       .name           = "timer12",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "wkupaon_clkdm",
-       .main_clk       = "secure_32k_clk_src_ck",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_WKUPAON_TIMER12_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_WKUPAON_TIMER12_CONTEXT_OFFSET,
-               },
-       },
-};
-
-/* timer13 */
-static struct omap_hwmod dra7xx_timer13_hwmod = {
-       .name           = "timer13",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "l4per3_clkdm",
-       .main_clk       = "timer13_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER3_TIMER13_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER3_TIMER13_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer14 */
-static struct omap_hwmod dra7xx_timer14_hwmod = {
-       .name           = "timer14",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "l4per3_clkdm",
-       .main_clk       = "timer14_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER3_TIMER14_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER3_TIMER14_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer15 */
-static struct omap_hwmod dra7xx_timer15_hwmod = {
-       .name           = "timer15",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "l4per3_clkdm",
-       .main_clk       = "timer15_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER3_TIMER15_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER3_TIMER15_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* timer16 */
-static struct omap_hwmod dra7xx_timer16_hwmod = {
-       .name           = "timer16",
-       .class          = &dra7xx_timer_hwmod_class,
-       .clkdm_name     = "l4per3_clkdm",
-       .main_clk       = "timer16_gfclk_mux",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4PER3_TIMER16_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4PER3_TIMER16_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_SWCTRL,
-               },
-       },
-};
-
-/* DES (the 'P' (public) device) */
-static struct omap_hwmod_class_sysconfig dra7xx_des_sysc = {
-       .rev_offs       = 0x0030,
-       .sysc_offs      = 0x0034,
-       .syss_offs      = 0x0038,
-       .sysc_flags     = SYSS_HAS_RESET_STATUS,
-};
-
-static struct omap_hwmod_class dra7xx_des_hwmod_class = {
-       .name   = "des",
-       .sysc   = &dra7xx_des_sysc,
-};
-
-/* DES */
-static struct omap_hwmod dra7xx_des_hwmod = {
-       .name           = "des",
-       .class          = &dra7xx_des_hwmod_class,
-       .clkdm_name     = "l4sec_clkdm",
-       .main_clk       = "l3_iclk_div",
-       .prcm = {
-               .omap4 = {
-                       .clkctrl_offs = DRA7XX_CM_L4SEC_DES3DES_CLKCTRL_OFFSET,
-                       .context_offs = DRA7XX_RM_L4SEC_DES3DES_CONTEXT_OFFSET,
-                       .modulemode   = MODULEMODE_HWCTRL,
-               },
-       },
-};
-
 /*
  * 'usb_otg_ss' class
  *
@@ -1690,30 +1077,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_wkup__ctrl_module_wkup = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_wkup -> dcan1 */
-static struct omap_hwmod_ocp_if dra7xx_l4_wkup__dcan1 = {
-       .master         = &dra7xx_l4_wkup_hwmod,
-       .slave          = &dra7xx_dcan1_hwmod,
-       .clk            = "wkupaon_iclk_mux",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per2 -> dcan2 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per2__dcan2 = {
-       .master         = &dra7xx_l4_per2_hwmod,
-       .slave          = &dra7xx_dcan2_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> dma_system */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__dma_system = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_dma_system_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_1 -> tpcc */
 static struct omap_hwmod_ocp_if dra7xx_l3_main_1__tpcc = {
        .master         = &dra7xx_l3_main_1_hwmod,
@@ -1762,38 +1125,6 @@ static struct omap_hwmod_ocp_if dra7xx_l3_main_1__hdmi = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l3_main_1 -> aes1 */
-static struct omap_hwmod_ocp_if dra7xx_l3_main_1__aes1 = {
-       .master         = &dra7xx_l3_main_1_hwmod,
-       .slave          = &dra7xx_aes1_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3_main_1 -> aes2 */
-static struct omap_hwmod_ocp_if dra7xx_l3_main_1__aes2 = {
-       .master         = &dra7xx_l3_main_1_hwmod,
-       .slave          = &dra7xx_aes2_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l3_main_1 -> sha0 */
-static struct omap_hwmod_ocp_if dra7xx_l3_main_1__sha0 = {
-       .master         = &dra7xx_l3_main_1_hwmod,
-       .slave          = &dra7xx_sha0_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per1 -> elm */
-static struct omap_hwmod_ocp_if dra7xx_l4_per1__elm = {
-       .master         = &dra7xx_l4_per1_hwmod,
-       .slave          = &dra7xx_elm_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_1 -> gpmc */
 static struct omap_hwmod_ocp_if dra7xx_l3_main_1__gpmc = {
        .master         = &dra7xx_l3_main_1_hwmod,
@@ -1810,22 +1141,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__mpu = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> ocp2scp1 */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp1 = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_ocp2scp1_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> ocp2scp3 */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__ocp2scp3 = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_ocp2scp3_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l3_main_1 -> pciess1 */
 static struct omap_hwmod_ocp_if dra7xx_l3_main_1__pciess1 = {
        .master         = &dra7xx_l3_main_1_hwmod,
@@ -1882,30 +1197,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_cfg__sata = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_cfg -> smartreflex_core */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__smartreflex_core = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_smartreflex_core_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> smartreflex_mpu */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__smartreflex_mpu = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_smartreflex_mpu_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_cfg -> spinlock */
-static struct omap_hwmod_ocp_if dra7xx_l4_cfg__spinlock = {
-       .master         = &dra7xx_l4_cfg_hwmod,
-       .slave          = &dra7xx_spinlock_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_wkup -> timer1 */
 static struct omap_hwmod_ocp_if dra7xx_l4_wkup__timer1 = {
        .master         = &dra7xx_l4_wkup_hwmod,
@@ -1938,110 +1229,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer4 = {
        .user           = OCP_USER_MPU | OCP_USER_SDMA,
 };
 
-/* l4_per3 -> timer5 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer5 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_timer5_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> timer6 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer6 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_timer6_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> timer7 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer7 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_timer7_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> timer8 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer8 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_timer8_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per1 -> timer9 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer9 = {
-       .master         = &dra7xx_l4_per1_hwmod,
-       .slave          = &dra7xx_timer9_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per1 -> timer10 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer10 = {
-       .master         = &dra7xx_l4_per1_hwmod,
-       .slave          = &dra7xx_timer10_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per1 -> timer11 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per1__timer11 = {
-       .master         = &dra7xx_l4_per1_hwmod,
-       .slave          = &dra7xx_timer11_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_wkup -> timer12 */
-static struct omap_hwmod_ocp_if dra7xx_l4_wkup__timer12 = {
-       .master         = &dra7xx_l4_wkup_hwmod,
-       .slave          = &dra7xx_timer12_hwmod,
-       .clk            = "wkupaon_iclk_mux",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> timer13 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer13 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_timer13_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> timer14 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer14 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_timer14_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> timer15 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer15 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_timer15_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per3 -> timer16 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per3__timer16 = {
-       .master         = &dra7xx_l4_per3_hwmod,
-       .slave          = &dra7xx_timer16_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
-/* l4_per1 -> des */
-static struct omap_hwmod_ocp_if dra7xx_l4_per1__des = {
-       .master         = &dra7xx_l4_per1_hwmod,
-       .slave          = &dra7xx_des_hwmod,
-       .clk            = "l3_iclk_div",
-       .user           = OCP_USER_MPU | OCP_USER_SDMA,
-};
-
 /* l4_per3 -> usb_otg_ss1 */
 static struct omap_hwmod_ocp_if dra7xx_l4_per3__usb_otg_ss1 = {
        .master         = &dra7xx_l4_per3_hwmod,
@@ -2106,30 +1293,6 @@ static struct omap_hwmod_ocp_if dra7xx_l4_per2__vcp2 = {
        .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,
-       .slave          = &dra7xx_epwmss0_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_per2 -> epwmss1 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per2__epwmss1 = {
-       .master         = &dra7xx_l4_per2_hwmod,
-       .slave          = &dra7xx_epwmss1_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU,
-};
-
-/* l4_per2 -> epwmss2 */
-static struct omap_hwmod_ocp_if dra7xx_l4_per2__epwmss2 = {
-       .master         = &dra7xx_l4_per2_hwmod,
-       .slave          = &dra7xx_epwmss2_hwmod,
-       .clk            = "l4_root_clk_div",
-       .user           = OCP_USER_MPU,
-};
-
 static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
        &dra7xx_l3_main_1__dmm,
        &dra7xx_l3_main_2__l3_instr,
@@ -2146,48 +1309,24 @@ static struct omap_hwmod_ocp_if *dra7xx_hwmod_ocp_ifs[] __initdata = {
        &dra7xx_l3_main_1__bb2d,
        &dra7xx_l4_wkup__counter_32k,
        &dra7xx_l4_wkup__ctrl_module_wkup,
-       &dra7xx_l4_wkup__dcan1,
-       &dra7xx_l4_per2__dcan2,
-       &dra7xx_l4_cfg__dma_system,
        &dra7xx_l3_main_1__tpcc,
        &dra7xx_l3_main_1__tptc0,
        &dra7xx_l3_main_1__tptc1,
        &dra7xx_l3_main_1__dss,
        &dra7xx_l3_main_1__dispc,
        &dra7xx_l3_main_1__hdmi,
-       &dra7xx_l3_main_1__aes1,
-       &dra7xx_l3_main_1__aes2,
-       &dra7xx_l3_main_1__sha0,
-       &dra7xx_l4_per1__elm,
        &dra7xx_l3_main_1__gpmc,
        &dra7xx_l4_cfg__mpu,
-       &dra7xx_l4_cfg__ocp2scp1,
-       &dra7xx_l4_cfg__ocp2scp3,
        &dra7xx_l3_main_1__pciess1,
        &dra7xx_l4_cfg__pciess1,
        &dra7xx_l3_main_1__pciess2,
        &dra7xx_l4_cfg__pciess2,
        &dra7xx_l3_main_1__qspi,
        &dra7xx_l4_cfg__sata,
-       &dra7xx_l4_cfg__smartreflex_core,
-       &dra7xx_l4_cfg__smartreflex_mpu,
-       &dra7xx_l4_cfg__spinlock,
        &dra7xx_l4_wkup__timer1,
        &dra7xx_l4_per1__timer2,
        &dra7xx_l4_per1__timer3,
        &dra7xx_l4_per1__timer4,
-       &dra7xx_l4_per3__timer5,
-       &dra7xx_l4_per3__timer6,
-       &dra7xx_l4_per3__timer7,
-       &dra7xx_l4_per3__timer8,
-       &dra7xx_l4_per1__timer9,
-       &dra7xx_l4_per1__timer10,
-       &dra7xx_l4_per1__timer11,
-       &dra7xx_l4_per3__timer13,
-       &dra7xx_l4_per3__timer14,
-       &dra7xx_l4_per3__timer15,
-       &dra7xx_l4_per3__timer16,
-       &dra7xx_l4_per1__des,
        &dra7xx_l4_per3__usb_otg_ss1,
        &dra7xx_l4_per3__usb_otg_ss2,
        &dra7xx_l4_per3__usb_otg_ss3,
@@ -2195,15 +1334,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_per2__epwmss0,
-       &dra7xx_l4_per2__epwmss1,
-       &dra7xx_l4_per2__epwmss2,
-       NULL,
-};
-
-/* GP-only hwmod links */
-static struct omap_hwmod_ocp_if *dra7xx_gp_hwmod_ocp_ifs[] __initdata = {
-       &dra7xx_l4_wkup__timer12,
        NULL,
 };
 
@@ -2256,8 +1386,5 @@ int __init dra7xx_hwmod_init(void)
                }
        }
 
-       if (!ret && omap_type() == OMAP2_DEVICE_TYPE_GP)
-               ret = omap_hwmod_register_links(dra7xx_gp_hwmod_ocp_ifs);
-
        return ret;
 }
index ca56563..c85cb8b 100644 (file)
@@ -98,7 +98,6 @@ extern struct omap_hwmod_class omap2_hdq1w_class;
 extern struct omap_hwmod_class omap2xxx_timer_hwmod_class;
 extern struct omap_hwmod_class omap2xxx_wd_timer_hwmod_class;
 extern struct omap_hwmod_class omap2xxx_gpio_hwmod_class;
-extern struct omap_hwmod_class omap2xxx_dma_hwmod_class;
 extern struct omap_hwmod_class omap2xxx_mailbox_hwmod_class;
 extern struct omap_hwmod_class omap2xxx_mcspi_class;
 
index d5ddba0..143623b 100644 (file)
@@ -26,8 +26,6 @@
 #include <linux/kernel.h>
 #include <linux/errno.h>
 
-#include <sound/aess.h>
-
 #include "omap_hwmod.h"
 #include "common.h"
 
 #define OMAP_RTC_MAX_READY_TIME        50
 
 /**
- * omap_hwmod_aess_preprogram - enable AESS internal autogating
- * @oh: struct omap_hwmod *
- *
- * The AESS will not IdleAck to the PRCM until its internal autogating
- * is enabled.  Since internal autogating is disabled by default after
- * AESS reset, we must enable autogating after the hwmod code resets
- * the AESS.  Returns 0.
- */
-int omap_hwmod_aess_preprogram(struct omap_hwmod *oh)
-{
-       void __iomem *va;
-
-       va = omap_hwmod_get_mpu_rt_va(oh);
-       if (!va)
-               return -EINVAL;
-
-       aess_enable_autogating(va);
-
-       return 0;
-}
-
-/**
  * omap_rtc_wait_not_busy - Wait for the RTC BUSY flag
  * @oh: struct omap_hwmod *
  *
index e95c224..dbb7c2a 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/platform_data/ti-sysc.h>
 #include <linux/platform_data/wkup_m3.h>
 #include <linux/platform_data/asoc-ti-mcbsp.h>
+#include <linux/platform_data/ti-prm.h>
 
 #include "clockdomain.h"
 #include "common.h"
@@ -42,6 +43,17 @@ struct pdata_init {
 static struct of_dev_auxdata omap_auxdata_lookup[];
 static struct twl4030_gpio_platform_data twl_gpio_auxdata;
 
+#if IS_ENABLED(CONFIG_OMAP_IOMMU)
+int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev, bool request,
+                                   u8 *pwrst);
+#else
+static inline int omap_iommu_set_pwrdm_constraint(struct platform_device *pdev,
+                                                 bool request, u8 *pwrst)
+{
+       return 0;
+}
+#endif
+
 #ifdef CONFIG_MACH_NOKIA_N8X0
 static void __init omap2420_n8x0_legacy_init(void)
 {
@@ -260,16 +272,6 @@ static void __init omap3_pandora_legacy_init(void)
 }
 #endif /* CONFIG_ARCH_OMAP3 */
 
-#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
-static struct iommu_platform_data omap4_iommu_pdata = {
-       .reset_name = "mmu_cache",
-       .assert_reset = omap_device_assert_hardreset,
-       .deassert_reset = omap_device_deassert_hardreset,
-       .device_enable = omap_device_enable,
-       .device_idle = omap_device_idle,
-};
-#endif
-
 #if defined(CONFIG_SOC_AM33XX) || defined(CONFIG_SOC_AM43XX)
 static struct wkup_m3_platform_data wkup_m3_data = {
        .reset_name = "wkup_m3",
@@ -285,6 +287,10 @@ static void __init omap5_uevm_legacy_init(void)
 #endif
 
 #ifdef CONFIG_SOC_DRA7XX
+static struct iommu_platform_data dra7_ipu1_dsp_iommu_pdata = {
+       .set_pwrdm_constraint = omap_iommu_set_pwrdm_constraint,
+};
+
 static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc1;
 static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc2;
 static struct omap_hsmmc_platform_data dra7_hsmmc_data_mmc3;
@@ -412,6 +418,12 @@ void omap_pcs_legacy_init(int irq, void (*rearm)(void))
        pcs_pdata.rearm = rearm;
 }
 
+static struct ti_prm_platform_data ti_prm_pdata = {
+       .clkdm_deny_idle = clkdm_deny_idle,
+       .clkdm_allow_idle = clkdm_allow_idle,
+       .clkdm_lookup = clkdm_lookup,
+};
+
 /*
  * GPIOs for TWL are initialized by the I2C bus and need custom
  * handing until DSS has device tree bindings.
@@ -492,10 +504,6 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
                       &wkup_m3_data),
 #endif
 #if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5)
-       OF_DEV_AUXDATA("ti,omap4-iommu", 0x4a066000, "4a066000.mmu",
-                      &omap4_iommu_pdata),
-       OF_DEV_AUXDATA("ti,omap4-iommu", 0x55082000, "55082000.mmu",
-                      &omap4_iommu_pdata),
        OF_DEV_AUXDATA("ti,omap4-smartreflex-iva", 0x4a0db000,
                       "4a0db000.smartreflex", &omap_sr_pdata[OMAP_SR_IVA]),
        OF_DEV_AUXDATA("ti,omap4-smartreflex-core", 0x4a0dd000,
@@ -510,10 +518,18 @@ static struct of_dev_auxdata omap_auxdata_lookup[] = {
                       &dra7_hsmmc_data_mmc2),
        OF_DEV_AUXDATA("ti,dra7-hsmmc", 0x480ad000, "480ad000.mmc",
                       &dra7_hsmmc_data_mmc3),
+       OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x40d01000, "40d01000.mmu",
+                      &dra7_ipu1_dsp_iommu_pdata),
+       OF_DEV_AUXDATA("ti,dra7-dsp-iommu", 0x41501000, "41501000.mmu",
+                      &dra7_ipu1_dsp_iommu_pdata),
+       OF_DEV_AUXDATA("ti,dra7-iommu", 0x58882000, "58882000.mmu",
+                      &dra7_ipu1_dsp_iommu_pdata),
 #endif
        /* Common auxdata */
        OF_DEV_AUXDATA("ti,sysc", 0, NULL, &ti_sysc_pdata),
        OF_DEV_AUXDATA("pinctrl-single", 0, NULL, &pcs_pdata),
+       OF_DEV_AUXDATA("ti,omap-prm-inst", 0, NULL, &ti_prm_pdata),
+       OF_DEV_AUXDATA("ti,omap-sdma", 0, NULL, &dma_plat_info),
        { /* sentinel */ },
 };
 
index 1581b6a..6953c47 100644 (file)
@@ -83,8 +83,6 @@ static int omap2_enter_full_retention(void)
        l = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0) | OMAP24XX_USBSTANDBYCTRL;
        omap_ctrl_writel(l, OMAP2_CONTROL_DEVCONF0);
 
-       cpu_cluster_pm_enter();
-
        /* One last check for pending IRQs to avoid extra latency due
         * to sleeping unnecessarily. */
        if (omap_irq_pending())
@@ -96,8 +94,6 @@ static int omap2_enter_full_retention(void)
                           OMAP_SDRC_REGADDR(SDRC_POWER));
 
 no_sleep:
-       cpu_cluster_pm_exit();
-
        clk_enable(osc_ck);
 
        /* clear CORE wake-up events */
@@ -162,25 +158,27 @@ static int omap2_can_sleep(void)
                return 0;
        if (__clk_is_enabled(osc_ck))
                return 0;
-       if (omap_dma_running())
-               return 0;
 
        return 1;
 }
 
 static void omap2_pm_idle(void)
 {
-       if (!omap2_can_sleep()) {
-               if (omap_irq_pending())
-                       return;
-               omap2_enter_mpu_retention();
-               return;
-       }
+       int error;
 
        if (omap_irq_pending())
                return;
 
+       error = cpu_cluster_pm_enter();
+       if (error || !omap2_can_sleep()) {
+               omap2_enter_mpu_retention();
+               goto out_cpu_cluster_pm;
+       }
+
        omap2_enter_full_retention();
+
+out_cpu_cluster_pm:
+       cpu_cluster_pm_exit();
 }
 
 static void __init prcm_setup_regs(void)
index f11442e..7461b03 100644 (file)
@@ -28,6 +28,7 @@
 #include "prm33xx.h"
 #include "soc.h"
 #include "sram.h"
+#include "omap-secure.h"
 
 static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
 static struct clockdomain *gfx_l4ls_clkdm;
@@ -166,6 +167,16 @@ static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
 {
        int ret = 0;
 
+       /* Suspend secure side on HS devices */
+       if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
+               if (optee_available)
+                       omap_smccc_smc(AM43xx_PPA_SVC_PM_SUSPEND, 0);
+               else
+                       omap_secure_dispatcher(AM43xx_PPA_SVC_PM_SUSPEND,
+                                              FLAG_START_CRITICAL,
+                                              0, 0, 0, 0, 0);
+       }
+
        amx3_pre_suspend_common();
        scu_power_mode(scu_base, SCU_PM_POWEROFF);
        ret = cpu_suspend(args, fn);
@@ -174,6 +185,19 @@ static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
        if (!am43xx_check_off_mode_enable())
                amx3_post_suspend_common();
 
+       /*
+        * Resume secure side on HS devices.
+        *
+        * Note that even on systems with OP-TEE available this resume call is
+        * issued to the ROM. This is because upon waking from suspend the ROM
+        * is restored as the secure monitor. On systems with OP-TEE ROM will
+        * restore OP-TEE during this call.
+        */
+       if (omap_type() != OMAP2_DEVICE_TYPE_GP)
+               omap_secure_dispatcher(AM43xx_PPA_SVC_PM_RESUME,
+                                      FLAG_START_CRITICAL,
+                                      0, 0, 0, 0, 0);
+
        return ret;
 }
 
index 54254fc..e66e994 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/slab.h>
-#include <linux/omap-dma.h>
 #include <linux/omap-gpmc.h>
 
 #include <trace/events/power.h>
@@ -85,7 +84,6 @@ static void omap3_core_save_context(void)
        omap3_gpmc_save_context();
        /* Save the system control module context, padconf already save above*/
        omap3_control_save_context();
-       omap_dma_global_context_save();
 }
 
 static void omap3_core_restore_context(void)
@@ -96,7 +94,6 @@ static void omap3_core_restore_context(void)
        omap3_gpmc_restore_context();
        /* Restore the interrupt controller context */
        omap_intc_restore_context();
-       omap_dma_global_context_restore();
 }
 
 /*
@@ -547,9 +544,7 @@ int __init omap3_pm_init(void)
 
                local_irq_disable();
 
-               omap_dma_global_context_save();
                omap3_save_secure_ram_context();
-               omap_dma_global_context_restore();
 
                local_irq_enable();
        }
index e2ad14e..7078a61 100644 (file)
@@ -68,6 +68,7 @@
 #define AM43XX_CM_PER_ICSS_CDOFFS                      0x0300
 #define AM43XX_CM_PER_L4LS_CDOFFS                      0x0400
 #define AM43XX_CM_PER_EMIF_CDOFFS                      0x0700
+#define AM43XX_CM_PER_LCDC_CDOFFS                      0x0800
 #define AM43XX_CM_PER_DSS_CDOFFS                       0x0a00
 #define AM43XX_CM_PER_CPSW_CDOFFS                      0x0b00
 #define AM43XX_CM_PER_OCPWP_L3_CDOFFS                  0x0c00
index 686f0bb..c5c06d9 100644 (file)
@@ -19,12 +19,12 @@ config PLAT_S3C24XX
 
 
 
-menu "SAMSUNG S3C24XX SoCs Support"
+menu "Samsung S3C24XX SoCs Support"
 
 comment "S3C24XX SoCs"
 
 config CPU_S3C2410
-       bool "SAMSUNG S3C2410"
+       bool "Samsung S3C2410"
        default y
        select CPU_ARM920T
        select S3C2410_COMMON_CLK
@@ -35,7 +35,7 @@ config CPU_S3C2410
          of Samsung Mobile CPUs.
 
 config CPU_S3C2412
-       bool "SAMSUNG S3C2412"
+       bool "Samsung S3C2412"
        select CPU_ARM926T
        select S3C2412_COMMON_CLK
        select S3C2412_PM if PM_SLEEP
@@ -43,7 +43,7 @@ config CPU_S3C2412
          Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
 
 config CPU_S3C2416
-       bool "SAMSUNG S3C2416/S3C2450"
+       bool "Samsung S3C2416/S3C2450"
        select CPU_ARM926T
        select S3C2416_PM if PM_SLEEP
        select S3C2443_COMMON_CLK
@@ -51,7 +51,7 @@ config CPU_S3C2416
          Support for the S3C2416 SoC from the S3C24XX line
 
 config CPU_S3C2440
-       bool "SAMSUNG S3C2440"
+       bool "Samsung S3C2440"
        select CPU_ARM920T
        select S3C2410_COMMON_CLK
        select S3C2410_PM if PM_SLEEP
@@ -59,7 +59,7 @@ config CPU_S3C2440
          Support for S3C2440 Samsung Mobile CPU based systems.
 
 config CPU_S3C2442
-       bool "SAMSUNG S3C2442"
+       bool "Samsung S3C2442"
        select CPU_ARM920T
        select S3C2410_COMMON_CLK
        select S3C2410_PM if PM_SLEEP
@@ -71,7 +71,7 @@ config CPU_S3C244X
        depends on CPU_S3C2440 || CPU_S3C2442
 
 config CPU_S3C2443
-       bool "SAMSUNG S3C2443"
+       bool "Samsung S3C2443"
        select CPU_ARM920T
        select S3C2443_COMMON_CLK
        help
@@ -591,6 +591,6 @@ config PM_H1940
        help
          Internal node for H1940 and related PM
 
-endmenu        # SAMSUNG S3C24XX SoCs Support
+endmenu        # Samsung S3C24XX SoCs Support
 
 endif  # ARCH_S3C24XX
index 29f9b34..03d8f27 100644 (file)
@@ -377,6 +377,7 @@ static struct pwm_lookup rx1950_pwm_lookup[] = {
 };
 
 static struct pwm_device *lcd_pwm;
+static struct pwm_state lcd_pwm_state;
 
 static void rx1950_lcd_power(int enable)
 {
@@ -429,15 +430,16 @@ static void rx1950_lcd_power(int enable)
 
                /* GPB1->OUTPUT, GPB1->0 */
                gpio_direction_output(S3C2410_GPB(1), 0);
-               pwm_config(lcd_pwm, 0, LCD_PWM_PERIOD);
-               pwm_disable(lcd_pwm);
+
+               lcd_pwm_state.enabled = false;
+               pwm_apply_state(lcd_pwm, &lcd_pwm_state);
 
                /* GPC0->0, GPC10->0 */
                gpio_direction_output(S3C2410_GPC(0), 0);
                gpio_direction_output(S3C2410_GPC(10), 0);
        } else {
-               pwm_config(lcd_pwm, LCD_PWM_DUTY, LCD_PWM_PERIOD);
-               pwm_enable(lcd_pwm);
+               lcd_pwm_state.enabled = true;
+               pwm_apply_state(lcd_pwm, &lcd_pwm_state);
 
                gpio_direction_output(S3C2410_GPC(0), 1);
                gpio_direction_output(S3C2410_GPC(5), 1);
@@ -493,10 +495,13 @@ static int rx1950_backlight_init(struct device *dev)
        }
 
        /*
-        * FIXME: pwm_apply_args() should be removed when switching to
-        * the atomic PWM API.
+        * This is only required to initialize .polarity; all other values are
+        * fixed in this driver.
         */
-       pwm_apply_args(lcd_pwm);
+       pwm_init_state(lcd_pwm, &lcd_pwm_state);
+
+       lcd_pwm_state.period = LCD_PWM_PERIOD;
+       lcd_pwm_state.duty_cycle = LCD_PWM_DUTY;
 
        rx1950_lcd_power(1);
        rx1950_bl_power(1);
index 5700822..ac3e356 100644 (file)
@@ -336,7 +336,6 @@ config MACH_WLF_CRAGG_6410
 
 config MACH_S3C64XX_DT
        bool "Samsung S3C6400/S3C6410 machine using Device Tree"
-       select TIMER_OF
        select CPU_S3C6400
        select CPU_S3C6410
        select PINCTRL
index 3341a12..02cc6ff 100644 (file)
@@ -59,6 +59,9 @@
 #define CLK_RESET_PLLX_MISC3_IDDQ      3
 #define CLK_RESET_PLLM_MISC_IDDQ       5
 #define CLK_RESET_PLLC_MISC_IDDQ       26
+#define CLK_RESET_PLLP_RESHIFT         0x528
+#define CLK_RESET_PLLP_RESHIFT_DEFAULT 0x3b
+#define CLK_RESET_PLLP_RESHIFT_ENABLE  0x3
 
 #define CLK_RESET_CLK_SOURCE_MSELECT   0x3b4
 
@@ -370,6 +373,18 @@ _pll_m_c_x_done:
        pll_locked r1, r0, CLK_RESET_PLLC_BASE
        pll_locked r1, r0, CLK_RESET_PLLX_BASE
 
+       tegra_get_soc_id TEGRA_APB_MISC_BASE, r1
+       cmp     r1, #TEGRA30
+       beq     1f
+
+       ldr     r1, [r0, #CLK_RESET_PLLP_BASE]
+       bic     r1, r1, #(1<<31)        @ disable PllP bypass
+       str     r1, [r0, #CLK_RESET_PLLP_BASE]
+
+       mov     r1, #CLK_RESET_PLLP_RESHIFT_DEFAULT
+       str     r1, [r0, #CLK_RESET_PLLP_RESHIFT]
+1:
+
        mov32   r7, TEGRA_TMRUS_BASE
        ldr     r1, [r7]
        add     r1, r1, #LOCK_DELAY
@@ -630,9 +645,16 @@ tegra30_switch_cpu_to_clk32k:
        str     r0, [r4, #PMC_PLLP_WB0_OVERRIDE]
 
        /* disable PLLP, PLLA, PLLC and PLLX */
+       tegra_get_soc_id TEGRA_APB_MISC_BASE, r1
+       cmp     r1, #TEGRA30
        ldr     r0, [r5, #CLK_RESET_PLLP_BASE]
+       orrne   r0, r0, #(1 << 31)      @ enable PllP bypass on fast cluster
        bic     r0, r0, #(1 << 30)
        str     r0, [r5, #CLK_RESET_PLLP_BASE]
+       beq     1f
+       mov     r0, #CLK_RESET_PLLP_RESHIFT_ENABLE
+       str     r0, [r5, #CLK_RESET_PLLP_RESHIFT]
+1:
        ldr     r0, [r5, #CLK_RESET_PLLA_BASE]
        bic     r0, r0, #(1 << 30)
        str     r0, [r5, #CLK_RESET_PLLA_BASE]
@@ -648,8 +670,12 @@ tegra30_switch_cpu_to_clk32k:
        pll_iddq_entry r1, r5, CLK_RESET_PLLX_MISC3, CLK_RESET_PLLX_MISC3_IDDQ
 _no_pll_in_iddq:
 
-       /* switch to CLKS */
-       mov     r0, #0  /* brust policy = 32KHz */
+       /*
+        * Switch to clk_s (32KHz); bits 28:31=0
+        * Enable burst on CPU IRQ; bit 24=1
+        * Set IRQ burst clock source to clk_m; bits 10:8=0
+        */
+       mov     r0, #(1 << 24)
        str     r0, [r5, #CLK_RESET_SCLK_BURST]
 
        ret     lr
index a10085b..68ec303 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/init.h>
 #include <linux/io.h>
 #include <asm/cacheflush.h>
+#include <asm/smp_plat.h>
 #include <asm/smp_scu.h>
 #include <linux/irqchip/arm-gic.h>
 #include "common.h"
@@ -30,6 +31,7 @@ int zynq_cpun_start(u32 address, int cpu)
 {
        u32 trampoline_code_size = &zynq_secondary_trampoline_end -
                                                &zynq_secondary_trampoline;
+       u32 phy_cpuid = cpu_logical_map(cpu);
 
        /* MS: Expectation that SLCR are directly map and accessible */
        /* Not possible to jump to non aligned address */
@@ -39,7 +41,7 @@ int zynq_cpun_start(u32 address, int cpu)
                u32 trampoline_size = &zynq_secondary_trampoline_jump -
                                                &zynq_secondary_trampoline;
 
-               zynq_slcr_cpu_stop(cpu);
+               zynq_slcr_cpu_stop(phy_cpuid);
                if (address) {
                        if (__pa(PAGE_OFFSET)) {
                                zero = ioremap(0, trampoline_code_size);
@@ -68,7 +70,7 @@ int zynq_cpun_start(u32 address, int cpu)
                        if (__pa(PAGE_OFFSET))
                                iounmap(zero);
                }
-               zynq_slcr_cpu_start(cpu);
+               zynq_slcr_cpu_start(phy_cpuid);
 
                return 0;
        }
index 788c5cf..84718ed 100644 (file)
@@ -162,12 +162,12 @@ static ssize_t alignment_proc_write(struct file *file, const char __user *buffer
        return count;
 }
 
-static const struct file_operations alignment_proc_fops = {
-       .open           = alignment_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = alignment_proc_write,
+static const struct proc_ops alignment_proc_ops = {
+       .proc_open      = alignment_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = alignment_proc_write,
 };
 #endif /* CONFIG_PROC_FS */
 
@@ -1016,7 +1016,7 @@ static int __init alignment_init(void)
        struct proc_dir_entry *res;
 
        res = proc_create("cpu/alignment", S_IWUSR | S_IRUGO, NULL,
-                         &alignment_proc_fops);
+                         &alignment_proc_ops);
        if (!res)
                return -ENOMEM;
 #endif
index e822af0..9414d72 100644 (file)
@@ -221,7 +221,7 @@ EXPORT_SYMBOL(arm_coherent_dma_ops);
 
 static int __dma_supported(struct device *dev, u64 mask, bool warn)
 {
-       unsigned long max_dma_pfn = min(max_pfn, arm_dma_pfn_limit);
+       unsigned long max_dma_pfn = min(max_pfn - 1, arm_dma_pfn_limit);
 
        /*
         * Translate the device's DMA mask to a PFN limit.  This
index 3ef2041..054be44 100644 (file)
@@ -324,7 +324,7 @@ static inline void poison_init_mem(void *s, size_t count)
                *p++ = 0xe7fddef0;
 }
 
-static inline void
+static inline void __init
 free_memmap(unsigned long start_pfn, unsigned long end_pfn)
 {
        struct page *start_pg, *end_pg;
index 08c9941..7d85999 100644 (file)
@@ -65,18 +65,9 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
 static struct omap_system_dma_plat_info *p;
 static struct omap_dma_dev_attr *d;
 static void omap_clear_dma(int lch);
-static int omap_dma_set_prio_lch(int lch, unsigned char read_prio,
-                                unsigned char write_prio);
 static int enable_1510_mode;
 static u32 errata;
 
-static struct omap_dma_global_context_registers {
-       u32 dma_irqenable_l0;
-       u32 dma_irqenable_l1;
-       u32 dma_ocp_sysconfig;
-       u32 dma_gcr;
-} omap_dma_global_context;
-
 struct dma_link_info {
        int *linked_dmach_q;
        int no_of_lchs_linked;
@@ -90,42 +81,6 @@ struct dma_link_info {
 
 };
 
-static struct dma_link_info *dma_linked_lch;
-
-#ifndef CONFIG_ARCH_OMAP1
-
-/* Chain handling macros */
-#define OMAP_DMA_CHAIN_QINIT(chain_id)                                 \
-       do {                                                            \
-               dma_linked_lch[chain_id].q_head =                       \
-               dma_linked_lch[chain_id].q_tail =                       \
-               dma_linked_lch[chain_id].q_count = 0;                   \
-       } while (0)
-#define OMAP_DMA_CHAIN_QFULL(chain_id)                                 \
-               (dma_linked_lch[chain_id].no_of_lchs_linked ==          \
-               dma_linked_lch[chain_id].q_count)
-#define OMAP_DMA_CHAIN_QLAST(chain_id)                                 \
-       do {                                                            \
-               ((dma_linked_lch[chain_id].no_of_lchs_linked-1) ==      \
-               dma_linked_lch[chain_id].q_count)                       \
-       } while (0)
-#define OMAP_DMA_CHAIN_QEMPTY(chain_id)                                        \
-               (0 == dma_linked_lch[chain_id].q_count)
-#define __OMAP_DMA_CHAIN_INCQ(end)                                     \
-       ((end) = ((end)+1) % dma_linked_lch[chain_id].no_of_lchs_linked)
-#define OMAP_DMA_CHAIN_INCQHEAD(chain_id)                              \
-       do {                                                            \
-               __OMAP_DMA_CHAIN_INCQ(dma_linked_lch[chain_id].q_head); \
-               dma_linked_lch[chain_id].q_count--;                     \
-       } while (0)
-
-#define OMAP_DMA_CHAIN_INCQTAIL(chain_id)                              \
-       do {                                                            \
-               __OMAP_DMA_CHAIN_INCQ(dma_linked_lch[chain_id].q_tail); \
-               dma_linked_lch[chain_id].q_count++; \
-       } while (0)
-#endif
-
 static int dma_lch_count;
 static int dma_chan_count;
 static int omap_dma_reserve_channels;
@@ -137,9 +92,6 @@ static inline void disable_lnk(int lch);
 static void omap_disable_channel_irq(int lch);
 static inline void omap_enable_channel_irq(int lch);
 
-#define REVISIT_24XX()         printk(KERN_ERR "FIXME: no %s on 24xx\n", \
-                                               __func__);
-
 #ifdef CONFIG_ARCH_OMAP15XX
 /* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
 static int omap_dma_in_1510_mode(void)
@@ -278,19 +230,6 @@ void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 }
 EXPORT_SYMBOL(omap_set_dma_transfer_params);
 
-void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
-{
-       if (dma_omap2plus()) {
-               u32 csdp;
-
-               csdp = p->dma_read(CSDP, lch);
-               csdp &= ~(0x3 << 16);
-               csdp |= (mode << 16);
-               p->dma_write(csdp, CSDP, lch);
-       }
-}
-EXPORT_SYMBOL(omap_set_dma_write_mode);
-
 void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode)
 {
        if (dma_omap1() && !dma_omap15xx()) {
@@ -332,25 +271,6 @@ void omap_set_dma_src_params(int lch, int src_port, int src_amode,
 }
 EXPORT_SYMBOL(omap_set_dma_src_params);
 
-void omap_set_dma_params(int lch, struct omap_dma_channel_params *params)
-{
-       omap_set_dma_transfer_params(lch, params->data_type,
-                                    params->elem_count, params->frame_count,
-                                    params->sync_mode, params->trigger,
-                                    params->src_or_dst_synch);
-       omap_set_dma_src_params(lch, params->src_port,
-                               params->src_amode, params->src_start,
-                               params->src_ei, params->src_fi);
-
-       omap_set_dma_dest_params(lch, params->dst_port,
-                                params->dst_amode, params->dst_start,
-                                params->dst_ei, params->dst_fi);
-       if (params->read_prio || params->write_prio)
-               omap_dma_set_prio_lch(lch, params->read_prio,
-                                     params->write_prio);
-}
-EXPORT_SYMBOL(omap_set_dma_params);
-
 void omap_set_dma_src_data_pack(int lch, int enable)
 {
        u32 l;
@@ -507,12 +427,6 @@ static inline void omap_disable_channel_irq(int lch)
                p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, lch);
 }
 
-void omap_enable_dma_irq(int lch, u16 bits)
-{
-       dma_chan[lch].enabled_irqs |= bits;
-}
-EXPORT_SYMBOL(omap_enable_dma_irq);
-
 void omap_disable_dma_irq(int lch, u16 bits)
 {
        dma_chan[lch].enabled_irqs &= ~bits;
@@ -532,12 +446,6 @@ static inline void enable_lnk(int lch)
        if (dma_chan[lch].next_lch != -1)
                l = dma_chan[lch].next_lch | (1 << 15);
 
-#ifndef CONFIG_ARCH_OMAP1
-       if (dma_omap2plus())
-               if (dma_chan[lch].next_linked_ch != -1)
-                       l = dma_chan[lch].next_linked_ch | (1 << 15);
-#endif
-
        p->dma_write(l, CLNK_CTRL, lch);
 }
 
@@ -564,42 +472,6 @@ static inline void disable_lnk(int lch)
        dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 }
 
-static inline void omap2_enable_irq_lch(int lch)
-{
-       u32 val;
-       unsigned long flags;
-
-       if (dma_omap1())
-               return;
-
-       spin_lock_irqsave(&dma_chan_lock, flags);
-       /* clear IRQ STATUS */
-       p->dma_write(1 << lch, IRQSTATUS_L0, lch);
-       /* Enable interrupt */
-       val = p->dma_read(IRQENABLE_L0, lch);
-       val |= 1 << lch;
-       p->dma_write(val, IRQENABLE_L0, lch);
-       spin_unlock_irqrestore(&dma_chan_lock, flags);
-}
-
-static inline void omap2_disable_irq_lch(int lch)
-{
-       u32 val;
-       unsigned long flags;
-
-       if (dma_omap1())
-               return;
-
-       spin_lock_irqsave(&dma_chan_lock, flags);
-       /* Disable interrupt */
-       val = p->dma_read(IRQENABLE_L0, lch);
-       val &= ~(1 << lch);
-       p->dma_write(val, IRQENABLE_L0, lch);
-       /* clear IRQ STATUS */
-       p->dma_write(1 << lch, IRQSTATUS_L0, lch);
-       spin_unlock_irqrestore(&dma_chan_lock, flags);
-}
-
 int omap_request_dma(int dev_id, const char *dev_name,
                     void (*callback)(int lch, u16 ch_status, void *data),
                     void *data, int *dma_ch_out)
@@ -628,9 +500,6 @@ int omap_request_dma(int dev_id, const char *dev_name,
        if (p->clear_lch_regs)
                p->clear_lch_regs(free_ch);
 
-       if (dma_omap2plus())
-               omap_clear_dma(free_ch);
-
        spin_unlock_irqrestore(&dma_chan_lock, flags);
 
        chan->dev_name = dev_name;
@@ -638,20 +507,10 @@ int omap_request_dma(int dev_id, const char *dev_name,
        chan->data = data;
        chan->flags = 0;
 
-#ifndef CONFIG_ARCH_OMAP1
-       if (dma_omap2plus()) {
-               chan->chain_id = -1;
-               chan->next_linked_ch = -1;
-       }
-#endif
-
        chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
 
        if (dma_omap1())
                chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ;
-       else if (dma_omap2plus())
-               chan->enabled_irqs |= OMAP2_DMA_MISALIGNED_ERR_IRQ |
-                       OMAP2_DMA_TRANS_ERR_IRQ;
 
        if (dma_omap16xx()) {
                /* If the sync device is set, configure it dynamically. */
@@ -668,11 +527,6 @@ int omap_request_dma(int dev_id, const char *dev_name,
                p->dma_write(dev_id, CCR, free_ch);
        }
 
-       if (dma_omap2plus()) {
-               omap_enable_channel_irq(free_ch);
-               omap2_enable_irq_lch(free_ch);
-       }
-
        *dma_ch_out = free_ch;
 
        return 0;
@@ -689,20 +543,12 @@ void omap_free_dma(int lch)
                return;
        }
 
-       /* Disable interrupt for logical channel */
-       if (dma_omap2plus())
-               omap2_disable_irq_lch(lch);
-
        /* Disable all DMA interrupts for the channel. */
        omap_disable_channel_irq(lch);
 
        /* Make sure the DMA transfer is stopped. */
        p->dma_write(0, CCR, lch);
 
-       /* Clear registers */
-       if (dma_omap2plus())
-               omap_clear_dma(lch);
-
        spin_lock_irqsave(&dma_chan_lock, flags);
        dma_chan[lch].dev_id = -1;
        dma_chan[lch].next_lch = -1;
@@ -711,71 +557,6 @@ void omap_free_dma(int lch)
 }
 EXPORT_SYMBOL(omap_free_dma);
 
-/**
- * @brief omap_dma_set_global_params : Set global priority settings for dma
- *
- * @param arb_rate
- * @param max_fifo_depth
- * @param tparams - Number of threads to reserve : DMA_THREAD_RESERVE_NORM
- *                                                DMA_THREAD_RESERVE_ONET
- *                                                DMA_THREAD_RESERVE_TWOT
- *                                                DMA_THREAD_RESERVE_THREET
- */
-void
-omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
-{
-       u32 reg;
-
-       if (dma_omap1()) {
-               printk(KERN_ERR "FIXME: no %s on 15xx/16xx\n", __func__);
-               return;
-       }
-
-       if (max_fifo_depth == 0)
-               max_fifo_depth = 1;
-       if (arb_rate == 0)
-               arb_rate = 1;
-
-       reg = 0xff & max_fifo_depth;
-       reg |= (0x3 & tparams) << 12;
-       reg |= (arb_rate & 0xff) << 16;
-
-       p->dma_write(reg, GCR, 0);
-}
-EXPORT_SYMBOL(omap_dma_set_global_params);
-
-/**
- * @brief omap_dma_set_prio_lch : Set channel wise priority settings
- *
- * @param lch
- * @param read_prio - Read priority
- * @param write_prio - Write priority
- * Both of the above can be set with one of the following values :
- *     DMA_CH_PRIO_HIGH/DMA_CH_PRIO_LOW
- */
-static int
-omap_dma_set_prio_lch(int lch, unsigned char read_prio,
-                     unsigned char write_prio)
-{
-       u32 l;
-
-       if (unlikely((lch < 0 || lch >= dma_lch_count))) {
-               printk(KERN_ERR "Invalid channel id\n");
-               return -EINVAL;
-       }
-       l = p->dma_read(CCR, lch);
-       l &= ~((1 << 6) | (1 << 26));
-       if (d->dev_caps & IS_RW_PRIORITY)
-               l |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
-       else
-               l |= ((read_prio & 0x1) << 6);
-
-       p->dma_write(l, CCR, lch);
-
-       return 0;
-}
-
-
 /*
  * Clears any DMA state so the DMA engine is ready to restart with new buffers
  * through omap_start_dma(). Any buffers in flight are discarded.
@@ -926,29 +707,6 @@ EXPORT_SYMBOL(omap_stop_dma);
  * Allows changing the DMA callback function or data. This may be needed if
  * the driver shares a single DMA channel for multiple dma triggers.
  */
-int omap_set_dma_callback(int lch,
-                         void (*callback)(int lch, u16 ch_status, void *data),
-                         void *data)
-{
-       unsigned long flags;
-
-       if (lch < 0)
-               return -ENODEV;
-
-       spin_lock_irqsave(&dma_chan_lock, flags);
-       if (dma_chan[lch].dev_id == -1) {
-               printk(KERN_ERR "DMA callback for not set for free channel\n");
-               spin_unlock_irqrestore(&dma_chan_lock, flags);
-               return -EINVAL;
-       }
-       dma_chan[lch].callback = callback;
-       dma_chan[lch].data = data;
-       spin_unlock_irqrestore(&dma_chan_lock, flags);
-
-       return 0;
-}
-EXPORT_SYMBOL(omap_set_dma_callback);
-
 /*
  * Returns current physical source address for the given DMA channel.
  * If the channel is running the caller must disable interrupts prior calling
@@ -1048,34 +806,6 @@ int omap_dma_running(void)
        return 0;
 }
 
-/*
- * lch_queue DMA will start right after lch_head one is finished.
- * For this DMA link to start, you still need to start (see omap_start_dma)
- * the first one. That will fire up the entire queue.
- */
-void omap_dma_link_lch(int lch_head, int lch_queue)
-{
-       if (omap_dma_in_1510_mode()) {
-               if (lch_head == lch_queue) {
-                       p->dma_write(p->dma_read(CCR, lch_head) | (3 << 8),
-                                                               CCR, lch_head);
-                       return;
-               }
-               printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
-               BUG();
-               return;
-       }
-
-       if ((dma_chan[lch_head].dev_id == -1) ||
-           (dma_chan[lch_queue].dev_id == -1)) {
-               pr_err("omap_dma: trying to link non requested channels\n");
-               dump_stack();
-       }
-
-       dma_chan[lch_head].next_lch = lch_queue;
-}
-EXPORT_SYMBOL(omap_dma_link_lch);
-
 /*----------------------------------------------------------------------------*/
 
 #ifdef CONFIG_ARCH_OMAP1
@@ -1136,145 +866,6 @@ static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
 #define omap1_dma_irq_handler  NULL
 #endif
 
-#ifdef CONFIG_ARCH_OMAP2PLUS
-
-static int omap2_dma_handle_ch(int ch)
-{
-       u32 status = p->dma_read(CSR, ch);
-
-       if (!status) {
-               if (printk_ratelimit())
-                       pr_warn("Spurious DMA IRQ for lch %d\n", ch);
-               p->dma_write(1 << ch, IRQSTATUS_L0, ch);
-               return 0;
-       }
-       if (unlikely(dma_chan[ch].dev_id == -1)) {
-               if (printk_ratelimit())
-                       pr_warn("IRQ %04x for non-allocated DMA channel %d\n",
-                               status, ch);
-               return 0;
-       }
-       if (unlikely(status & OMAP_DMA_DROP_IRQ))
-               pr_info("DMA synchronization event drop occurred with device %d\n",
-                       dma_chan[ch].dev_id);
-       if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ)) {
-               printk(KERN_INFO "DMA transaction error with device %d\n",
-                      dma_chan[ch].dev_id);
-               if (IS_DMA_ERRATA(DMA_ERRATA_i378)) {
-                       u32 ccr;
-
-                       ccr = p->dma_read(CCR, ch);
-                       ccr &= ~OMAP_DMA_CCR_EN;
-                       p->dma_write(ccr, CCR, ch);
-                       dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
-               }
-       }
-       if (unlikely(status & OMAP2_DMA_SECURE_ERR_IRQ))
-               printk(KERN_INFO "DMA secure error with device %d\n",
-                      dma_chan[ch].dev_id);
-       if (unlikely(status & OMAP2_DMA_MISALIGNED_ERR_IRQ))
-               printk(KERN_INFO "DMA misaligned error with device %d\n",
-                      dma_chan[ch].dev_id);
-
-       p->dma_write(status, CSR, ch);
-       p->dma_write(1 << ch, IRQSTATUS_L0, ch);
-       /* read back the register to flush the write */
-       p->dma_read(IRQSTATUS_L0, ch);
-
-       /* If the ch is not chained then chain_id will be -1 */
-       if (dma_chan[ch].chain_id != -1) {
-               int chain_id = dma_chan[ch].chain_id;
-               dma_chan[ch].state = DMA_CH_NOTSTARTED;
-               if (p->dma_read(CLNK_CTRL, ch) & (1 << 15))
-                       dma_chan[dma_chan[ch].next_linked_ch].state =
-                                                       DMA_CH_STARTED;
-               if (dma_linked_lch[chain_id].chain_mode ==
-                                               OMAP_DMA_DYNAMIC_CHAIN)
-                       disable_lnk(ch);
-
-               if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
-                       OMAP_DMA_CHAIN_INCQHEAD(chain_id);
-
-               status = p->dma_read(CSR, ch);
-               p->dma_write(status, CSR, ch);
-       }
-
-       if (likely(dma_chan[ch].callback != NULL))
-               dma_chan[ch].callback(ch, status, dma_chan[ch].data);
-
-       return 0;
-}
-
-/* STATUS register count is from 1-32 while our is 0-31 */
-static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
-{
-       u32 val, enable_reg;
-       int i;
-
-       val = p->dma_read(IRQSTATUS_L0, 0);
-       if (val == 0) {
-               if (printk_ratelimit())
-                       printk(KERN_WARNING "Spurious DMA IRQ\n");
-               return IRQ_HANDLED;
-       }
-       enable_reg = p->dma_read(IRQENABLE_L0, 0);
-       val &= enable_reg; /* Dispatch only relevant interrupts */
-       for (i = 0; i < dma_lch_count && val != 0; i++) {
-               if (val & 1)
-                       omap2_dma_handle_ch(i);
-               val >>= 1;
-       }
-
-       return IRQ_HANDLED;
-}
-
-static struct irqaction omap24xx_dma_irq = {
-       .name = "DMA",
-       .handler = omap2_dma_irq_handler,
-};
-
-#else
-static struct irqaction omap24xx_dma_irq;
-#endif
-
-/*----------------------------------------------------------------------------*/
-
-/*
- * Note that we are currently using only IRQENABLE_L0 and L1.
- * As the DSP may be using IRQENABLE_L2 and L3, let's not
- * touch those for now.
- */
-void omap_dma_global_context_save(void)
-{
-       omap_dma_global_context.dma_irqenable_l0 =
-               p->dma_read(IRQENABLE_L0, 0);
-       omap_dma_global_context.dma_irqenable_l1 =
-               p->dma_read(IRQENABLE_L1, 0);
-       omap_dma_global_context.dma_ocp_sysconfig =
-               p->dma_read(OCP_SYSCONFIG, 0);
-       omap_dma_global_context.dma_gcr = p->dma_read(GCR, 0);
-}
-
-void omap_dma_global_context_restore(void)
-{
-       int ch;
-
-       p->dma_write(omap_dma_global_context.dma_gcr, GCR, 0);
-       p->dma_write(omap_dma_global_context.dma_ocp_sysconfig,
-               OCP_SYSCONFIG, 0);
-       p->dma_write(omap_dma_global_context.dma_irqenable_l0,
-               IRQENABLE_L0, 0);
-       p->dma_write(omap_dma_global_context.dma_irqenable_l1,
-               IRQENABLE_L1, 0);
-
-       if (IS_DMA_ERRATA(DMA_ROMCODE_BUG))
-               p->dma_write(0x3 , IRQSTATUS_L0, 0);
-
-       for (ch = 0; ch < dma_chan_count; ch++)
-               if (dma_chan[ch].dev_id != -1)
-                       omap_clear_dma(ch);
-}
-
 struct omap_system_dma_plat_info *omap_get_plat_info(void)
 {
        return p;
@@ -1286,7 +877,6 @@ static int omap_system_dma_probe(struct platform_device *pdev)
        int ch, ret = 0;
        int dma_irq;
        char irq_name[4];
-       int irq_rel;
 
        p = pdev->dev.platform_data;
        if (!p) {
@@ -1312,21 +902,9 @@ static int omap_system_dma_probe(struct platform_device *pdev)
        if (!dma_chan)
                return -ENOMEM;
 
-       if (dma_omap2plus()) {
-               dma_linked_lch = kcalloc(dma_lch_count,
-                                        sizeof(*dma_linked_lch),
-                                        GFP_KERNEL);
-               if (!dma_linked_lch) {
-                       ret = -ENOMEM;
-                       goto exit_dma_lch_fail;
-               }
-       }
-
        spin_lock_init(&dma_chan_lock);
        for (ch = 0; ch < dma_chan_count; ch++) {
                omap_clear_dma(ch);
-               if (dma_omap2plus())
-                       omap2_disable_irq_lch(ch);
 
                dma_chan[ch].dev_id = -1;
                dma_chan[ch].next_lch = -1;
@@ -1359,26 +937,6 @@ static int omap_system_dma_probe(struct platform_device *pdev)
                }
        }
 
-       if (d->dev_caps & IS_RW_PRIORITY)
-               omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE,
-                               DMA_DEFAULT_FIFO_DEPTH, 0);
-
-       if (dma_omap2plus() && !(d->dev_caps & DMA_ENGINE_HANDLE_IRQ)) {
-               strcpy(irq_name, "0");
-               dma_irq = platform_get_irq_byname(pdev, irq_name);
-               if (dma_irq < 0) {
-                       dev_err(&pdev->dev, "failed: request IRQ %d", dma_irq);
-                       ret = dma_irq;
-                       goto exit_dma_lch_fail;
-               }
-               ret = setup_irq(dma_irq, &omap24xx_dma_irq);
-               if (ret) {
-                       dev_err(&pdev->dev, "set_up failed for IRQ %d for DMA (error %d)\n",
-                               dma_irq, ret);
-                       goto exit_dma_lch_fail;
-               }
-       }
-
        /* reserve dma channels 0 and 1 in high security devices on 34xx */
        if (d->dev_caps & HS_CHANNELS_RESERVED) {
                pr_info("Reserving DMA channels 0 and 1 for HS ROM code\n");
@@ -1389,34 +947,21 @@ static int omap_system_dma_probe(struct platform_device *pdev)
        return 0;
 
 exit_dma_irq_fail:
-       dev_err(&pdev->dev, "unable to request IRQ %d for DMA (error %d)\n",
-               dma_irq, ret);
-       for (irq_rel = 0; irq_rel < ch; irq_rel++) {
-               dma_irq = platform_get_irq(pdev, irq_rel);
-               free_irq(dma_irq, (void *)(irq_rel + 1));
-       }
-
-exit_dma_lch_fail:
        return ret;
 }
 
 static int omap_system_dma_remove(struct platform_device *pdev)
 {
-       int dma_irq;
+       int dma_irq, irq_rel = 0;
 
-       if (dma_omap2plus()) {
-               char irq_name[4];
-               strcpy(irq_name, "0");
-               dma_irq = platform_get_irq_byname(pdev, irq_name);
-               if (dma_irq >= 0)
-                       remove_irq(dma_irq, &omap24xx_dma_irq);
-       } else {
-               int irq_rel = 0;
-               for ( ; irq_rel < dma_chan_count; irq_rel++) {
-                       dma_irq = platform_get_irq(pdev, irq_rel);
-                       free_irq(dma_irq, (void *)(irq_rel + 1));
-               }
+       if (dma_omap2plus())
+               return 0;
+
+       for ( ; irq_rel < dma_chan_count; irq_rel++) {
+               dma_irq = platform_get_irq(pdev, irq_rel);
+               free_irq(dma_irq, (void *)(irq_rel + 1));
        }
+
        return 0;
 }
 
index ee3d5c9..4f7b272 100644 (file)
@@ -40,7 +40,7 @@ enum s3c_cpu_type {
        TYPE_ADCV11, /* S3C2443 */
        TYPE_ADCV12, /* S3C2416, S3C2450 */
        TYPE_ADCV2, /* S3C64XX */
-       TYPE_ADCV3, /* S5PV210, S5PC110, EXYNOS4210 */
+       TYPE_ADCV3, /* S5PV210, S5PC110, Exynos4210 */
 };
 
 struct s3c_adc_client {
index 1602f6d..089a176 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2011 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com
 //
-// Base SAMSUNG platform device definitions
+// Base Samsung platform device definitions
 
 #include <linux/kernel.h>
 #include <linux/types.h>
index f66c820..8955fd6 100644 (file)
@@ -8,7 +8,7 @@
 //      Ben Dooks <ben@simtec.co.uk>
 //      http://armlinux.simtec.co.uk/
 //
-// SAMSUNG - GPIOlib support
+// Samsung - GPIOlib support
 
 #include <linux/kernel.h>
 #include <linux/irq.h>
index d16eefe..32ab086 100644 (file)
@@ -9,7 +9,7 @@
 #ifndef __ASM_PLAT_SAMSUNG_TIME_H
 #define __ASM_PLAT_SAMSUNG_TIME_H __FILE__
 
-/* SAMSUNG HR-Timer Clock mode */
+/* Samsung HR-Timer Clock mode */
 enum samsung_timer_mode {
        SAMSUNG_PWM0,
        SAMSUNG_PWM1,
index de238b5..0b30e88 100644 (file)
@@ -104,6 +104,7 @@ config ARM64
        select GENERIC_IRQ_SHOW
        select GENERIC_IRQ_SHOW_LEVEL
        select GENERIC_PCI_IOMAP
+       select GENERIC_PTDUMP
        select GENERIC_SCHED_CLOCK
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_STRNCPY_FROM_USER
@@ -164,7 +165,7 @@ config ARM64
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_FUNCTION_ARG_ACCESS_API
        select HAVE_FUTEX_CMPXCHG if FUTEX
-       select HAVE_RCU_TABLE_FREE
+       select MMU_GATHER_RCU_TABLE_FREE
        select HAVE_RSEQ
        select HAVE_STACKPROTECTOR
        select HAVE_SYSCALL_TRACEPOINTS
index cf09010..1c906d9 100644 (file)
@@ -1,22 +1,5 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-config ARM64_PTDUMP_CORE
-       def_bool n
-
-config ARM64_PTDUMP_DEBUGFS
-       bool "Export kernel pagetable layout to userspace via debugfs"
-       depends on DEBUG_KERNEL
-       select ARM64_PTDUMP_CORE
-       select DEBUG_FS
-        help
-         Say Y here if you want to show the kernel pagetable layout in a
-         debugfs file. This information is only useful for kernel developers
-         who are working in architecture specific areas of the kernel.
-         It is probably not a good idea to enable this feature in a production
-         kernel.
-
-         If in doubt, say N.
-
 config PID_IN_CONTEXTIDR
        bool "Write the current PID to the CONTEXTIDR register"
        help
@@ -42,7 +25,7 @@ config ARM64_RANDOMIZE_TEXT_OFFSET
 
 config DEBUG_WX
        bool "Warn on W+X mappings at boot"
-       select ARM64_PTDUMP_CORE
+       select PTDUMP_CORE
        ---help---
          Generate a warning if any W+X mappings are found at boot.
 
index d241802..cf4f786 100644 (file)
@@ -15,6 +15,8 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-emlid-neutis-n5-devboard.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-libretech-all-h3-cc.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-libretech-all-h3-it.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-libretech-all-h5-cc.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-nanopi-neo-plus2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-orangepi-pc2.dtb
@@ -26,4 +28,5 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-3.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-lite2.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-orangepi-one-plus.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64.dtb
+dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-pine-h64-model-b.dtb
 dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h6-tanix-tx6.dtb
index f0349ef..10e9186 100644 (file)
@@ -1,44 +1,5 @@
-/*
- * Copyright 2017 Icenowy Zheng <icenowy@aosc.xyz>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright 2017 Icenowy Zheng <icenowy@aosc.xyz>
 
 /*
  * AXP803 Integrated Power Management Chip
index 5634245..c7bd73f 100644 (file)
@@ -1,12 +1,11 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2018 Amarula Solutions B.V.
- * Author: Jagan Teki <jagan@amarulasolutions.com>
- */
+// Copyright (C) 2018 Amarula Solutions B.V.
+// Author: Jagan Teki <jagan@amarulasolutions.com>
 
 /dts-v1/;
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 
        };
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &csi {
        status = "okay";
 
index 208373e..883f217 100644 (file)
@@ -1,48 +1,10 @@
-/*
- * Copyright (c) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2016 ARM Ltd.
 
 /dts-v1/;
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &dai {
        status = "okay";
 };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-a64-cpu-opp.dtsi
new file mode 100644 (file)
index 0000000..578c374
--- /dev/null
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2020 Vasily khoruzhick <anarsoul@gmail.com>
+ */
+
+/ {
+       cpu0_opp_table: opp_table0 {
+               compatible = "operating-points-v2";
+               opp-shared;
+
+               opp-648000000 {
+                       opp-hz = /bits/ 64 <648000000>;
+                       opp-microvolt = <1040000>;
+                       clock-latency-ns = <244144>; /* 8 32k periods */
+               };
+
+               opp-816000000 {
+                       opp-hz = /bits/ 64 <816000000>;
+                       opp-microvolt = <1100000>;
+                       clock-latency-ns = <244144>; /* 8 32k periods */
+               };
+
+               opp-912000000 {
+                       opp-hz = /bits/ 64 <912000000>;
+                       opp-microvolt = <1120000>;
+                       clock-latency-ns = <244144>; /* 8 32k periods */
+               };
+
+               opp-960000000 {
+                       opp-hz = /bits/ 64 <960000000>;
+                       opp-microvolt = <1160000>;
+                       clock-latency-ns = <244144>; /* 8 32k periods */
+               };
+
+               opp-1008000000 {
+                       opp-hz = /bits/ 64 <1008000000>;
+                       opp-microvolt = <1200000>;
+                       clock-latency-ns = <244144>; /* 8 32k periods */
+               };
+
+               opp-1056000000 {
+                       opp-hz = /bits/ 64 <1056000000>;
+                       opp-microvolt = <1240000>;
+                       clock-latency-ns = <244144>; /* 8 32k periods */
+               };
+
+               opp-1104000000 {
+                       opp-hz = /bits/ 64 <1104000000>;
+                       opp-microvolt = <1260000>;
+                       clock-latency-ns = <244144>; /* 8 32k periods */
+               };
+
+               opp-1152000000 {
+                       opp-hz = /bits/ 64 <1152000000>;
+                       opp-microvolt = <1300000>;
+                       clock-latency-ns = <244144>; /* 8 32k periods */
+               };
+       };
+};
+
+&cpu0 {
+       operating-points-v2 = <&cpu0_opp_table>;
+};
+
+&cpu1 {
+       operating-points-v2 = <&cpu0_opp_table>;
+};
+
+&cpu2 {
+       operating-points-v2 = <&cpu0_opp_table>;
+};
+
+&cpu3 {
+       operating-points-v2 = <&cpu0_opp_table>;
+};
index 9b9d915..e58db8a 100644 (file)
@@ -1,48 +1,10 @@
-/*
- * Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
 
 /dts-v1/;
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 
        };
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &de {
        status = "okay";
 };
index 787ebd8..577f9e1 100644 (file)
@@ -1,9 +1,7 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2019 Oceanic Systems (UK) Ltd.
- * Copyright (C) 2019 Amarula Solutions B.V.
- * Author: Jagan Teki <jagan@amarulasolutions.com>
- */
+// Copyright (C) 2019 Oceanic Systems (UK) Ltd.
+// Copyright (C) 2019 Amarula Solutions B.V.
+// Author: Jagan Teki <jagan@amarulasolutions.com>
 
 /dts-v1/;
 
index 121e6cc..efb2084 100644 (file)
@@ -1,8 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2018 Martin Ayotte <martinayotte@gmail.com>
- * Copyright (C) 2019 Sunil Mohan Adapa <sunil@medhas.org>
- */
+// Copyright (C) 2018 Martin Ayotte <martinayotte@gmail.com>
+// Copyright (C) 2019 Sunil Mohan Adapa <sunil@medhas.org>
 
 #include "sun50i-a64-olinuxino.dts"
 
@@ -21,3 +19,7 @@
        cap-mmc-hw-reset;
        status = "okay";
 };
+
+&pio {
+       vcc-pc-supply = <&reg_eldo1>;
+};
index 393c194..6dfafa1 100644 (file)
@@ -1,48 +1,10 @@
-/*
- * Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
 
 /dts-v1/;
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 
        };
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &de {
        status = "okay";
 };
        status = "okay";
 };
 
+&pio {
+       vcc-pc-supply = <&reg_dcdc1>;
+       vcc-pd-supply = <&reg_dcdc1>;
+       vcc-pe-supply = <&reg_aldo1>;
+       vcc-pg-supply = <&reg_dldo4>;
+};
+
+&r_pio {
+       /*
+        * FIXME: We can't add that supply for now since it would
+        * create a circular dependency between pinctrl, the regulator
+        * and the RSB Bus.
+        *
+        * vcc-pl-supply = <&reg_aldo2>;
+        */
+};
+
 &r_rsb {
        status = "okay";
 
index f54a415..fde9c7a 100644 (file)
@@ -1,49 +1,11 @@
-/*
- * Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
- * Copyright (C) 2017-2018 Samuel Holland <samuel@sholland.org>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * 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 (C) 2017 Jagan Teki <jteki@openedev.com>
+// Copyright (C) 2017-2018 Samuel Holland <samuel@sholland.org>
 
 /dts-v1/;
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &dai {
        status = "okay";
 };
index 72d6961..302e24b 100644 (file)
@@ -1,8 +1,5 @@
-/*
- * SPDX-License-Identifier: (GPL-2.0+ OR MIT)
- *
- * Copyright (c) 2018 ARM Ltd.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2018 ARM Ltd.
 
 #include "sun50i-a64-sopine-baseboard.dts"
 
index d5b6e81..b26181c 100644 (file)
@@ -1,44 +1,5 @@
-/*
- * Copyright (c) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2016 ARM Ltd.
 
 #include "sun50i-a64-pine64.dts"
 
index 409523c..2165f23 100644 (file)
@@ -1,48 +1,10 @@
-/*
- * Copyright (c) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2016 ARM Ltd.
 
 /dts-v1/;
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &dai {
        status = "okay";
 };
index 78c82a6..3d894b2 100644 (file)
@@ -1,15 +1,14 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
- * Copyright (C) 2018 Vasily Khoruzhick <anarsoul@gmail.com>
- *
- */
+// Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
+// Copyright (C) 2018 Vasily Khoruzhick <anarsoul@gmail.com>
 
 /dts-v1/;
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/gpio-keys.h>
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/pwm/pwm.h>
 
@@ -60,6 +59,7 @@
                        linux,code = <SW_LID>;
                        linux,can-disable;
                        wakeup-source;
+                       wakeup-event-action = <EV_ACT_DEASSERTED>;
                };
        };
 
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &dai {
        status = "okay";
 };
index 920103e..2f6ea9f 100644 (file)
@@ -1,47 +1,7 @@
-/*
- * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.xyz>
- *
- * Based on sun50i-a64-pine64.dts, which is:
- *   Copyright (c) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.xyz>
+// Based on sun50i-a64-pine64.dts, which is:
+//   Copyright (c) 2016 ARM Ltd.
 
 /dts-v1/;
 
index 9d20e13..c48692b 100644 (file)
@@ -1,49 +1,10 @@
-/*
- * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.xyz>
- *
- * Based on sun50i-a64-pine64.dts, which is:
- *   Copyright (c) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.xyz>
+// Based on sun50i-a64-pine64.dts, which is:
+//   Copyright (c) 2016 ARM Ltd.
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 
        cpvdd-supply = <&reg_eldo1>;
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &mmc0 {
        pinctrl-names = "default";
        pinctrl-0 = <&mmc0_pins>;
index 9704151..f5df5f7 100644 (file)
@@ -1,13 +1,11 @@
-/*
- * Copyright (C) Harald Geyer <harald@ccbib.org>
- * based on sun50i-a64-olinuxino.dts by Jagan Teki <jteki@openedev.com>
- *
- * SPDX-License-Identifier: (GPL-2.0 OR MIT)
- */
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+// Copyright (C) Harald Geyer <harald@ccbib.org>
+// based on sun50i-a64-olinuxino.dts by Jagan Teki <jteki@openedev.com>
 
 /dts-v1/;
 
 #include "sun50i-a64.dtsi"
+#include "sun50i-a64-cpu-opp.dtsi"
 
 #include <dt-bindings/gpio/gpio.h>
 #include <dt-bindings/input/input.h>
        status = "okay";
 };
 
+&cpu0 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu1 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu2 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
+&cpu3 {
+       cpu-supply = <&reg_dcdc2>;
+};
+
 &ehci1 {
        status = "okay";
 };
index 27e4823..862b47d 100644 (file)
@@ -1,46 +1,7 @@
-/*
- * Copyright (C) 2016 ARM Ltd.
- * based on the Allwinner H3 dtsi:
- *    Copyright (C) 2015 Jens Kuske <jenskuske@gmail.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2016 ARM Ltd.
+// based on the Allwinner H3 dtsi:
+//    Copyright (C) 2015 Jens Kuske <jenskuske@gmail.com>
 
 #include <dt-bindings/clock/sun50i-a64-ccu.h>
 #include <dt-bindings/clock/sun8i-de2.h>
@@ -49,6 +10,7 @@
 #include <dt-bindings/reset/sun50i-a64-ccu.h>
 #include <dt-bindings/reset/sun8i-de2.h>
 #include <dt-bindings/reset/sun8i-r-ccu.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
        interrupt-parent = <&gic>;
@@ -89,6 +51,9 @@
                        reg = <0>;
                        enable-method = "psci";
                        next-level-cache = <&L2>;
+                       clocks = <&ccu 21>;
+                       clock-names = "cpu";
+                       #cooling-cells = <2>;
                };
 
                cpu1: cpu@1 {
@@ -97,6 +62,9 @@
                        reg = <1>;
                        enable-method = "psci";
                        next-level-cache = <&L2>;
+                       clocks = <&ccu 21>;
+                       clock-names = "cpu";
+                       #cooling-cells = <2>;
                };
 
                cpu2: cpu@2 {
                        reg = <2>;
                        enable-method = "psci";
                        next-level-cache = <&L2>;
+                       clocks = <&ccu 21>;
+                       clock-names = "cpu";
+                       #cooling-cells = <2>;
                };
 
                cpu3: cpu@3 {
                        reg = <3>;
                        enable-method = "psci";
                        next-level-cache = <&L2>;
+                       clocks = <&ccu 21>;
+                       clock-names = "cpu";
+                       #cooling-cells = <2>;
                };
 
                L2: l2-cache {
                        (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
        };
 
+       thermal-zones {
+               cpu_thermal: cpu0-thermal {
+                       /* milliseconds */
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 0>;
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu_alert0>;
+                                       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>;
+                               };
+                               map1 {
+                                       trip = <&cpu_alert1>;
+                                       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>;
+                               };
+                       };
+
+                       trips {
+                               cpu_alert0: cpu_alert0 {
+                                       /* milliCelsius */
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu_alert1: cpu_alert1 {
+                                       /* milliCelsius */
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+
+                               cpu_crit: cpu_crit {
+                                       /* milliCelsius */
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               gpu0_thermal: gpu0-thermal {
+                       /* milliseconds */
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 1>;
+               };
+
+               gpu1_thermal: gpu1-thermal {
+                       /* milliseconds */
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 2>;
+               };
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <1>;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
                                        reg = <1>;
+
+                                       tcon0_out_dsi: endpoint@1 {
+                                               reg = <1>;
+                                               remote-endpoint = <&dsi_in_tcon0>;
+                                               allwinner,tcon-channel = <1>;
+                                       };
                                };
                        };
                };
                sid: eeprom@1c14000 {
                        compatible = "allwinner,sun50i-a64-sid";
                        reg = <0x1c14000 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       ths_calibration: thermal-sensor-calibration@34 {
+                               reg = <0x34 0x8>;
+                       };
                };
 
                crypto: crypto@1c15000 {
                        interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&ccu 58>, <&osc24M>, <&rtc 0>;
+                       clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&rtc 0>;
                        clock-names = "apb", "hosc", "losc";
                        gpio-controller;
                        #gpio-cells = <3>;
                        status = "disabled";
                };
 
+               ths: thermal-sensor@1c25000 {
+                       compatible = "allwinner,sun50i-a64-ths";
+                       reg = <0x01c25000 0x100>;
+                       clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
+                       clock-names = "bus", "mod";
+                       interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+                       resets = <&ccu RST_BUS_THS>;
+                       nvmem-cells = <&ths_calibration>;
+                       nvmem-cell-names = "calibration";
+                       #thermal-sensor-cells = <1>;
+               };
+
                uart0: serial@1c28000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x01c28000 0x400>;
                        status = "disabled";
                };
 
+               dsi: dsi@1ca0000 {
+                       compatible = "allwinner,sun50i-a64-mipi-dsi";
+                       reg = <0x01ca0000 0x1000>;
+                       interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_MIPI_DSI>;
+                       resets = <&ccu RST_BUS_MIPI_DSI>;
+                       phys = <&dphy>;
+                       phy-names = "dphy";
+                       status = "disabled";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port {
+                               dsi_in_tcon0: endpoint {
+                                       remote-endpoint = <&tcon0_out_dsi>;
+                               };
+                       };
+               };
+
+               dphy: d-phy@1ca1000 {
+                       compatible = "allwinner,sun50i-a64-mipi-dphy",
+                                    "allwinner,sun6i-a31-mipi-dphy";
+                       reg = <0x01ca1000 0x1000>;
+                       clocks = <&ccu CLK_BUS_MIPI_DSI>,
+                                <&ccu CLK_DSI_DPHY>;
+                       clock-names = "bus", "mod";
+                       resets = <&ccu RST_BUS_MIPI_DSI>;
+                       status = "disabled";
+                       #phy-cells = <0>;
+               };
+
                hdmi: hdmi@1ee0000 {
                        compatible = "allwinner,sun50i-a64-dw-hdmi",
                                     "allwinner,sun8i-a83t-dw-hdmi";
                        compatible = "allwinner,sun50i-a64-hdmi-phy";
                        reg = <0x01ef0000 0x10000>;
                        clocks = <&ccu CLK_BUS_HDMI>, <&ccu CLK_HDMI_DDC>,
-                                <&ccu 7>;
+                                <&ccu CLK_PLL_VIDEO0>;
                        clock-names = "bus", "mod", "pll-0";
                        resets = <&ccu RST_BUS_HDMI0>;
                        reset-names = "phy";
                r_ccu: clock@1f01400 {
                        compatible = "allwinner,sun50i-a64-r-ccu";
                        reg = <0x01f01400 0x100>;
-                       clocks = <&osc24M>, <&rtc 0>, <&rtc 2>, <&ccu 11>;
+                       clocks = <&osc24M>, <&rtc 0>, <&rtc 2>,
+                                <&ccu CLK_PLL_PERIPH0>;
                        clock-names = "hosc", "losc", "iosc", "pll-periph";
                        #clock-cells = <1>;
                        #reset-cells = <1>;
index c924090..076a0b9 100644 (file)
@@ -1,8 +1,8 @@
 // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+// Copyright (C) 2018 Aleksandr Aleksandrov <aleksandr.aleksandrov@emlid.com>
+
 /*
  * DTS for Emlid Neutis N5 Dev board.
- *
- * Copyright (C) 2018 Aleksandr Aleksandrov <aleksandr.aleksandrov@emlid.com>
  */
 
 /dts-v1/;
                     "emlid,neutis-n5",
                     "allwinner,sun50i-h5";
 
-       aliases {
-               serial0 = &uart0;
-       };
-
-       chosen {
-               stdout-path = "serial0:115200n8";
-       };
-
        connector {
                compatible = "hdmi-connector";
                type = "a";
                };
        };
 
-       reg_usb0_vbus: usb0-vbus {
-               compatible = "regulator-fixed";
-               regulator-name = "usb0-vbus";
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               enable-active-high;
-               gpio = <&r_pio 0 9 GPIO_ACTIVE_HIGH>;   /* PL9 */
-               status = "okay";
-       };
-
        vdd_cpux: gpio-regulator {
                compatible = "regulator-gpio";
                regulator-name = "vdd-cpux";
        };
 };
 
-&codec {
-       allwinner,audio-routing =
-               "Line Out", "LINEOUT",
-               "LINEIN", "Line In",
-               "MIC1", "Mic",
-               "MIC2", "Mic",
-               "Mic",  "MBIAS";
-       status = "okay";
-};
-
-&de {
-       status = "okay";
-};
-
-&ehci0 {
-       status = "okay";
+&cpu0 {
+       cpu-supply = <&vdd_cpux>;
 };
 
-&ehci1 {
-       status = "okay";
-};
-
-&ehci2 {
-       status = "okay";
-};
-
-&ehci3 {
+&codec {
        status = "okay";
 };
 
        };
 };
 
-&mmc0 {
-       vmmc-supply = <&reg_vcc3v3>;
-       bus-width = <4>;
-       cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */
-       status = "okay";
-};
-
-&ohci0 {
-       status = "okay";
-};
-
-&ohci1 {
-       status = "okay";
-};
-
-&ohci2 {
-       status = "okay";
-};
-
-&ohci3 {
-       status = "okay";
-};
-
-&uart0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart0_pa_pins>;
-       status = "okay";
-};
-
-&usb_otg {
-       dr_mode = "otg";
-       status = "okay";
-};
-
-&usbphy {
-       usb0_id_det-gpios = <&r_pio 0 8 GPIO_ACTIVE_HIGH>; /* PL8 */
-       usb0_vbus-supply = <&reg_usb0_vbus>;
+&i2c1 {
        status = "okay";
 };
index 5bec574..fc57001 100644 (file)
@@ -1,73 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0-or-later OR MIT
+// Copyright (C) 2018 Aleksandr Aleksandrov <aleksandr.aleksandrov@emlid.com>
+
 /*
  * DTSI for Emlid Neutis N5 SoM.
- *
- * Copyright (C) 2018 Aleksandr Aleksandrov <aleksandr.aleksandrov@emlid.com>
  */
 
 /dts-v1/;
 
 #include "sun50i-h5.dtsi"
-
-#include <dt-bindings/gpio/gpio.h>
-
-/ {
-       reg_vcc3v3: vcc3v3 {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc3v3";
-               regulator-min-microvolt = <3300000>;
-               regulator-max-microvolt = <3300000>;
-       };
-
-       wifi_pwrseq: wifi_pwrseq {
-               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";
-       };
-};
-
-&mmc1 {
-       vmmc-supply = <&reg_vcc3v3>;
-       vqmmc-supply = <&reg_vcc3v3>;
-       mmc-pwrseq = <&wifi_pwrseq>;
-       bus-width = <4>;
-       non-removable;
-       status = "okay";
-
-       brcmf: wifi@1 {
-               reg = <1>;
-               compatible = "brcm,bcm4329-fmac";
-               interrupt-parent = <&r_pio>;
-               interrupts = <0 5 IRQ_TYPE_LEVEL_LOW>;  /* PL5 */
-               interrupt-names = "host-wake";
-       };
-};
-
-&mmc2 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&mmc2_8bit_pins>;
-       vmmc-supply = <&reg_vcc3v3>;
-       bus-width = <8>;
-       non-removable;
-       cap-mmc-hw-reset;
-       status = "okay";
-};
-
-&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 */
-       };
-};
+#include <arm/sunxi-h3-h5-emlid-neutis.dtsi>
index d68bdfe..64d35da 100644 (file)
@@ -1,8 +1,6 @@
 // SPDX-License-Identifier: (GPL-2.0+ OR MIT)
-/*
- * Copyright (C) 2018 BayLibre, SAS
- * Author: Neil Armstrong <narmstrong@baylibre.com>
- */
+// Copyright (C) 2018 BayLibre, SAS
+// Author: Neil Armstrong <narmstrong@baylibre.com>
 
 /dts-v1/;
 #include "sun50i-h5.dtsi"
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h3-it.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h3-it.dts
new file mode 100644 (file)
index 0000000..e59d68b
--- /dev/null
@@ -0,0 +1,11 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2019 Chen-Yu Tsai <wens@csie.org>
+
+/dts-v1/;
+#include "sun50i-h5.dtsi"
+#include <arm/sunxi-libretech-all-h3-it.dtsi>
+
+/ {
+       model = "Libre Computer Board ALL-H3-IT H5";
+       compatible = "libretech,all-h3-it-h5", "allwinner,sun50i-h5";
+};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h5-cc.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-libretech-all-h5-cc.dts
new file mode 100644 (file)
index 0000000..df1b926
--- /dev/null
@@ -0,0 +1,61 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2020 Chen-Yu Tsai <wens@csie.org>
+
+#include "sun50i-h5-libretech-all-h3-cc.dts"
+
+/ {
+       model = "Libre Computer Board ALL-H5-CC H5";
+       compatible = "libretech,all-h5-cc-h5", "allwinner,sun50i-h5";
+
+       aliases {
+               spi0 = &spi0;
+       };
+
+       reg_gmac_3v3: gmac-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "gmac-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <5000>;
+               enable-active-high;
+               gpio = <&pio 3 6 GPIO_ACTIVE_HIGH>;
+               vin-supply = <&reg_vcc5v0>;
+       };
+};
+
+&codec {
+       /* No line out; only onboard microphone */
+       allwinner,audio-routing =
+               "MIC1", "Mic",
+               "Mic",  "MBIAS";
+};
+
+/* This board has external PHY */
+&emac {
+       pinctrl-names = "default";
+       pinctrl-0 = <&emac_rgmii_pins>;
+       phy-supply = <&reg_gmac_3v3>;
+       phy-handle = <&ext_rgmii_phy>;
+       phy-mode = "rgmii";
+       /delete-property/ allwinner,leds-active-low;
+       status = "okay";
+};
+
+&external_mdio {
+       ext_rgmii_phy: ethernet-phy@1 {
+               compatible = "ethernet-phy-ieee802.3-c22";
+               reg = <1>;
+       };
+};
+
+&spi0  {
+       status = "okay";
+
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <50000000>;
+       };
+};
index 1c7dde8..4f9ba53 100644 (file)
@@ -1,45 +1,6 @@
-/*
- * Copyright (C) 2017 Antony Antony <antony@phenome.org>
- * Copyright (C) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2017 Antony Antony <antony@phenome.org>
+// Copyright (C) 2016 ARM Ltd.
 
 /dts-v1/;
 #include "sun50i-h5.dtsi"
index 57a6f45..b059e20 100644 (file)
@@ -1,44 +1,5 @@
-/*
- * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
 
 /dts-v1/;
 #include "sun50i-h5.dtsi"
index e126c1c..70b5f09 100644 (file)
@@ -1,44 +1,5 @@
-/*
- * Copyright (C) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2016 ARM Ltd.
 
 /dts-v1/;
 #include "sun50i-h5.dtsi"
index d9b3ed2..cb44bfa 100644 (file)
@@ -1,47 +1,7 @@
-/*
- * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
- *
- * Based on sun50i-h5-orangepi-pc2.dts, which is:
- *   Copyright (C) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.xyz>
+// Based on sun50i-h5-orangepi-pc2.dts, which is:
+//   Copyright (C) 2016 ARM Ltd.
 
 /dts-v1/;
 #include "sun50i-h5.dtsi"
index db6ea7b..ef5ca64 100644 (file)
@@ -1,9 +1,6 @@
-/*
- * Copyright (C) 2016 ARM Ltd.
- * Copyright (C) 2018 Hauke Mehrtens <hauke@hauke-m.de>
- *
- * SPDX-License-Identifier: (GPL-2.0+ OR X11)
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2016 ARM Ltd.
+// Copyright (C) 2018 Hauke Mehrtens <hauke@hauke-m.de>
 
 /dts-v1/;
 #include "sun50i-h5.dtsi"
index dacf613..c95a685 100644 (file)
@@ -1,44 +1,5 @@
-/*
- * Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This library is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This library is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2017 Jagan Teki <jteki@openedev.com>
 
 /dts-v1/;
 
index e92c4de..9893aa6 100644 (file)
@@ -1,44 +1,5 @@
-/*
- * Copyright (C) 2016 ARM Ltd.
- *
- * This file is dual-licensed: you can use it either under the terms
- * of the GPL or the X11 license, at your option. Note that this dual
- * licensing only applies to this file, and not this project as a
- * whole.
- *
- *  a) This file is free software; you can redistribute it and/or
- *     modify it under the terms of the GNU General Public License as
- *     published by the Free Software Foundation; either version 2 of the
- *     License, or (at your option) any later version.
- *
- *     This file is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- * Or, alternatively,
- *
- *  b) Permission is hereby granted, free of charge, to any person
- *     obtaining a copy of this software and associated documentation
- *     files (the "Software"), to deal in the Software without
- *     restriction, including without limitation the rights to use,
- *     copy, modify, merge, publish, distribute, sublicense, and/or
- *     sell copies of the Software, and to permit persons to whom the
- *     Software is furnished to do so, subject to the following
- *     conditions:
- *
- *     The above copyright notice and this permission notice shall be
- *     included in all copies or substantial portions of the Software.
- *
- *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
- *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
- *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
- *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
- *     OTHER DEALINGS IN THE SOFTWARE.
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2016 ARM Ltd.
 
 #include <arm/sunxi-h3-h5.dtsi>
 
                        enable-method = "psci";
                };
 
-               cpu@1 {
+               cpu1: cpu@1 {
                        compatible = "arm,cortex-a53";
                        device_type = "cpu";
                        reg = <1>;
                        enable-method = "psci";
                };
 
-               cpu@2 {
+               cpu2: cpu@2 {
                        compatible = "arm,cortex-a53";
                        device_type = "cpu";
                        reg = <2>;
                        enable-method = "psci";
                };
 
-               cpu@3 {
+               cpu3: cpu@3 {
                        compatible = "arm,cortex-a53";
                        device_type = "cpu";
                        reg = <3>;
                };
        };
 
+       pmu {
+               compatible = "arm,cortex-a53-pmu",
+                            "arm,armv8-pmuv3";
+               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";
                        assigned-clocks = <&ccu CLK_GPU>;
                        assigned-clock-rates = <384000000>;
                };
+
+               ths: thermal-sensor@1c25000 {
+                       compatible = "allwinner,sun50i-h5-ths";
+                       reg = <0x01c25000 0x400>;
+                       interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>;
+                       resets = <&ccu RST_BUS_THS>;
+                       clocks = <&ccu CLK_BUS_THS>, <&ccu CLK_THS>;
+                       clock-names = "bus", "mod";
+                       nvmem-cells = <&ths_calibration>;
+                       nvmem-cell-names = "calibration";
+                       #thermal-sensor-cells = <1>;
+               };
+       };
+
+       thermal-zones {
+               cpu_thermal: cpu-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 0>;
+               };
+
+               gpu_thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 1>;
+               };
        };
 };
 
index f335f74..df6d872 100644 (file)
@@ -1,7 +1,5 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-/*
- * Copyright (C) 2019 Clément Péron <peron.clem@gmail.com>
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2019 Clément Péron <peron.clem@gmail.com>
 
 /dts-v1/;
 
        status = "okay";
 };
 
+&dwc3 {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
        usb0_vbus-supply = <&reg_vcc5v>;
        status = "okay";
 };
+
+&usb3phy {
+       status = "okay";
+};
index 4ed3fc2..c311eee 100644 (file)
@@ -1,7 +1,5 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-/*
- * Copyright (C) 2019 Ondřej Jirman <megous@megous.com>
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2019 Ondřej Jirman <megous@megous.com>
 
 /dts-v1/;
 
        };
 };
 
+&r_ir {
+       status = "okay";
+};
+
 &uart0 {
        pinctrl-names = "default";
        pinctrl-0 = <&uart0_ph_pins>;
index e098a24..e7ca75c 100644 (file)
@@ -1,7 +1,5 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-/*
- * Copyright (C) 2018 Jagan Teki <jagan@openedev.com>
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2018 Jagan Teki <jagan@openedev.com>
 
 #include "sun50i-h6-orangepi.dtsi"
 
index 12e1756..83aab73 100644 (file)
@@ -1,8 +1,6 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-/*
- * Copyright (C) 2018 Amarula Solutions
- * Author: Jagan Teki <jagan@amarulasolutions.com>
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2018 Amarula Solutions
+// Author: Jagan Teki <jagan@amarulasolutions.com>
 
 #include "sun50i-h6-orangepi.dtsi"
 
index df4cbd7..37f4c57 100644 (file)
@@ -1,8 +1,6 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-/*
- * Copyright (C) 2018 Amarula Solutions
- * Author: Jagan Teki <jagan@amarulasolutions.com>
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2018 Amarula Solutions
+// Author: Jagan Teki <jagan@amarulasolutions.com>
 
 /dts-v1/;
 
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts b/arch/arm64/boot/dts/allwinner/sun50i-h6-pine-h64-model-b.dts
new file mode 100644 (file)
index 0000000..f4c8966
--- /dev/null
@@ -0,0 +1,21 @@
+// SPDX-License-Identifier: (GPL-2.0+ or MIT)
+/*
+ * Copyright (C) 2019 Corentin LABBE <clabbe@baylibre.com>
+ */
+
+#include "sun50i-h6-pine-h64.dts"
+
+/ {
+       model = "Pine H64 model B";
+       compatible = "pine64,pine-h64-model-b", "allwinner,sun50i-h6";
+
+       /delete-node/ reg_gmac_3v3;
+};
+
+&hdmi_connector {
+       /delete-property/ ddc-en-gpios;
+};
+
+&emac {
+       phy-supply = <&reg_aldo2>;
+};
index 74899ed..d1c2aa5 100644 (file)
@@ -1,7 +1,5 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-/*
- * Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io>
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2017 Icenowy Zheng <icenowy@aosc.io>
 
 /dts-v1/;
 
@@ -10,7 +8,7 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
-       model = "Pine H64";
+       model = "Pine H64 model A";
        compatible = "pine64,pine-h64", "allwinner,sun50i-h6";
 
        aliases {
                stdout-path = "serial0:115200n8";
        };
 
-       connector {
+       hdmi_connector: connector {
                compatible = "hdmi-connector";
                type = "a";
+               ddc-en-gpios = <&pio 7 2 GPIO_ACTIVE_HIGH>; /* PH2 */
 
                port {
                        hdmi_con_in: endpoint {
                };
        };
 
+       reg_gmac_3v3: gmac-3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc-gmac-3v3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               startup-delay-us = <100000>;
+               gpio = <&pio 2 16 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
        reg_usb_vbus: vbus {
                compatible = "regulator-fixed";
                regulator-name = "usb-vbus";
@@ -68,7 +77,7 @@
        pinctrl-0 = <&ext_rgmii_pins>;
        phy-mode = "rgmii";
        phy-handle = <&ext_rgmii_phy>;
-       phy-supply = <&reg_aldo2>;
+       phy-supply = <&reg_gmac_3v3>;
        allwinner,rx-delay-ps = <200>;
        allwinner,tx-delay-ps = <200>;
        status = "okay";
index bccfe1e..83e6cb0 100644 (file)
@@ -1,7 +1,5 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-/*
- * Copyright (c) 2019 Jernej Skrabec <jernej.skrabec@siol.net>
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (c) 2019 Jernej Skrabec <jernej.skrabec@siol.net>
 
 /dts-v1/;
 
        status = "okay";
 };
 
+&dwc3 {
+       status = "okay";
+};
+
 &ehci0 {
        status = "okay";
 };
@@ -85,6 +87,7 @@
 };
 
 &r_ir {
+       linux,rc-map-name = "rc-tanix-tx5max";
        status = "okay";
 };
 
 &usb2phy {
        status = "okay";
 };
+
+&usb3phy {
+       status = "okay";
+};
index 2982408..3329283 100644 (file)
@@ -1,7 +1,5 @@
-// SPDX-License-Identifier: (GPL-2.0+ or MIT)
-/*
- * Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
- */
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/sun50i-h6-ccu.h>
@@ -11,6 +9,7 @@
 #include <dt-bindings/reset/sun50i-h6-ccu.h>
 #include <dt-bindings/reset/sun50i-h6-r-ccu.h>
 #include <dt-bindings/reset/sun8i-de2.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
        interrupt-parent = <&gic>;
                clock-output-names = "ext_osc32k";
        };
 
+       pmu {
+               compatible = "arm,cortex-a53-pmu",
+                            "arm,armv8-pmuv3";
+               interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>;
+       };
+
        psci {
                compatible = "arm,psci-0.2";
                method = "smc";
                sid: efuse@3006000 {
                        compatible = "allwinner,sun50i-h6-sid";
                        reg = <0x03006000 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       ths_calibration: thermal-sensor-calibration@14 {
+                               reg = <0x14 0x8>;
+                       };
                };
 
                watchdog: watchdog@30090a0 {
                        status = "disabled";
                };
 
+               pwm: pwm@300a000 {
+                       compatible = "allwinner,sun50i-h6-pwm";
+                       reg = <0x0300a000 0x400>;
+                       clocks = <&osc24M>, <&ccu CLK_BUS_PWM>;
+                       clock-names = "mod", "bus";
+                       resets = <&ccu RST_BUS_PWM>;
+                       #pwm-cells = <3>;
+                       status = "disabled";
+               };
+
                pio: pinctrl@300b000 {
                        compatible = "allwinner,sun50i-h6-pinctrl";
                        reg = <0x0300b000 0x400>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                };
+
+               ths: thermal-sensor@5070400 {
+                       compatible = "allwinner,sun50i-h6-ths";
+                       reg = <0x05070400 0x100>;
+                       interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&ccu CLK_BUS_THS>;
+                       clock-names = "bus";
+                       resets = <&ccu RST_BUS_THS>;
+                       nvmem-cells = <&ths_calibration>;
+                       nvmem-cell-names = "calibration";
+                       #thermal-sensor-cells = <1>;
+               };
+       };
+
+       thermal-zones {
+               cpu-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 0>;
+               };
+
+               gpu-thermal {
+                       polling-delay-passive = <0>;
+                       polling-delay = <0>;
+                       thermal-sensors = <&ths 1>;
+               };
        };
 };
index 27bb925..10119c7 100644 (file)
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
-dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb
+dtb-$(CONFIG_ARCH_STRATIX10) += socfpga_stratix10_socdk.dtb \
+                               socfpga_stratix10_socdk_nand.dtb
diff --git a/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts b/arch/arm64/boot/dts/altera/socfpga_stratix10_socdk_nand.dts
new file mode 100644 (file)
index 0000000..9946515
--- /dev/null
@@ -0,0 +1,223 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright Altera Corporation (C) 2015. All rights reserved.
+ */
+
+#include "socfpga_stratix10.dtsi"
+
+/ {
+       model = "SoCFPGA Stratix 10 SoCDK";
+
+       aliases {
+               serial0 = &uart0;
+               ethernet0 = &gmac0;
+               ethernet1 = &gmac1;
+               ethernet2 = &gmac2;
+       };
+
+       chosen {
+               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 */
+               reg = <0 0 0 0>;
+       };
+
+       ref_033v: 033-v-ref {
+               compatible = "regulator-fixed";
+               regulator-name = "0.33V";
+               regulator-min-microvolt = <330000>;
+               regulator-max-microvolt = <330000>;
+       };
+
+       soc {
+               clocks {
+                       osc1 {
+                               clock-frequency = <25000000>;
+                       };
+               };
+
+               eccmgr {
+                       sdmmca-ecc@ff8c8c00 {
+                               compatible = "altr,socfpga-s10-sdmmc-ecc",
+                                            "altr,socfpga-sdmmc-ecc";
+                               reg = <0xff8c8c00 0x100>;
+                               altr,ecc-parent = <&mmc>;
+                               interrupts = <14 4>,
+                                            <15 4>;
+                       };
+               };
+       };
+};
+
+&gpio1 {
+       status = "okay";
+};
+
+&gmac2 {
+       status = "okay";
+       phy-mode = "rgmii";
+       phy-handle = <&phy0>;
+
+       max-frame-size = <9000>;
+
+       mdio0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "snps,dwmac-mdio";
+               phy0: ethernet-phy@0 {
+                       reg = <4>;
+
+                       txd0-skew-ps = <0>; /* -420ps */
+                       txd1-skew-ps = <0>; /* -420ps */
+                       txd2-skew-ps = <0>; /* -420ps */
+                       txd3-skew-ps = <0>; /* -420ps */
+                       rxd0-skew-ps = <420>; /* 0ps */
+                       rxd1-skew-ps = <420>; /* 0ps */
+                       rxd2-skew-ps = <420>; /* 0ps */
+                       rxd3-skew-ps = <420>; /* 0ps */
+                       txen-skew-ps = <0>; /* -420ps */
+                       txc-skew-ps = <900>; /* 0ps */
+                       rxdv-skew-ps = <420>; /* 0ps */
+                       rxc-skew-ps = <1680>; /* 780ps */
+               };
+       };
+};
+
+&nand {
+       status = "okay";
+
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0>;
+               nand-bus-width = <16>;
+
+               partition@0 {
+                       label = "u-boot";
+                       reg = <0 0x200000>;
+               };
+
+               partition@200000 {
+                       label = "env";
+                       reg = <0x200000 0x40000>;
+               };
+
+               partition@240000 {
+                       label = "dtb";
+                       reg = <0x240000 0x40000>;
+               };
+
+               partition@280000 {
+                       label = "kernel";
+                       reg = <0x280000 0x2000000>;
+               };
+
+               partition@2280000 {
+                       label = "misc";
+                       reg = <0x2280000 0x2000000>;
+               };
+
+               partition@4280000 {
+                       label = "rootfs";
+                       reg = <0x4280000 0x3bd80000>;
+               };
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       disable-over-current;
+};
+
+&watchdog0 {
+       status = "okay";
+};
+
+&i2c2 {
+       status = "okay";
+       clock-frequency = <100000>;
+       i2c-sda-falling-time-ns = <890>;  /* hcnt */
+       i2c-sdl-falling-time-ns = <890>;  /* lcnt */
+
+       adc@14 {
+               compatible = "lltc,ltc2497";
+               reg = <0x14>;
+               vref-supply = <&ref_033v>;
+       };
+
+       temp@4c {
+               compatible = "maxim,max1619";
+               reg = <0x4c>;
+       };
+
+       eeprom@51 {
+               compatible = "atmel,24c32";
+               reg = <0x51>;
+               pagesize = <32>;
+       };
+
+       rtc@68 {
+               compatible = "dallas,ds1339";
+               reg = <0x68>;
+       };
+};
+
+&qspi {
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "n25q00a";
+               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@4000000 {
+                               label = "Root Filesystem - JFFS2";
+                               reg = <0x034B0000 0x0EB50000>;
+                       };
+               };
+       };
+};
index 6340053..eef0045 100644 (file)
@@ -7,6 +7,7 @@ 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-kii-pro.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
@@ -29,11 +30,13 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-phicomm-n1.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s805x-p241.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-p281.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905w-tx3-mini.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-libretech-pc.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-khadas-vim2.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q200.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-q201.dtb
 dtb-$(CONFIG_ARCH_MESON) += meson-gxm-rbox-pro.dtb
+dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-libretech-pc.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
index 7210ad0..4dec518 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/gpio/meson-a1-gpio.h>
 
 / {
        compatible = "amlogic,a1";
                        #size-cells = <2>;
                        ranges = <0x0 0x0 0x0 0xfe000000 0x0 0x1000000>;
 
+
+                       reset: reset-controller@0 {
+                               compatible = "amlogic,meson-a1-reset";
+                               reg = <0x0 0x0 0x0 0x8c>;
+                               #reset-cells = <1>;
+                       };
+
+                       periphs_pinctrl: pinctrl@0400 {
+                               compatible = "amlogic,meson-a1-periphs-pinctrl";
+                               #address-cells = <2>;
+                               #size-cells = <2>;
+                               ranges;
+
+                               gpio: bank@0400 {
+                                       reg = <0x0 0x0400 0x0 0x003c>,
+                                             <0x0 0x0480 0x0 0x0118>;
+                                       reg-names = "mux", "gpio";
+                                       gpio-controller;
+                                       #gpio-cells = <2>;
+                                       gpio-ranges = <&periphs_pinctrl 0 0 62>;
+                               };
+
+                       };
+
                        uart_AO: serial@1c00 {
                                compatible = "amlogic,meson-gx-uart",
                                             "amlogic,meson-ao-uart";
index 04803c3..aace3d3 100644 (file)
                                interrupts = <GIC_SPI 84 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&clkc_audio AUD_CLKID_TODDR_A>;
                                resets = <&arb AXG_ARB_TODDR_A>;
+                               amlogic,fifo-depth = <512>;
                                status = "disabled";
                        };
 
                                interrupts = <GIC_SPI 85 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&clkc_audio AUD_CLKID_TODDR_B>;
                                resets = <&arb AXG_ARB_TODDR_B>;
+                               amlogic,fifo-depth = <256>;
                                status = "disabled";
                        };
 
                                interrupts = <GIC_SPI 86 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&clkc_audio AUD_CLKID_TODDR_C>;
                                resets = <&arb AXG_ARB_TODDR_C>;
+                               amlogic,fifo-depth = <256>;
                                status = "disabled";
                        };
 
                                interrupts = <GIC_SPI 88 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&clkc_audio AUD_CLKID_FRDDR_A>;
                                resets = <&arb AXG_ARB_FRDDR_A>;
+                               amlogic,fifo-depth = <512>;
                                status = "disabled";
                        };
 
                                interrupts = <GIC_SPI 89 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&clkc_audio AUD_CLKID_FRDDR_B>;
                                resets = <&arb AXG_ARB_FRDDR_B>;
+                               amlogic,fifo-depth = <256>;
                                status = "disabled";
                        };
 
                                interrupts = <GIC_SPI 90 IRQ_TYPE_EDGE_RISING>;
                                clocks = <&clkc_audio AUD_CLKID_FRDDR_C>;
                                resets = <&arb AXG_ARB_FRDDR_C>;
+                               amlogic,fifo-depth = <256>;
                                status = "disabled";
                        };
 
index 7fabc8d..abe04f4 100644 (file)
                        };
                };
 
+               vdec: video-decoder@ff620000 {
+                       compatible = "amlogic,g12a-vdec";
+                       reg = <0x0 0xff620000 0x0 0x10000>,
+                             <0x0 0xffd0e180 0x0 0xe4>;
+                       reg-names = "dos", "esparser";
+                       interrupts = <GIC_SPI 44 IRQ_TYPE_EDGE_RISING>,
+                                    <GIC_SPI 32 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "vdec", "esparser";
+
+                       amlogic,ao-sysctrl = <&rti>;
+                       amlogic,canvas = <&canvas>;
+
+                       clocks = <&clkc CLKID_PARSER>,
+                                <&clkc CLKID_DOS>,
+                                <&clkc CLKID_VDEC_1>,
+                                <&clkc CLKID_VDEC_HEVC>,
+                                <&clkc CLKID_VDEC_HEVCF>;
+                       clock-names = "dos_parser", "dos", "vdec_1",
+                                     "vdec_hevc", "vdec_hevcf";
+                       resets = <&reset RESET_PARSER>;
+                       reset-names = "esparser";
+               };
+
                vpu: vpu@ff900000 {
                        compatible = "amlogic,meson-g12a-vpu";
                        reg = <0x0 0xff900000 0x0 0x100000>,
index b3ba2fd..03054c4 100644 (file)
                        resets = <&arb AXG_ARB_TODDR_A>,
                                 <&clkc_audio AUD_RESET_TODDR_A>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <512>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_TODDR_B>,
                                 <&clkc_audio AUD_RESET_TODDR_B>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_TODDR_C>,
                                 <&clkc_audio AUD_RESET_TODDR_C>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_FRDDR_A>,
                                 <&clkc_audio AUD_RESET_FRDDR_A>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <512>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_FRDDR_B>,
                                 <&clkc_audio AUD_RESET_FRDDR_B>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_FRDDR_C>,
                                 <&clkc_audio AUD_RESET_FRDDR_C>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
diff --git a/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi b/arch/arm64/boot/dts/amlogic/meson-gx-libretech-pc.dtsi
new file mode 100644 (file)
index 0000000..248b018
--- /dev/null
@@ -0,0 +1,375 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 BayLibre SAS.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+/* Libretech Amlogic GX PC form factor - AKA: Tartiflette */
+
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+
+/ {
+       adc-keys {
+               compatible = "adc-keys";
+               io-channels = <&saradc 0>;
+               io-channel-names = "buttons";
+               keyup-threshold-microvolt = <1800000>;
+
+               update-button {
+                       label = "update";
+                       linux,code = <KEY_VENDOR>;
+                       press-threshold-microvolt = <1300000>;
+               };
+       };
+
+       aliases {
+               serial0 = &uart_AO;
+               ethernet0 = &ethmac;
+               spi0 = &spifc;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       cvbs-connector {
+               compatible = "composite-video-connector";
+               status = "disabled";
+
+               port {
+                       cvbs_connector_in: endpoint {
+                               remote-endpoint = <&cvbs_vdac_out>;
+                       };
+               };
+       };
+
+       emmc_pwrseq: emmc-pwrseq {
+               compatible = "mmc-pwrseq-emmc";
+               reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
+       };
+
+       hdmi-connector {
+               compatible = "hdmi-connector";
+               type = "a";
+
+               port {
+                       hdmi_connector_in: endpoint {
+                               remote-endpoint = <&hdmi_tx_tmds_out>;
+                       };
+               };
+       };
+
+       gpio-keys-polled {
+               compatible = "gpio-keys-polled";
+               poll-interval = <100>;
+
+               power-button {
+                       label = "power";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio_ao GPIOAO_2 GPIO_ACTIVE_LOW>;
+               };
+       };
+
+       memory@0 {
+               device_type = "memory";
+               reg = <0x0 0x0 0x0 0x80000000>;
+       };
+
+       ao_5v: regulator-ao_5v {
+               compatible = "regulator-fixed";
+               regulator-name = "AO_5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&dc_in>;
+               regulator-always-on;
+       };
+
+       dc_in: regulator-dc_in {
+               compatible = "regulator-fixed";
+               regulator-name = "DC_IN";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               regulator-always-on;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+
+               green {
+                       color = <LED_COLOR_ID_GREEN>;
+                       function = LED_FUNCTION_DISK_ACTIVITY;
+                       gpios = <&gpio_ao GPIOAO_9 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "disk-activity";
+               };
+
+               blue {
+                       color = <LED_COLOR_ID_BLUE>;
+                       function = LED_FUNCTION_STATUS;
+                       gpios = <&gpio GPIODV_28 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+                       panic-indicator;
+               };
+       };
+
+       vcc_card: regulator-vcc_card {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_CARD";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&vddio_ao3v3>;
+
+               gpio = <&gpio GPIODV_4 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       vcc5v: regulator-vcc5v {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC5V";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&ao_5v>;
+
+               gpio = <&gpio GPIOH_3 GPIO_OPEN_DRAIN>;
+       };
+
+       vddio_ao18: regulator-vddio_ao18 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO18";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&ao_5v>;
+               regulator-always-on;
+       };
+
+       vddio_ao3v3: regulator-vddio_ao3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_AO3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               vin-supply = <&ao_5v>;
+               regulator-always-on;
+       };
+
+       vddio_boot: regulator-vddio_boot {
+               compatible = "regulator-fixed";
+               regulator-name = "VDDIO_BOOT";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               vin-supply = <&vddio_ao3v3>;
+               regulator-always-on;
+       };
+
+       vddio_card: regulator-vddio-card {
+               compatible = "regulator-gpio";
+               regulator-name = "VDDIO_CARD";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <3300000>;
+
+               gpios = <&gpio GPIODV_5 GPIO_ACTIVE_HIGH>;
+               gpios-states = <0>;
+
+               states = <3300000 0>,
+                        <1800000 1>;
+
+               regulator-settling-time-up-us = <200>;
+               regulator-settling-time-down-us = <50000>;
+       };
+};
+
+&cec_AO {
+       pinctrl-0 = <&ao_cec_pins>;
+       pinctrl-names = "default";
+       hdmi-phandle = <&hdmi_tx>;
+       status = "okay";
+};
+
+&cvbs_vdac_port {
+       cvbs_vdac_out: endpoint {
+               remote-endpoint = <&cvbs_connector_in>;
+       };
+};
+
+&ethmac {
+       pinctrl-0 = <&eth_pins>, <&eth_phy_irq_pins>;
+       pinctrl-names = "default";
+       phy-handle = <&external_phy>;
+       amlogic,tx-delay-ns = <2>;
+       phy-mode = "rgmii";
+       status = "okay";
+};
+
+&external_mdio {
+       external_phy: ethernet-phy@0 {
+               reg = <0>;
+               max-speed = <1000>;
+               reset-assert-us = <10000>;
+               reset-deassert-us = <30000>;
+               reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>;
+               interrupt-parent = <&gpio_intc>;
+               interrupts = <25 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
+
+&pinctrl_periphs {
+       /*
+        * Make sure the reset pin of the usb HUB is driven high to take
+        * it out of reset.
+        */
+       usb1_rst_pins: usb1_rst_irq {
+               mux {
+                       groups = "GPIODV_3";
+                       function = "gpio_periphs";
+                       bias-disable;
+                       output-high;
+               };
+       };
+
+       /* Make sure the phy irq pin is properly configured as input */
+       eth_phy_irq_pins: eth_phy_irq {
+               mux {
+                       groups = "GPIOZ_15";
+                       function = "gpio_periphs";
+                       bias-disable;
+                       output-disable;
+               };
+       };
+};
+
+&hdmi_tx {
+       pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>;
+       pinctrl-names = "default";
+       hdmi-supply = <&vcc5v>;
+       status = "okay";
+};
+
+&hdmi_tx_tmds_port {
+       hdmi_tx_tmds_out: endpoint {
+               remote-endpoint = <&hdmi_connector_in>;
+       };
+};
+
+&ir {
+       pinctrl-0 = <&remote_input_ao_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&i2c_C {
+       pinctrl-0 = <&i2c_c_dv18_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       rtc: rtc@51 {
+               reg = <0x51>;
+               compatible = "nxp,pcf8563";
+               #clock-cells = <0>;
+               clock-output-names = "rtc_clkout";
+       };
+};
+
+&pwm_AO_ab {
+       pinctrl-0 = <&pwm_ao_a_3_pins>;
+       pinctrl-names = "default";
+       clocks = <&clkc CLKID_FCLK_DIV4>;
+       clock-names = "clkin0";
+       status = "okay";
+};
+
+&pwm_ab {
+       pinctrl-0 = <&pwm_b_pins>;
+       pinctrl-names = "default";
+       clocks = <&clkc CLKID_FCLK_DIV4>;
+       clock-names = "clkin0";
+       status = "okay";
+};
+
+&pwm_ef {
+       pinctrl-0 = <&pwm_e_pins>, <&pwm_f_clk_pins>;
+       pinctrl-names = "default";
+       clocks = <&clkc CLKID_FCLK_DIV4>;
+       clock-names = "clkin0";
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vddio_ao18>;
+       status = "okay";
+};
+
+/* SD card */
+&sd_emmc_b {
+       pinctrl-0 = <&sdcard_pins>;
+       pinctrl-1 = <&sdcard_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <4>;
+       cap-sd-highspeed;
+       sd-uhs-sdr12;
+       sd-uhs-sdr25;
+       sd-uhs-sdr50;
+       sd-uhs-ddr50;
+       max-frequency = <200000000>;
+       disable-wp;
+
+       cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_LOW>;
+
+       vmmc-supply = <&vcc_card>;
+       vqmmc-supply = <&vddio_card>;
+
+       status = "okay";
+};
+
+/* eMMC */
+&sd_emmc_c {
+       pinctrl-0 = <&emmc_pins>;
+       pinctrl-1 = <&emmc_clk_gate_pins>;
+       pinctrl-names = "default", "clk-gate";
+
+       bus-width = <8>;
+       cap-mmc-highspeed;
+       mmc-ddr-1_8v;
+       mmc-hs200-1_8v;
+       max-frequency = <200000000>;
+       disable-wp;
+
+       mmc-pwrseq = <&emmc_pwrseq>;
+       vmmc-supply = <&vddio_ao3v3>;
+       vqmmc-supply = <&vddio_boot>;
+
+       status = "okay";
+};
+
+&spifc {
+       pinctrl-0 = <&nor_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+
+       gd25lq128: spi-flash@0 {
+               compatible = "jedec,spi-nor";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0>;
+               spi-max-frequency = <12000000>;
+       };
+};
+
+&uart_AO {
+       pinctrl-0 = <&uart_ao_a_pins>;
+       pinctrl-names = "default";
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+};
+
+&usb2_phy0 {
+       pinctrl-0 = <&usb1_rst_pins>;
+       pinctrl-names = "default";
+       phy-supply = <&vcc5v>;
+};
+
+&usb2_phy1 {
+       phy-supply = <&vcc5v>;
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-kii-pro.dts
new file mode 100644 (file)
index 0000000..2f1f829
--- /dev/null
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Mohammad Rasim <mohammad.rasim96@gmail.com>
+ */
+
+/dts-v1/;
+
+#include "meson-gxbb-p20x.dtsi"
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/leds/common.h>
+/ {
+       compatible = "videostrong,kii-pro", "amlogic,p201", "amlogic,s905", "amlogic,meson-gxbb";
+       model = "Videostrong KII Pro";
+
+       leds {
+               compatible = "gpio-leds";
+               status {
+                       gpios = <&gpio_ao GPIOAO_13 GPIO_ACTIVE_LOW>;
+                       default-state = "off";
+                       color = <LED_COLOR_ID_RED>;
+                       function = LED_FUNCTION_STATUS;
+               };
+       };
+
+       gpio-keys-polled {
+               compatible = "gpio-keys-polled";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               poll-interval = <20>;
+
+               button-reset {
+                       label = "reset";
+                       linux,code = <KEY_POWER>;
+                       gpios = <&gpio_ao GPIOAO_3 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+};
+
+
+
+&uart_A {
+       status = "okay";
+       pinctrl-0 = <&uart_a_pins>, <&uart_a_cts_rts_pins>;
+       pinctrl-names = "default";
+       uart-has-rtscts;
+
+       bluetooth {
+               compatible = "brcm,bcm4335a0";
+       };
+};
+
+
+
+&ethmac {
+       status = "okay";
+       pinctrl-0 = <&eth_rmii_pins>;
+       pinctrl-names = "default";
+
+       phy-handle = <&eth_phy0>;
+       phy-mode = "rmii";
+
+       mdio {
+               compatible = "snps,dwmac-mdio";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               eth_phy0: ethernet-phy@0 {
+                       /* IC Plus IP101GR (0x02430c54) */
+                       reg = <0>;
+                       reset-assert-us = <10000>;
+                       reset-deassert-us = <10000>;
+                       reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>;
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-libretech-pc.dts b/arch/arm64/boot/dts/amlogic/meson-gxl-s905d-libretech-pc.dts
new file mode 100644 (file)
index 0000000..100a1cf
--- /dev/null
@@ -0,0 +1,16 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+/dts-v1/;
+
+#include "meson-gxl-s905d.dtsi"
+#include "meson-gx-libretech-pc.dtsi"
+
+/ {
+       compatible = "libretech,aml-s905d-pc", "amlogic,s905d",
+                    "amlogic,meson-gxl";
+       model = "Libre Computer AML-S905D-PC";
+};
index ed33d8e..259d863 100644 (file)
                        };
                };
 
+               i2c_c_dv18_pins: i2c_c_dv18 {
+                       mux {
+                               groups = "i2c_sck_c_dv19",
+                                     "i2c_sda_c_dv18";
+                               function = "i2c_c";
+                               bias-disable;
+                       };
+               };
+
                eth_pins: eth_c {
                        mux {
                                groups = "eth_mdio",
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-s912-libretech-pc.dts
new file mode 100644 (file)
index 0000000..444c249
--- /dev/null
@@ -0,0 +1,62 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 BayLibre SAS. All rights reserved.
+ * Author: Jerome Brunet <jbrunet@baylibre.com>
+ */
+
+/dts-v1/;
+
+#include "meson-gxm.dtsi"
+#include "meson-gx-libretech-pc.dtsi"
+
+/ {
+       compatible = "libretech,aml-s912-pc", "amlogic,s912",
+                    "amlogic,meson-gxm";
+       model = "Libre Computer AML-S912-PC";
+
+       typec2_vbus: regulator-typec2_vbus {
+               compatible = "regulator-fixed";
+               regulator-name = "TYPEC2_VBUS";
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc5v>;
+
+               gpio = <&gpio GPIODV_1 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+};
+
+&pinctrl_periphs {
+       /*
+        * Make sure the irq pin of the TYPE C controller is not driven
+        * by the SoC.
+        */
+       fusb302_irq_pins: fusb302_irq {
+               mux {
+                       groups = "GPIODV_0";
+                       function = "gpio_periphs";
+                       bias-pull-up;
+                       output-disable;
+               };
+       };
+};
+
+&i2c_C {
+       fusb302@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+
+               pinctrl-0 = <&fusb302_irq_pins>;
+               pinctrl-names = "default";
+               interrupt-parent = <&gpio_intc>;
+               interrupts = <59 IRQ_TYPE_LEVEL_LOW>;
+
+               vbus-supply = <&typec2_vbus>;
+
+               status = "okay";
+       };
+};
+
+&usb2_phy2 {
+       phy-supply = <&typec2_vbus>;
+};
index 7894a54..d847a3f 100644 (file)
                        resets = <&arb AXG_ARB_TODDR_A>,
                                 <&clkc_audio AUD_RESET_TODDR_A>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <8192>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_TODDR_B>,
                                 <&clkc_audio AUD_RESET_TODDR_B>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_TODDR_C>,
                                 <&clkc_audio AUD_RESET_TODDR_C>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_FRDDR_A>,
                                 <&clkc_audio AUD_RESET_FRDDR_A>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <512>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_FRDDR_B>,
                                 <&clkc_audio AUD_RESET_FRDDR_B>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_FRDDR_C>,
                                 <&clkc_audio AUD_RESET_FRDDR_C>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_TODDR_D>,
                                 <&clkc_audio AUD_RESET_TODDR_D>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
 
                        resets = <&arb AXG_ARB_FRDDR_D>,
                                 <&clkc_audio AUD_RESET_FRDDR_D>;
                        reset-names = "arb", "rst";
+                       amlogic,fifo-depth = <256>;
                        status = "disabled";
                };
        };
        power-domains = <&pwrc PWRC_SM1_VPU_ID>;
 };
 
+&vdec {
+       compatible = "amlogic,sm1-vdec";
+};
+
 &vpu {
        power-domains = <&pwrc PWRC_SM1_VPU_ID>;
 };
index 3e8c707..7a2c7f9 100644 (file)
                reg = <0x1 0x00000000 0x0 0x40000000>; // 1GB
        };
 
-       uart_clk: uart-clk {
-               compatible = "fixed-clock";
-               clock-frequency = <500000000>;
-               #clock-cells = <0>;
-       };
-
        soc {
                gpio0: gpio@50027000 {
                        porta: gpio-controller@0 {
 
 &uart0 {
        status = "okay";
-       clocks = <&uart_clk>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart0_default>;
 };
 
 &uart1 {
        status = "okay";
-       clocks = <&uart_clk>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart1_default>;
 };
 
 &uart2 {
        status = "okay";
-       clocks = <&uart_clk>;
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_uart2_default>;
 };
index d65453f..fa6e690 100644 (file)
@@ -4,6 +4,7 @@
  * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
  */
 
+#include <dt-bindings/clock/bm1880-clock.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset/bitmain,bm1880-reset.h>
 
                             <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
        };
 
+       osc: osc {
+               compatible = "fixed-clock";
+               clock-frequency = <25000000>;
+               #clock-cells = <0>;
+       };
+
        soc {
                compatible = "simple-bus";
                #address-cells = <2>;
                                reg = <0x400 0x120>;
                        };
 
+                       clk: clock-controller@e8 {
+                               compatible = "bitmain,bm1880-clk";
+                               reg = <0xe8 0x0c>, <0x800 0xb0>;
+                               reg-names = "pll", "sys";
+                               clocks = <&osc>;
+                               clock-names = "osc";
+                               #clock-cells = <1>;
+                       };
+
                        rst: reset-controller@c00 {
                                compatible = "bitmain,bm1880-reset";
                                reg = <0xc00 0x8>;
                uart0: serial@58018000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x0 0x58018000 0x0 0x2000>;
+                       clocks = <&clk BM1880_CLK_UART_500M>,
+                                <&clk BM1880_CLK_APB_UART>;
+                       clock-names = "baudclk", "apb_pclk";
                        interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                uart1: serial@5801A000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x0 0x5801a000 0x0 0x2000>;
+                       clocks = <&clk BM1880_CLK_UART_500M>,
+                                <&clk BM1880_CLK_APB_UART>;
+                       clock-names = "baudclk", "apb_pclk";
                        interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                uart2: serial@5801C000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x0 0x5801c000 0x0 0x2000>;
+                       clocks = <&clk BM1880_CLK_UART_500M>,
+                                <&clk BM1880_CLK_APB_UART>;
+                       clock-names = "baudclk", "apb_pclk";
                        interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
                uart3: serial@5801E000 {
                        compatible = "snps,dw-apb-uart";
                        reg = <0x0 0x5801e000 0x0 0x2000>;
+                       clocks = <&clk BM1880_CLK_UART_500M>,
+                                <&clk BM1880_CLK_APB_UART>;
+                       clock-names = "baudclk", "apb_pclk";
                        interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
                        reg-shift = <2>;
                        reg-io-width = <4>;
index 6f90b0e..250fc01 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG Exynos5433 TM2 board device tree source
+ * Samsung Exynos5433 TM2 board device tree source
  *
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
index dda5d27..fdd0796 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG Exynos5433 TM2 board device tree source
+ * Samsung Exynos5433 TM2 board device tree source
  *
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
index 1e207ce..089fc7a 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG Exynos5433 TM2E board device tree source
+ * Samsung Exynos5433 TM2E board device tree source
  *
  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
  *
index 080e0f5..7af288f 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG Exynos7 Espresso board device tree source
+ * Samsung Exynos7 Espresso board device tree source
  *
  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
@@ -13,7 +13,7 @@
 #include <dt-bindings/gpio/gpio.h>
 
 / {
-       model = "Samsung Exynos7 Espresso board based on EXYNOS7";
+       model = "Samsung Exynos7 Espresso board based on Exynos7";
        compatible = "samsung,exynos7-espresso", "samsung,exynos7";
 
        aliases {
index 3a00ef0..5558045 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * SAMSUNG EXYNOS7 SoC device tree source
+ * Samsung Exynos7 SoC device tree source
  *
  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
index 38e344a..bac293e 100644 (file)
@@ -18,6 +18,8 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-rdb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2080a-simu.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls2088a-rdb.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-clearfog-cx.dtb
+dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-honeycomb.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb
 dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-rdb.dtb
 
@@ -28,7 +30,9 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mq-evk.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-hummingboard-pulse.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-librem5-devkit.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-nitrogen.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mq-phanbell.dtb
 dtb-$(CONFIG_ARCH_MXC) += imx8mq-pico-pi.dtb
+dtb-$(CONFIG_ARCH_MXC) += imx8mq-thor96.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
index 5b9d4b3..ca409d9 100644 (file)
        status = "okay";
 };
 
+&fspi {
+       status = "okay";
+
+       mt35xu02g0: flash@0 {
+               compatible = "jedec,spi-nor";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               spi-max-frequency = <50000000>;
+               /* The following setting enables 1-1-8 (CMD-ADDR-DATA) mode */
+               spi-rx-bus-width = <8>; /* 8 SPI Rx lines */
+               spi-tx-bus-width = <1>; /* 1 SPI Tx line */
+               reg = <0>;
+       };
+};
+
 &i2c0 {
        status = "okay";
 
index 9720a19..afb5565 100644 (file)
 
 &esdhc1 {
        mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
+       bus-width = <8>;
        status = "okay";
 };
 
+&fspi {
+       status = "okay";
+
+       mt35xu02g0: flash@0 {
+               compatible = "jedec,spi-nor";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               spi-max-frequency = <50000000>;
+               /* The following setting enables 1-1-8 (CMD-ADDR-DATA) mode */
+               spi-rx-bus-width = <8>; /* 8 SPI Rx lines */
+               spi-tx-bus-width = <1>; /* 1 SPI Tx line */
+               reg = <0>;
+       };
+};
+
 &i2c0 {
        status = "okay";
 
index a6f9b77..0bf375e 100644 (file)
                        status = "disabled";
                };
 
+               fspi: spi@20c0000 {
+                       compatible = "nxp,lx2160a-fspi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x20c0000 0x0 0x10000>,
+                             <0x0 0x20000000 0x0 0x10000000>;
+                       reg-names = "fspi_base", "fspi_mmap";
+                       interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       clock-names = "fspi_en", "fspi";
+                       status = "disabled";
+               };
+
                esdhc: mmc@2140000 {
                        compatible = "fsl,ls1028a-esdhc", "fsl,esdhc";
                        reg = <0x0 0x2140000 0x0 0x10000>;
 
                edma0: dma-controller@22c0000 {
                        #dma-cells = <2>;
-                       compatible = "fsl,vf610-edma";
+                       compatible = "fsl,ls1028a-edma";
                        reg = <0x0 0x22c0000 0x0 0x10000>,
                              <0x0 0x22d0000 0x0 0x10000>,
                              <0x0 0x22e0000 0x0 0x10000>;
                        dma-names = "tx", "rx";
                        dmas = <&edma0 1 4>,
                               <&edma0 1 3>;
+                       fsl,sai-asynchronous;
                        status = "disabled";
                };
 
                        dma-names = "tx", "rx";
                        dmas = <&edma0 1 6>,
                               <&edma0 1 5>;
+                       fsl,sai-asynchronous;
+                       status = "disabled";
+               };
+
+               sai3: audio-controller@f120000 {
+                       #sound-dai-cells = <0>;
+                       compatible = "fsl,vf610-sai";
+                       reg = <0x0 0xf120000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+                                <&clockgen 4 1>, <&clockgen 4 1>;
+                       clock-names = "bus", "mclk1", "mclk2", "mclk3";
+                       dma-names = "tx", "rx";
+                       dmas = <&edma0 1 8>,
+                              <&edma0 1 7>;
+                       fsl,sai-asynchronous;
                        status = "disabled";
                };
 
                        dma-names = "tx", "rx";
                        dmas = <&edma0 1 10>,
                               <&edma0 1 9>;
+                       fsl,sai-asynchronous;
+                       status = "disabled";
+               };
+
+               sai5: audio-controller@f140000 {
+                       #sound-dai-cells = <0>;
+                       compatible = "fsl,vf610-sai";
+                       reg = <0x0 0xf140000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+                                <&clockgen 4 1>, <&clockgen 4 1>;
+                       clock-names = "bus", "mclk1", "mclk2", "mclk3";
+                       dma-names = "tx", "rx";
+                       dmas = <&edma0 1 12>,
+                              <&edma0 1 11>;
+                       fsl,sai-asynchronous;
+                       status = "disabled";
+               };
+
+               sai6: audio-controller@f150000 {
+                       #sound-dai-cells = <0>;
+                       compatible = "fsl,vf610-sai";
+                       reg = <0x0 0xf150000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&clockgen 4 1>, <&clockgen 4 1>,
+                                <&clockgen 4 1>, <&clockgen 4 1>;
+                       clock-names = "bus", "mclk1", "mclk2", "mclk3";
+                       dma-names = "tx", "rx";
+                       dmas = <&edma0 1 14>,
+                              <&edma0 1 13>;
+                       fsl,sai-asynchronous;
                        status = "disabled";
                };
 
index 3595be0..db3d303 100644 (file)
 
 };
 
+&qspi {
+       status = "okay";
+
+       mt25qu512a0: flash@0 {
+               compatible = "jedec,spi-nor";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               spi-max-frequency = <50000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
+               reg = <0>;
+       };
+};
+
 #include "fsl-ls1046-post.dtsi"
 
 &fman0 {
index 0c742be..dbc23d6 100644 (file)
 &qspi {
        status = "okay";
 
-       qflash0: flash@0 {
-               compatible = "spansion,m25p80";
+       s25fs512s0: flash@0 {
+               compatible = "jedec,spi-nor";
                #address-cells = <1>;
                #size-cells = <1>;
-               spi-max-frequency = <20000000>;
+               spi-max-frequency = <50000000>;
                spi-rx-bus-width = <4>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                reg = <0>;
        };
 
-       qflash1: flash@1 {
-               compatible = "spansion,m25p80";
+       s25fs512s1: flash@1 {
+               compatible = "jedec,spi-nor";
                #address-cells = <1>;
                #size-cells = <1>;
-               spi-max-frequency = <20000000>;
+               spi-max-frequency = <50000000>;
                spi-rx-bus-width = <4>;
-               spi-tx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
                reg = <1>;
        };
 };
index 120e62d..41d8b15 100644 (file)
        status = "okay";
 };
 
+&qspi {
+       status = "okay";
+
+       s25fs512s0: flash@0 {
+               compatible = "jedec,spi-nor";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               spi-max-frequency = <50000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
+               reg = <0>;
+       };
+
+       s25fs512s1: flash@1 {
+               compatible = "jedec,spi-nor";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               spi-max-frequency = <50000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
+               reg = <1>;
+       };
+};
+
 &sata {
        status = "okay";
 };
index 90b1989..4d77b34 100644 (file)
        status = "okay";
 };
 
+&qspi {
+       status = "okay";
+
+       s25fs512s0: flash@0 {
+               compatible = "jedec,spi-nor";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               spi-max-frequency = <50000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
+               reg = <0>;
+       };
+
+       s25fs512s1: flash@1 {
+               compatible = "jedec,spi-nor";
+               #address-cells = <1>;
+               #size-cells = <1>;
+               spi-max-frequency = <50000000>;
+               spi-rx-bus-width = <4>;
+               spi-tx-bus-width = <1>;
+               reg = <1>;
+       };
+};
+
 &sata {
        status = "okay";
 };
index c676d07..5945662 100644 (file)
                        status = "disabled";
                };
 
+               qspi: spi@20c0000 {
+                       compatible = "fsl,ls2080a-qspi";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <0x0 0x20c0000 0x0 0x10000>,
+                             <0x0 0x20000000 0x0 0x10000000>;
+                       reg-names = "QuadSPI", "QuadSPI-memory";
+                       interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
+                       clock-names = "qspi_en", "qspi";
+                       clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+                       status = "disabled";
+               };
+
                esdhc: esdhc@2140000 {
                        compatible = "fsl,ls1088a-esdhc", "fsl,esdhc";
                        reg = <0x0 0x2140000 0x0 0x10000>;
index 6fd7f63..d0d6702 100644 (file)
 };
 
 &qspi {
-       status = "disabled";
+       status = "okay";
+
+       s25fs512s0: flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "jedec,spi-nor";
+               spi-max-frequency = <50000000>;
+               reg = <0>;
+       };
 };
 
 &sata0 {
index 7a0be8e..f96d06d 100644 (file)
                };
 
                qspi: spi@20c0000 {
-                       status = "disabled";
-                       compatible = "fsl,ls2080a-qspi", "fsl,ls1021a-qspi";
+                       compatible = "fsl,ls2080a-qspi";
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <0x0 0x20c0000 0x0 0x10000>,
                              <0x0 0x20000000 0x0 0x10000000>;
                        reg-names = "QuadSPI", "QuadSPI-memory";
-                       interrupts = <0 25 0x4>; /* Level high type */
+                       interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&clockgen 4 3>, <&clockgen 4 3>;
                        clock-names = "qspi_en", "qspi";
+                       status = "disabled";
                };
 
                pcie1: pcie@3400000 {
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-cex7.dtsi
new file mode 100644 (file)
index 0000000..071e216
--- /dev/null
@@ -0,0 +1,127 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Device Tree file for LX2160A-CEx7
+//
+// Copyright 2019 SolidRun Ltd.
+
+/dts-v1/;
+
+#include "fsl-lx2160a.dtsi"
+
+/ {
+       model = "SolidRun LX2160A COM Express Type 7 module";
+       compatible = "solidrun,lx2160a-cex7", "fsl,lx2160a";
+
+       aliases {
+               crypto = &crypto;
+       };
+
+       sb_3v3: regulator-sb3v3 {
+               compatible = "regulator-fixed";
+               regulator-name = "RT7290";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&crypto {
+       status = "okay";
+};
+
+&dpmac17 {
+       phy-handle = <&rgmii_phy1>;
+       phy-connection-type = "rgmii-id";
+};
+
+&emdio1 {
+       status = "okay";
+
+       rgmii_phy1: ethernet-phy@1 {
+               reg = <1>;
+       };
+};
+
+&esdhc1 {
+       mmc-hs200-1_8v;
+       mmc-hs400-1_8v;
+       bus-width = <8>;
+       status = "okay";
+};
+
+&i2c0 {
+       status = "okay";
+
+       i2c-switch@77 {
+               compatible = "nxp,pca9547";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               reg = <0x77>;
+
+               i2c@1 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <1>;
+
+                       fan-temperature-ctrlr@18 {
+                               compatible = "ti,amc6821";
+                               reg = <0x18>;
+                               cooling-min-state = <0>;
+                               cooling-max-state = <9>;
+                               #cooling-cells = <2>;
+                       };
+               };
+
+               i2c@3 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       reg = <3>;
+
+                       temperature-sensor@48 {
+                               compatible = "nxp,sa56004";
+                               reg = <0x48>;
+                               vcc-supply = <&sb_3v3>;
+                       };
+               };
+       };
+};
+
+&i2c2 {
+       status = "okay";
+};
+
+&i2c4 {
+       status = "okay";
+
+       rtc@51 {
+               compatible = "nxp,pcf2129";
+               reg = <0x51>;
+               // IRQ10_B
+               interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>;
+       };
+};
+
+&fspi {
+       status = "okay";
+
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               compatible = "micron,m25p80";
+               m25p,fast-read;
+               spi-max-frequency = <50000000>;
+               reg = <0>;
+               /* The following setting enables 1-1-8 (CMD-ADDR-DATA) mode */
+               spi-rx-bus-width = <8>;
+               spi-tx-bus-width = <1>;
+       };
+};
+
+&usb0 {
+       status = "okay";
+};
+
+&usb1 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-cx.dts
new file mode 100644 (file)
index 0000000..86a9b77
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Device Tree file for LX2160A Clearfog CX board
+//
+// Copyright 2019 SolidRun Ltd.
+
+/dts-v1/;
+
+#include "fsl-lx2160a-clearfog-itx.dtsi"
+
+/ {
+       model = "SolidRun LX2160A Clearfog CX";
+       compatible = "solidrun,clearfog-cx",
+               "solidrun,lx2160a-cex7", "fsl,lx2160a";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-clearfog-itx.dtsi
new file mode 100644 (file)
index 0000000..f3741a3
--- /dev/null
@@ -0,0 +1,57 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Device Tree file for LX2160A Clearfog ITX board; this contains the
+// common parts shared between the Clearfog CX and Honeycomb builds.
+//
+// Copyright 2019 SolidRun Ltd.
+
+/dts-v1/;
+
+#include "fsl-lx2160a-cex7.dtsi"
+
+/ {
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&emdio2 {
+       status = "okay";
+};
+
+&esdhc0 {
+       sd-uhs-sdr104;
+       sd-uhs-sdr50;
+       sd-uhs-sdr25;
+       sd-uhs-sdr12;
+       status = "okay";
+};
+
+&sata0 {
+       status = "okay";
+};
+
+&sata1 {
+       status = "okay";
+};
+
+&sata2 {
+       status = "okay";
+};
+
+&sata3 {
+       status = "okay";
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-honeycomb.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-honeycomb.dts
new file mode 100644 (file)
index 0000000..fe19f30
--- /dev/null
@@ -0,0 +1,15 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+//
+// Device Tree file for LX2160A Honeycomb board
+//
+// Copyright 2019 SolidRun Ltd.
+
+/dts-v1/;
+
+#include "fsl-lx2160a-clearfog-itx.dtsi"
+
+/ {
+       model = "SolidRun LX2160A Honeycomb";
+       compatible = "solidrun,honeycomb",
+               "solidrun,lx2160a-cex7", "fsl,lx2160a";
+};
index c2817b7..51615de 100644 (file)
        status = "okay";
 };
 
+&dpmac17 {
+       phy-handle = <&rgmii_phy1>;
+       phy-connection-type = "rgmii-id";
+};
+
+&dpmac18 {
+       phy-handle = <&rgmii_phy2>;
+       phy-connection-type = "rgmii-id";
+};
+
+&emdio1 {
+       status = "okay";
+
+       rgmii_phy1: ethernet-phy@1 {
+               /* AR8035 PHY */
+               compatible = "ethernet-phy-id004d.d072";
+               reg = <0x1>;
+               eee-broken-1000t;
+       };
+
+       rgmii_phy2: ethernet-phy@2 {
+               /* AR8035 PHY */
+               compatible = "ethernet-phy-id004d.d072";
+               reg = <0x2>;
+               eee-broken-1000t;
+       };
+};
+
 &esdhc0 {
        sd-uhs-sdr104;
        sd-uhs-sdr50;
index e883fe0..e5ee559 100644 (file)
                        fsl,extts-fifo;
                };
 
+               /* WRIOP0: 0x8b8_0000, E-MDIO1: 0x1_6000 */
+               emdio1: mdio@8b96000 {
+                       compatible = "fsl,fman-memac-mdio";
+                       reg = <0x0 0x8b96000 0x0 0x1000>;
+                       interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       little-endian;
+                       status = "disabled";
+               };
+
+               emdio2: mdio@8b97000 {
+                       compatible = "fsl,fman-memac-mdio";
+                       reg = <0x0 0x8b97000 0x0 0x1000>;
+                       interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+                       little-endian;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
+
                fsl_mc: fsl-mc@80c000000 {
                        compatible = "fsl,qoriq-mc";
                        reg = <0x00000008 0x0c000000 0 0x40>,
index 28ab17a..9e54747 100644 (file)
                stdout-path = &uart2;
        };
 
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x0 0x40000000 0 0x80000000>;
+       };
+
        leds {
                compatible = "gpio-leds";
                pinctrl-names = "default";
        cpu-supply = <&buck2_reg>;
 };
 
+&ddrc {
+       operating-points-v2 = <&ddrc_opp_table>;
+
+       ddrc_opp_table: opp-table {
+               compatible = "operating-points-v2";
+
+               opp-25M {
+                       opp-hz = /bits/ 64 <25000000>;
+               };
+
+               opp-100M {
+                       opp-hz = /bits/ 64 <100000000>;
+               };
+
+               opp-750M {
+                       opp-hz = /bits/ 64 <750000000>;
+               };
+       };
+};
+
 &fec1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_fec1>;
index cffa899..5ccc4cc 100644 (file)
 #define MX8MM_IOMUXC_SAI1_MCLK_SIM_M_HRESP                                  0x1AC 0x414 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI2_RXFS_SAI2_RX_SYNC                                 0x1B0 0x418 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI2_RXFS_SAI5_TX_SYNC                                 0x1B0 0x418 0x4EC 0x1 0x2
+#define MX8MM_IOMUXC_SAI2_RXFS_UART1_DCE_TX                                 0x1B0 0x418 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI2_RXFS_UART1_DTE_RX                                 0x1B0 0x418 0x4F4 0x4 0x2
 #define MX8MM_IOMUXC_SAI2_RXFS_GPIO4_IO21                                   0x1B0 0x418 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI2_RXFS_SIM_M_HSIZE0                                 0x1B0 0x418 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI2_RXC_SAI2_RX_BCLK                                  0x1B4 0x41C 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI2_RXC_SAI5_TX_BCLK                                  0x1B4 0x41C 0x4E8 0x1 0x2
+#define MX8MM_IOMUXC_SAI2_RXC_UART1_DCE_RX                                  0x1B4 0x41C 0x4F4 0x4 0x3
+#define MX8MM_IOMUXC_SAI2_RXC_UART1_DTE_TX                                  0x1B4 0x41C 0x000 0x4 0x0
 #define MX8MM_IOMUXC_SAI2_RXC_GPIO4_IO22                                    0x1B4 0x41C 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI2_RXC_SIM_M_HSIZE1                                  0x1B4 0x41C 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0                                0x1B8 0x420 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI2_RXD0_SAI5_TX_DATA0                                0x1B8 0x420 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI2_RXD0_UART1_DCE_RTS_B                              0x1B8 0x420 0x4F0 0x4 0x2
+#define MX8MM_IOMUXC_SAI2_RXD0_UART1_DTE_CTS_B                              0x1B8 0x420 0x000 0x4 0x0
 #define MX8MM_IOMUXC_SAI2_RXD0_GPIO4_IO23                                   0x1B8 0x420 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI2_RXD0_SIM_M_HSIZE2                                 0x1B8 0x420 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC                                 0x1BC 0x424 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI2_TXFS_SAI5_TX_DATA1                                0x1BC 0x424 0x000 0x1 0x0
+#define MX8MM_IOMUXC_SAI2_TXFS_UART1_DCE_CTS_B                              0x1BC 0x424 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI2_TXFS_UART1_DTE_RTS_B                              0x1BC 0x424 0x4F0 0x4 0x3
 #define MX8MM_IOMUXC_SAI2_TXFS_GPIO4_IO24                                   0x1BC 0x424 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI2_TXFS_SIM_M_HWRITE                                 0x1BC 0x424 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI2_TXC_SAI2_TX_BCLK                                  0x1C0 0x428 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI3_RXC_SAI3_RX_BCLK                                  0x1D0 0x438 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI3_RXC_GPT1_CLK                                      0x1D0 0x438 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_RXC_SAI5_RX_BCLK                                  0x1D0 0x438 0x4D0 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_RXC_UART2_DCE_CTS_B                               0x1D0 0x438 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI3_RXC_UART2_DTE_RTS_B                               0x1D0 0x438 0x4F8 0x4 0x2
 #define MX8MM_IOMUXC_SAI3_RXC_GPIO4_IO29                                    0x1D0 0x438 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_RXC_TPSMP_HTRANS1                                 0x1D0 0x438 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0                                 0x1D4 0x43C 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI3_RXD_GPT1_COMPARE1                                 0x1D4 0x43C 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_RXD_SAI5_RX_DATA0                                 0x1D4 0x43C 0x4D4 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B                               0x1D4 0x43C 0x4F8 0x4 0x3
+#define MX8MM_IOMUXC_SAI3_RXD_UART2_DTE_CTS_B                               0x1D4 0x43C 0x000 0x4 0x0
 #define MX8MM_IOMUXC_SAI3_RXD_GPIO4_IO30                                    0x1D4 0x43C 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_RXD_TPSMP_HDATA0                                  0x1D4 0x43C 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC                                 0x1D8 0x440 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_GPT1_CAPTURE2                                0x1D8 0x440 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_SAI5_RX_DATA1                                0x1D8 0x440 0x4D8 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX                                 0x1D8 0x440 0x4Fc 0x4 0x2
+#define MX8MM_IOMUXC_SAI3_TXFS_UART2_DTE_TX                                 0x1D8 0x440 0x000 0x4 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31                                   0x1D8 0x440 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_TXFS_TPSMP_HDATA1                                 0x1D8 0x440 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK                                  0x1DC 0x444 0x000 0x0 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_GPT1_COMPARE2                                 0x1DC 0x444 0x000 0x1 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_SAI5_RX_DATA2                                 0x1DC 0x444 0x4DC 0x2 0x2
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX                                  0x1DC 0x444 0x000 0x4 0x0
+#define MX8MM_IOMUXC_SAI3_TXC_UART2_DTE_RX                                  0x1DC 0x444 0x4Fc 0x4 0x3
 #define MX8MM_IOMUXC_SAI3_TXC_GPIO5_IO0                                     0x1DC 0x444 0x000 0x5 0x0
 #define MX8MM_IOMUXC_SAI3_TXC_TPSMP_HDATA2                                  0x1DC 0x444 0x000 0x7 0x0
 #define MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0                                 0x1E0 0x448 0x000 0x0 0x0
index 3d95b66..1e5e115 100644 (file)
                };
        };
 
-       memory@40000000 {
-               device_type = "memory";
-               reg = <0x0 0x40000000 0 0x80000000>;
-       };
-
        osc_32k: clock-osc-32k {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                ranges = <0x0 0x0 0x0 0x3e000000>;
 
                aips1: bus@30000000 {
-                       compatible = "fsl,aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x30000000 0x30000000 0x400000>;
                        };
 
                        anatop: anatop@30360000 {
-                               compatible = "fsl,imx8mm-anatop", "syscon", "simple-bus";
+                               compatible = "fsl,imx8mm-anatop", "syscon";
                                reg = <0x30360000 0x10000>;
                        };
 
                };
 
                aips2: bus@30400000 {
-                       compatible = "fsl,aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x30400000 0x30400000 0x400000>;
                };
 
                aips3: bus@30800000 {
-                       compatible = "fsl,aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x30800000 0x30800000 0x400000>;
                                status = "disabled";
                        };
 
+                       crypto: crypto@30900000 {
+                               compatible = "fsl,sec-v4.0";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x30900000 0x40000>;
+                               ranges = <0 0x30900000 0x40000>;
+                               interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MM_CLK_AHB>,
+                                        <&clk IMX8MM_CLK_IPG_ROOT>;
+                               clock-names = "aclk", "ipg";
+
+                               sec_jr0: jr@1000 {
+                                       compatible = "fsl,sec-v4.0-job-ring";
+                                       reg = <0x1000 0x1000>;
+                                       interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               sec_jr1: jr@2000 {
+                                       compatible = "fsl,sec-v4.0-job-ring";
+                                       reg = <0x2000 0x1000>;
+                                       interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               sec_jr2: jr@3000 {
+                                       compatible = "fsl,sec-v4.0-job-ring";
+                                       reg = <0x3000 0x1000>;
+                                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+                       };
+
                        i2c1: i2c@30a20000 {
                                compatible = "fsl,imx8mm-i2c", "fsl,imx21-i2c";
                                #address-cells = <1>;
                };
 
                aips4: bus@32c00000 {
-                       compatible = "fsl,aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x32c00000 0x32c00000 0x400000>;
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+               ddrc: memory-controller@3d400000 {
+                       compatible = "fsl,imx8mm-ddrc", "fsl,imx8m-ddrc";
+                       reg = <0x3d400000 0x400000>;
+                       clock-names = "core", "pll", "alt", "apb";
+                       clocks = <&clk IMX8MM_CLK_DRAM_CORE>,
+                                <&clk IMX8MM_DRAM_PLL>,
+                                <&clk IMX8MM_CLK_DRAM_ALT>,
+                                <&clk IMX8MM_CLK_DRAM_APB>;
+               };
+
                ddr-pmu@3d800000 {
                        compatible = "fsl,imx8mm-ddr-pmu", "fsl,imx8m-ddr-pmu";
                        reg = <0x3d800000 0x400000>;
index 0719494..2497eeb 100644 (file)
        cpu-supply = <&buck2_reg>;
 };
 
+&ddrc {
+       operating-points-v2 = <&ddrc_opp_table>;
+
+       ddrc_opp_table: opp-table {
+               compatible = "operating-points-v2";
+
+               opp-25M {
+                       opp-hz = /bits/ 64 <25000000>;
+               };
+
+               opp-100M {
+                       opp-hz = /bits/ 64 <100000000>;
+               };
+
+               opp-600M {
+                       opp-hz = /bits/ 64 <600000000>;
+               };
+       };
+};
+
 &i2c1 {
        pmic@4b {
                compatible = "rohm,bd71847";
index 2a74330..0d2ec4a 100644 (file)
@@ -3,6 +3,7 @@
  * Copyright 2019 NXP
  */
 
+#include <dt-bindings/usb/pd.h>
 #include "imx8mn.dtsi"
 
 / {
                };
        };
 
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x0 0x40000000 0 0x80000000>;
+       };
+
        reg_usdhc2_vmmc: regulator-usdhc2 {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
        status = "okay";
 };
 
+&i2c2 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       ptn5110: tcpc@50 {
+               compatible = "nxp,ptn5110";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_typec1>;
+               reg = <0x50>;
+               interrupt-parent = <&gpio2>;
+               interrupts = <11 IRQ_TYPE_LEVEL_LOW>;
+               status = "okay";
+
+               port {
+                       typec1_dr_sw: endpoint {
+                               remote-endpoint = <&usb1_drd_sw>;
+                       };
+               };
+
+               typec1_con: connector {
+                       compatible = "usb-c-connector";
+                       label = "USB-C";
+                       power-role = "dual";
+                       data-role = "dual";
+                       try-power-role = "sink";
+                       source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>;
+                       sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)
+                                    PDO_VAR(5000, 20000, 3000)>;
+                       op-sink-microwatt = <15000000>;
+                       self-powered;
+               };
+       };
+};
+
 &snvs_pwrkey {
        status = "okay";
 };
        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 IMX8MN_CLK_USDHC2>;
        assigned-clock-rates = <200000000>;
                >;
        };
 
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_I2C2_SCL_I2C2_SCL          0x400001c3
+                       MX8MN_IOMUXC_I2C2_SDA_I2C2_SDA          0x400001c3
+               >;
+       };
+
        pinctrl_reg_usdhc2_vmmc: regusdhc2vmmc {
                fsl,pins = <
                        MX8MN_IOMUXC_SD2_RESET_B_GPIO2_IO19     0x41
                >;
        };
 
+       pinctrl_typec1: typec1grp {
+               fsl,pins = <
+                       MX8MN_IOMUXC_SD1_STROBE_GPIO2_IO11      0x159
+               >;
+       };
+
        pinctrl_uart2: uart2grp {
                fsl,pins = <
                        MX8MN_IOMUXC_UART2_RXD_UART2_DCE_RX     0x140
index e916250..a44b543 100644 (file)
                };
        };
 
-       memory@40000000 {
-               device_type = "memory";
-               reg = <0x0 0x40000000 0 0x80000000>;
-       };
-
        osc_32k: clock-osc-32k {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                ranges = <0x0 0x0 0x0 0x3e000000>;
 
                aips1: bus@30000000 {
-                       compatible = "fsl,aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        reg = <0x30000000 0x400000>;
                        #address-cells = <1>;
                        #size-cells = <1>;
 
                        anatop: anatop@30360000 {
                                compatible = "fsl,imx8mn-anatop", "fsl,imx8mm-anatop",
-                                            "syscon", "simple-bus";
+                                            "syscon";
                                reg = <0x30360000 0x10000>;
                        };
 
                };
 
                aips2: bus@30400000 {
-                       compatible = "fsl,aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        reg = <0x30400000 0x400000>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                };
 
                aips3: bus@30800000 {
-                       compatible = "fsl,aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        reg = <0x30800000 0x400000>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                                status = "disabled";
                        };
 
+                       crypto: crypto@30900000 {
+                               compatible = "fsl,sec-v4.0";
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+                               reg = <0x30900000 0x40000>;
+                               ranges = <0 0x30900000 0x40000>;
+                               interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MN_CLK_AHB>,
+                                        <&clk IMX8MN_CLK_IPG_ROOT>;
+                               clock-names = "aclk", "ipg";
+
+                               sec_jr0: jr0@1000 {
+                                        compatible = "fsl,sec-v4.0-job-ring";
+                                        reg = <0x1000 0x1000>;
+                                        interrupts = <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               sec_jr1: jr1@2000 {
+                                        compatible = "fsl,sec-v4.0-job-ring";
+                                        reg = <0x2000 0x1000>;
+                                        interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+
+                               sec_jr2: jr2@3000 {
+                                        compatible = "fsl,sec-v4.0-job-ring";
+                                        reg = <0x3000 0x1000>;
+                                        interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                               };
+                       };
+
                        i2c1: i2c@30a20000 {
                                compatible = "fsl,imx8mn-i2c", "fsl,imx21-i2c";
                                #address-cells = <1>;
                };
 
                aips4: bus@32c00000 {
-                       compatible = "fsl,aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        reg = <0x32c00000 0x400000>;
                        #address-cells = <1>;
                        #size-cells = <1>;
                                interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clk IMX8MN_CLK_USB1_CTRL_ROOT>;
                                clock-names = "usb1_ctrl_root_clk";
-                               assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>,
-                                                 <&clk IMX8MN_CLK_USB_CORE_REF>;
-                               assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>,
-                                                        <&clk IMX8MN_SYS_PLL1_100M>;
+                               assigned-clocks = <&clk IMX8MN_CLK_USB_BUS>;
+                               assigned-clock-parents = <&clk IMX8MN_SYS_PLL2_500M>;
                                fsl,usbphy = <&usbphynop1>;
                                fsl,usbmisc = <&usbmisc1 0>;
                                status = "disabled";
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
                };
 
+               ddrc: memory-controller@3d400000 {
+                       compatible = "fsl,imx8mn-ddrc", "fsl,imx8m-ddrc";
+                       reg = <0x3d400000 0x400000>;
+                       clock-names = "core", "pll", "alt", "apb";
+                       clocks = <&clk IMX8MN_CLK_DRAM_CORE>,
+                                <&clk IMX8MN_DRAM_PLL>,
+                                <&clk IMX8MN_CLK_DRAM_ALT>,
+                                <&clk IMX8MN_CLK_DRAM_APB>;
+               };
+
                ddr-pmu@3d800000 {
                        compatible = "fsl,imx8mn-ddr-pmu", "fsl,imx8m-ddr-pmu";
                        reg = <0x3d800000 0x400000>;
index c366859..94066d4 100644 (file)
        cpu-supply = <&buck2_reg>;
 };
 
+&ddrc {
+       operating-points-v2 = <&ddrc_opp_table>;
+
+       ddrc_opp_table: opp-table {
+               compatible = "operating-points-v2";
+
+               opp-25M {
+                       opp-hz = /bits/ 64 <25000000>;
+               };
+
+               opp-100M {
+                       opp-hz = /bits/ 64 <100000000>;
+               };
+
+               /*
+                * On imx8mq B0 PLL can't be bypassed so low bus is 166M
+                */
+               opp-166M {
+                       opp-hz = /bits/ 64 <166935483>;
+               };
+
+               opp-800M {
+                       opp-hz = /bits/ 64 <800000000>;
+               };
+       };
+};
+
 &fec1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_fec1>;
index b8cb20c..bfd91c1 100644 (file)
        clock-frequency = <100000>;
        status = "okay";
 
+       eeprom@57 {
+               compatible = "atmel,24c02";
+               reg = <0x57>;
+               status = "okay";
+       };
+
        rtc@69 {
                compatible = "abracon,ab1805";
                reg = <0x69>;
index 596bc65..764a4cb 100644 (file)
                AVDD28-supply = <&reg_2v8_p>;
                VDDIO-supply = <&reg_1v8_p>;
        };
+
+       accel-gyro@6a {
+               compatible = "st,lsm9ds1-imu";
+               reg = <0x6a>;
+               vdd-supply = <&reg_3v3_p>;
+               vddio-supply = <&reg_3v3_p>;
+       };
 };
 
 &iomuxc {
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts b/arch/arm64/boot/dts/freescale/imx8mq-phanbell.dts
new file mode 100644 (file)
index 0000000..3f2a489
--- /dev/null
@@ -0,0 +1,376 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright 2017-2019 NXP
+ */
+
+/dts-v1/;
+
+#include "imx8mq.dtsi"
+
+/ {
+       model = "Google i.MX8MQ Phanbell";
+       compatible = "google,imx8mq-phanbell", "fsl,imx8mq";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x00000000 0x40000000 0 0x40000000>;
+       };
+
+       pmic_osc: clock-pmic {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <32768>;
+               clock-output-names = "pmic_osc";
+       };
+
+       reg_usdhc2_vmmc: regulator-usdhc2-vmmc {
+               compatible = "regulator-fixed";
+               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>;
+};
+
+&A53_1 {
+       cpu-supply = <&buck2>;
+};
+
+&A53_2 {
+       cpu-supply = <&buck2>;
+};
+
+&A53_3 {
+       cpu-supply = <&buck2>;
+};
+
+&i2c1 {
+       clock-frequency = <400000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic: pmic@4b {
+               compatible = "rohm,bd71837";
+               reg = <0x4b>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_pmic>;
+               #clock-cells = <0>;
+               clocks = <&pmic_osc>;
+               clock-output-names = "pmic_clk";
+               interrupt-parent = <&gpio1>;
+               interrupts = <3 GPIO_ACTIVE_LOW>;
+
+               regulators {
+                       buck1: BUCK1 {
+                               regulator-name = "buck1";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               regulator-ramp-delay = <1250>;
+                               rohm,dvs-run-voltage = <900000>;
+                               rohm,dvs-idle-voltage = <900000>;
+                               rohm,dvs-suspend-voltage = <800000>;
+                       };
+
+                       buck2: BUCK2 {
+                               regulator-name = "buck2";
+                               regulator-min-microvolt = <850000>;
+                               regulator-max-microvolt = <1000000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               rohm,dvs-run-voltage = <1000000>;
+                               rohm,dvs-idle-voltage = <900000>;
+                       };
+
+                       buck3: BUCK3 {
+                               regulator-name = "buck3";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               rohm,dvs-run-voltage = <900000>;
+                       };
+
+                       buck4: BUCK4 {
+                               regulator-name = "buck4";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                               rohm,dvs-run-voltage = <900000>;
+                       };
+
+                       buck5: BUCK5 {
+                               regulator-name = "buck5";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       buck6: BUCK6 {
+                               regulator-name = "buck6";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       buck7: BUCK7 {
+                               regulator-name = "buck7";
+                               regulator-min-microvolt = <1605000>;
+                               regulator-max-microvolt = <1995000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       buck8: BUCK8 {
+                               regulator-name = "buck8";
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1400000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo1: LDO1 {
+                               regulator-name = "ldo1";
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo2: LDO2 {
+                               regulator-name = "ldo2";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo3: LDO3 {
+                               regulator-name = "ldo3";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo4: LDO4 {
+                               regulator-name = "ldo4";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo5: LDO5 {
+                               regulator-name = "ldo5";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo6: LDO6 {
+                               regulator-name = "ldo6";
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+
+                       ldo7: LDO7 {
+                               regulator-name = "ldo7";
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-boot-on;
+                               regulator-always-on;
+                       };
+               };
+       };
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       status = "okay";
+};
+
+&usdhc1 {
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+       bus-width = <8>;
+       non-removable;
+       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>;
+       bus-width = <4>;
+       cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+       vmmc-supply = <&reg_usdhc2_vmmc>;
+       status = "okay";
+};
+
+&usb3_phy0 {
+       status = "okay";
+};
+
+&usb_dwc3_0 {
+       dr_mode = "otg";
+       status = "okay";
+};
+
+&usb3_phy1 {
+       status = "okay";
+};
+
+&usb_dwc3_1 {
+       dr_mode = "host";
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_pmic: pmicirq {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO03_GPIO1_IO3       0x41
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX             0x49
+                       MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX             0x49
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x83
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc3
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x83
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1grp100mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x85
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc5
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc5
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc5
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x85
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1grp200mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x87
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc7
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA4_USDHC1_DATA4             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA5_USDHC1_DATA5             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA6_USDHC1_DATA6             0xc7
+                       MX8MQ_IOMUXC_SD1_DATA7_USDHC1_DATA7             0xc7
+                       MX8MQ_IOMUXC_SD1_STROBE_USDHC1_STROBE           0x87
+                       MX8MQ_IOMUXC_SD1_RESET_B_USDHC1_RESET_B         0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_gpio: usdhc2grpgpio {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12        0x41
+                       MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19     0x41
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x83
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc3
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2grp100mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x85
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc5
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc5
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc5
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2grp200mhz {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x87
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc7
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc7
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc7
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B 0xc6
+               >;
+       };
+};
index 3dc4411..602c870 100644 (file)
                        };
                };
        };
+
+       eeprom@50 {
+               compatible = "atmel,24c01";
+               reg = <0x50>;
+               status = "okay";
+       };
 };
 
 &pgc_gpu{
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts b/arch/arm64/boot/dts/freescale/imx8mq-thor96.dts
new file mode 100644 (file)
index 0000000..b4795a0
--- /dev/null
@@ -0,0 +1,581 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Copyright 2019 Einfochips
+ * Copyright 2019 Linaro Ltd.
+ */
+
+/dts-v1/;
+
+#include "imx8mq.dtsi"
+
+/ {
+       model = "Einfochips i.MX8MQ Thor96";
+       compatible = "einfochips,imx8mq-thor96", "fsl,imx8mq";
+
+       chosen {
+               stdout-path = &uart1;
+       };
+
+       memory@40000000 {
+               device_type = "memory";
+               reg = <0x00000000 0x40000000 0 0x80000000>;
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_leds>;
+
+               user-led1 {
+                       label = "green:user1";
+                       gpios = <&gpio4 21 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+
+               user-led2 {
+                       label = "green:user2";
+                       gpios = <&gpio4 22 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "none";
+               };
+
+               user-led3 {
+                       label = "green:user3";
+                       gpios = <&gpio4 28 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "mmc1";
+                       default-state = "off";
+               };
+
+               user-led4 {
+                       label = "green:user4";
+                       gpios = <&gpio4 29 GPIO_ACTIVE_HIGH>;
+                       panic-indicator;
+                       linux,default-trigger = "none";
+               };
+
+               wlan-active-led {
+                       label = "yellow:wlan";
+                       gpios = <&gpio4 1 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "phy0tx";
+                       default-state = "off";
+               };
+
+               bt-active-led {
+                       label = "blue:bt";
+                       gpios = <&gpio4 0 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "hci0-power";
+                       default-state = "off";
+               };
+       };
+
+       reg_usdhc1_vmmc: reg-usdhc1-vmmc {
+               compatible = "regulator-fixed";
+               regulator-name = "VDD_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       reg_usdhc1_vqmmc: reg-usdhc1-vqmmc {
+               compatible = "regulator-fixed";
+               regulator-name = "VCC_1V8_EXT";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-always-on;
+       };
+
+       reg_usdhc2_vmmc: reg-usdhc2-vmmc {
+               compatible = "regulator-fixed";
+               regulator-name = "VSD_3V3";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_reg_usdhc2>;
+               gpio = <&gpio2 19 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+       };
+
+       reg_usdhc2_vqmmc: reg-usdhc2-vqmmc {
+               compatible = "regulator-fixed";
+               regulator-name = "NVCC_SD2";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               regulator-always-on;
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_wifi_reg_on>;
+               gpio = <&gpio3 3 GPIO_ACTIVE_HIGH>;
+       };
+};
+
+/* LS-SPI0 */
+&ecspi2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi2>;
+       status = "okay";
+};
+
+&fec1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_fec1>;
+       phy-mode = "rgmii-id";
+       phy-reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>;
+       phy-handle = <&ethphy>;
+       fsl,magic-packet;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               ethphy: ethernet-phy@3 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <3>;
+               };
+       };
+};
+
+/* LS-I2C0 */
+&i2c1 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c1>;
+       status = "okay";
+
+       pmic@8 {
+               compatible = "fsl,pfuze100";
+               reg = <0x8>;
+
+               regulators {
+                       sw1a_reg: sw1ab {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                       };
+
+                       sw1c_reg: sw1c {
+                               regulator-min-microvolt = <300000>;
+                               regulator-max-microvolt = <1875000>;
+                       };
+
+                       sw2_reg: sw2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       sw3a_reg: sw3ab {
+                               regulator-min-microvolt = <400000>;
+                               regulator-max-microvolt = <1975000>;
+                               regulator-always-on;
+                       };
+
+                       sw4_reg: sw4 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       swbst_reg: swbst {
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5150000>;
+                       };
+
+                       snvs_reg: vsnvs {
+                               regulator-min-microvolt = <1000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-always-on;
+                       };
+
+                       vref_reg: vrefddr {
+                               regulator-always-on;
+                       };
+
+                       vgen1_reg: vgen1 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                       };
+
+                       vgen2_reg: vgen2 {
+                               regulator-min-microvolt = <800000>;
+                               regulator-max-microvolt = <1550000>;
+                               regulator-always-on;
+                       };
+
+                       vgen3_reg: vgen3 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen4_reg: vgen4 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen5_reg: vgen5 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-always-on;
+                       };
+
+                       vgen6_reg: vgen6 {
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                       };
+               };
+       };
+};
+
+/* LS-I2C1 */
+&i2c2 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c2>;
+       status = "okay";
+
+       eeprom: eeprom@50 {
+               compatible = "atmel,24c256";
+               reg = <0x50>;
+       };
+};
+
+/* HS-I2C2 */
+&i2c3 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       status = "okay";
+};
+
+/* HS-I2C3 */
+&i2c4 {
+       clock-frequency = <100000>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c4>;
+       status = "okay";
+};
+
+&pgc_gpu {
+       power-supply = <&sw1a_reg>;
+};
+
+&pgc_vpu {
+       power-supply = <&sw1c_reg>;
+};
+
+&qspi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_qspi0>;
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               spi-max-frequency = <100000000>;
+               reg = <0>;
+       };
+};
+
+/* Debug UART */
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART1>;
+       assigned-clock-parents = <&clk IMX8MQ_CLK_25M>;
+       status = "okay";
+};
+
+/* LS-UART0 */
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART2>;
+       assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
+       uart-has-rtscts;
+       status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               device-wakeup-gpios = <&gpio3 22 GPIO_ACTIVE_HIGH>;
+               host-wakeup-gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
+               shutdown-gpios = <&gpio3 5 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_bt_gpios>;
+       };
+};
+
+/* LS-UART1 */
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3>;
+       assigned-clocks = <&clk IMX8MQ_CLK_UART3>;
+       assigned-clock-parents = <&clk IMX8MQ_SYS1_PLL_80M>;
+       status = "okay";
+};
+
+&usb3_phy1 {
+       status = "okay";
+};
+
+&usb_dwc3_1 {
+       dr_mode = "host";
+       status = "okay";
+};
+
+/* SDIO */
+&usdhc1 {
+       #address-cells = <0x1>;
+       #size-cells = <0x0>;
+       pinctrl-names = "default", "state_100mhz", "state_200mhz";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       pinctrl-1 = <&pinctrl_usdhc1_100mhz>;
+       pinctrl-2 = <&pinctrl_usdhc1_200mhz>;
+       vmmc-supply = <&reg_usdhc1_vmmc>;
+       vqmmc-supply = <&reg_usdhc1_vqmmc>;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       bus-width = <4>;
+       non-removable;
+       no-sd;
+       no-emmc;
+       status = "okay";
+
+       brcmf: wifi@1 {
+               reg = <1>;
+               compatible = "brcm,bcm4329-fmac";
+       };
+};
+
+/* uSD */
+&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>;
+       vmmc-supply = <&reg_usdhc2_vmmc>;
+       vqmmc-supply = <&reg_usdhc2_vqmmc>;
+       cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>;
+       bus-width = <4>;
+       no-sdio;
+       no-emmc;
+       disable-wp;
+       status = "okay";
+};
+
+&wdog1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_wdog>;
+       fsl,ext-reset-output;
+       status = "okay";
+};
+
+&iomuxc {
+       pinctrl_bt_gpios: btgpiosgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SAI5_RXD1_GPIO3_IO22               0x19
+                       MX8MQ_IOMUXC_NAND_DQS_GPIO3_IO14                0x19
+                       MX8MQ_IOMUXC_NAND_CLE_GPIO3_IO5                 0x19
+               >;
+       };
+
+       pinctrl_ecspi2: ecspi2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK            0x16
+                       MX8MQ_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI            0x16
+                       MX8MQ_IOMUXC_ECSPI2_MISO_ECSPI2_MISO            0x16
+                       MX8MQ_IOMUXC_ECSPI2_SS0_ECSPI2_SS0              0x16
+               >;
+       };
+
+       pinctrl_fec1: fec1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_ENET_MDC_ENET1_MDC                 0x4
+                       MX8MQ_IOMUXC_ENET_MDIO_ENET1_MDIO               0x24
+                       MX8MQ_IOMUXC_ENET_TD3_ENET1_RGMII_TD3           0x1c
+                       MX8MQ_IOMUXC_ENET_TD2_ENET1_RGMII_TD2           0x1c
+                       MX8MQ_IOMUXC_ENET_TD1_ENET1_RGMII_TD1           0x1c
+                       MX8MQ_IOMUXC_ENET_TD0_ENET1_RGMII_TD0           0x1c
+                       MX8MQ_IOMUXC_ENET_RD3_ENET1_RGMII_RD3           0x91
+                       MX8MQ_IOMUXC_ENET_RD2_ENET1_RGMII_RD2           0x91
+                       MX8MQ_IOMUXC_ENET_RD1_ENET1_RGMII_RD1           0x91
+                       MX8MQ_IOMUXC_ENET_RD0_ENET1_RGMII_RD0           0x91
+                       MX8MQ_IOMUXC_ENET_TXC_ENET1_RGMII_TXC           0x1c
+                       MX8MQ_IOMUXC_ENET_RXC_ENET1_RGMII_RXC           0x91
+                       MX8MQ_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL     0x91
+                       MX8MQ_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL     0x1c
+                       MX8MQ_IOMUXC_GPIO1_IO09_GPIO1_IO9               0x19
+               >;
+       };
+
+       pinctrl_i2c1: i2c1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C1_SCL_I2C1_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C1_SDA_I2C1_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_i2c2: i2c2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C2_SCL_I2C2_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C2_SDA_I2C2_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_i2c3: i2c3grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C3_SCL_I2C3_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C3_SDA_I2C3_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_i2c4: i2c4grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_I2C4_SCL_I2C4_SCL                  0x4000007f
+                       MX8MQ_IOMUXC_I2C4_SDA_I2C4_SDA                  0x4000007f
+               >;
+       };
+
+       pinctrl_leds: ledsgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SAI2_RXFS_GPIO4_IO21               0x19
+                       MX8MQ_IOMUXC_SAI2_RXC_GPIO4_IO22                0x19
+                       MX8MQ_IOMUXC_SAI3_RXFS_GPIO4_IO28               0x19
+                       MX8MQ_IOMUXC_SAI3_RXC_GPIO4_IO29                0x19
+                       MX8MQ_IOMUXC_SAI1_RXC_GPIO4_IO1                 0x19
+                       MX8MQ_IOMUXC_SAI1_RXFS_GPIO4_IO0                0x19
+               >;
+       };
+
+       pinctrl_qspi0: qspi0grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_NAND_ALE_QSPI_A_SCLK               0x82
+                       MX8MQ_IOMUXC_NAND_CE0_B_QSPI_A_SS0_B            0x82
+                       MX8MQ_IOMUXC_NAND_DATA00_QSPI_A_DATA0           0x82
+                       MX8MQ_IOMUXC_NAND_DATA01_QSPI_A_DATA1           0x82
+                       MX8MQ_IOMUXC_NAND_DATA02_QSPI_A_DATA2           0x82
+                       MX8MQ_IOMUXC_NAND_DATA03_QSPI_A_DATA3           0x82
+
+               >;
+       };
+
+       pinctrl_reg_usdhc2: regusdhc2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_RESET_B_GPIO2_IO19             0x41
+               >;
+       };
+
+       pinctrl_uart1: uart1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART1_RXD_UART1_DCE_RX             0x49
+                       MX8MQ_IOMUXC_UART1_TXD_UART1_DCE_TX             0x49
+               >;
+       };
+
+       pinctrl_uart2: uart2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART2_RXD_UART2_DCE_RX             0x49
+                       MX8MQ_IOMUXC_UART2_TXD_UART2_DCE_TX             0x49
+                       MX8MQ_IOMUXC_UART4_RXD_UART2_DCE_CTS_B          0x49
+                       MX8MQ_IOMUXC_UART4_TXD_UART2_DCE_RTS_B          0x49
+               >;
+       };
+
+       pinctrl_uart3: uart3grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_UART3_TXD_UART3_DCE_TX             0x49
+                       MX8MQ_IOMUXC_UART3_RXD_UART3_DCE_RX             0x49
+               >;
+       };
+
+       pinctrl_usdhc1: usdhc1grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x83
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xc3
+                       MX8MQ_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K      0x85
+               >;
+       };
+
+       pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x8d
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xcd
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xcd
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xcd
+                       MX8MQ_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K      0x85
+               >;
+       };
+
+       pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD1_CLK_USDHC1_CLK                 0x9f
+                       MX8MQ_IOMUXC_SD1_CMD_USDHC1_CMD                 0xdf
+                       MX8MQ_IOMUXC_SD1_DATA0_USDHC1_DATA0             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA1_USDHC1_DATA1             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA2_USDHC1_DATA2             0xdf
+                       MX8MQ_IOMUXC_SD1_DATA3_USDHC1_DATA3             0xdf
+                       MX8MQ_IOMUXC_GPIO1_IO00_ANAMIX_REF_CLK_32K      0x85
+               >;
+       };
+
+       pinctrl_usdhc2_gpio: usdhc2gpiogrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CD_B_GPIO2_IO12                0x41
+               >;
+       };
+
+       pinctrl_usdhc2: usdhc2grp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x83
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xc3
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xc3
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xc3
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x8c
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xcc
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xcc
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xcc
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xcc
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xcc
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xc1
+               >;
+       };
+
+       pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_SD2_CLK_USDHC2_CLK                 0x9c
+                       MX8MQ_IOMUXC_SD2_CMD_USDHC2_CMD                 0xdc
+                       MX8MQ_IOMUXC_SD2_DATA0_USDHC2_DATA0             0xdc
+                       MX8MQ_IOMUXC_SD2_DATA1_USDHC2_DATA1             0xdc
+                       MX8MQ_IOMUXC_SD2_DATA2_USDHC2_DATA2             0xdc
+                       MX8MQ_IOMUXC_SD2_DATA3_USDHC2_DATA3             0xdc
+                       MX8MQ_IOMUXC_GPIO1_IO04_USDHC2_VSELECT          0xcc
+               >;
+       };
+
+       pinctrl_wdog: wdoggrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_GPIO1_IO02_WDOG1_WDOG_B            0xc6
+               >;
+       };
+
+       pinctrl_wifi_reg_on: wifiregongrp {
+               fsl,pins = <
+                       MX8MQ_IOMUXC_NAND_CE2_B_GPIO3_IO3               0x17059
+               >;
+       };
+};
index d2a6da4..6b35813 100644 (file)
@@ -8,7 +8,7 @@
 #include "imx8mq-zii-ultra.dtsi"
 
 / {
-       model = "ZII i.MX8MQ Ultra RMB3 Board";
+       model = "ZII Ultra RMB3 Board";
        compatible = "zii,imx8mq-ultra-rmb3", "zii,imx8mq-ultra", "fsl,imx8mq";
 };
 
index 1084d93..173b9e9 100644 (file)
@@ -8,7 +8,7 @@
 #include "imx8mq-zii-ultra.dtsi"
 
 / {
-       model = "ZII i.MX8MQ Ultra Zest Board";
+       model = "ZII Ultra Zest Board";
        compatible = "zii,imx8mq-ultra-zest", "zii,imx8mq-ultra", "fsl,imx8mq";
 };
 
index 7f93194..6a1e839 100644 (file)
                dma-ranges = <0x40000000 0x0 0x40000000 0xc0000000>;
 
                bus@30000000 { /* AIPS1 */
-                       compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x30000000 0x30000000 0x400000>;
 
+                       sai1: sai@30010000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx8mq-sai";
+                               reg = <0x30010000 0x10000>;
+                               interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_SAI1_IPG>,
+                                        <&clk IMX8MQ_CLK_SAI1_ROOT>,
+                                        <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+                               clock-names = "bus", "mclk1", "mclk2", "mclk3";
+                               dmas = <&sdma2 8 24 0>, <&sdma1 9 24 0>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       sai6: sai@30030000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx8mq-sai";
+                               reg = <0x30030000 0x10000>;
+                               interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_SAI6_IPG>,
+                                        <&clk IMX8MQ_CLK_SAI6_ROOT>,
+                                        <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+                               clock-names = "bus", "mclk1", "mclk2", "mclk3";
+                               dmas = <&sdma2 4 24 0>, <&sdma2 5 24 0>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       sai5: sai@30040000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx8mq-sai";
+                               reg = <0x30040000 0x10000>;
+                               interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_SAI5_IPG>,
+                                        <&clk IMX8MQ_CLK_SAI5_ROOT>,
+                                        <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+                               clock-names = "bus", "mclk1", "mclk2", "mclk3";
+                               dmas = <&sdma2 2 24 0>, <&sdma2 3 24 0>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
+                       sai4: sai@30050000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx8mq-sai";
+                               reg = <0x30050000 0x10000>;
+                               interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_SAI4_IPG>,
+                                        <&clk IMX8MQ_CLK_SAI4_ROOT>,
+                                        <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+                               clock-names = "bus", "mclk1", "mclk2", "mclk3";
+                               dmas = <&sdma2 0 24 0>, <&sdma2 1 24 0>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
                        gpio1: gpio@30200000 {
                                compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio";
                                reg = <0x30200000 0x10000>;
                                fsl,sdma-ram-script-name = "imx/sdma/sdma-imx7d.bin";
                        };
 
+                       lcdif: lcd-controller@30320000 {
+                               compatible = "fsl,imx8mq-lcdif", "fsl,imx28-lcdif";
+                               reg = <0x30320000 0x10000>;
+                               interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_LCDIF_PIXEL>;
+                               clock-names = "pix";
+                               assigned-clocks = <&clk IMX8MQ_VIDEO_PLL1_REF_SEL>,
+                                                 <&clk IMX8MQ_VIDEO_PLL1_BYPASS>,
+                                                 <&clk IMX8MQ_CLK_LCDIF_PIXEL>,
+                                                 <&clk IMX8MQ_VIDEO_PLL1>;
+                               assigned-clock-parents = <&clk IMX8MQ_CLK_25M>,
+                                                 <&clk IMX8MQ_VIDEO_PLL1>,
+                                                 <&clk IMX8MQ_VIDEO_PLL1_OUT>;
+                               assigned-clock-rates = <0>, <0>, <0>, <594000000>;
+                               status = "disabled";
+                       };
+
                        iomuxc: iomuxc@30330000 {
                                compatible = "fsl,imx8mq-iomuxc";
                                reg = <0x30330000 0x10000>;
                                clock-names = "ckil", "osc_25m", "osc_27m",
                                              "clk_ext1", "clk_ext2",
                                              "clk_ext3", "clk_ext4";
+                               assigned-clocks = <&clk IMX8MQ_CLK_NOC>;
+                               assigned-clock-rates = <800000000>;
                        };
 
                        src: reset-controller@30390000 {
                };
 
                bus@30400000 { /* AIPS2 */
-                       compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x30400000 0x30400000 0x400000>;
                };
 
                bus@30800000 { /* AIPS3 */
-                       compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x30800000 0x30800000 0x400000>,
                                status = "disabled";
                        };
 
+                       sai3: sai@308c0000 {
+                               #sound-dai-cells = <0>;
+                               compatible = "fsl,imx8mq-sai";
+                               reg = <0x308c0000 0x10000>;
+                               interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&clk IMX8MQ_CLK_SAI3_IPG>,
+                                        <&clk IMX8MQ_CLK_SAI3_ROOT>,
+                                        <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>;
+                               clock-names = "bus", "mclk1", "mclk2", "mclk3";
+                               dmas = <&sdma1 12 24 0>, <&sdma1 13 24 0>;
+                               dma-names = "rx", "tx";
+                               status = "disabled";
+                       };
+
                        crypto: crypto@30900000 {
                                compatible = "fsl,sec-v4.0";
                                #address-cells = <1>;
                };
 
                bus@32c00000 { /* AIPS4 */
-                       compatible = "fsl,imx8mq-aips-bus", "simple-bus";
+                       compatible = "simple-bus";
                        #address-cells = <1>;
                        #size-cells = <1>;
                        ranges = <0x32c00000 0x32c00000 0x400000>;
                        interrupt-parent = <&gic>;
                };
 
+               ddrc: memory-controller@3d400000 {
+                       compatible = "fsl,imx8mq-ddrc", "fsl,imx8m-ddrc";
+                       reg = <0x3d400000 0x400000>;
+                       clock-names = "core", "pll", "alt", "apb";
+                       clocks = <&clk IMX8MQ_CLK_DRAM_CORE>,
+                                <&clk IMX8MQ_DRAM_PLL_OUT>,
+                                <&clk IMX8MQ_CLK_DRAM_ALT>,
+                                <&clk IMX8MQ_CLK_DRAM_APB>;
+               };
+
                ddr-pmu@3d800000 {
                        compatible = "fsl,imx8mq-ddr-pmu", "fsl,imx8m-ddr-pmu";
                        reg = <0x3d800000 0x400000>;
index 9646a41..fb5f752 100644 (file)
                        compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
                        reg = <0x5a060000 0x1000>;
                        interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-parent = <&gic>;
                        clocks = <&adma_lpcg IMX_ADMA_LPCG_UART0_IPG_CLK>,
                                 <&adma_lpcg IMX_ADMA_LPCG_UART0_BAUD_CLK>;
                        clock-names = "ipg", "baud";
                        compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
                        reg = <0x5a070000 0x1000>;
                        interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-parent = <&gic>;
                        clocks = <&adma_lpcg IMX_ADMA_LPCG_UART1_IPG_CLK>,
                                 <&adma_lpcg IMX_ADMA_LPCG_UART1_BAUD_CLK>;
                        clock-names = "ipg", "baud";
                        compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
                        reg = <0x5a080000 0x1000>;
                        interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-parent = <&gic>;
                        clocks = <&adma_lpcg IMX_ADMA_LPCG_UART2_IPG_CLK>,
                                 <&adma_lpcg IMX_ADMA_LPCG_UART2_BAUD_CLK>;
                        clock-names = "ipg", "baud";
                        compatible = "fsl,imx8qxp-lpuart", "fsl,imx7ulp-lpuart";
                        reg = <0x5a090000 0x1000>;
                        interrupts = <GIC_SPI 228 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-parent = <&gic>;
                        clocks = <&adma_lpcg IMX_ADMA_LPCG_UART3_IPG_CLK>,
                                 <&adma_lpcg IMX_ADMA_LPCG_UART3_BAUD_CLK>;
                        clock-names = "ipg", "baud";
                        compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
                        reg = <0x5a800000 0x4000>;
                        interrupts = <GIC_SPI 220 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-parent = <&gic>;
                        clocks = <&adma_lpcg IMX_ADMA_LPCG_I2C0_CLK>;
                        clock-names = "per";
                        assigned-clocks = <&clk IMX_ADMA_I2C0_CLK>;
                        compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
                        reg = <0x5a810000 0x4000>;
                        interrupts = <GIC_SPI 221 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-parent = <&gic>;
                        clocks = <&adma_lpcg IMX_ADMA_LPCG_I2C1_CLK>;
                        clock-names = "per";
                        assigned-clocks = <&clk IMX_ADMA_I2C1_CLK>;
                        compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
                        reg = <0x5a820000 0x4000>;
                        interrupts = <GIC_SPI 222 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-parent = <&gic>;
                        clocks = <&adma_lpcg IMX_ADMA_LPCG_I2C2_CLK>;
                        clock-names = "per";
                        assigned-clocks = <&clk IMX_ADMA_I2C2_CLK>;
                        compatible = "fsl,imx8qxp-lpi2c", "fsl,imx7ulp-lpi2c";
                        reg = <0x5a830000 0x4000>;
                        interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-parent = <&gic>;
                        clocks = <&adma_lpcg IMX_ADMA_LPCG_I2C3_CLK>;
                        clock-names = "per";
                        assigned-clocks = <&clk IMX_ADMA_I2C3_CLK>;
 
                usdhc1: mmc@5b010000 {
                        compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
-                       interrupt-parent = <&gic>;
                        interrupts = <GIC_SPI 232 IRQ_TYPE_LEVEL_HIGH>;
                        reg = <0x5b010000 0x10000>;
                        clocks = <&conn_lpcg IMX_CONN_LPCG_SDHC0_IPG_CLK>,
 
                usdhc2: mmc@5b020000 {
                        compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
-                       interrupt-parent = <&gic>;
                        interrupts = <GIC_SPI 233 IRQ_TYPE_LEVEL_HIGH>;
                        reg = <0x5b020000 0x10000>;
                        clocks = <&conn_lpcg IMX_CONN_LPCG_SDHC1_IPG_CLK>,
 
                usdhc3: mmc@5b030000 {
                        compatible = "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc";
-                       interrupt-parent = <&gic>;
                        interrupts = <GIC_SPI 234 IRQ_TYPE_LEVEL_HIGH>;
                        reg = <0x5b030000 0x10000>;
                        clocks = <&conn_lpcg IMX_CONN_LPCG_SDHC2_IPG_CLK>,
                ddr-pmu@5c020000 {
                        compatible = "fsl,imx8-ddr-pmu";
                        reg = <0x5c020000 0x10000>;
-                       interrupt-parent = <&gic>;
                        interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>;
                };
        };
index c563d3e..7d370da 100644 (file)
 };
 
 &ir {
+       linux,rc-map-name = "rc-hisi-poplar";
        status = "okay";
 };
 
index 13821a0..12bc1d3 100644 (file)
                        #address-cells = <3>;
                        #size-cells = <2>;
                        device_type = "pci";
-                       bus-range = <0 15>;
+                       bus-range = <0x00 0xff>;
                        num-lanes = <1>;
                        ranges = <0x81000000 0x0 0x00000000 0x4f00000 0x0 0x100000
                                  0x82000000 0x0 0x3000000 0x3000000 0x0 0x01f00000>;
index 1253af3..40cb16e 100644 (file)
@@ -1,2 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
-dtb-$(CONFIG_ARCH_AGILEX) += socfpga_agilex_socdk.dtb
+dtb-$(CONFIG_ARCH_AGILEX) += socfpga_agilex_socdk.dtb \
+                            socfpga_agilex_socdk_nand.dtb
index d43e129..e1d357e 100644 (file)
                        rx-fifo-depth = <16384>;
                        snps,multicast-filter-bins = <256>;
                        iommus = <&smmu 1>;
+                       altr,sysmgr-syscon = <&sysmgr 0x44 0>;
                        status = "disabled";
                };
 
                        rx-fifo-depth = <16384>;
                        snps,multicast-filter-bins = <256>;
                        iommus = <&smmu 2>;
+                       altr,sysmgr-syscon = <&sysmgr 0x48 8>;
                        status = "disabled";
                };
 
                        rx-fifo-depth = <16384>;
                        snps,multicast-filter-bins = <256>;
                        iommus = <&smmu 3>;
+                       altr,sysmgr-syscon = <&sysmgr 0x4c 16>;
                        status = "disabled";
                };
 
                        status = "disabled";
                };
 
+               nand: nand@ffb90000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "altr,socfpga-denali-nand";
+                       reg = <0xffb90000 0x10000>,
+                             <0xffb80000 0x1000>;
+                       reg-names = "nand_data", "denali_reg";
+                       interrupts = <0 97 4>;
+                       resets = <&rst NAND_RESET>, <&rst NAND_OCP_RESET>;
+                       status = "disabled";
+               };
+
                ocram: sram@ffe00000 {
                        compatible = "mmio-sram";
                        reg = <0xffe00000 0x40000>;
                };
 
                sysmgr: sysmgr@ffd12000 {
-                       compatible = "altr,sys-mgr", "syscon";
+                       compatible = "altr,sys-mgr-s10","altr,sys-mgr";
                        reg = <0xffd12000 0x500>;
                };
 
                        reg = <0xf8011100 0xc0>;
                };
 
+               eccmgr {
+                       compatible = "altr,socfpga-s10-ecc-manager",
+                                    "altr,socfpga-a10-ecc-manager";
+                       altr,sysmgr-syscon = <&sysmgr>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       interrupts = <0 15 4>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       ranges;
+
+                       sdramedac {
+                               compatible = "altr,sdram-edac-s10";
+                               altr,sdr-syscon = <&sdr>;
+                               interrupts = <16 4>;
+                       };
+
+                       ocram-ecc@ff8cc000 {
+                               compatible = "altr,socfpga-s10-ocram-ecc",
+                                            "altr,socfpga-a10-ocram-ecc";
+                               reg = <0xff8cc000 0x100>;
+                               altr,ecc-parent = <&ocram>;
+                               interrupts = <1 4>;
+                       };
+
+                       usb0-ecc@ff8c4000 {
+                               compatible = "altr,socfpga-s10-usb-ecc",
+                                            "altr,socfpga-usb-ecc";
+                               reg = <0xff8c4000 0x100>;
+                               altr,ecc-parent = <&usb0>;
+                               interrupts = <2 4>;
+                       };
+
+                       emac0-rx-ecc@ff8c0000 {
+                               compatible = "altr,socfpga-s10-eth-mac-ecc",
+                                            "altr,socfpga-eth-mac-ecc";
+                               reg = <0xff8c0000 0x100>;
+                               altr,ecc-parent = <&gmac0>;
+                               interrupts = <4 4>;
+                       };
+
+                       emac0-tx-ecc@ff8c0400 {
+                               compatible = "altr,socfpga-s10-eth-mac-ecc",
+                                            "altr,socfpga-eth-mac-ecc";
+                               reg = <0xff8c0400 0x100>;
+                               altr,ecc-parent = <&gmac0>;
+                               interrupts = <5 4>;
+                       };
+
+                       sdmmca-ecc@ff8c8c00 {
+                               compatible = "altr,socfpga-s10-sdmmc-ecc",
+                                            "altr,socfpga-sdmmc-ecc";
+                               reg = <0xff8c8c00 0x100>;
+                               altr,ecc-parent = <&mmc>;
+                               interrupts = <14 4>,
+                                            <15 4>;
+                       };
+               };
+
                qspi: spi@ff8d2000 {
                        compatible = "cdns,qspi-nor";
                        #address-cells = <1>;
diff --git a/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts b/arch/arm64/boot/dts/intel/socfpga_agilex_socdk_nand.dts
new file mode 100644 (file)
index 0000000..979aa59
--- /dev/null
@@ -0,0 +1,135 @@
+// SPDX-License-Identifier:     GPL-2.0
+/*
+ * Copyright (C) 2019, Intel Corporation
+ */
+#include "socfpga_agilex.dtsi"
+
+/ {
+       model = "SoCFPGA Agilex SoCDK";
+
+       aliases {
+               serial0 = &uart0;
+               ethernet0 = &gmac0;
+               ethernet1 = &gmac1;
+               ethernet2 = &gmac2;
+       };
+
+       chosen {
+               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 */
+               reg = <0 0 0 0>;
+       };
+
+       soc {
+               clocks {
+                       osc1 {
+                               clock-frequency = <25000000>;
+                       };
+               };
+       };
+};
+
+&gpio1 {
+       status = "okay";
+};
+
+&gmac2 {
+       status = "okay";
+       phy-mode = "rgmii";
+       phy-handle = <&phy0>;
+
+       max-frame-size = <9000>;
+
+       mdio0 {
+               #address-cells = <1>;
+               #size-cells = <0>;
+               compatible = "snps,dwmac-mdio";
+               phy0: ethernet-phy@0 {
+                       reg = <4>;
+
+                       txd0-skew-ps = <0>; /* -420ps */
+                       txd1-skew-ps = <0>; /* -420ps */
+                       txd2-skew-ps = <0>; /* -420ps */
+                       txd3-skew-ps = <0>; /* -420ps */
+                       rxd0-skew-ps = <420>; /* 0ps */
+                       rxd1-skew-ps = <420>; /* 0ps */
+                       rxd2-skew-ps = <420>; /* 0ps */
+                       rxd3-skew-ps = <420>; /* 0ps */
+                       txen-skew-ps = <0>; /* -420ps */
+                       txc-skew-ps = <900>; /* 0ps */
+                       rxdv-skew-ps = <420>; /* 0ps */
+                       rxc-skew-ps = <1680>; /* 780ps */
+               };
+       };
+};
+
+&nand {
+       status = "okay";
+
+       flash@0 {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               reg = <0>;
+               nand-bus-width = <16>;
+
+               partition@0 {
+                       label = "u-boot";
+                       reg = <0 0x200000>;
+               };
+               partition@200000 {
+                       label = "env";
+                       reg = <0x200000 0x40000>;
+               };
+               partition@240000 {
+                       label = "dtb";
+                       reg = <0x240000 0x40000>;
+               };
+               partition@280000 {
+                       label = "kernel";
+                       reg = <0x280000 0x2000000>;
+               };
+               partition@2280000 {
+                       label = "misc";
+                       reg = <0x2280000 0x2000000>;
+               };
+               partition@4280000 {
+                       label = "rootfs";
+                       reg = <0x4280000 0x3bd80000>;
+               };
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&usb0 {
+       status = "okay";
+       disable-over-current;
+};
+
+&watchdog0 {
+       status = "okay";
+};
index bd4aab6..7eb6c17 100644 (file)
@@ -69,6 +69,7 @@
                mod-def0-gpio = <&gpiosb 3 GPIO_ACTIVE_LOW>;
                tx-disable-gpio = <&gpiosb 4 GPIO_ACTIVE_HIGH>;
                tx-fault-gpio = <&gpiosb 5 GPIO_ACTIVE_HIGH>;
+               maximum-power-milliwatt = <3000>;
        };
 
        sfp_eth1: sfp-eth1 {
@@ -78,6 +79,7 @@
                mod-def0-gpio = <&gpiosb 8 GPIO_ACTIVE_LOW>;
                tx-disable-gpio = <&gpiosb 9 GPIO_ACTIVE_HIGH>;
                tx-fault-gpio = <&gpiosb 10 GPIO_ACTIVE_HIGH>;
+               maximum-power-milliwatt = <3000>;
        };
 };
 
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&i2c1_pins>;
+       /delete-property/mrvl,i2c-fast-mode;
 };
 
 &i2c1 {
        status = "okay";
        pinctrl-names = "default";
        pinctrl-0 = <&i2c2_pins>;
+       /delete-property/mrvl,i2c-fast-mode;
 
        lm75@48 {
                status = "okay";
        phy-mode = "sgmii";
        status = "okay";
        managed = "in-band-status";
+       phys = <&comphy1 0>;
        sfp = <&sfp_eth0>;
 };
 
        phy-mode = "sgmii";
        status = "okay";
        managed = "in-band-status";
+       phys = <&comphy0 1>;
        sfp = <&sfp_eth1>;
 };
 
 &usb3 {
        status = "okay";
+       phys = <&usb2_utmi_otg_phy>;
+       phy-names = "usb2-utmi-otg-phy";
 };
 
 &uart0 {
index bd88149..a211a04 100644 (file)
                                reg = <5>;
                                label = "cpu";
                                ethernet = <&cp1_eth2>;
+                               phy-mode = "2500base-x";
+                               managed = "in-band-status";
                        };
                };
 
index 15f1842..8b4e806 100644 (file)
                        enable-method = "psci";
                        cpu-idle-states = <&CPU_SLEEP_0>;
                        #cooling-cells = <2>;
+                       dynamic-power-coefficient = <263>;
                        clocks = <&infracfg CLK_INFRA_CA53SEL>,
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
                        enable-method = "psci";
                        cpu-idle-states = <&CPU_SLEEP_0>;
                        #cooling-cells = <2>;
+                       dynamic-power-coefficient = <263>;
                        clocks = <&infracfg CLK_INFRA_CA53SEL>,
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
                        enable-method = "psci";
                        cpu-idle-states = <&CPU_SLEEP_0>;
                        #cooling-cells = <2>;
+                       dynamic-power-coefficient = <530>;
                        clocks = <&infracfg CLK_INFRA_CA72SEL>,
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
                        enable-method = "psci";
                        cpu-idle-states = <&CPU_SLEEP_0>;
                        #cooling-cells = <2>;
+                       dynamic-power-coefficient = <530>;
                        clocks = <&infracfg CLK_INFRA_CA72SEL>,
                                 <&apmixedsys CLK_APMIXED_MAINPLL>;
                        clock-names = "cpu", "intermediate";
                                                 <&topckgen CLK_TOP_UNIVPLL1_D2>;
                };
 
+               jpegdec: jpegdec@18004000 {
+                       compatible = "mediatek,mt8173-jpgdec";
+                       reg = <0 0x18004000 0 0x1000>;
+                       interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_LOW>;
+                       clocks = <&vencsys CLK_VENC_CKE0>,
+                                <&vencsys CLK_VENC_CKE3>;
+                       clock-names = "jpgdec-smi",
+                                     "jpgdec";
+                       power-domains = <&scpsys MT8173_POWER_DOMAIN_VENC>;
+                       mediatek,larb = <&larb3>;
+                       iommus = <&iommu M4U_PORT_JPGDEC_WDMA>,
+                                <&iommu M4U_PORT_JPGDEC_BSDMA>;
+               };
+
                vencltsys: clock-controller@19000000 {
                        compatible = "mediatek,mt8173-vencltsys", "syscon";
                        reg = <0 0x19000000 0 0x1000>;
index 10b3247..124f9d3 100644 (file)
@@ -8,6 +8,7 @@
 #include <dt-bindings/clock/mt8183-clk.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/reset-controller/mt8183-resets.h>
 #include "mt8183-pinfunc.h"
 
 / {
                        compatible = "mediatek,mt8183-infracfg", "syscon";
                        reg = <0 0x10001000 0 0x1000>;
                        #clock-cells = <1>;
+                       #reset-cells = <1>;
                };
 
                pio: pinctrl@10005000 {
                        clock-names = "clk13m";
                };
 
+               gce: mailbox@10238000 {
+                       compatible = "mediatek,mt8183-gce";
+                       reg = <0 0x10238000 0 0x4000>;
+                       interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_LOW>;
+                       #mbox-cells = <3>;
+                       clocks = <&infracfg CLK_INFRA_GCE>;
+                       clock-names = "gce";
+               };
+
                auxadc: auxadc@11001000 {
                        compatible = "mediatek,mt8183-auxadc",
                                     "mediatek,mt8173-auxadc";
index 631a7f7..6238e6e 100644 (file)
                #iommu-cells = <1>;
        };
 
-       emc: emc@7001b000 {
+       emc: external-memory-controller@7001b000 {
                compatible = "nvidia,tegra132-emc", "nvidia,tegra124-emc";
                reg = <0x0 0x7001b000 0x0 0x1000>;
+               clocks = <&tegra_car TEGRA124_CLK_EMC>;
+               clock-names = "emc";
 
                nvidia,memory-controller = <&mc>;
        };
index 5e18acf..947744d 100644 (file)
@@ -8,6 +8,7 @@
        compatible = "nvidia,p3310", "nvidia,tegra186";
 
        aliases {
+               ethernet0 = "/ethernet@2490000";
                sdhci0 = "/sdhci@3460000";
                sdhci1 = "/sdhci@3400000";
                serial0 = &uarta;
index 7893d78..c905527 100644 (file)
        memory-controller@2c00000 {
                compatible = "nvidia,tegra186-mc";
                reg = <0x0 0x02c00000 0x0 0xb0000>;
+               interrupts = <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
+
+               #address-cells = <2>;
+               #size-cells = <2>;
+
+               ranges = <0x0 0x02c00000 0x0 0x02c00000 0x0 0xb0000>;
+
+               /*
+                * Memory clients have access to all 40 bits that the memory
+                * controller can address.
+                */
+               dma-ranges = <0x0 0x0 0x0 0x0 0x100 0x0>;
+
+               emc: external-memory-controller@2c60000 {
+                       compatible = "nvidia,tegra186-emc";
+                       reg = <0x0 0x02c60000 0x0 0x50000>;
+                       interrupts = <GIC_SPI 224 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&bpmp TEGRA186_CLK_EMC>;
+                       clock-names = "emc";
+
+                       nvidia,bpmp = <&bpmp>;
+               };
        };
 
        uarta: serial@3100000 {
                reg = <0x0 0x03530000 0x0 0x8000>,
                      <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>;
-
                clocks = <&bpmp TEGRA186_CLK_XUSB_HOST>,
                         <&bpmp TEGRA186_CLK_XUSB_FALCON>,
                         <&bpmp TEGRA186_CLK_XUSB_SS>,
                clock-names = "xusb_host", "xusb_falcon_src", "xusb_ss",
                              "xusb_ss_src", "xusb_hs_src", "xusb_fs_src",
                              "pll_u_480m", "clk_m", "pll_e";
-
                power-domains = <&bpmp TEGRA186_POWER_DOMAIN_XUSBC>,
                                <&bpmp TEGRA186_POWER_DOMAIN_XUSBA>;
                power-domain-names = "xusb_host", "xusb_ss";
-               nvidia,xusb-padctl = <&padctl>;
-
-               status = "disabled";
-
+               iommus = <&smmu TEGRA186_SID_XUSB_HOST>;
                #address-cells = <1>;
                #size-cells = <0>;
+               status = "disabled";
+
+               nvidia,xusb-padctl = <&padctl>;
        };
 
        fuse@3820000 {
index c7f2a20..bdd33ff 100644 (file)
                        };
                };
 
+               memory-controller@2c00000 {
+                       status = "okay";
+               };
+
                serial@3110000 {
                        status = "okay";
                };
index 353a6a2..985e7d8 100644 (file)
                        gpios = <&gpio TEGRA194_MAIN_GPIO(G, 0)
                                       GPIO_ACTIVE_LOW>;
                        linux,input-type = <EV_KEY>;
-                       linux,code = <BTN_1>;
+                       linux,code = <KEY_SLEEP>;
                        debounce-interval = <10>;
                };
 
index 11220d9..ccac43b 100644 (file)
@@ -7,6 +7,7 @@
 #include <dt-bindings/power/tegra194-powergate.h>
 #include <dt-bindings/reset/tegra194-reset.h>
 #include <dt-bindings/thermal/tegra194-bpmp-thermal.h>
+#include <dt-bindings/memory/tegra194-mc.h>
 
 / {
        compatible = "nvidia,tegra194";
                #size-cells = <1>;
                ranges = <0x0 0x0 0x0 0x40000000>;
 
+               misc@100000 {
+                       compatible = "nvidia,tegra194-misc";
+                       reg = <0x00100000 0xf000>,
+                             <0x0010f000 0x1000>;
+               };
+
                gpio: gpio@2200000 {
                        compatible = "nvidia,tegra194-gpio";
                        reg-names = "security", "gpio";
                        };
                };
 
+               mc: memory-controller@2c00000 {
+                       compatible = "nvidia,tegra194-mc";
+                       reg = <0x02c00000 0x100000>,
+                             <0x02b80000 0x040000>,
+                             <0x01700000 0x100000>;
+                       status = "disabled";
+
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+
+                       ranges = <0x01700000 0x0 0x01700000 0x0 0x100000>,
+                                <0x02b80000 0x0 0x02b80000 0x0 0x040000>,
+                                <0x02c00000 0x0 0x02c00000 0x0 0x100000>;
+
+                       /*
+                        * Bit 39 of addresses passing through the memory
+                        * controller selects the XBAR format used when memory
+                        * is accessed. This is used to transparently access
+                        * memory in the XBAR format used by the discrete GPU
+                        * (bit 39 set) or Tegra (bit 39 clear).
+                        *
+                        * As a consequence, the operating system must ensure
+                        * that bit 39 is never used implicitly, for example
+                        * via an I/O virtual address mapping of an IOMMU. If
+                        * devices require access to the XBAR switch, their
+                        * drivers must set this bit explicitly.
+                        *
+                        * Limit the DMA range for memory clients to [38:0].
+                        */
+                       dma-ranges = <0x0 0x0 0x0 0x80 0x0>;
+
+                       emc: external-memory-controller@2c60000 {
+                               compatible = "nvidia,tegra194-emc";
+                               reg = <0x0 0x02c60000 0x0 0x90000>,
+                                     <0x0 0x01780000 0x0 0x80000>;
+                               clocks = <&bpmp TEGRA194_CLK_EMC>;
+                               clock-names = "emc";
+
+                               nvidia,bpmp = <&bpmp>;
+                       };
+               };
+
                uarta: serial@3100000 {
                        compatible = "nvidia,tegra194-uart", "nvidia,tegra20-uart";
                        reg = <0x03100000 0x40>;
                        status = "disabled";
                };
 
+               fuse@3820000 {
+                       compatible = "nvidia,tegra194-efuse";
+                       reg = <0x03820000 0x10000>;
+                       clocks = <&bpmp TEGRA194_CLK_FUSE>;
+                       clock-names = "fuse";
+               };
+
                gic: interrupt-controller@3881000 {
                        compatible = "arm,gic-400";
                        #interrupt-cells = <3>;
index 90381d5..9101d3a 100644 (file)
                vmmc-supply = <&vdd_3v3_sd>;
        };
 
+       sdhci@700b0400 {
+               status = "okay";
+               bus-width = <4>;
+
+               vqmmc-supply = <&vdd_1v8>;
+               vmmc-supply = <&vdd_3v3_sys>;
+
+               non-removable;
+               cap-sdio-irq;
+               keep-power-in-suspend;
+               wakeup-source;
+       };
+
        clocks {
                compatible = "simple-bus";
                #address-cells = <1>;
                };
        };
 
+       fan: fan {
+               compatible = "pwm-fan";
+               pwms = <&pwm 3 45334>;
+
+               cooling-levels = <0 64 128 255>;
+               #cooling-cells = <2>;
+       };
+
+       thermal-zones {
+               cpu {
+                       trips {
+                               cpu_trip_critical: critical {
+                                       temperature = <96500>;
+                                       hysteresis = <0>;
+                                       type = "critical";
+                               };
+
+                               cpu_trip_hot: hot {
+                                       temperature = <70000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+
+                               cpu_trip_active: active {
+                                       temperature = <50000>;
+                                       hysteresis = <2000>;
+                                       type = "active";
+                               };
+
+                               cpu_trip_passive: passive {
+                                       temperature = <30000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+                       };
+
+                       cooling-maps {
+                               cpu-critical {
+                                       cooling-device = <&fan 3 3>;
+                                       trip = <&cpu_trip_critical>;
+                               };
+
+                               cpu-hot {
+                                       cooling-device = <&fan 2 2>;
+                                       trip = <&cpu_trip_hot>;
+                               };
+
+                               cpu-active {
+                                       cooling-device = <&fan 1 1>;
+                                       trip = <&cpu_trip_active>;
+                               };
+
+                               cpu-passive {
+                                       cooling-device = <&fan 0 0>;
+                                       trip = <&cpu_trip_passive>;
+                               };
+                       };
+               };
+       };
+
        gpio-keys {
                compatible = "gpio-keys";
 
index 6498a1e..973c0f0 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_QCOM)        += apq8016-sbc.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += apq8096-db820c.dtb
+dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += ipq8074-hk01.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8916-mtp.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8916-longcheer-l8150.dtb
@@ -13,6 +14,7 @@ dtb-$(CONFIG_ARCH_QCOM)       += msm8998-asus-novago-tp370ql.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8998-hp-envy-x2.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8998-lenovo-miix-630.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += msm8998-mtp.dtb
+dtb-$(CONFIG_ARCH_QCOM)        += sc7180-idp.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-cheza-r1.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-cheza-r2.dtb
 dtb-$(CONFIG_ARCH_QCOM)        += sdm845-cheza-r3.dtb
index ec2f0de..aff218c 100644 (file)
@@ -8,6 +8,15 @@
                pinconf {
                        pins = "gpio3";
                        function = PMIC_GPIO_FUNC_NORMAL;
+                       input-disable;
+                       output-high;
+               };
+       };
+
+       usb_hub_reset_pm_device: usb_hub_reset_pm_device {
+               pinconf {
+                       pins = "gpio3";
+                       function = PMIC_GPIO_FUNC_NORMAL;
                        output-low;
                };
        };
                };
        };
 
+       usb_sw_sel_pm_device: usb_sw_sel_pm_device {
+               pinconf {
+                       pins = "gpio4";
+                       function = PMIC_GPIO_FUNC_NORMAL;
+                       power-source = <PM8916_GPIO_VPH>;
+                       input-disable;
+                       output-low;
+               };
+       };
+
        pm8916_gpios_leds: pm8916_gpios_leds {
                pinconf {
                        pins = "gpio1", "gpio2";
index e12a36c..037e26b 100644 (file)
                };
 
                usb@78d9000 {
-                       extcon = <&usb_id>;
+                       extcon = <&usb_id>, <&usb_id>;
                        status = "okay";
                        adp-disable;
                        hnp-disable;
                        srp-disable;
-                       dr_mode = "host";
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&usb_sw_sel_pm>;
+                       dr_mode = "otg";
+                       pinctrl-names = "default", "device";
+                       pinctrl-0 = <&usb_sw_sel_pm &usb_hub_reset_pm>;
+                       pinctrl-1 = <&usb_sw_sel_pm_device &usb_hub_reset_pm_device>;
                        ulpi {
                                phy {
                                        v1p8-supply = <&pm8916_l7>;
 
        usb_id: usb-id {
                compatible = "linux,extcon-usb-gpio";
-               vbus-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>;
+               id-gpio = <&msmgpio 121 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
                pinctrl-0 = <&usb_id_default>;
        };
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c-pins.dtsi
deleted file mode 100644 (file)
index a5cc80d..0000000
+++ /dev/null
@@ -1,109 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/*
- * Copyright (c) 2013-2016, The Linux Foundation. All rights reserved.
- */
-&msmgpio {
-       sdc2_cd_on: sdc2_cd_on {
-               mux {
-                       pins = "gpio38";
-                       function = "gpio";
-               };
-
-               config {
-                       pins = "gpio38";
-                       bias-pull-up;           /* pull up */
-                       drive-strength = <16>;  /* 16 MA */
-               };
-       };
-
-       sdc2_cd_off: sdc2_cd_off {
-               mux {
-                       pins = "gpio38";
-                       function = "gpio";
-               };
-
-               config {
-                       pins = "gpio38";
-                       bias-pull-up;           /* pull up */
-                       drive-strength = <2>;   /* 2 MA */
-               };
-       };
-
-       blsp1_uart1_default: blsp1_uart1_default {
-               mux {
-                       pins = "gpio41", "gpio42", "gpio43", "gpio44";
-                       function = "blsp_uart2";
-               };
-
-               config {
-                       pins = "gpio41", "gpio42", "gpio43", "gpio44";
-                       drive-strength = <16>;
-                       bias-disable;
-               };
-       };
-
-       blsp1_uart1_sleep: blsp1_uart1_sleep {
-               mux {
-                       pins = "gpio41", "gpio42", "gpio43", "gpio44";
-                       function = "gpio";
-               };
-
-               config {
-                       pins = "gpio41", "gpio42", "gpio43", "gpio44";
-                       drive-strength = <2>;
-                       bias-disable;
-               };
-       };
-
-       hdmi_hpd_active: hdmi_hpd_active {
-               mux {
-                       pins = "gpio34";
-                       function = "hdmi_hot";
-               };
-
-               config {
-                       pins = "gpio34";
-                       bias-pull-down;
-                       drive-strength = <16>;
-               };
-       };
-
-       hdmi_hpd_suspend: hdmi_hpd_suspend {
-               mux {
-                       pins = "gpio34";
-                       function = "hdmi_hot";
-               };
-
-               config {
-                       pins = "gpio34";
-                       bias-pull-down;
-                       drive-strength = <2>;
-               };
-       };
-
-       hdmi_ddc_active: hdmi_ddc_active {
-               mux {
-                       pins = "gpio32", "gpio33";
-                       function = "hdmi_ddc";
-               };
-
-               config {
-                       pins = "gpio32", "gpio33";
-                       drive-strength = <2>;
-                       bias-pull-up;
-               };
-       };
-
-       hdmi_ddc_suspend: hdmi_ddc_suspend {
-               mux {
-                       pins = "gpio32", "gpio33";
-                       function = "hdmi_ddc";
-               };
-
-               config {
-                       pins = "gpio32", "gpio33";
-                       drive-strength = <2>;
-                       bias-pull-down;
-               };
-       };
-};
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c-pmic-pins.dtsi
deleted file mode 100644 (file)
index 31a3e33..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-
-#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
-&pm8994_gpios {
-
-       pinctrl-names = "default";
-       pinctrl-0 = <&ls_exp_gpio_f &bt_en_gpios>;
-
-       ls_exp_gpio_f: pm8994_gpio5 {
-               pinconf {
-                       pins = "gpio5";
-                       output-low;
-                       power-source = <2>; // PM8994_GPIO_S4, 1.8V
-               };
-       };
-
-       bt_en_gpios: bt_en_gpios {
-               pinconf {
-                       pins = "gpio19";
-                       function = PMIC_GPIO_FUNC_NORMAL;
-                       output-low;
-                       power-source = <PM8994_GPIO_S4>; // 1.8V
-                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
-                       bias-pull-down;
-               };
-       };
-
-       wlan_en_gpios: wlan_en_gpios {
-               pinconf {
-                       pins = "gpio8";
-                       function = PMIC_GPIO_FUNC_NORMAL;
-                       output-low;
-                       power-source = <PM8994_GPIO_S4>; // 1.8V
-                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
-                       bias-pull-down;
-               };
-       };
-
-       audio_mclk: clk_div1 {
-               pinconf {
-                       pins = "gpio15";
-                       function = "func1";
-                       power-source = <PM8994_GPIO_S4>; // 1.8V
-               };
-       };
-
-       volume_up_gpio: pm8996_gpio2 {
-               pinconf {
-                       pins = "gpio2";
-                       function = "normal";
-                       input-enable;
-                       drive-push-pull;
-                       bias-pull-up;
-                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
-                       power-source = <PM8994_GPIO_S4>; // 1.8V
-               };
-       };
-
-       divclk4_pin_a: divclk4 {
-               pinconf {
-                       pins = "gpio18";
-                       function = PMIC_GPIO_FUNC_FUNC2;
-
-                       bias-disable;
-                       power-source = <PM8994_GPIO_S4>;
-               };
-       };
-
-       usb3_vbus_det_gpio: pm8996_gpio22 {
-               pinconf {
-                       pins = "gpio22";
-                       function = PMIC_GPIO_FUNC_NORMAL;
-                       input-enable;
-                       bias-pull-down;
-                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
-                       power-source = <PM8994_GPIO_S4>; // 1.8V
-               };
-       };
-};
-
-&pmi8994_gpios {
-       usb2_vbus_det_gpio: pmi8996_gpio6 {
-               pinconf {
-                       pins = "gpio6";
-                       function = PMIC_GPIO_FUNC_NORMAL;
-                       input-enable;
-                       bias-pull-down;
-                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
-                       power-source = <PM8994_GPIO_S4>; // 1.8V
-               };
-       };
-};
index dba3488..fff6115 100644 (file)
@@ -6,10 +6,9 @@
 #include "msm8996.dtsi"
 #include "pm8994.dtsi"
 #include "pmi8994.dtsi"
-#include "apq8096-db820c-pins.dtsi"
-#include "apq8096-db820c-pmic-pins.dtsi"
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
 #include <dt-bindings/sound/qcom,q6afe.h>
 #include <dt-bindings/sound/qcom,q6asm.h>
 
                };
        };
 
-       soc {
-               serial@7570000 {
-                       label = "BT-UART";
-                       status = "okay";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&blsp1_uart1_default>;
-                       pinctrl-1 = <&blsp1_uart1_sleep>;
-
-                       bluetooth {
-                               compatible = "qcom,qca6174-bt";
+       gpio_keys {
+               compatible = "gpio-keys";
+               #address-cells = <1>;
+               #size-cells = <0>;
+               autorepeat;
 
-                               /* bt_disable_n gpio */
-                               enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&volume_up_gpio>;
 
-                               clocks = <&divclk4>;
-                       };
+               button@0 {
+                       label = "Volume Up";
+                       linux,code = <KEY_VOLUMEUP>;
+                       gpios = <&pm8994_gpios 2 GPIO_ACTIVE_LOW>;
                };
+       };
 
-               serial@75b0000 {
-                       label = "LS-UART1";
-                       status = "okay";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&blsp2_uart1_2pins_default>;
-                       pinctrl-1 = <&blsp2_uart1_2pins_sleep>;
-               };
-
-               serial@75b1000 {
-                       label = "LS-UART0";
-                       status = "disabled";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&blsp2_uart2_4pins_default>;
-                       pinctrl-1 = <&blsp2_uart2_4pins_sleep>;
-               };
-
-               i2c@7577000 {
-               /* On Low speed expansion */
-                       label = "LS-I2C0";
-                       status = "okay";
-               };
-
-               i2c@75b6000 {
-               /* On Low speed expansion */
-                       label = "LS-I2C1";
-                       status = "okay";
-               };
-
-               spi@7575000 {
-               /* On Low speed expansion */
-                       label = "LS-SPI0";
-                       status = "okay";
-               };
-
-               i2c@75b5000 {
-               /* On High speed expansion */
-                       label = "HS-I2C2";
-                       status = "okay";
-               };
-
-               spi@75ba000{
-               /* On High speed expansion */
-                       label = "HS-SPI1";
-                       status = "okay";
-               };
-
-               sdhci@74a4900 {
-               /* External SD card */
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
-                       pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
-                       cd-gpios = <&msmgpio 38 0x1>;
-                       vmmc-supply = <&pm8994_l21>;
-                       vqmmc-supply = <&pm8994_l13>;
-                       status = "okay";
-               };
-
-               phy@627000 {
-                       status = "okay";
-               };
-
-               ufshc@624000 {
-                       status = "okay";
-               };
-
-               pinctrl@1010000 {
-                       gpio-line-names =
-                               "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC pin 14 */
-                               "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC pin 10 */
-                               "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC pin 12 */
-                               "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC pin 8 */
-                               "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC pin 11 */
-                               "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC pin 13 */
-                               "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC pin 21 */
-                               "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC pin 19 */
-                               "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 */
-                               "TP93", /* GPIO_9 */
-                               "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 */
-                               "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */
-                               "NC", /* GPIO_12 */
-                               "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC pin 15 */
-                               "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */
-                               "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC pin 17 */
-                               "TP99", /* GPIO_16 */
-                               "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC pin 34 */
-                               "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC pin 32 */
-                               "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */
-                               "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */
-                               "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */
-                               "FLASH_STROBE_TRIG", /* GPIO_22, S HSEC pin 1 */
-                               "GPIO-K", /* GPIO_23, CAM2_RST_N, LSEC pin 33 */
-                               "GPIO-D", /* GPIO_24, LSEC pin 26 */
-                               "GPIO-I", /* GPIO_25, CAM0_RST_N, LSEC pin 31 */
-                               "GPIO-J", /* GPIO_26, CAM0_STANDBY_N, LSEC pin 32 */
-                               "BLSP6_I2C_SDA", /* GPIO_27 */
-                               "BLSP6_I2C_SCL", /* GPIO_28 */
-                               "GPIO-B", /* GPIO_29, TS0_RESET_N, LSEC pin 24 */
-                               "GPIO30", /* GPIO_30, S HSEC pin 4 */
-                               "HDMI_CEC", /* GPIO_31 */
-                               "HDMI_DDC_CLOCK", /* GPIO_32 */
-                               "HDMI_DDC_DATA", /* GPIO_33 */
-                               "HDMI_HOT_PLUG_DETECT", /* GPIO_34 */
-                               "PCIE0_RST_N", /* GPIO_35 */
-                               "PCIE0_CLKREQ_N", /* GPIO_36 */
-                               "PCIE0_WAKE", /* GPIO_37 */
-                               "SD_CARD_DET_N", /* GPIO_38 */
-                               "TSIF1_SYNC", /* GPIO_39, S HSEC pin 48 */
-                               "W_DISABLE_N", /* GPIO_40 */
-                               "[BLSP9_UART_TX]", /* GPIO_41 */
-                               "[BLSP9_UART_RX]", /* GPIO_42 */
-                               "[BLSP2_UART_CTS_N]", /* GPIO_43 */
-                               "[BLSP2_UART_RFR_N]", /* GPIO_44 */
-                               "[BLSP3_UART_TX]", /* GPIO_45 */
-                               "[BLSP3_UART_RX]", /* GPIO_46 */
-                               "[I2C0_SDA]", /* GPIO_47, LS_I2C0_SDA, LSEC pin 17 */
-                               "[I2C0_SCL]", /* GPIO_48, LS_I2C0_SCL, LSEC pin 15 */
-                               "[UART0_TxD]", /* GPIO_49, BLSP9_UART_TX, LSEC pin 5 */
-                               "[UART0_RxD]", /* GPIO_50, BLSP9_UART_RX, LSEC pin 7 */
-                               "[UART0_CTS]", /* GPIO_51, BLSP9_UART_CTS_N, LSEC pin 3 */
-                               "[UART0_RTS]", /* GPIO_52, BLSP9_UART_RFR_N, LSEC pin 9 */
-                               "[CODEC_INT1_N]", /* GPIO_53 */
-                               "[CODEC_INT2_N]", /* GPIO_54 */
-                               "[BLSP7_I2C_SDA]", /* GPIO_55 */
-                               "[BLSP7_I2C_SCL]", /* GPIO_56 */
-                               "MI2S_MCLK", /* GPIO_57, S HSEC pin 3 */
-                               "[PCM_CLK]", /* GPIO_58, QUA_MI2S_SCK, LSEC pin 18 */
-                               "[PCM_FS]", /* GPIO_59, QUA_MI2S_WS, LSEC pin 16 */
-                               "[PCM_DO]", /* GPIO_60, QUA_MI2S_DATA0, LSEC pin 20 */
-                               "[PCM_DI]", /* GPIO_61, QUA_MI2S_DATA1, LSEC pin 22 */
-                               "GPIO-E", /* GPIO_62, LSEC pin 27 */
-                               "TP87", /* GPIO_63 */
-                               "[CODEC_RST_N]", /* GPIO_64 */
-                               "[PCM1_CLK]", /* GPIO_65 */
-                               "[PCM1_SYNC]", /* GPIO_66 */
-                               "[PCM1_DIN]", /* GPIO_67 */
-                               "[PCM1_DOUT]", /* GPIO_68 */
-                               "AUDIO_REF_CLK", /* GPIO_69 */
-                               "SLIMBUS_CLK", /* GPIO_70 */
-                               "SLIMBUS_DATA0", /* GPIO_71 */
-                               "SLIMBUS_DATA1", /* GPIO_72 */
-                               "NC", /* GPIO_73 */
-                               "NC", /* GPIO_74 */
-                               "NC", /* GPIO_75 */
-                               "NC", /* GPIO_76 */
-                               "TP94", /* GPIO_77 */
-                               "NC", /* GPIO_78 */
-                               "TP95", /* GPIO_79 */
-                               "GPIO-A", /* GPIO_80, MEMS_RESET_N, LSEC pin 23 */
-                               "TP88", /* GPIO_81 */
-                               "TP89", /* GPIO_82 */
-                               "TP90", /* GPIO_83 */
-                               "TP91", /* GPIO_84 */
-                               "[SD_DAT0]", /* GPIO_85, BLSP12_SPI_MOSI, P HSEC pin 1 */
-                               "[SD_CMD]", /* GPIO_86, BLSP12_SPI_MISO, P HSEC pin 11 */
-                               "[SD_DAT3]", /* GPIO_87, BLSP12_SPI_CS_N, P HSEC pin 7 */
-                               "[SD_SCLK]", /* GPIO_88, BLSP12_SPI_CLK, P HSEC pin 9 */
-                               "TSIF1_CLK", /* GPIO_89, S HSEC pin 42 */
-                               "TSIF1_EN", /* GPIO_90, S HSEC pin 46 */
-                               "TSIF1_DATA", /* GPIO_91, S HSEC pin 44 */
-                               "NC", /* GPIO_92 */
-                               "TSIF2_CLK", /* GPIO_93, S HSEC pin 52 */
-                               "TSIF2_EN", /* GPIO_94, S HSEC pin 56 */
-                               "TSIF2_DATA", /* GPIO_95, S HSEC pin 54 */
-                               "TSIF2_SYNC", /* GPIO_96, S HSEC pin 58 */
-                               "NC", /* GPIO_97 */
-                               "CAM1_STANDBY_N", /* GPIO_98 */
-                               "NC", /* GPIO_99 */
-                               "NC", /* GPIO_100 */
-                               "[LCD1_RESET_N]", /* GPIO_101, S HSEC pin 51 */
-                               "BOOT_CONFIG1", /* GPIO_102 */
-                               "USB_HUB_RESET", /* GPIO_103 */
-                               "CAM1_RST_N", /* GPIO_104 */
-                               "NC", /* GPIO_105 */
-                               "NC", /* GPIO_106 */
-                               "NC", /* GPIO_107 */
-                               "NC", /* GPIO_108 */
-                               "NC", /* GPIO_109 */
-                               "NC", /* GPIO_110 */
-                               "NC", /* GPIO_111 */
-                               "NC", /* GPIO_112 */
-                               "PMI8994_BUA", /* GPIO_113 */
-                               "PCIE2_RST_N", /* GPIO_114 */
-                               "PCIE2_CLKREQ_N", /* GPIO_115 */
-                               "PCIE2_WAKE", /* GPIO_116 */
-                               "SSC_IRQ_0", /* GPIO_117 */
-                               "SSC_IRQ_1", /* GPIO_118 */
-                               "SSC_IRQ_2", /* GPIO_119 */
-                               "NC", /* GPIO_120 */
-                               "GPIO121", /* GPIO_121, S HSEC pin 2 */
-                               "NC", /* GPIO_122 */
-                               "SSC_IRQ_6", /* GPIO_123 */
-                               "SSC_IRQ_7", /* GPIO_124 */
-                               "GPIO-C", /* GPIO_125, TS_INT0, LSEC pin 25 */
-                               "BOOT_CONFIG5", /* GPIO_126 */
-                               "NC", /* GPIO_127 */
-                               "NC", /* GPIO_128 */
-                               "BOOT_CONFIG7", /* GPIO_129 */
-                               "PCIE1_RST_N", /* GPIO_130 */
-                               "PCIE1_CLKREQ_N", /* GPIO_131 */
-                               "PCIE1_WAKE", /* GPIO_132 */
-                               "GPIO-L", /* GPIO_133, CAM2_STANDBY_N, LSEC pin 34 */
-                               "NC", /* GPIO_134 */
-                               "NC", /* GPIO_135 */
-                               "BOOT_CONFIG8", /* GPIO_136 */
-                               "NC", /* GPIO_137 */
-                               "NC", /* GPIO_138 */
-                               "GPS_SSBI2", /* GPIO_139 */
-                               "GPS_SSBI1", /* GPIO_140 */
-                               "NC", /* GPIO_141 */
-                               "NC", /* GPIO_142 */
-                               "NC", /* GPIO_143 */
-                               "BOOT_CONFIG6", /* GPIO_144 */
-                               "NC", /* GPIO_145 */
-                               "NC", /* GPIO_146 */
-                               "NC", /* GPIO_147 */
-                               "NC", /* GPIO_148 */
-                               "NC"; /* GPIO_149 */
-               };
-
-               qcom,spmi@400f000 {
-                       pmic@0 {
-                               gpios@c000 {
-                                       gpio-line-names =
-                                               "NC",
-                                               "KEY_VOLP_N",
-                                               "NC",
-                                               "BL1_PWM",
-                                               "GPIO-F", /* BL0_PWM, LSEC pin 28 */
-                                               "BL1_EN",
-                                               "NC",
-                                               "WLAN_EN",
-                                               "NC",
-                                               "NC",
-                                               "NC",
-                                               "NC",
-                                               "NC",
-                                               "NC",
-                                               "DIVCLK1",
-                                               "DIVCLK2",
-                                               "DIVCLK3",
-                                               "DIVCLK4",
-                                               "BT_EN",
-                                               "PMIC_SLB",
-                                               "PMIC_BUA",
-                                               "USB_VBUS_DET";
-                               };
-
-                               mpps@a000 {
-                                       gpio-line-names =
-                                               "VDDPX_BIAS",
-                                               "WIFI_LED",
-                                               "NC",
-                                               "BT_LED",
-                                               "PM_MPP05",
-                                               "PM_MPP06",
-                                               "PM_MPP07",
-                                               "NC";
-                               };
-                       };
+       usb2_id: usb2-id {
+               compatible = "linux,extcon-usb-gpio";
+               id-gpio = <&pmi8994_gpios 6 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb2_vbus_det_gpio>;
+       };
 
-                       pmic@2 {
-                               gpios@c000 {
-                                       gpio-line-names =
-                                               "NC",
-                                               "SPKR_AMP_EN1",
-                                               "SPKR_AMP_EN2",
-                                               "TP61",
-                                               "NC",
-                                               "USB2_VBUS_DET",
-                                               "NC",
-                                               "NC",
-                                               "NC",
-                                               "NC";
-                               };
-                       };
-               };
+       usb3_id: usb3-id {
+               compatible = "linux,extcon-usb-gpio";
+               id-gpio = <&pm8994_gpios 22 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&usb3_vbus_det_gpio>;
+       };
 
-               phy@34000 {
-                       status = "okay";
-               };
+       vph_pwr: vph-pwr-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vph_pwr";
+               regulator-always-on;
+               regulator-boot-on;
+
+               regulator-min-microvolt = <3700000>;
+               regulator-max-microvolt = <3700000>;
+       };
+
+       vreg_s8a_l3a_input: vreg-s8a-l3a-input {
+               compatible = "regulator-fixed";
+               regulator-name = "vreg_s8a_l3a_input";
+               regulator-always-on;
+               regulator-boot-on;
+
+               regulator-min-microvolt = <0>;
+               regulator-max-microvolt = <0>;
+       };
+
+       wlan_en: wlan-en-1-8v {
+               pinctrl-names = "default";
+               pinctrl-0 = <&wlan_en_gpios>;
+               compatible = "regulator-fixed";
+               regulator-name = "wlan-en-regulator";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+
+               gpio = <&pm8994_gpios 8 0>;
+
+               /* WLAN card specific delay */
+               startup-delay-us = <70000>;
+               enable-active-high;
+       };
+};
+
+&blsp1_i2c2 {
+       /* On Low speed expansion */
+       label = "LS-I2C0";
+       status = "okay";
+};
+
+&blsp1_spi0 {
+       /* On Low speed expansion */
+       label = "LS-SPI0";
+       status = "okay";
+};
+
+&blsp1_uart1 {
+       label = "BT-UART";
+       status = "okay";
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&blsp1_uart1_default>;
+       pinctrl-1 = <&blsp1_uart1_sleep>;
+
+       bluetooth {
+               compatible = "qcom,qca6174-bt";
+
+               /* bt_disable_n gpio */
+               enable-gpios = <&pm8994_gpios 19 GPIO_ACTIVE_HIGH>;
+
+               clocks = <&divclk4>;
+       };
+};
+
+&blsp2_i2c0 {
+       /* On High speed expansion */
+       label = "HS-I2C2";
+       status = "okay";
+};
+
+&blsp2_i2c1 {
+       /* On Low speed expansion */
+       label = "LS-I2C1";
+       status = "okay";
+};
+
+&blsp2_spi5 {
+       /* On High speed expansion */
+       label = "HS-SPI1";
+       status = "okay";
+};
+
+&blsp2_uart1 {
+       label = "LS-UART1";
+       status = "okay";
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&blsp2_uart1_2pins_default>;
+       pinctrl-1 = <&blsp2_uart1_2pins_sleep>;
+};
+
+&blsp2_uart2 {
+       label = "LS-UART0";
+       status = "disabled";
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&blsp2_uart2_4pins_default>;
+       pinctrl-1 = <&blsp2_uart2_4pins_sleep>;
+};
+
+&camss {
+       vdda-supply = <&vreg_l2a_1p25>;
+};
+
+&hdmi {
+       status = "okay";
+
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&hdmi_hpd_active &hdmi_ddc_active>;
+       pinctrl-1 = <&hdmi_hpd_suspend &hdmi_ddc_suspend>;
+
+       core-vdda-supply = <&vreg_l12a_1p8>;
+       core-vcc-supply = <&vreg_s4a_1p8>;
+};
+
+&hdmi_phy {
+       status = "okay";
+
+       vddio-supply = <&vreg_l12a_1p8>;
+       vcca-supply = <&vreg_l28a_0p925>;
+       #phy-cells = <0>;
+};
+
+&hsusb_phy1 {
+       status = "okay";
+
+       vdda-pll-supply = <&vreg_l12a_1p8>;
+       vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
+};
+
+&hsusb_phy2 {
+       status = "okay";
+
+       vdda-pll-supply = <&vreg_l12a_1p8>;
+       vdda-phy-dpdm-supply = <&vreg_l24a_3p075>;
+};
+
+&mdp {
+       status = "okay";
+};
+
+&mdss {
+       status = "okay";
+};
 
-               phy@7410000 {
-                       status = "okay";
+&msmgpio {
+       gpio-line-names =
+               "[SPI0_DOUT]", /* GPIO_0, BLSP1_SPI_MOSI, LSEC pin 14 */
+               "[SPI0_DIN]", /* GPIO_1, BLSP1_SPI_MISO, LSEC pin 10 */
+               "[SPI0_CS]", /* GPIO_2, BLSP1_SPI_CS_N, LSEC pin 12 */
+               "[SPI0_SCLK]", /* GPIO_3, BLSP1_SPI_CLK, LSEC pin 8 */
+               "[UART1_TxD]", /* GPIO_4, BLSP8_UART_TX, LSEC pin 11 */
+               "[UART1_RxD]", /* GPIO_5, BLSP8_UART_RX, LSEC pin 13 */
+               "[I2C1_SDA]", /* GPIO_6, BLSP8_I2C_SDA, LSEC pin 21 */
+               "[I2C1_SCL]", /* GPIO_7, BLSP8_I2C_SCL, LSEC pin 19 */
+               "GPIO-H", /* GPIO_8, LCD0_RESET_N, LSEC pin 30 */
+               "TP93", /* GPIO_9 */
+               "GPIO-G", /* GPIO_10, MDP_VSYNC_P, LSEC pin 29 */
+               "[MDP_VSYNC_S]", /* GPIO_11, S HSEC pin 55 */
+               "NC", /* GPIO_12 */
+               "[CSI0_MCLK]", /* GPIO_13, CAM_MCLK0, P HSEC pin 15 */
+               "[CAM_MCLK1]", /* GPIO_14, J14 pin 11 */
+               "[CSI1_MCLK]", /* GPIO_15, CAM_MCLK2, P HSEC pin 17 */
+               "TP99", /* GPIO_16 */
+               "[I2C2_SDA]", /* GPIO_17, CCI_I2C_SDA0, P HSEC pin 34 */
+               "[I2C2_SCL]", /* GPIO_18, CCI_I2C_SCL0, P HSEC pin 32 */
+               "[CCI_I2C_SDA1]", /* GPIO_19, S HSEC pin 38 */
+               "[CCI_I2C_SCL1]", /* GPIO_20, S HSEC pin 36 */
+               "FLASH_STROBE_EN", /* GPIO_21, S HSEC pin 5 */
+               "FLASH_STROBE_TRIG", /* GPIO_22, S HSEC pin 1 */
+               "GPIO-K", /* GPIO_23, CAM2_RST_N, LSEC pin 33 */
+               "GPIO-D", /* GPIO_24, LSEC pin 26 */
+               "GPIO-I", /* GPIO_25, CAM0_RST_N, LSEC pin 31 */
+               "GPIO-J", /* GPIO_26, CAM0_STANDBY_N, LSEC pin 32 */
+               "BLSP6_I2C_SDA", /* GPIO_27 */
+               "BLSP6_I2C_SCL", /* GPIO_28 */
+               "GPIO-B", /* GPIO_29, TS0_RESET_N, LSEC pin 24 */
+               "GPIO30", /* GPIO_30, S HSEC pin 4 */
+               "HDMI_CEC", /* GPIO_31 */
+               "HDMI_DDC_CLOCK", /* GPIO_32 */
+               "HDMI_DDC_DATA", /* GPIO_33 */
+               "HDMI_HOT_PLUG_DETECT", /* GPIO_34 */
+               "PCIE0_RST_N", /* GPIO_35 */
+               "PCIE0_CLKREQ_N", /* GPIO_36 */
+               "PCIE0_WAKE", /* GPIO_37 */
+               "SD_CARD_DET_N", /* GPIO_38 */
+               "TSIF1_SYNC", /* GPIO_39, S HSEC pin 48 */
+               "W_DISABLE_N", /* GPIO_40 */
+               "[BLSP9_UART_TX]", /* GPIO_41 */
+               "[BLSP9_UART_RX]", /* GPIO_42 */
+               "[BLSP2_UART_CTS_N]", /* GPIO_43 */
+               "[BLSP2_UART_RFR_N]", /* GPIO_44 */
+               "[BLSP3_UART_TX]", /* GPIO_45 */
+               "[BLSP3_UART_RX]", /* GPIO_46 */
+               "[I2C0_SDA]", /* GPIO_47, LS_I2C0_SDA, LSEC pin 17 */
+               "[I2C0_SCL]", /* GPIO_48, LS_I2C0_SCL, LSEC pin 15 */
+               "[UART0_TxD]", /* GPIO_49, BLSP9_UART_TX, LSEC pin 5 */
+               "[UART0_RxD]", /* GPIO_50, BLSP9_UART_RX, LSEC pin 7 */
+               "[UART0_CTS]", /* GPIO_51, BLSP9_UART_CTS_N, LSEC pin 3 */
+               "[UART0_RTS]", /* GPIO_52, BLSP9_UART_RFR_N, LSEC pin 9 */
+               "[CODEC_INT1_N]", /* GPIO_53 */
+               "[CODEC_INT2_N]", /* GPIO_54 */
+               "[BLSP7_I2C_SDA]", /* GPIO_55 */
+               "[BLSP7_I2C_SCL]", /* GPIO_56 */
+               "MI2S_MCLK", /* GPIO_57, S HSEC pin 3 */
+               "[PCM_CLK]", /* GPIO_58, QUA_MI2S_SCK, LSEC pin 18 */
+               "[PCM_FS]", /* GPIO_59, QUA_MI2S_WS, LSEC pin 16 */
+               "[PCM_DO]", /* GPIO_60, QUA_MI2S_DATA0, LSEC pin 20 */
+               "[PCM_DI]", /* GPIO_61, QUA_MI2S_DATA1, LSEC pin 22 */
+               "GPIO-E", /* GPIO_62, LSEC pin 27 */
+               "TP87", /* GPIO_63 */
+               "[CODEC_RST_N]", /* GPIO_64 */
+               "[PCM1_CLK]", /* GPIO_65 */
+               "[PCM1_SYNC]", /* GPIO_66 */
+               "[PCM1_DIN]", /* GPIO_67 */
+               "[PCM1_DOUT]", /* GPIO_68 */
+               "AUDIO_REF_CLK", /* GPIO_69 */
+               "SLIMBUS_CLK", /* GPIO_70 */
+               "SLIMBUS_DATA0", /* GPIO_71 */
+               "SLIMBUS_DATA1", /* GPIO_72 */
+               "NC", /* GPIO_73 */
+               "NC", /* GPIO_74 */
+               "NC", /* GPIO_75 */
+               "NC", /* GPIO_76 */
+               "TP94", /* GPIO_77 */
+               "NC", /* GPIO_78 */
+               "TP95", /* GPIO_79 */
+               "GPIO-A", /* GPIO_80, MEMS_RESET_N, LSEC pin 23 */
+               "TP88", /* GPIO_81 */
+               "TP89", /* GPIO_82 */
+               "TP90", /* GPIO_83 */
+               "TP91", /* GPIO_84 */
+               "[SD_DAT0]", /* GPIO_85, BLSP12_SPI_MOSI, P HSEC pin 1 */
+               "[SD_CMD]", /* GPIO_86, BLSP12_SPI_MISO, P HSEC pin 11 */
+               "[SD_DAT3]", /* GPIO_87, BLSP12_SPI_CS_N, P HSEC pin 7 */
+               "[SD_SCLK]", /* GPIO_88, BLSP12_SPI_CLK, P HSEC pin 9 */
+               "TSIF1_CLK", /* GPIO_89, S HSEC pin 42 */
+               "TSIF1_EN", /* GPIO_90, S HSEC pin 46 */
+               "TSIF1_DATA", /* GPIO_91, S HSEC pin 44 */
+               "NC", /* GPIO_92 */
+               "TSIF2_CLK", /* GPIO_93, S HSEC pin 52 */
+               "TSIF2_EN", /* GPIO_94, S HSEC pin 56 */
+               "TSIF2_DATA", /* GPIO_95, S HSEC pin 54 */
+               "TSIF2_SYNC", /* GPIO_96, S HSEC pin 58 */
+               "NC", /* GPIO_97 */
+               "CAM1_STANDBY_N", /* GPIO_98 */
+               "NC", /* GPIO_99 */
+               "NC", /* GPIO_100 */
+               "[LCD1_RESET_N]", /* GPIO_101, S HSEC pin 51 */
+               "BOOT_CONFIG1", /* GPIO_102 */
+               "USB_HUB_RESET", /* GPIO_103 */
+               "CAM1_RST_N", /* GPIO_104 */
+               "NC", /* GPIO_105 */
+               "NC", /* GPIO_106 */
+               "NC", /* GPIO_107 */
+               "NC", /* GPIO_108 */
+               "NC", /* GPIO_109 */
+               "NC", /* GPIO_110 */
+               "NC", /* GPIO_111 */
+               "NC", /* GPIO_112 */
+               "PMI8994_BUA", /* GPIO_113 */
+               "PCIE2_RST_N", /* GPIO_114 */
+               "PCIE2_CLKREQ_N", /* GPIO_115 */
+               "PCIE2_WAKE", /* GPIO_116 */
+               "SSC_IRQ_0", /* GPIO_117 */
+               "SSC_IRQ_1", /* GPIO_118 */
+               "SSC_IRQ_2", /* GPIO_119 */
+               "NC", /* GPIO_120 */
+               "GPIO121", /* GPIO_121, S HSEC pin 2 */
+               "NC", /* GPIO_122 */
+               "SSC_IRQ_6", /* GPIO_123 */
+               "SSC_IRQ_7", /* GPIO_124 */
+               "GPIO-C", /* GPIO_125, TS_INT0, LSEC pin 25 */
+               "BOOT_CONFIG5", /* GPIO_126 */
+               "NC", /* GPIO_127 */
+               "NC", /* GPIO_128 */
+               "BOOT_CONFIG7", /* GPIO_129 */
+               "PCIE1_RST_N", /* GPIO_130 */
+               "PCIE1_CLKREQ_N", /* GPIO_131 */
+               "PCIE1_WAKE", /* GPIO_132 */
+               "GPIO-L", /* GPIO_133, CAM2_STANDBY_N, LSEC pin 34 */
+               "NC", /* GPIO_134 */
+               "NC", /* GPIO_135 */
+               "BOOT_CONFIG8", /* GPIO_136 */
+               "NC", /* GPIO_137 */
+               "NC", /* GPIO_138 */
+               "GPS_SSBI2", /* GPIO_139 */
+               "GPS_SSBI1", /* GPIO_140 */
+               "NC", /* GPIO_141 */
+               "NC", /* GPIO_142 */
+               "NC", /* GPIO_143 */
+               "BOOT_CONFIG6", /* GPIO_144 */
+               "NC", /* GPIO_145 */
+               "NC", /* GPIO_146 */
+               "NC", /* GPIO_147 */
+               "NC", /* GPIO_148 */
+               "NC"; /* GPIO_149 */
+
+       sdc2_cd_on: sdc2_cd_on {
+               mux {
+                       pins = "gpio38";
+                       function = "gpio";
                };
 
-               phy@7411000 {
-                       status = "okay";
+               config {
+                       pins = "gpio38";
+                       bias-pull-up;           /* pull up */
+                       drive-strength = <16>;  /* 16 MA */
                };
+       };
 
-               phy@7412000 {
-                       status = "okay";
+       sdc2_cd_off: sdc2_cd_off {
+               mux {
+                       pins = "gpio38";
+                       function = "gpio";
                };
 
-               usb@6af8800 {
-                       status = "okay";
-                       extcon = <&usb3_id>;
+               config {
+                       pins = "gpio38";
+                       bias-pull-up;           /* pull up */
+                       drive-strength = <2>;   /* 2 MA */
+               };
+       };
 
-                       dwc3@6a00000 {
-                               extcon = <&usb3_id>;
-                               dr_mode = "otg";
-                       };
+       blsp1_uart1_default: blsp1_uart1_default {
+               mux {
+                       pins = "gpio41", "gpio42", "gpio43", "gpio44";
+                       function = "blsp_uart2";
                };
 
-               usb3_id: usb3-id {
-                       compatible = "linux,extcon-usb-gpio";
-                       id-gpio = <&pm8994_gpios 22 GPIO_ACTIVE_HIGH>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&usb3_vbus_det_gpio>;
+               config {
+                       pins = "gpio41", "gpio42", "gpio43", "gpio44";
+                       drive-strength = <16>;
+                       bias-disable;
                };
+       };
 
-               usb@76f8800 {
-                       status = "okay";
-                       extcon = <&usb2_id>;
+       blsp1_uart1_sleep: blsp1_uart1_sleep {
+               mux {
+                       pins = "gpio41", "gpio42", "gpio43", "gpio44";
+                       function = "gpio";
+               };
 
-                       dwc3@7600000 {
-                               extcon = <&usb2_id>;
-                               dr_mode = "otg";
-                               maximum-speed = "high-speed";
-                       };
+               config {
+                       pins = "gpio41", "gpio42", "gpio43", "gpio44";
+                       drive-strength = <2>;
+                       bias-disable;
                };
+       };
 
-               usb2_id: usb2-id {
-                       compatible = "linux,extcon-usb-gpio";
-                       id-gpio = <&pmi8994_gpios 6 GPIO_ACTIVE_HIGH>;
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&usb2_vbus_det_gpio>;
+       hdmi_hpd_active: hdmi_hpd_active {
+               mux {
+                       pins = "gpio34";
+                       function = "hdmi_hot";
                };
 
-               wlan_en: wlan-en-1-8v {
-                       pinctrl-names = "default";
-                       pinctrl-0 = <&wlan_en_gpios>;
-                       compatible = "regulator-fixed";
-                       regulator-name = "wlan-en-regulator";
-                       regulator-min-microvolt = <1800000>;
-                       regulator-max-microvolt = <1800000>;
+               config {
+                       pins = "gpio34";
+                       bias-pull-down;
+                       drive-strength = <16>;
+               };
+       };
 
-                       gpio = <&pm8994_gpios 8 0>;
+       hdmi_hpd_suspend: hdmi_hpd_suspend {
+               mux {
+                       pins = "gpio34";
+                       function = "hdmi_hot";
+               };
 
-                       /* WLAN card specific delay */
-                       startup-delay-us = <70000>;
-                       enable-active-high;
+               config {
+                       pins = "gpio34";
+                       bias-pull-down;
+                       drive-strength = <2>;
                };
+       };
 
-               agnoc@0 {
-                       pcie@600000 {
-                               status = "okay";
-                               perst-gpio = <&msmgpio 35 GPIO_ACTIVE_LOW>;
-                               vddpe-3v3-supply = <&wlan_en>;
-                       };
+       hdmi_ddc_active: hdmi_ddc_active {
+               mux {
+                       pins = "gpio32", "gpio33";
+                       function = "hdmi_ddc";
+               };
 
-                       pcie@608000 {
-                               status = "okay";
-                               perst-gpio = <&msmgpio 130 GPIO_ACTIVE_LOW>;
-                       };
+               config {
+                       pins = "gpio32", "gpio33";
+                       drive-strength = <2>;
+                       bias-pull-up;
+               };
+       };
 
-                       pcie@610000 {
-                               status = "okay";
-                               perst-gpio = <&msmgpio 114 GPIO_ACTIVE_LOW>;
-                       };
+       hdmi_ddc_suspend: hdmi_ddc_suspend {
+               mux {
+                       pins = "gpio32", "gpio33";
+                       function = "hdmi_ddc";
                };
 
-               slim_msm: slim@91c0000 {
-                       ngd@1 {
-                               wcd9335: codec@1{
-                                       clock-names = "mclk", "slimbus";
-                                       clocks = <&div1_mclk>,
-                                                <&rpmcc RPM_SMD_BB_CLK1>;
-                               };
-                       };
+               config {
+                       pins = "gpio32", "gpio33";
+                       drive-strength = <2>;
+                       bias-pull-down;
                };
+       };
+};
 
-               mdss@900000 {
-                       status = "okay";
+&pcie0 {
+       status = "okay";
+       perst-gpio = <&msmgpio 35 GPIO_ACTIVE_LOW>;
+       vddpe-3v3-supply = <&wlan_en>;
+       vdda-supply = <&vreg_l28a_0p925>;
+};
 
-                       mdp@901000 {
-                               status = "okay";
-                       };
+&pcie1 {
+       status = "okay";
+       perst-gpio = <&msmgpio 130 GPIO_ACTIVE_LOW>;
+       vdda-supply = <&vreg_l28a_0p925>;
+};
 
-                       hdmi-phy@9a0600 {
-                               status = "okay";
+&pcie2 {
+       status = "okay";
+       perst-gpio = <&msmgpio 114 GPIO_ACTIVE_LOW>;
+       vdda-supply = <&vreg_l28a_0p925>;
+};
 
-                               vddio-supply = <&pm8994_l12>;
-                               vcca-supply = <&pm8994_l28>;
-                               #phy-cells = <0>;
-                       };
+&pcie_phy {
+       status = "okay";
 
-                       hdmi-tx@9a0000 {
-                               status = "okay";
+       vdda-phy-supply = <&vreg_l28a_0p925>;
+       vdda-pll-supply = <&vreg_l12a_1p8>;
+};
 
-                               pinctrl-names = "default", "sleep";
-                               pinctrl-0 = <&hdmi_hpd_active &hdmi_ddc_active>;
-                               pinctrl-1 = <&hdmi_hpd_suspend &hdmi_ddc_suspend>;
+&pm8994_gpios {
+       gpio-line-names =
+               "NC",
+               "KEY_VOLP_N",
+               "NC",
+               "BL1_PWM",
+               "GPIO-F", /* BL0_PWM, LSEC pin 28 */
+               "BL1_EN",
+               "NC",
+               "WLAN_EN",
+               "NC",
+               "NC",
+               "NC",
+               "NC",
+               "NC",
+               "NC",
+               "DIVCLK1",
+               "DIVCLK2",
+               "DIVCLK3",
+               "DIVCLK4",
+               "BT_EN",
+               "PMIC_SLB",
+               "PMIC_BUA",
+               "USB_VBUS_DET";
+
+       pinctrl-names = "default";
+       pinctrl-0 = <&ls_exp_gpio_f &bt_en_gpios>;
+
+       ls_exp_gpio_f: pm8994_gpio5 {
+               pinconf {
+                       pins = "gpio5";
+                       output-low;
+                       power-source = <2>; // PM8994_GPIO_S4, 1.8V
+               };
+       };
 
-                               core-vdda-supply = <&pm8994_l12>;
-                               core-vcc-supply = <&pm8994_s4>;
-                       };
+       bt_en_gpios: bt_en_gpios {
+               pinconf {
+                       pins = "gpio19";
+                       function = PMIC_GPIO_FUNC_NORMAL;
+                       output-low;
+                       power-source = <PM8994_GPIO_S4>; // 1.8V
+                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+                       bias-pull-down;
                };
        };
 
+       wlan_en_gpios: wlan_en_gpios {
+               pinconf {
+                       pins = "gpio8";
+                       function = PMIC_GPIO_FUNC_NORMAL;
+                       output-low;
+                       power-source = <PM8994_GPIO_S4>; // 1.8V
+                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>;
+                       bias-pull-down;
+               };
+       };
 
-       gpio_keys {
-               compatible = "gpio-keys";
-               #address-cells = <1>;
-               #size-cells = <0>;
-               autorepeat;
+       audio_mclk: clk_div1 {
+               pinconf {
+                       pins = "gpio15";
+                       function = "func1";
+                       power-source = <PM8994_GPIO_S4>; // 1.8V
+               };
+       };
 
-               pinctrl-names = "default";
-               pinctrl-0 = <&volume_up_gpio>;
+       volume_up_gpio: pm8996_gpio2 {
+               pinconf {
+                       pins = "gpio2";
+                       function = "normal";
+                       input-enable;
+                       drive-push-pull;
+                       bias-pull-up;
+                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
+                       power-source = <PM8994_GPIO_S4>; // 1.8V
+               };
+       };
 
-               button@0 {
-                       label = "Volume Up";
-                       linux,code = <KEY_VOLUMEUP>;
-                       gpios = <&pm8994_gpios 2 GPIO_ACTIVE_LOW>;
+       divclk4_pin_a: divclk4 {
+               pinconf {
+                       pins = "gpio18";
+                       function = PMIC_GPIO_FUNC_FUNC2;
+
+                       bias-disable;
+                       power-source = <PM8994_GPIO_S4>;
                };
        };
 
-       rpm-glink {
-               rpm_requests {
-                       pm8994-regulators {
-                               vdd_l1-supply = <&pm8994_s3>;
-                               vdd_l2_l26_l28-supply = <&pm8994_s3>;
-                               vdd_l3_l11-supply = <&pm8994_s3>;
-                               vdd_l4_l27_l31-supply = <&pm8994_s3>;
-                               vdd_l5_l7-supply = <&pm8994_s5>;
-                               vdd_l14_l15-supply = <&pm8994_s5>;
-                               vdd_l20_l21-supply = <&pm8994_s5>;
-                               vdd_l25-supply = <&pm8994_s3>;
-
-                               s3 {
-                                       regulator-min-microvolt = <1300000>;
-                                       regulator-max-microvolt = <1300000>;
-                               };
-
-                               /**
-                                * 1.8v required on LS expansion
-                                * for mezzanine boards
-                                */
-                               s4 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                                       regulator-always-on;
-                               };
-                               s5 {
-                                       regulator-min-microvolt = <2150000>;
-                                       regulator-max-microvolt = <2150000>;
-                               };
-                               s7 {
-                                       regulator-min-microvolt = <800000>;
-                                       regulator-max-microvolt = <800000>;
-                               };
-
-                               l1 {
-                                       regulator-min-microvolt = <1000000>;
-                                       regulator-max-microvolt = <1000000>;
-                               };
-                               l2 {
-                                       regulator-min-microvolt = <1250000>;
-                                       regulator-max-microvolt = <1250000>;
-                               };
-                               l3 {
-                                       regulator-min-microvolt = <850000>;
-                                       regulator-max-microvolt = <850000>;
-                               };
-                               l4 {
-                                       regulator-min-microvolt = <1225000>;
-                                       regulator-max-microvolt = <1225000>;
-                               };
-                               l6 {
-                                       regulator-min-microvolt = <1200000>;
-                                       regulator-max-microvolt = <1200000>;
-                               };
-                               l8 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-                               l9 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-                               l10 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-                               l11 {
-                                       regulator-min-microvolt = <1150000>;
-                                       regulator-max-microvolt = <1150000>;
-                               };
-                               l12 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-                               l13 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <2950000>;
-                               };
-                               l14 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-                               l15 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-                               l16 {
-                                       regulator-min-microvolt = <2700000>;
-                                       regulator-max-microvolt = <2700000>;
-                               };
-                               l17 {
-                                       regulator-min-microvolt = <2500000>;
-                                       regulator-max-microvolt = <2500000>;
-                               };
-                               l18 {
-                                       regulator-min-microvolt = <2700000>;
-                                       regulator-max-microvolt = <2900000>;
-                               };
-                               l19 {
-                                       regulator-min-microvolt = <3000000>;
-                                       regulator-max-microvolt = <3000000>;
-                               };
-                               l20 {
-                                       regulator-min-microvolt = <2950000>;
-                                       regulator-max-microvolt = <2950000>;
-                                       regulator-allow-set-load;
-                               };
-                               l21 {
-                                       regulator-min-microvolt = <2950000>;
-                                       regulator-max-microvolt = <2950000>;
-                                       regulator-allow-set-load;
-                                       regulator-system-load = <200000>;
-                               };
-                               l22 {
-                                       regulator-min-microvolt = <3300000>;
-                                       regulator-max-microvolt = <3300000>;
-                               };
-                               l23 {
-                                       regulator-min-microvolt = <2800000>;
-                                       regulator-max-microvolt = <2800000>;
-                               };
-                               l24 {
-                                       regulator-min-microvolt = <3075000>;
-                                       regulator-max-microvolt = <3075000>;
-                               };
-                               l25 {
-                                       regulator-min-microvolt = <1200000>;
-                                       regulator-max-microvolt = <1200000>;
-                                       regulator-allow-set-load;
-                               };
-                               l27 {
-                                       regulator-min-microvolt = <1000000>;
-                                       regulator-max-microvolt = <1000000>;
-                               };
-                               l28 {
-                                       regulator-min-microvolt = <925000>;
-                                       regulator-max-microvolt = <925000>;
-                                       regulator-allow-set-load;
-                               };
-                               l29 {
-                                       regulator-min-microvolt = <2800000>;
-                                       regulator-max-microvolt = <2800000>;
-                               };
-                               l30 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-                               l32 {
-                                       regulator-min-microvolt = <1800000>;
-                                       regulator-max-microvolt = <1800000>;
-                               };
-                       };
+       usb3_vbus_det_gpio: pm8996_gpio22 {
+               pinconf {
+                       pins = "gpio22";
+                       function = PMIC_GPIO_FUNC_NORMAL;
+                       input-enable;
+                       bias-pull-down;
+                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
+                       power-source = <PM8994_GPIO_S4>; // 1.8V
                };
        };
 };
 
-&spmi_bus {
-       pmic@0 {
-               pon@800 {
-                       resin {
-                               compatible = "qcom,pm8941-resin";
-                               interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
-                               debounce = <15625>;
-                               bias-pull-up;
-                               linux,code = <KEY_VOLUMEDOWN>;
-                       };
+&pm8994_mpps {
+       gpio-line-names =
+               "VDDPX_BIAS",
+               "WIFI_LED",
+               "NC",
+               "BT_LED",
+               "PM_MPP05",
+               "PM_MPP06",
+               "PM_MPP07",
+               "NC";
+};
+
+&pm8994_spmi_regulators {
+       qcom,saw-reg = <&saw3>;
+       s9 {
+               qcom,saw-slave;
+       };
+       s10 {
+               qcom,saw-slave;
+       };
+       s11 {
+               qcom,saw-leader;
+               regulator-always-on;
+               regulator-min-microvolt = <1230000>;
+               regulator-max-microvolt = <1230000>;
+       };
+};
+
+&pmi8994_gpios {
+       gpio-line-names =
+               "NC",
+               "SPKR_AMP_EN1",
+               "SPKR_AMP_EN2",
+               "TP61",
+               "NC",
+               "USB2_VBUS_DET",
+               "NC",
+               "NC",
+               "NC",
+               "NC";
+
+       usb2_vbus_det_gpio: pmi8996_gpio6 {
+               pinconf {
+                       pins = "gpio6";
+                       function = PMIC_GPIO_FUNC_NORMAL;
+                       input-enable;
+                       bias-pull-down;
+                       qcom,drive-strength = <PMIC_GPIO_STRENGTH_NO>;
+                       power-source = <PM8994_GPIO_S4>; // 1.8V
                };
        };
 };
 
+&rpm_requests {
+       pm8994-regulators {
+               compatible = "qcom,rpm-pm8994-regulators";
+
+               vdd_s1-supply = <&vph_pwr>;
+               vdd_s2-supply = <&vph_pwr>;
+               vdd_s3-supply = <&vph_pwr>;
+               vdd_s4-supply = <&vph_pwr>;
+               vdd_s5-supply = <&vph_pwr>;
+               vdd_s6-supply = <&vph_pwr>;
+               vdd_s7-supply = <&vph_pwr>;
+               vdd_s8-supply = <&vph_pwr>;
+               vdd_s9-supply = <&vph_pwr>;
+               vdd_s10-supply = <&vph_pwr>;
+               vdd_s11-supply = <&vph_pwr>;
+               vdd_s12-supply = <&vph_pwr>;
+               vdd_l2_l26_l28-supply = <&vreg_s3a_1p3>;
+               vdd_l3_l11-supply = <&vreg_s8a_l3a_input>;
+               vdd_l4_l27_l31-supply = <&vreg_s3a_1p3>;
+               vdd_l5_l7-supply = <&vreg_s5a_2p15>;
+               vdd_l6_l12_l32-supply = <&vreg_s5a_2p15>;
+               vdd_l8_l16_l30-supply = <&vph_pwr>;
+               vdd_l14_l15-supply = <&vreg_s5a_2p15>;
+               vdd_l25-supply = <&vreg_s3a_1p3>;
+               vdd_lvs1_2-supply = <&vreg_s4a_1p8>;
+
+               vreg_s3a_1p3: s3 {
+                       regulator-name = "vreg_s3a_1p3";
+                       regulator-min-microvolt = <1300000>;
+                       regulator-max-microvolt = <1300000>;
+               };
+
+               /**
+                * 1.8v required on LS expansion
+                * for mezzanine boards
+                */
+               vreg_s4a_1p8: s4 {
+                       regulator-name = "vreg_s4a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+               vreg_s5a_2p15: s5 {
+                       regulator-name = "vreg_s5a_2p15";
+                       regulator-min-microvolt = <2150000>;
+                       regulator-max-microvolt = <2150000>;
+               };
+               vreg_s7a_1p0: s7 {
+                       regulator-name = "vreg_s7a_1p0";
+                       regulator-min-microvolt = <800000>;
+                       regulator-max-microvolt = <800000>;
+               };
+
+               vreg_l1a_1p0: l1 {
+                       regulator-name = "vreg_l1a_1p0";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+               };
+               vreg_l2a_1p25: l2 {
+                       regulator-name = "vreg_l2a_1p25";
+                       regulator-min-microvolt = <1250000>;
+                       regulator-max-microvolt = <1250000>;
+               };
+               vreg_l3a_0p875: l3 {
+                       regulator-name = "vreg_l3a_0p875";
+                       regulator-min-microvolt = <850000>;
+                       regulator-max-microvolt = <850000>;
+               };
+               vreg_l4a_1p225: l4 {
+                       regulator-name = "vreg_l4a_1p225";
+                       regulator-min-microvolt = <1225000>;
+                       regulator-max-microvolt = <1225000>;
+               };
+               vreg_l6a_1p2: l6 {
+                       regulator-name = "vreg_l6a_1p2";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+               vreg_l8a_1p8: l8 {
+                       regulator-name = "vreg_l8a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l9a_1p8: l9 {
+                       regulator-name = "vreg_l9a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l10a_1p8: l10 {
+                       regulator-name = "vreg_l10a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l11a_1p15: l11 {
+                       regulator-name = "vreg_l11a_1p15";
+                       regulator-min-microvolt = <1150000>;
+                       regulator-max-microvolt = <1150000>;
+               };
+               vreg_l12a_1p8: l12 {
+                       regulator-name = "vreg_l12a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l13a_2p95: l13 {
+                       regulator-name = "vreg_l13a_2p95";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+               vreg_l14a_1p8: l14 {
+                       regulator-name = "vreg_l14a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l15a_1p8: l15 {
+                       regulator-name = "vreg_l15a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l16a_2p7: l16 {
+                       regulator-name = "vreg_l16a_2p7";
+                       regulator-min-microvolt = <2700000>;
+                       regulator-max-microvolt = <2700000>;
+               };
+               vreg_l17a_2p8: l17 {
+                       regulator-name = "vreg_l17a_2p8";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+               };
+               vreg_l18a_2p85: l18 {
+                       regulator-name = "vreg_l18a_2p85";
+                       regulator-min-microvolt = <2700000>;
+                       regulator-max-microvolt = <2900000>;
+               };
+               vreg_l19a_2p8: l19 {
+                       regulator-name = "vreg_l19a_2p8";
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3000000>;
+               };
+               vreg_l20a_2p95: l20 {
+                       regulator-name = "vreg_l20a_2p95";
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l21a_2p95: l21 {
+                       regulator-name = "vreg_l21a_2p95";
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-allow-set-load;
+                       regulator-system-load = <200000>;
+               };
+               vreg_l22a_3p0: l22 {
+                       regulator-name = "vreg_l22a_3p0";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+               vreg_l23a_2p8: l23 {
+                       regulator-name = "vreg_l23a_2p8";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+               };
+               vreg_l24a_3p075: l24 {
+                       regulator-name = "vreg_l24a_3p075";
+                       regulator-min-microvolt = <3075000>;
+                       regulator-max-microvolt = <3075000>;
+               };
+               vreg_l25a_1p2: l25 {
+                       regulator-name = "vreg_l25a_1p2";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l26a_0p8: l27 {
+                       regulator-name = "vreg_l26a_0p8";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+               };
+               vreg_l28a_0p925: l28 {
+                       regulator-name = "vreg_l28a_0p925";
+                       regulator-min-microvolt = <925000>;
+                       regulator-max-microvolt = <925000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l29a_2p8: l29 {
+                       regulator-name = "vreg_l29a_2p8";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+               };
+               vreg_l30a_1p8: l30 {
+                       regulator-name = "vreg_l30a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l32a_1p8: l32 {
+                       regulator-name = "vreg_l32a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               vreg_lvs1a_1p8: lvs1 {
+                       regulator-name = "vreg_lvs1a_1p8";
+               };
+
+               vreg_lvs2a_1p8: lvs2 {
+                       regulator-name = "vreg_lvs2a_1p8";
+               };
+       };
+};
+
+&sdhc2 {
+       /* External SD card */
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_on>;
+       pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>;
+       cd-gpios = <&msmgpio 38 0x1>;
+       vmmc-supply = <&vreg_l21a_2p95>;
+       vqmmc-supply = <&vreg_l13a_2p95>;
+       status = "okay";
+};
+
 &sound {
        compatible = "qcom,apq8096-sndcard";
        model = "DB820c";
                };
        };
 };
+
+&spmi_bus {
+       pmic@0 {
+               pon@800 {
+                       resin {
+                               compatible = "qcom,pm8941-resin";
+                               interrupts = <0x0 0x8 1 IRQ_TYPE_EDGE_BOTH>;
+                               debounce = <15625>;
+                               bias-pull-up;
+                               linux,code = <KEY_VOLUMEDOWN>;
+                       };
+               };
+       };
+};
+
+&ufsphy {
+       status = "okay";
+
+       vdda-phy-supply = <&vreg_l28a_0p925>;
+       vdda-pll-supply = <&vreg_l12a_1p8>;
+
+       vdda-phy-max-microamp = <18380>;
+       vdda-pll-max-microamp = <9440>;
+
+       vddp-ref-clk-supply = <&vreg_l25a_1p2>;
+       vddp-ref-clk-max-microamp = <100>;
+       vddp-ref-clk-always-on;
+};
+
+&ufshc {
+       status = "okay";
+
+       vcc-supply = <&vreg_l20a_2p95>;
+       vccq-supply = <&vreg_l25a_1p2>;
+       vccq2-supply = <&vreg_s4a_1p8>;
+
+       vcc-max-microamp = <600000>;
+       vccq-max-microamp = <450000>;
+       vccq2-max-microamp = <450000>;
+};
+
+&usb2 {
+       status = "okay";
+       extcon = <&usb2_id>;
+
+       dwc3@7600000 {
+               extcon = <&usb2_id>;
+               dr_mode = "otg";
+               maximum-speed = "high-speed";
+       };
+};
+
+&usb3 {
+       status = "okay";
+       extcon = <&usb3_id>;
+
+       dwc3@6a00000 {
+               extcon = <&usb3_id>;
+               dr_mode = "otg";
+       };
+};
+
+&usb3phy {
+       status = "okay";
+
+       vdda-phy-supply = <&vreg_l28a_0p925>;
+       vdda-pll-supply = <&vreg_l12a_1p8>;
+
+};
+
+&wcd9335 {
+       clock-names = "mclk", "slimbus";
+       clocks = <&div1_mclk>,
+                <&rpmcc RPM_SMD_BB_CLK1>;
+
+       vdd-buck-supply = <&vreg_s4a_1p8>;
+       vdd-buck-sido-supply = <&vreg_s4a_1p8>;
+       vdd-tx-supply = <&vreg_s4a_1p8>;
+       vdd-rx-supply = <&vreg_s4a_1p8>;
+       vdd-io-supply = <&vreg_s4a_1p8>;
+};
diff --git a/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts b/arch/arm64/boot/dts/qcom/apq8096-ifc6640.dts
new file mode 100644 (file)
index 0000000..f6ddf17
--- /dev/null
@@ -0,0 +1,385 @@
+// SPDX-License-Identifier: BSD-3-Clause
+
+/dts-v1/;
+
+#include "msm8996.dtsi"
+#include "pm8994.dtsi"
+#include "pmi8994.dtsi"
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pinctrl/qcom,pmic-gpio.h>
+
+/ {
+       model = "Inforce 6640 Single Board Computer";
+       compatible = "inforce,ifc6640", "qcom,apq8096-sbc", "qcom,apq8096";
+
+       qcom,msm-id = <291 0x00030001>;
+       qcom,board-id = <0x00010018 0>;
+
+       aliases {
+               serial0 = &blsp2_uart1;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+
+       v1p05: v1p05-regulator {
+               compatible = "regulator-fixed";
+               reglator-name = "v1p05";
+               regulator-always-on;
+               regulator-boot-on;
+
+               regulator-min-microvolt = <1050000>;
+               regulator-max-microvolt = <1050000>;
+
+               vin-supply = <&v5p0>;
+       };
+
+       v12_poe: v12-poe-regulator {
+               compatible = "regulator-fixed";
+               reglator-name = "v12_poe";
+               regulator-always-on;
+               regulator-boot-on;
+
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+       };
+
+       v3p3: v3p3-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "v3p3";
+               regulator-always-on;
+               regulator-boot-on;
+
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+
+               vin-supply = <&v12_poe>;
+       };
+
+       v5p0: v5p0-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "v5p0";
+               regulator-always-on;
+               regulator-boot-on;
+
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+
+               vin-supply = <&v12_poe>;
+       };
+
+       vph_pwr: vph-pwr-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vph_pwr";
+               regulator-always-on;
+               regulator-boot-on;
+
+               regulator-min-microvolt = <3800000>;
+               regulator-max-microvolt = <3800000>;
+       };
+};
+
+&blsp2_uart1 {
+       status = "okay";
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&blsp2_uart1_2pins_default>;
+       pinctrl-1 = <&blsp2_uart1_2pins_sleep>;
+};
+
+&msmgpio {
+       sdc2_pins_default: sdc2-pins-default {
+               clk {
+                       pins = "sdc2_clk";
+                       bias-disable;
+                       drive-strength = <16>;
+               };
+
+               cmd {
+                       pins = "sdc2_cmd";
+                       bias-pull-up;
+                       drive-strength = <10>;
+               };
+
+               data {
+                       pins = "sdc2_data";
+                       bias-pull-up;
+                       drive-strength = <10>;
+               };
+
+               cd {
+                       pins = "gpio38";
+                       function = "gpio";
+
+                       bias-pull-up;
+                       drive-strength = <16>;
+               };
+       };
+
+       sdc2_pins_sleep: sdc2-pins-sleep {
+               clk {
+                       pins = "sdc2_clk";
+                       bias-disable;
+                       drive-strength = <2>;
+               };
+
+               cmd {
+                       pins = "sdc2_cmd";
+                       bias-pull-up;
+                       drive-strength = <2>;
+               };
+
+               data {
+                       pins = "sdc2_data";
+                       bias-pull-up;
+                       drive-strength = <2>;
+               };
+
+               cd {
+                       pins = "gpio38";
+                       function = "gpio";
+                       bias-pull-up;
+                       drive-strength = <2>;
+               };
+       };
+};
+
+&rpm_requests {
+       pm8994-regulators {
+               compatible = "qcom,rpm-pm8994-regulators";
+
+               vdd_s1-supply = <&vph_pwr>;
+               vdd_s2-supply = <&vph_pwr>;
+               vdd_s3-supply = <&vph_pwr>;
+               vdd_s4-supply = <&vph_pwr>;
+               vdd_s5-supply = <&vph_pwr>;
+               vdd_s6-supply = <&vph_pwr>;
+               vdd_s7-supply = <&vph_pwr>;
+               vdd_s8-supply = <&vph_pwr>;
+               vdd_s9-supply = <&vph_pwr>;
+               vdd_s10-supply = <&vph_pwr>;
+               vdd_s11-supply = <&vph_pwr>;
+               vdd_s12-supply = <&vph_pwr>;
+               vdd_l2_l26_l28-supply = <&vreg_s3a_1p3>;
+               vdd_l3_l11-supply = <&vreg_s3a_1p3>;
+               vdd_l4_l27_l31-supply = <&vreg_s3a_1p3>;
+               vdd_l5_l7-supply = <&vreg_s5a_2p15>;
+               vdd_l6_l12_l32-supply = <&vreg_s5a_2p15>;
+               vdd_l8_l16_l30-supply = <&vph_pwr>;
+               vdd_l25-supply = <&vreg_s3a_1p3>;
+               vdd_lvs1_2-supply = <&vreg_s4a_1p8>;
+
+               vreg_s3a_1p3: s3 {
+                       regulator-name = "vreg_s3a_1p3";
+                       regulator-min-microvolt = <1300000>;
+                       regulator-max-microvolt = <1300000>;
+               };
+
+               vreg_s4a_1p8: s4 {
+                       regulator-name = "vreg_s4a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+                       regulator-always-on;
+               };
+               vreg_s5a_2p15: s5 {
+                       regulator-name = "vreg_s5a_2p15";
+                       regulator-min-microvolt = <2150000>;
+                       regulator-max-microvolt = <2150000>;
+               };
+               vreg_s7a_1p0: s7 {
+                       regulator-name = "vreg_s7a_1p0";
+                       regulator-min-microvolt = <800000>;
+                       regulator-max-microvolt = <800000>;
+               };
+
+               vreg_l1a_1p0: l1 {
+                       regulator-name = "vreg_l1a_1p0";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+               };
+               vreg_l2a_1p25: l2 {
+                       regulator-name = "vreg_l2a_1p25";
+                       regulator-min-microvolt = <1250000>;
+                       regulator-max-microvolt = <1250000>;
+               };
+               vreg_l3a_0p875: l3 {
+                       regulator-name = "vreg_l3a_0p875";
+                       regulator-min-microvolt = <850000>;
+                       regulator-max-microvolt = <850000>;
+               };
+               vreg_l4a_1p225: l4 {
+                       regulator-name = "vreg_l4a_1p225";
+                       regulator-min-microvolt = <1225000>;
+                       regulator-max-microvolt = <1225000>;
+               };
+               vreg_l6a_1p2: l6 {
+                       regulator-name = "vreg_l6a_1p2";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+               };
+               vreg_l8a_1p8: l8 {
+                       regulator-name = "vreg_l8a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l9a_1p8: l9 {
+                       regulator-name = "vreg_l9a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l10a_1p8: l10 {
+                       regulator-name = "vreg_l10a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l11a_1p15: l11 {
+                       regulator-name = "vreg_l11a_1p15";
+                       regulator-min-microvolt = <1150000>;
+                       regulator-max-microvolt = <1150000>;
+               };
+               vreg_l12a_1p8: l12 {
+                       regulator-name = "vreg_l12a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l13a_2p95: l13 {
+                       regulator-name = "vreg_l13a_2p95";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+               vreg_l14a_1p8: l14 {
+                       regulator-name = "vreg_l14a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l15a_1p8: l15 {
+                       regulator-name = "vreg_l15a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l16a_2p7: l16 {
+                       regulator-name = "vreg_l16a_2p7";
+                       regulator-min-microvolt = <2700000>;
+                       regulator-max-microvolt = <2700000>;
+               };
+               vreg_l17a_2p8: l17 {
+                       regulator-name = "vreg_l17a_2p8";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+               };
+               vreg_l18a_2p85: l18 {
+                       regulator-name = "vreg_l18a_2p85";
+                       regulator-min-microvolt = <2700000>;
+                       regulator-max-microvolt = <2900000>;
+               };
+               vreg_l19a_2p8: l19 {
+                       regulator-name = "vreg_l19a_2p8";
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3000000>;
+               };
+               vreg_l20a_2p95: l20 {
+                       regulator-name = "vreg_l20a_2p95";
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l21a_2p95: l21 {
+                       regulator-name = "vreg_l21a_2p95";
+                       regulator-min-microvolt = <2950000>;
+                       regulator-max-microvolt = <2950000>;
+               };
+               vreg_l22a_3p0: l22 {
+                       regulator-name = "vreg_l22a_3p0";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+               };
+               vreg_l23a_2p8: l23 {
+                       regulator-name = "vreg_l23a_2p8";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+               };
+               vreg_l24a_3p075: l24 {
+                       regulator-name = "vreg_l24a_3p075";
+                       regulator-min-microvolt = <3075000>;
+                       regulator-max-microvolt = <3075000>;
+               };
+               vreg_l25a_1p2: l25 {
+                       regulator-name = "vreg_l25a_1p2";
+                       regulator-min-microvolt = <1200000>;
+                       regulator-max-microvolt = <1200000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l26a_0p8: l27 {
+                       regulator-name = "vreg_l26a_0p8";
+                       regulator-min-microvolt = <1000000>;
+                       regulator-max-microvolt = <1000000>;
+               };
+               vreg_l28a_0p925: l28 {
+                       regulator-name = "vreg_l28a_0p925";
+                       regulator-min-microvolt = <925000>;
+                       regulator-max-microvolt = <925000>;
+                       regulator-allow-set-load;
+               };
+               vreg_l29a_2p8: l29 {
+                       regulator-name = "vreg_l29a_2p8";
+                       regulator-min-microvolt = <2800000>;
+                       regulator-max-microvolt = <2800000>;
+               };
+               vreg_l30a_1p8: l30 {
+                       regulator-name = "vreg_l30a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+               vreg_l32a_1p8: l32 {
+                       regulator-name = "vreg_l32a_1p8";
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1800000>;
+               };
+
+               vreg_lvs1a_1p8: lvs1 {
+                       regulator-name = "vreg_lvs1a_1p8";
+               };
+
+               vreg_lvs2a_1p8: lvs2 {
+                       regulator-name = "vreg_lvs2a_1p8";
+               };
+       };
+};
+
+&sdhc2 {
+       status = "okay";
+
+       bus-width = <4>;
+
+       cd-gpios = <&msmgpio 38 0x1>;
+
+       vmmc-supply = <&vreg_l21a_2p95>;
+       vqmmc-supply = <&vreg_l13a_2p95>;
+
+       pinctrl-names = "default", "sleep";
+       pinctrl-0 = <&sdc2_pins_default>;
+       pinctrl-1 = <&sdc2_pins_sleep>;
+};
+
+&ufshc {
+       status = "okay";
+
+       vcc-supply = <&vreg_l20a_2p95>;
+       vccq-supply = <&vreg_l25a_1p2>;
+       vccq2-supply = <&vreg_s4a_1p8>;
+
+       vcc-max-microamp = <600000>;
+       vccq-max-microamp = <450000>;
+       vccq2-max-microamp = <450000>;
+};
+
+&ufsphy {
+       status = "okay";
+
+       vdda-phy-supply = <&vreg_l28a_0p925>;
+       vdda-pll-supply = <&vreg_l12a_1p8>;
+
+       vdda-phy-max-microamp = <18380>;
+       vdda-pll-max-microamp = <9440>;
+};
index 8686e10..9f31064 100644 (file)
                        reg = <0x0>;
                        next-level-cache = <&L2_0>;
                        enable-method = "psci";
-                       cpu-idle-states = <&CPU_SLEEP_0>;
                        clocks = <&apcs>;
                        operating-points-v2 = <&cpu_opp_table>;
                        #cooling-cells = <2>;
+                       power-domains = <&CPU_PD0>;
+                       power-domain-names = "psci";
                };
 
                CPU1: cpu@1 {
                        reg = <0x1>;
                        next-level-cache = <&L2_0>;
                        enable-method = "psci";
-                       cpu-idle-states = <&CPU_SLEEP_0>;
                        clocks = <&apcs>;
                        operating-points-v2 = <&cpu_opp_table>;
                        #cooling-cells = <2>;
+                       power-domains = <&CPU_PD1>;
+                       power-domain-names = "psci";
                };
 
                CPU2: cpu@2 {
                        reg = <0x2>;
                        next-level-cache = <&L2_0>;
                        enable-method = "psci";
-                       cpu-idle-states = <&CPU_SLEEP_0>;
                        clocks = <&apcs>;
                        operating-points-v2 = <&cpu_opp_table>;
                        #cooling-cells = <2>;
+                       power-domains = <&CPU_PD2>;
+                       power-domain-names = "psci";
                };
 
                CPU3: cpu@3 {
                        reg = <0x3>;
                        next-level-cache = <&L2_0>;
                        enable-method = "psci";
-                       cpu-idle-states = <&CPU_SLEEP_0>;
                        clocks = <&apcs>;
                        operating-points-v2 = <&cpu_opp_table>;
                        #cooling-cells = <2>;
+                       power-domains = <&CPU_PD3>;
+                       power-domain-names = "psci";
                };
 
                L2_0: l2-cache {
                                min-residency-us = <2000>;
                                local-timer-stop;
                        };
+
+                       CLUSTER_RET: cluster-retention {
+                               compatible = "domain-idle-state";
+                               arm,psci-suspend-param = <0x41000012>;
+                               entry-latency-us = <500>;
+                               exit-latency-us = <500>;
+                               min-residency-us = <2000>;
+                       };
+
+                       CLUSTER_PWRDN: cluster-gdhs {
+                               compatible = "domain-idle-state";
+                               arm,psci-suspend-param = <0x41000032>;
+                               entry-latency-us = <2000>;
+                               exit-latency-us = <2000>;
+                               min-residency-us = <6000>;
+                       };
                };
        };
 
        psci {
                compatible = "arm,psci-1.0";
                method = "smc";
+
+               CPU_PD0: cpu-pd0 {
+                       #power-domain-cells = <0>;
+                       power-domains = <&CLUSTER_PD>;
+                       domain-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               CPU_PD1: cpu-pd1 {
+                       #power-domain-cells = <0>;
+                       power-domains = <&CLUSTER_PD>;
+                       domain-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               CPU_PD2: cpu-pd2 {
+                       #power-domain-cells = <0>;
+                       power-domains = <&CLUSTER_PD>;
+                       domain-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               CPU_PD3: cpu-pd3 {
+                       #power-domain-cells = <0>;
+                       power-domains = <&CLUSTER_PD>;
+                       domain-idle-states = <&CPU_SLEEP_0>;
+               };
+
+               CLUSTER_PD: cluster-pd {
+                       #power-domain-cells = <0>;
+                       domain-idle-states = <&CLUSTER_RET>, <&CLUSTER_PWRDN>;
+               };
        };
 
        pmu {
                        compatible = "qcom,msm8916-apcs-kpss-global", "syscon";
                        reg = <0xb011000 0x1000>;
                        #mbox-cells = <1>;
-                       clocks = <&a53pll>;
+                       clocks = <&a53pll>, <&gcc GPLL0_VOTE>;
+                       clock-names = "pll", "aux";
                        #clock-cells = <0>;
                };
 
                        nvmem-cells = <&tsens_caldata>, <&tsens_calsel>;
                        nvmem-cell-names = "calib", "calib_sel";
                        #qcom,sensors = <5>;
+                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow";
                        #thermal-sensor-cells = <1>;
                };
 
index 4ca2e7b..7ae082e 100644 (file)
 
        chosen { };
 
-       memory {
-               device_type = "memory";
-               /* We expect the bootloader to fill in the reg */
-               reg = <0 0 0 0>;
-       };
-
-       reserved-memory {
-               #address-cells = <2>;
-               #size-cells = <2>;
-               ranges;
-
-               mba_region: mba@91500000 {
-                       reg = <0x0 0x91500000 0x0 0x200000>;
-                       no-map;
-               };
-
-               slpi_region: slpi@90b00000 {
-                       reg = <0x0 0x90b00000 0x0 0xa00000>;
-                       no-map;
-               };
-
-               venus_region: venus@90400000 {
-                       reg = <0x0 0x90400000 0x0 0x700000>;
-                       no-map;
-               };
-
-               adsp_region: adsp@8ea00000 {
-                       reg = <0x0 0x8ea00000 0x0 0x1a00000>;
-                       no-map;
-               };
-
-               mpss_region: mpss@88800000 {
-                       reg = <0x0 0x88800000 0x0 0x6200000>;
-                       no-map;
-               };
-
-               smem_mem: smem-mem@86000000 {
-                       reg = <0x0 0x86000000 0x0 0x200000>;
-                       no-map;
-               };
-
-               memory@85800000 {
-                       reg = <0x0 0x85800000 0x0 0x800000>;
-                       no-map;
-               };
-
-               memory@86200000 {
-                       reg = <0x0 0x86200000 0x0 0x2600000>;
-                       no-map;
-               };
-
-               rmtfs@86700000 {
-                       compatible = "qcom,rmtfs-mem";
-
-                       size = <0x0 0x200000>;
-                       alloc-ranges = <0x0 0xa0000000 0x0 0x2000000>;
-                       no-map;
-
-                       qcom,client-id = <1>;
-                       qcom,vmid = <15>;
+       clocks {
+               xo_board: xo_board {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <19200000>;
+                       clock-output-names = "xo_board";
                };
 
-               zap_shader_region: gpu@8f200000 {
-                       compatible = "shared-dma-pool";
-                       reg = <0x0 0x90b00000 0x0 0xa00000>;
-                       no-map;
+               sleep_clk: sleep_clk {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <32764>;
+                       clock-output-names = "sleep_clk";
                };
        };
 
                };
        };
 
-       thermal-zones {
-               cpu0-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
+       firmware {
+               scm {
+                       compatible = "qcom,scm-msm8996";
+                       qcom,dload-mode = <&tcsr 0x13000>;
+               };
+       };
 
-                       thermal-sensors = <&tsens0 3>;
+       tcsr_mutex: hwlock {
+               compatible = "qcom,tcsr-mutex";
+               syscon = <&tcsr_mutex_regs 0 0x1000>;
+               #hwlock-cells = <1>;
+       };
 
-                       trips {
-                               cpu0_alert0: trip-point@0 {
-                                       temperature = <75000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
+       memory {
+               device_type = "memory";
+               /* We expect the bootloader to fill in the reg */
+               reg = <0 0 0 0>;
+       };
 
-                               cpu0_crit: cpu_crit {
-                                       temperature = <110000>;
-                                       hysteresis = <2000>;
-                                       type = "critical";
-                               };
-                       };
-               };
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
 
-               cpu1-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
+       reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
 
-                       thermal-sensors = <&tsens0 5>;
+               mba_region: mba@91500000 {
+                       reg = <0x0 0x91500000 0x0 0x200000>;
+                       no-map;
+               };
 
-                       trips {
-                               cpu1_alert0: trip-point@0 {
-                                       temperature = <75000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
+               slpi_region: slpi@90b00000 {
+                       reg = <0x0 0x90b00000 0x0 0xa00000>;
+                       no-map;
+               };
 
-                               cpu1_crit: cpu_crit {
-                                       temperature = <110000>;
-                                       hysteresis = <2000>;
-                                       type = "critical";
-                               };
-                       };
+               venus_region: venus@90400000 {
+                       reg = <0x0 0x90400000 0x0 0x700000>;
+                       no-map;
                };
 
-               cpu2-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
+               adsp_region: adsp@8ea00000 {
+                       reg = <0x0 0x8ea00000 0x0 0x1a00000>;
+                       no-map;
+               };
 
-                       thermal-sensors = <&tsens0 8>;
+               mpss_region: mpss@88800000 {
+                       reg = <0x0 0x88800000 0x0 0x6200000>;
+                       no-map;
+               };
 
-                       trips {
-                               cpu2_alert0: trip-point@0 {
-                                       temperature = <75000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
+               smem_mem: smem-mem@86000000 {
+                       reg = <0x0 0x86000000 0x0 0x200000>;
+                       no-map;
+               };
 
-                               cpu2_crit: cpu_crit {
-                                       temperature = <110000>;
-                                       hysteresis = <2000>;
-                                       type = "critical";
-                               };
-                       };
+               memory@85800000 {
+                       reg = <0x0 0x85800000 0x0 0x800000>;
+                       no-map;
                };
 
-               cpu3-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
+               memory@86200000 {
+                       reg = <0x0 0x86200000 0x0 0x2600000>;
+                       no-map;
+               };
 
-                       thermal-sensors = <&tsens0 10>;
+               rmtfs@86700000 {
+                       compatible = "qcom,rmtfs-mem";
 
-                       trips {
-                               cpu3_alert0: trip-point@0 {
-                                       temperature = <75000>;
-                                       hysteresis = <2000>;
-                                       type = "passive";
-                               };
+                       size = <0x0 0x200000>;
+                       alloc-ranges = <0x0 0xa0000000 0x0 0x2000000>;
+                       no-map;
 
-                               cpu3_crit: cpu_crit {
-                                       temperature = <110000>;
-                                       hysteresis = <2000>;
-                                       type = "critical";
-                               };
-                       };
+                       qcom,client-id = <1>;
+                       qcom,vmid = <15>;
                };
 
-               gpu-thermal-top {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&tsens1 6>;
-
-                       trips {
-                               gpu1_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
+               zap_shader_region: gpu@8f200000 {
+                       compatible = "shared-dma-pool";
+                       reg = <0x0 0x90b00000 0x0 0xa00000>;
+                       no-map;
                };
+       };
 
-               gpu-thermal-bottom {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
+       rpm-glink {
+               compatible = "qcom,glink-rpm";
 
-                       thermal-sensors = <&tsens1 7>;
+               interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
 
-                       trips {
-                               gpu2_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
+               qcom,rpm-msg-ram = <&rpm_msg_ram>;
 
-               m4m-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
+               mboxes = <&apcs_glb 0>;
 
-                       thermal-sensors = <&tsens0 1>;
+               rpm_requests: rpm-requests {
+                       compatible = "qcom,rpm-msm8996";
+                       qcom,glink-channels = "rpm_requests";
 
-                       trips {
-                               m4m_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
-
-               l3-or-venus-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&tsens0 2>;
-
-                       trips {
-                               l3_or_venus_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
-
-               cluster0-l2-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&tsens0 7>;
-
-                       trips {
-                               cluster0_l2_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
-
-               cluster1-l2-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&tsens0 12>;
-
-                       trips {
-                               cluster1_l2_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
-
-               camera-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&tsens1 1>;
-
-                       trips {
-                               camera_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
-
-               q6-dsp-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&tsens1 2>;
-
-                       trips {
-                               q6_dsp_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
-
-               mem-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&tsens1 3>;
-
-                       trips {
-                               mem_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
-
-               modemtx-thermal {
-                       polling-delay-passive = <250>;
-                       polling-delay = <1000>;
-
-                       thermal-sensors = <&tsens1 4>;
-
-                       trips {
-                               modemtx_alert0: trip-point@0 {
-                                       temperature = <90000>;
-                                       hysteresis = <2000>;
-                                       type = "hot";
-                               };
-                       };
-               };
-       };
-
-       timer {
-               compatible = "arm,armv8-timer";
-               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
-                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
-                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
-                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
-       };
-
-       clocks {
-               xo_board: xo_board {
-                       compatible = "fixed-clock";
-                       #clock-cells = <0>;
-                       clock-frequency = <19200000>;
-                       clock-output-names = "xo_board";
-               };
-
-               sleep_clk: sleep_clk {
-                       compatible = "fixed-clock";
-                       #clock-cells = <0>;
-                       clock-frequency = <32764>;
-                       clock-output-names = "sleep_clk";
-               };
-       };
-
-       psci {
-               compatible = "arm,psci-1.0";
-               method = "smc";
-       };
-
-       firmware {
-               scm {
-                       compatible = "qcom,scm-msm8996";
-
-                       qcom,dload-mode = <&tcsr 0x13000>;
-               };
-       };
-
-       tcsr_mutex: hwlock {
-               compatible = "qcom,tcsr-mutex";
-               syscon = <&tcsr_mutex_regs 0 0x1000>;
-               #hwlock-cells = <1>;
-       };
-
-       smem {
-               compatible = "qcom,smem";
-               memory-region = <&smem_mem>;
-               hwlocks = <&tcsr_mutex 3>;
-       };
-
-       rpm-glink {
-               compatible = "qcom,glink-rpm";
-
-               interrupts = <GIC_SPI 168 IRQ_TYPE_EDGE_RISING>;
-
-               qcom,rpm-msg-ram = <&rpm_msg_ram>;
-
-               mboxes = <&apcs_glb 0>;
-
-               rpm_requests {
-                       compatible = "qcom,rpm-msm8996";
-                       qcom,glink-channels = "rpm_requests";
-
-                       rpmcc: qcom,rpmcc {
-                               compatible = "qcom,rpmcc-msm8996";
-                               #clock-cells = <1>;
+                       rpmcc: qcom,rpmcc {
+                               compatible = "qcom,rpmcc-msm8996";
+                               #clock-cells = <1>;
                        };
 
                        rpmpd: power-controller {
                                        };
                                };
                        };
-
-                       pm8994-regulators {
-                               compatible = "qcom,rpm-pm8994-regulators";
-
-                               pm8994_s1: s1 {};
-                               pm8994_s2: s2 {};
-                               pm8994_s3: s3 {};
-                               pm8994_s4: s4 {};
-                               pm8994_s5: s5 {};
-                               pm8994_s6: s6 {};
-                               pm8994_s7: s7 {};
-                               pm8994_s8: s8 {};
-                               pm8994_s9: s9 {};
-                               pm8994_s10: s10 {};
-                               pm8994_s11: s11 {};
-                               pm8994_s12: s12 {};
-
-                               pm8994_l1: l1 {};
-                               pm8994_l2: l2 {};
-                               pm8994_l3: l3 {};
-                               pm8994_l4: l4 {};
-                               pm8994_l5: l5 {};
-                               pm8994_l6: l6 {};
-                               pm8994_l7: l7 {};
-                               pm8994_l8: l8 {};
-                               pm8994_l9: l9 {};
-                               pm8994_l10: l10 {};
-                               pm8994_l11: l11 {};
-                               pm8994_l12: l12 {};
-                               pm8994_l13: l13 {};
-                               pm8994_l14: l14 {};
-                               pm8994_l15: l15 {};
-                               pm8994_l16: l16 {};
-                               pm8994_l17: l17 {};
-                               pm8994_l18: l18 {};
-                               pm8994_l19: l19 {};
-                               pm8994_l20: l20 {};
-                               pm8994_l21: l21 {};
-                               pm8994_l22: l22 {};
-                               pm8994_l23: l23 {};
-                               pm8994_l24: l24 {};
-                               pm8994_l25: l25 {};
-                               pm8994_l26: l26 {};
-                               pm8994_l27: l27 {};
-                               pm8994_l28: l28 {};
-                               pm8994_l29: l29 {};
-                               pm8994_l30: l30 {};
-                               pm8994_l31: l31 {};
-                               pm8994_l32: l32 {};
-                       };
-
                };
        };
 
-       soc: soc {
-               #address-cells = <1>;
-               #size-cells = <1>;
-               ranges = <0 0 0 0xffffffff>;
-               compatible = "simple-bus";
+       smem {
+               compatible = "qcom,smem";
+               memory-region = <&smem_mem>;
+               hwlocks = <&tcsr_mutex 3>;
+       };
 
-               rpm_msg_ram: memory@68000 {
-                       compatible = "qcom,rpm-msg-ram";
-                       reg = <0x68000 0x6000>;
-               };
+       smp2p-adsp {
+               compatible = "qcom,smp2p";
+               qcom,smem = <443>, <429>;
 
-               rng: rng@83000 {
-                       compatible = "qcom,prng-ee";
-                       reg = <0x00083000 0x1000>;
-                       clocks = <&gcc GCC_PRNG_AHB_CLK>;
-                       clock-names = "core";
-               };
+               interrupts = <0 158 IRQ_TYPE_EDGE_RISING>;
 
-               tcsr_mutex_regs: syscon@740000 {
-                       compatible = "syscon";
-                       reg = <0x740000 0x20000>;
-               };
+               mboxes = <&apcs_glb 10>;
 
-               tsens0: thermal-sensor@4a9000 {
-                       compatible = "qcom,msm8996-tsens";
-                       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>;
-               };
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <2>;
 
-               tsens1: thermal-sensor@4ad000 {
-                       compatible = "qcom,msm8996-tsens";
-                       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>;
+               smp2p_adsp_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
                };
 
-               tcsr: syscon@7a0000 {
-                       compatible = "qcom,tcsr-msm8996", "syscon";
-                       reg = <0x7a0000 0x18000>;
-               };
+               smp2p_adsp_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
 
-               intc: interrupt-controller@9bc0000 {
-                       compatible = "qcom,msm8996-gic-v3", "arm,gic-v3";
-                       #interrupt-cells = <3>;
                        interrupt-controller;
-                       #redistributor-regions = <1>;
-                       redistributor-stride = <0x0 0x40000>;
-                       reg = <0x09bc0000 0x10000>,
-                             <0x09c00000 0x100000>;
-                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                       #interrupt-cells = <2>;
                };
+       };
 
-               apcs_glb: mailbox@9820000 {
-                       compatible = "qcom,msm8996-apcs-hmss-global";
-                       reg = <0x9820000 0x1000>;
+       smp2p-modem {
+               compatible = "qcom,smp2p";
+               qcom,smem = <435>, <428>;
 
-                       #mbox-cells = <1>;
-               };
+               interrupts = <GIC_SPI 451 IRQ_TYPE_EDGE_RISING>;
 
-               gcc: clock-controller@300000 {
-                       compatible = "qcom,gcc-msm8996";
-                       #clock-cells = <1>;
-                       #reset-cells = <1>;
-                       #power-domain-cells = <1>;
-                       reg = <0x300000 0x90000>;
-               };
+               mboxes = <&apcs_glb 14>;
 
-               stm@3002000 {
-                       compatible = "arm,coresight-stm", "arm,primecell";
-                       reg = <0x3002000 0x1000>,
-                             <0x8280000 0x180000>;
-                       reg-names = "stm-base", "stm-stimulus-base";
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <1>;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+               modem_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
 
-                       out-ports {
-                               port {
-                                       stm_out: endpoint {
-                                               remote-endpoint =
-                                                 <&funnel0_in>;
-                                       };
-                               };
-                       };
-               };
-
-               tpiu@3020000 {
-                       compatible = "arm,coresight-tpiu", "arm,primecell";
-                       reg = <0x3020000 0x1000>;
-
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+               modem_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
 
-                       in-ports {
-                               port {
-                                       tpiu_in: endpoint {
-                                               remote-endpoint =
-                                                 <&replicator_out1>;
-                                       };
-                               };
-                       };
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
                };
+       };
 
-               funnel@3021000 {
-                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
-                       reg = <0x3021000 0x1000>;
+       smp2p-slpi {
+               compatible = "qcom,smp2p";
+               qcom,smem = <481>, <430>;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+               interrupts = <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>;
 
-                       in-ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
+               mboxes = <&apcs_glb 26>;
 
-                               port@7 {
-                                       reg = <7>;
-                                       funnel0_in: endpoint {
-                                               remote-endpoint =
-                                                 <&stm_out>;
-                                       };
-                               };
-                       };
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <3>;
 
-                       out-ports {
-                               port {
-                                       funnel0_out: endpoint {
-                                               remote-endpoint =
-                                                 <&merge_funnel_in0>;
-                                       };
-                               };
-                       };
+               smp2p_slpi_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
                };
 
-               funnel@3022000 {
-                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
-                       reg = <0x3022000 0x1000>;
+               smp2p_slpi_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+       };
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+       soc: soc {
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0 0 0 0xffffffff>;
+               compatible = "simple-bus";
 
-                       in-ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
+               pcie_phy: phy@34000 {
+                       compatible = "qcom,msm8996-qmp-pcie-phy";
+                       reg = <0x00034000 0x488>;
+                       #clock-cells = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
 
-                               port@6 {
-                                       reg = <6>;
-                                       funnel1_in: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_merge_funnel_out>;
-                                       };
-                               };
-                       };
+                       clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
+                               <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>,
+                               <&gcc GCC_PCIE_CLKREF_CLK>;
+                       clock-names = "aux", "cfg_ahb", "ref";
 
-                       out-ports {
-                               port {
-                                       funnel1_out: endpoint {
-                                               remote-endpoint =
-                                                 <&merge_funnel_in1>;
-                                       };
-                               };
-                       };
-               };
+                       resets = <&gcc GCC_PCIE_PHY_BCR>,
+                               <&gcc GCC_PCIE_PHY_COM_BCR>,
+                               <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>;
+                       reset-names = "phy", "common", "cfg";
+                       status = "disabled";
 
-               funnel@3023000 {
-                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
-                       reg = <0x3023000 0x1000>;
+                       pciephy_0: lane@35000 {
+                               reg = <0x00035000 0x130>,
+                                     <0x00035200 0x200>,
+                                     <0x00035400 0x1dc>;
+                               #phy-cells = <0>;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+                               clock-output-names = "pcie_0_pipe_clk_src";
+                               clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
+                               clock-names = "pipe0";
+                               resets = <&gcc GCC_PCIE_0_PHY_BCR>;
+                               reset-names = "lane0";
+                       };
 
+                       pciephy_1: lane@36000 {
+                               reg = <0x00036000 0x130>,
+                                     <0x00036200 0x200>,
+                                     <0x00036400 0x1dc>;
+                               #phy-cells = <0>;
 
-                       out-ports {
-                               port {
-                                       funnel2_out: endpoint {
-                                               remote-endpoint =
-                                                 <&merge_funnel_in2>;
-                                       };
-                               };
+                               clock-output-names = "pcie_1_pipe_clk_src";
+                               clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
+                               clock-names = "pipe1";
+                               resets = <&gcc GCC_PCIE_1_PHY_BCR>;
+                               reset-names = "lane1";
                        };
-               };
 
-               funnel@3025000 {
-                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
-                       reg = <0x3025000 0x1000>;
+                       pciephy_2: lane@37000 {
+                               reg = <0x00037000 0x130>,
+                                     <0x00037200 0x200>,
+                                     <0x00037400 0x1dc>;
+                               #phy-cells = <0>;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+                               clock-output-names = "pcie_2_pipe_clk_src";
+                               clocks = <&gcc GCC_PCIE_2_PIPE_CLK>;
+                               clock-names = "pipe2";
+                               resets = <&gcc GCC_PCIE_2_PHY_BCR>;
+                               reset-names = "lane2";
+                       };
+               };
 
-                       in-ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
+               rpm_msg_ram: memory@68000 {
+                       compatible = "qcom,rpm-msg-ram";
+                       reg = <0x00068000 0x6000>;
+               };
 
-                               port@0 {
-                                       reg = <0>;
-                                       merge_funnel_in0: endpoint {
-                                               remote-endpoint =
-                                                 <&funnel0_out>;
-                                       };
-                               };
+               qfprom@74000 {
+                       compatible = "qcom,qfprom";
+                       reg = <0x00074000 0x8ff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
 
-                               port@1 {
-                                       reg = <1>;
-                                       merge_funnel_in1: endpoint {
-                                               remote-endpoint =
-                                                 <&funnel1_out>;
-                                       };
-                               };
+                       qusb2p_hstx_trim: hstx_trim@24e {
+                               reg = <0x24e 0x2>;
+                               bits = <5 4>;
+                       };
 
-                               port@2 {
-                                       reg = <2>;
-                                       merge_funnel_in2: endpoint {
-                                               remote-endpoint =
-                                                 <&funnel2_out>;
-                                       };
-                               };
+                       qusb2s_hstx_trim: hstx_trim@24f {
+                               reg = <0x24f 0x1>;
+                               bits = <1 4>;
                        };
 
-                       out-ports {
-                               port {
-                                       merge_funnel_out: endpoint {
-                                               remote-endpoint =
-                                                 <&etf_in>;
-                                       };
-                               };
+                       gpu_speed_bin: gpu_speed_bin@133 {
+                               reg = <0x133 0x1>;
+                               bits = <5 3>;
                        };
                };
 
-               replicator@3026000 {
-                       compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
-                       reg = <0x3026000 0x1000>;
+               rng: rng@83000 {
+                       compatible = "qcom,prng-ee";
+                       reg = <0x00083000 0x1000>;
+                       clocks = <&gcc GCC_PRNG_AHB_CLK>;
+                       clock-names = "core";
+               };
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+               gcc: clock-controller@300000 {
+                       compatible = "qcom,gcc-msm8996";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+                       reg = <0x00300000 0x90000>;
+               };
 
-                       in-ports {
-                               port {
-                                       replicator_in: endpoint {
-                                               remote-endpoint =
-                                                 <&etf_out>;
-                                       };
-                               };
-                       };
+               tsens0: thermal-sensor@4a9000 {
+                       compatible = "qcom,msm8996-tsens";
+                       reg = <0x004a9000 0x1000>, /* TM */
+                             <0x004a8000 0x1000>; /* SROT */
+                       #qcom,sensors = <13>;
+                       interrupts = <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow", "critical";
+                       #thermal-sensor-cells = <1>;
+               };
 
-                       out-ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
+               tsens1: thermal-sensor@4ad000 {
+                       compatible = "qcom,msm8996-tsens";
+                       reg = <0x004ad000 0x1000>, /* TM */
+                             <0x004ac000 0x1000>; /* SROT */
+                       #qcom,sensors = <8>;
+                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow", "critical";
+                       #thermal-sensor-cells = <1>;
+               };
 
-                               port@0 {
-                                       reg = <0>;
-                                       replicator_out0: endpoint {
-                                               remote-endpoint =
-                                                 <&etr_in>;
-                                       };
-                               };
+               tcsr_mutex_regs: syscon@740000 {
+                       compatible = "syscon";
+                       reg = <0x00740000 0x20000>;
+               };
 
-                               port@1 {
-                                       reg = <1>;
-                                       replicator_out1: endpoint {
-                                               remote-endpoint =
-                                                 <&tpiu_in>;
-                                       };
-                               };
-                       };
+               tcsr: syscon@7a0000 {
+                       compatible = "qcom,tcsr-msm8996", "syscon";
+                       reg = <0x007a0000 0x18000>;
                };
 
-               etf@3027000 {
-                       compatible = "arm,coresight-tmc", "arm,primecell";
-                       reg = <0x3027000 0x1000>;
-
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+               mmcc: clock-controller@8c0000 {
+                       compatible = "qcom,mmcc-msm8996";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+                       reg = <0x008c0000 0x40000>;
+                       assigned-clocks = <&mmcc MMPLL9_PLL>,
+                                         <&mmcc MMPLL1_PLL>,
+                                         <&mmcc MMPLL3_PLL>,
+                                         <&mmcc MMPLL4_PLL>,
+                                         <&mmcc MMPLL5_PLL>;
+                       assigned-clock-rates = <624000000>,
+                                              <810000000>,
+                                              <980000000>,
+                                              <960000000>,
+                                              <825000000>;
+               };
 
-                       in-ports {
-                               port {
-                                       etf_in: endpoint {
-                                               remote-endpoint =
-                                                 <&merge_funnel_out>;
-                                       };
-                               };
-                       };
+               mdss: mdss@900000 {
+                       compatible = "qcom,mdss";
 
-                       out-ports {
-                               port {
-                                       etf_out: endpoint {
-                                               remote-endpoint =
-                                                 <&replicator_in>;
-                                       };
-                               };
-                       };
-               };
+                       reg = <0x00900000 0x1000>,
+                             <0x009b0000 0x1040>,
+                             <0x009b8000 0x1040>;
+                       reg-names = "mdss_phys",
+                                   "vbif_phys",
+                                   "vbif_nrt_phys";
 
-               etr@3028000 {
-                       compatible = "arm,coresight-tmc", "arm,primecell";
-                       reg = <0x3028000 0x1000>;
+                       power-domains = <&mmcc MDSS_GDSC>;
+                       interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
-                       arm,scatter-gather;
+                       interrupt-controller;
+                       #interrupt-cells = <1>;
 
-                       in-ports {
-                               port {
-                                       etr_in: endpoint {
-                                               remote-endpoint =
-                                                 <&replicator_out0>;
-                                       };
-                               };
-                       };
-               };
+                       clocks = <&mmcc MDSS_AHB_CLK>;
+                       clock-names = "iface";
 
-               debug@3810000 {
-                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
-                       reg = <0x3810000 0x1000>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>;
-                       clock-names = "apb_pclk";
+                       mdp: mdp@901000 {
+                               compatible = "qcom,mdp5";
+                               reg = <0x00901000 0x90000>;
+                               reg-names = "mdp_phys";
 
-                       cpu = <&CPU0>;
-               };
+                               interrupt-parent = <&mdss>;
+                               interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
 
-               etm@3840000 {
-                       compatible = "arm,coresight-etm4x", "arm,primecell";
-                       reg = <0x3840000 0x1000>;
+                               clocks = <&mmcc MDSS_AHB_CLK>,
+                                        <&mmcc MDSS_AXI_CLK>,
+                                        <&mmcc MDSS_MDP_CLK>,
+                                        <&mmcc SMMU_MDP_AXI_CLK>,
+                                        <&mmcc MDSS_VSYNC_CLK>;
+                               clock-names = "iface",
+                                             "bus",
+                                             "core",
+                                             "iommu",
+                                             "vsync";
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+                               iommus = <&mdp_smmu 0>;
 
-                       cpu = <&CPU0>;
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
 
-                       out-ports {
-                               port {
-                                       etm0_out: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_funnel0_in0>;
+                                       port@0 {
+                                               reg = <0>;
+                                               mdp5_intf3_out: endpoint {
+                                                       remote-endpoint = <&hdmi_in>;
+                                               };
                                        };
                                };
                        };
-               };
-
-               debug@3910000 {
-                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
-                       reg = <0x3910000 0x1000>;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>;
-                       clock-names = "apb_pclk";
+                       hdmi: hdmi-tx@9a0000 {
+                               compatible = "qcom,hdmi-tx-8996";
+                               reg =   <0x009a0000 0x50c>,
+                                       <0x00070000 0x6158>,
+                                       <0x009e0000 0xfff>;
+                               reg-names = "core_physical",
+                                           "qfprom_physical",
+                                           "hdcp_physical";
 
-                       cpu = <&CPU1>;
-               };
+                               interrupt-parent = <&mdss>;
+                               interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
 
-               etm@3940000 {
-                       compatible = "arm,coresight-etm4x", "arm,primecell";
-                       reg = <0x3940000 0x1000>;
+                               clocks = <&mmcc MDSS_MDP_CLK>,
+                                        <&mmcc MDSS_AHB_CLK>,
+                                        <&mmcc MDSS_HDMI_CLK>,
+                                        <&mmcc MDSS_HDMI_AHB_CLK>,
+                                        <&mmcc MDSS_EXTPCLK_CLK>;
+                               clock-names =
+                                       "mdp_core",
+                                       "iface",
+                                       "core",
+                                       "alt_iface",
+                                       "extp";
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+                               phys = <&hdmi_phy>;
+                               phy-names = "hdmi_phy";
+                               #sound-dai-cells = <1>;
 
-                       cpu = <&CPU1>;
+                               ports {
+                                       #address-cells = <1>;
+                                       #size-cells = <0>;
 
-                       out-ports {
-                               port {
-                                       etm1_out: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_funnel0_in1>;
+                                       port@0 {
+                                               reg = <0>;
+                                               hdmi_in: endpoint {
+                                                       remote-endpoint = <&mdp5_intf3_out>;
+                                               };
                                        };
                                };
                        };
-               };
-
-               funnel@39b0000 { /* APSS Funnel 0 */
-                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
-                       reg = <0x39b0000 0x1000>;
-
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
-
-                       in-ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
-
-                               port@0 {
-                                       reg = <0>;
-                                       apss_funnel0_in0: endpoint {
-                                               remote-endpoint = <&etm0_out>;
-                                       };
-                               };
 
-                               port@1 {
-                                       reg = <1>;
-                                       apss_funnel0_in1: endpoint {
-                                               remote-endpoint = <&etm1_out>;
-                                       };
-                               };
-                       };
+                       hdmi_phy: hdmi-phy@9a0600 {
+                               #phy-cells = <0>;
+                               compatible = "qcom,hdmi-phy-8996";
+                               reg = <0x009a0600 0x1c4>,
+                                     <0x009a0a00 0x124>,
+                                     <0x009a0c00 0x124>,
+                                     <0x009a0e00 0x124>,
+                                     <0x009a1000 0x124>,
+                                     <0x009a1200 0x0c8>;
+                               reg-names = "hdmi_pll",
+                                           "hdmi_tx_l0",
+                                           "hdmi_tx_l1",
+                                           "hdmi_tx_l2",
+                                           "hdmi_tx_l3",
+                                           "hdmi_phy";
 
-                       out-ports {
-                               port {
-                                       apss_funnel0_out: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_merge_funnel_in0>;
-                                       };
-                               };
+                               clocks = <&mmcc MDSS_AHB_CLK>,
+                                        <&gcc GCC_HDMI_CLKREF_CLK>;
+                               clock-names = "iface",
+                                             "ref";
                        };
                };
+               gpu@b00000 {
+                       compatible = "qcom,adreno-530.2", "qcom,adreno";
+                       #stream-id-cells = <16>;
 
-               debug@3a10000 {
-                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
-                       reg = <0x3a10000 0x1000>;
+                       reg = <0x00b00000 0x3f000>;
+                       reg-names = "kgsl_3d0_reg_memory";
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>;
-                       clock-names = "apb_pclk";
+                       interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>;
 
-                       cpu = <&CPU2>;
-               };
+                       clocks = <&mmcc GPU_GX_GFX3D_CLK>,
+                               <&mmcc GPU_AHB_CLK>,
+                               <&mmcc GPU_GX_RBBMTIMER_CLK>,
+                               <&gcc GCC_BIMC_GFX_CLK>,
+                               <&gcc GCC_MMSS_BIMC_GFX_CLK>;
 
-               etm@3a40000 {
-                       compatible = "arm,coresight-etm4x", "arm,primecell";
-                       reg = <0x3a40000 0x1000>;
+                       clock-names = "core",
+                               "iface",
+                               "rbbmtimer",
+                               "mem",
+                               "mem_iface";
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+                       power-domains = <&mmcc GPU_GDSC>;
+                       iommus = <&adreno_smmu 0>;
 
-                       cpu = <&CPU2>;
+                       nvmem-cells = <&gpu_speed_bin>;
+                       nvmem-cell-names = "speed_bin";
 
-                       out-ports {
-                               port {
-                                       etm2_out: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_funnel1_in0>;
-                                       };
-                               };
-                       };
-               };
+                       qcom,gpu-quirk-two-pass-use-wfi;
+                       qcom,gpu-quirk-fault-detect-mask;
 
-               debug@3b10000 {
-                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
-                       reg = <0x3b10000 0x1000>;
+                       operating-points-v2 = <&gpu_opp_table>;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>;
-                       clock-names = "apb_pclk";
-
-                       cpu = <&CPU3>;
-               };
+                       gpu_opp_table: opp-table {
+                               compatible  ="operating-points-v2";
 
-               etm@3b40000 {
-                       compatible = "arm,coresight-etm4x", "arm,primecell";
-                       reg = <0x3b40000 0x1000>;
+                               /*
+                                * 624Mhz and 560Mhz are only available on speed
+                                * bin (1 << 0). All the rest are available on
+                                * all bins of the hardware
+                                */
+                               opp-624000000 {
+                                       opp-hz = /bits/ 64 <624000000>;
+                                       opp-supported-hw = <0x01>;
+                               };
+                               opp-560000000 {
+                                       opp-hz = /bits/ 64 <560000000>;
+                                       opp-supported-hw = <0x01>;
+                               };
+                               opp-510000000 {
+                                       opp-hz = /bits/ 64 <510000000>;
+                                       opp-supported-hw = <0xFF>;
+                               };
+                               opp-401800000 {
+                                       opp-hz = /bits/ 64 <401800000>;
+                                       opp-supported-hw = <0xFF>;
+                               };
+                               opp-315000000 {
+                                       opp-hz = /bits/ 64 <315000000>;
+                                       opp-supported-hw = <0xFF>;
+                               };
+                               opp-214000000 {
+                                       opp-hz = /bits/ 64 <214000000>;
+                                       opp-supported-hw = <0xFF>;
+                               };
+                               opp-133000000 {
+                                       opp-hz = /bits/ 64 <133000000>;
+                                       opp-supported-hw = <0xFF>;
+                               };
+                       };
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+                       zap-shader {
+                               memory-region = <&zap_shader_region>;
+                       };
+               };
 
-                       cpu = <&CPU3>;
+               msmgpio: pinctrl@1010000 {
+                       compatible = "qcom,msm8996-pinctrl";
+                       reg = <0x01010000 0x300000>;
+                       interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
 
-                       out-ports {
-                               port {
-                                       etm3_out: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_funnel1_in1>;
-                                       };
-                               };
-                       };
+               spmi_bus: qcom,spmi@400f000 {
+                       compatible = "qcom,spmi-pmic-arb";
+                       reg = <0x0400f000 0x1000>,
+                             <0x04400000 0x800000>,
+                             <0x04c00000 0x800000>,
+                             <0x05800000 0x200000>,
+                             <0x0400a000 0x002100>;
+                       reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+                       interrupt-names = "periph_irq";
+                       interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>;
+                       qcom,ee = <0>;
+                       qcom,channel = <0>;
+                       #address-cells = <2>;
+                       #size-cells = <0>;
+                       interrupt-controller;
+                       #interrupt-cells = <4>;
                };
 
-               funnel@3bb0000 { /* APSS Funnel 1 */
-                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
-                       reg = <0x3bb0000 0x1000>;
+               agnoc@0 {
+                       power-domains = <&gcc AGGRE0_NOC_GDSC>;
+                       compatible = "simple-pm-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+                       pcie0: pcie@600000 {
+                               compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
+                               status = "disabled";
+                               power-domains = <&gcc PCIE0_GDSC>;
+                               bus-range = <0x00 0xff>;
+                               num-lanes = <1>;
 
-                       in-ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
+                               reg = <0x00600000 0x2000>,
+                                     <0x0c000000 0xf1d>,
+                                     <0x0c000f20 0xa8>,
+                                     <0x0c100000 0x100000>;
+                               reg-names = "parf", "dbi", "elbi","config";
 
-                               port@0 {
-                                       reg = <0>;
-                                       apss_funnel1_in0: endpoint {
-                                               remote-endpoint = <&etm2_out>;
-                                       };
-                               };
+                               phys = <&pciephy_0>;
+                               phy-names = "pciephy";
 
-                               port@1 {
-                                       reg = <1>;
-                                       apss_funnel1_in1: endpoint {
-                                               remote-endpoint = <&etm3_out>;
-                                       };
-                               };
-                       };
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges = <0x01000000 0x0 0x0c200000 0x0c200000 0x0 0x100000>,
+                                       <0x02000000 0x0 0x0c300000 0x0c300000 0x0 0xd00000>;
 
-                       out-ports {
-                               port {
-                                       apss_funnel1_out: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_merge_funnel_in1>;
-                                       };
-                               };
-                       };
-               };
+                               interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "msi";
+                               #interrupt-cells = <1>;
+                               interrupt-map-mask = <0 0 0 0x7>;
+                               interrupt-map = <0 0 0 1 &intc 0 244 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                                               <0 0 0 2 &intc 0 245 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                                               <0 0 0 3 &intc 0 247 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                                               <0 0 0 4 &intc 0 248 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
 
-               funnel@3bc0000 {
-                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
-                       reg = <0x3bc0000 0x1000>;
+                               pinctrl-names = "default", "sleep";
+                               pinctrl-0 = <&pcie0_clkreq_default &pcie0_perst_default &pcie0_wake_default>;
+                               pinctrl-1 = <&pcie0_clkreq_sleep &pcie0_perst_default &pcie0_wake_sleep>;
 
-                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
-                       clock-names = "apb_pclk", "atclk";
+                               linux,pci-domain = <0>;
 
-                       in-ports {
-                               #address-cells = <1>;
-                               #size-cells = <0>;
+                               clocks = <&gcc GCC_PCIE_0_PIPE_CLK>,
+                                       <&gcc GCC_PCIE_0_AUX_CLK>,
+                                       <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
+                                       <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
+                                       <&gcc GCC_PCIE_0_SLV_AXI_CLK>;
 
-                               port@0 {
-                                       reg = <0>;
-                                       apss_merge_funnel_in0: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_funnel0_out>;
-                                       };
-                               };
+                               clock-names =  "pipe",
+                                               "aux",
+                                               "cfg",
+                                               "bus_master",
+                                               "bus_slave";
 
-                               port@1 {
-                                       reg = <1>;
-                                       apss_merge_funnel_in1: endpoint {
-                                               remote-endpoint =
-                                                 <&apss_funnel1_out>;
-                                       };
-                               };
                        };
 
-                       out-ports {
-                               port {
-                                       apss_merge_funnel_out: endpoint {
-                                               remote-endpoint =
-                                                 <&funnel1_in>;
-                                       };
-                               };
-                       };
-               };
+                       pcie1: pcie@608000 {
+                               compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
+                               power-domains = <&gcc PCIE1_GDSC>;
+                               bus-range = <0x00 0xff>;
+                               num-lanes = <1>;
 
-               kryocc: clock-controller@6400000 {
-                       compatible = "qcom,apcc-msm8996";
-                       reg = <0x6400000 0x90000>;
-                       #clock-cells = <1>;
-               };
+                               status  = "disabled";
 
-               blsp1_uart1: serial@7570000 {
-                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
-                       reg = <0x07570000 0x1000>;
-                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>,
-                                <&gcc GCC_BLSP1_AHB_CLK>;
-                       clock-names = "core", "iface";
-                       status = "disabled";
-               };
+                               reg = <0x00608000 0x2000>,
+                                     <0x0d000000 0xf1d>,
+                                     <0x0d000f20 0xa8>,
+                                     <0x0d100000 0x100000>;
 
-               blsp1_spi0: spi@7575000 {
-                       compatible = "qcom,spi-qup-v2.2.1";
-                       reg = <0x07575000 0x600>;
-                       interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>,
-                                <&gcc GCC_BLSP1_AHB_CLK>;
-                       clock-names = "core", "iface";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&blsp1_spi0_default>;
-                       pinctrl-1 = <&blsp1_spi0_sleep>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
+                               reg-names = "parf", "dbi", "elbi","config";
 
-               blsp2_i2c0: i2c@75b5000 {
-                       compatible = "qcom,i2c-qup-v2.2.1";
-                       reg = <0x075b5000 0x1000>;
-                       interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP2_AHB_CLK>,
-                               <&gcc GCC_BLSP2_QUP1_I2C_APPS_CLK>;
-                       clock-names = "iface", "core";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&blsp2_i2c0_default>;
-                       pinctrl-1 = <&blsp2_i2c0_sleep>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
+                               phys = <&pciephy_1>;
+                               phy-names = "pciephy";
 
-               blsp2_uart1: serial@75b0000 {
-                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
-                       reg = <0x75b0000 0x1000>;
-                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>,
-                                <&gcc GCC_BLSP2_AHB_CLK>;
-                       clock-names = "core", "iface";
-                       status = "disabled";
-               };
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges = <0x01000000 0x0 0x0d200000 0x0d200000 0x0 0x100000>,
+                                       <0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>;
 
-               blsp2_i2c1: i2c@75b6000 {
-                       compatible = "qcom,i2c-qup-v2.2.1";
-                       reg = <0x075b6000 0x1000>;
-                       interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP2_AHB_CLK>,
-                               <&gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>;
-                       clock-names = "iface", "core";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&blsp2_i2c1_default>;
-                       pinctrl-1 = <&blsp2_i2c1_sleep>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
-
-               blsp2_uart2: serial@75b1000 {
-                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
-                       reg = <0x075b1000 0x1000>;
-                       interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP2_UART3_APPS_CLK>,
-                                <&gcc GCC_BLSP2_AHB_CLK>;
-                       clock-names = "core", "iface";
-                       status = "disabled";
-               };
-
-               blsp1_i2c2: i2c@7577000 {
-                       compatible = "qcom,i2c-qup-v2.2.1";
-                       reg = <0x07577000 0x1000>;
-                       interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP1_AHB_CLK>,
-                               <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
-                       clock-names = "iface", "core";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&blsp1_i2c2_default>;
-                       pinctrl-1 = <&blsp1_i2c2_sleep>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
-
-               blsp2_spi5: spi@75ba000{
-                       compatible = "qcom,spi-qup-v2.2.1";
-                       reg = <0x075ba000 0x600>;
-                       interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
-                       clocks = <&gcc GCC_BLSP2_QUP6_SPI_APPS_CLK>,
-                                <&gcc GCC_BLSP2_AHB_CLK>;
-                       clock-names = "core", "iface";
-                       pinctrl-names = "default", "sleep";
-                       pinctrl-0 = <&blsp2_spi5_default>;
-                       pinctrl-1 = <&blsp2_spi5_sleep>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       status = "disabled";
-               };
-
-               sdhc2: sdhci@74a4900 {
-                        status = "disabled";
-                        compatible = "qcom,sdhci-msm-v4";
-                        reg = <0x74a4900 0x314>, <0x74a4000 0x800>;
-                        reg-names = "hc_mem", "core_mem";
-
-                        interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>,
-                                     <0 221 IRQ_TYPE_LEVEL_HIGH>;
-                        interrupt-names = "hc_irq", "pwr_irq";
-
-                        clock-names = "iface", "core", "xo";
-                        clocks = <&gcc GCC_SDCC2_AHB_CLK>,
-                        <&gcc GCC_SDCC2_APPS_CLK>,
-                        <&xo_board>;
-                        bus-width = <4>;
-                };
-
-               msmgpio: pinctrl@1010000 {
-                       compatible = "qcom,msm8996-pinctrl";
-                       reg = <0x01010000 0x300000>;
-                       interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
-                       gpio-controller;
-                       #gpio-cells = <2>;
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
-               };
-
-               timer@9840000 {
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-                       compatible = "arm,armv7-timer-mem";
-                       reg = <0x09840000 0x1000>;
-                       clock-frequency = <19200000>;
+                               interrupts = <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "msi";
+                               #interrupt-cells = <1>;
+                               interrupt-map-mask = <0 0 0 0x7>;
+                               interrupt-map = <0 0 0 1 &intc 0 272 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                                               <0 0 0 2 &intc 0 273 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                                               <0 0 0 3 &intc 0 274 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                                               <0 0 0 4 &intc 0 275 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
 
-                       frame@9850000 {
-                               frame-number = <0>;
-                               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
-                                            <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
-                               reg = <0x09850000 0x1000>,
-                                     <0x09860000 0x1000>;
-                       };
+                               pinctrl-names = "default", "sleep";
+                               pinctrl-0 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_default>;
+                               pinctrl-1 = <&pcie1_clkreq_sleep &pcie1_perst_default &pcie1_wake_sleep>;
 
-                       frame@9870000 {
-                               frame-number = <1>;
-                               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
-                               reg = <0x09870000 0x1000>;
-                               status = "disabled";
-                       };
+                               linux,pci-domain = <1>;
 
-                       frame@9880000 {
-                               frame-number = <2>;
-                               interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
-                               reg = <0x09880000 0x1000>;
-                               status = "disabled";
-                       };
+                               clocks = <&gcc GCC_PCIE_1_PIPE_CLK>,
+                                       <&gcc GCC_PCIE_1_AUX_CLK>,
+                                       <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
+                                       <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
+                                       <&gcc GCC_PCIE_1_SLV_AXI_CLK>;
 
-                       frame@9890000 {
-                               frame-number = <3>;
-                               interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
-                               reg = <0x09890000 0x1000>;
-                               status = "disabled";
+                               clock-names =  "pipe",
+                                               "aux",
+                                               "cfg",
+                                               "bus_master",
+                                               "bus_slave";
                        };
 
-                       frame@98a0000 {
-                               frame-number = <4>;
-                               interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
-                               reg = <0x098a0000 0x1000>;
+                       pcie2: pcie@610000 {
+                               compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
+                               power-domains = <&gcc PCIE2_GDSC>;
+                               bus-range = <0x00 0xff>;
+                               num-lanes = <1>;
                                status = "disabled";
-                       };
+                               reg = <0x00610000 0x2000>,
+                                     <0x0e000000 0xf1d>,
+                                     <0x0e000f20 0xa8>,
+                                     <0x0e100000 0x100000>;
 
-                       frame@98b0000 {
-                               frame-number = <5>;
-                               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
-                               reg = <0x098b0000 0x1000>;
-                               status = "disabled";
-                       };
+                               reg-names = "parf", "dbi", "elbi","config";
 
-                       frame@98c0000 {
-                               frame-number = <6>;
-                               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-                               reg = <0x098c0000 0x1000>;
-                               status = "disabled";
-                       };
-               };
+                               phys = <&pciephy_2>;
+                               phy-names = "pciephy";
 
-               spmi_bus: qcom,spmi@400f000 {
-                       compatible = "qcom,spmi-pmic-arb";
-                       reg = <0x400f000 0x1000>,
-                             <0x4400000 0x800000>,
-                             <0x4c00000 0x800000>,
-                             <0x5800000 0x200000>,
-                             <0x400a000 0x002100>;
-                       reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
-                       interrupt-names = "periph_irq";
-                       interrupts = <GIC_SPI 326 IRQ_TYPE_LEVEL_HIGH>;
-                       qcom,ee = <0>;
-                       qcom,channel = <0>;
-                       #address-cells = <2>;
-                       #size-cells = <0>;
-                       interrupt-controller;
-                       #interrupt-cells = <4>;
-               };
+                               #address-cells = <3>;
+                               #size-cells = <2>;
+                               ranges = <0x01000000 0x0 0x0e200000 0x0e200000 0x0 0x100000>,
+                                       <0x02000000 0x0 0x0e300000 0x0e300000 0x0 0x1d00000>;
 
-               ufsphy: phy@627000 {
-                       compatible = "qcom,msm8996-ufs-phy-qmp-14nm";
-                       reg = <0x627000 0xda8>;
-                       reg-names = "phy_mem";
-                       #phy-cells = <0>;
+                               device_type = "pci";
 
-                       vdda-phy-supply = <&pm8994_l28>;
-                       vdda-pll-supply = <&pm8994_l12>;
+                               interrupts = <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupt-names = "msi";
+                               #interrupt-cells = <1>;
+                               interrupt-map-mask = <0 0 0 0x7>;
+                               interrupt-map = <0 0 0 1 &intc 0 142 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
+                                               <0 0 0 2 &intc 0 143 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
+                                               <0 0 0 3 &intc 0 144 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
+                                               <0 0 0 4 &intc 0 145 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
 
-                       vdda-phy-max-microamp = <18380>;
-                       vdda-pll-max-microamp = <9440>;
+                               pinctrl-names = "default", "sleep";
+                               pinctrl-0 = <&pcie2_clkreq_default &pcie2_perst_default &pcie2_wake_default>;
+                               pinctrl-1 = <&pcie2_clkreq_sleep &pcie2_perst_default &pcie2_wake_sleep >;
 
-                       vddp-ref-clk-supply = <&pm8994_l25>;
-                       vddp-ref-clk-max-microamp = <100>;
-                       vddp-ref-clk-always-on;
+                               linux,pci-domain = <2>;
+                               clocks = <&gcc GCC_PCIE_2_PIPE_CLK>,
+                                       <&gcc GCC_PCIE_2_AUX_CLK>,
+                                       <&gcc GCC_PCIE_2_CFG_AHB_CLK>,
+                                       <&gcc GCC_PCIE_2_MSTR_AXI_CLK>,
+                                       <&gcc GCC_PCIE_2_SLV_AXI_CLK>;
 
-                       clock-names = "ref_clk_src", "ref_clk";
-                       clocks = <&rpmcc RPM_SMD_LN_BB_CLK>,
-                                <&gcc GCC_UFS_CLKREF_CLK>;
-                       resets = <&ufshc 0>;
-                       status = "disabled";
+                               clock-names =  "pipe",
+                                               "aux",
+                                               "cfg",
+                                               "bus_master",
+                                               "bus_slave";
+                       };
                };
 
                ufshc: ufshc@624000 {
                        compatible = "qcom,ufshc";
-                       reg = <0x624000 0x2500>;
+                       reg = <0x00624000 0x2500>;
                        interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
 
                        phys = <&ufsphy>;
                        phy-names = "ufsphy";
 
-                       vcc-supply = <&pm8994_l20>;
-                       vccq-supply = <&pm8994_l25>;
-                       vccq2-supply = <&pm8994_s4>;
-
-                       vcc-max-microamp = <600000>;
-                       vccq-max-microamp = <450000>;
-                       vccq2-max-microamp = <450000>;
-
                        power-domains = <&gcc UFS_GDSC>;
 
                        clock-names =
                        };
                };
 
-               mmcc: clock-controller@8c0000 {
-                       compatible = "qcom,mmcc-msm8996";
-                       #clock-cells = <1>;
-                       #reset-cells = <1>;
-                       #power-domain-cells = <1>;
-                       reg = <0x8c0000 0x40000>;
-                       assigned-clocks = <&mmcc MMPLL9_PLL>,
-                                         <&mmcc MMPLL1_PLL>,
-                                         <&mmcc MMPLL3_PLL>,
-                                         <&mmcc MMPLL4_PLL>,
-                                         <&mmcc MMPLL5_PLL>;
-                       assigned-clock-rates = <624000000>,
-                                              <810000000>,
-                                              <980000000>,
-                                              <960000000>,
-                                              <825000000>;
-               };
-
-               qfprom@74000 {
-                       compatible = "qcom,qfprom";
-                       reg = <0x74000 0x8ff>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-
-                       qusb2p_hstx_trim: hstx_trim@24e {
-                               reg = <0x24e 0x2>;
-                               bits = <5 4>;
-                       };
-
-                       qusb2s_hstx_trim: hstx_trim@24f {
-                               reg = <0x24f 0x1>;
-                               bits = <1 4>;
-                       };
+               ufsphy: phy@627000 {
+                       compatible = "qcom,msm8996-ufs-phy-qmp-14nm";
+                       reg = <0x00627000 0xda8>;
+                       reg-names = "phy_mem";
+                       #phy-cells = <0>;
 
-                       gpu_speed_bin: gpu_speed_bin@133 {
-                               reg = <0x133 0x1>;
-                               bits = <5 3>;
-                       };
-               };
-
-               phy@34000 {
-                       compatible = "qcom,msm8996-qmp-pcie-phy";
-                       reg = <0x34000 0x488>;
-                       #clock-cells = <1>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-
-                       clocks = <&gcc GCC_PCIE_PHY_AUX_CLK>,
-                               <&gcc GCC_PCIE_PHY_CFG_AHB_CLK>,
-                               <&gcc GCC_PCIE_CLKREF_CLK>;
-                       clock-names = "aux", "cfg_ahb", "ref";
-
-                       vdda-phy-supply = <&pm8994_l28>;
-                       vdda-pll-supply = <&pm8994_l12>;
-
-                       resets = <&gcc GCC_PCIE_PHY_BCR>,
-                               <&gcc GCC_PCIE_PHY_COM_BCR>,
-                               <&gcc GCC_PCIE_PHY_COM_NOCSR_BCR>;
-                       reset-names = "phy", "common", "cfg";
-                       status = "disabled";
-
-                       pciephy_0: lane@35000 {
-                               reg = <0x035000 0x130>,
-                                       <0x035200 0x200>,
-                                       <0x035400 0x1dc>;
-                               #phy-cells = <0>;
-
-                               clock-output-names = "pcie_0_pipe_clk_src";
-                               clocks = <&gcc GCC_PCIE_0_PIPE_CLK>;
-                               clock-names = "pipe0";
-                               resets = <&gcc GCC_PCIE_0_PHY_BCR>;
-                               reset-names = "lane0";
-                       };
-
-                       pciephy_1: lane@36000 {
-                               reg = <0x036000 0x130>,
-                                       <0x036200 0x200>,
-                                       <0x036400 0x1dc>;
-                               #phy-cells = <0>;
-
-                               clock-output-names = "pcie_1_pipe_clk_src";
-                               clocks = <&gcc GCC_PCIE_1_PIPE_CLK>;
-                               clock-names = "pipe1";
-                               resets = <&gcc GCC_PCIE_1_PHY_BCR>;
-                               reset-names = "lane1";
-                       };
-
-                       pciephy_2: lane@37000 {
-                               reg = <0x037000 0x130>,
-                                       <0x037200 0x200>,
-                                       <0x037400 0x1dc>;
-                               #phy-cells = <0>;
-
-                               clock-output-names = "pcie_2_pipe_clk_src";
-                               clocks = <&gcc GCC_PCIE_2_PIPE_CLK>;
-                               clock-names = "pipe2";
-                               resets = <&gcc GCC_PCIE_2_PHY_BCR>;
-                               reset-names = "lane2";
-                       };
-               };
-
-               phy@7410000 {
-                       compatible = "qcom,msm8996-qmp-usb3-phy";
-                       reg = <0x7410000 0x1c4>;
-                       #clock-cells = <1>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-
-                       clocks = <&gcc GCC_USB3_PHY_AUX_CLK>,
-                               <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
-                               <&gcc GCC_USB3_CLKREF_CLK>;
-                       clock-names = "aux", "cfg_ahb", "ref";
-
-                       vdda-phy-supply = <&pm8994_l28>;
-                       vdda-pll-supply = <&pm8994_l12>;
-
-                       resets = <&gcc GCC_USB3_PHY_BCR>,
-                               <&gcc GCC_USB3PHY_PHY_BCR>;
-                       reset-names = "phy", "common";
-                       status = "disabled";
-
-                       ssusb_phy_0: lane@7410200 {
-                               reg = <0x7410200 0x200>,
-                                       <0x7410400 0x130>,
-                                       <0x7410600 0x1a8>;
-                               #phy-cells = <0>;
-
-                               clock-output-names = "usb3_phy_pipe_clk_src";
-                               clocks = <&gcc GCC_USB3_PHY_PIPE_CLK>;
-                               clock-names = "pipe0";
-                       };
-               };
-
-               hsusb_phy1: phy@7411000 {
-                       compatible = "qcom,msm8996-qusb2-phy";
-                       reg = <0x7411000 0x180>;
-                       #phy-cells = <0>;
-
-                       clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
-                               <&gcc GCC_RX1_USB2_CLKREF_CLK>;
-                       clock-names = "cfg_ahb", "ref";
-
-                       vdda-pll-supply = <&pm8994_l12>;
-                       vdda-phy-dpdm-supply = <&pm8994_l24>;
-
-                       resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
-                       nvmem-cells = <&qusb2p_hstx_trim>;
-                       status = "disabled";
-               };
-
-               hsusb_phy2: phy@7412000 {
-                       compatible = "qcom,msm8996-qusb2-phy";
-                       reg = <0x7412000 0x180>;
-                       #phy-cells = <0>;
-
-                       clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
-                               <&gcc GCC_RX2_USB2_CLKREF_CLK>;
-                       clock-names = "cfg_ahb", "ref";
-
-                       vdda-pll-supply = <&pm8994_l12>;
-                       vdda-phy-dpdm-supply = <&pm8994_l24>;
-
-                       resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
-                       nvmem-cells = <&qusb2s_hstx_trim>;
-                       status = "disabled";
-               };
-
-               usb2: usb@76f8800 {
-                       compatible = "qcom,msm8996-dwc3", "qcom,dwc3";
-                       reg = <0x76f8800 0x400>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-
-                       clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>,
-                               <&gcc GCC_USB20_MASTER_CLK>,
-                               <&gcc GCC_USB20_MOCK_UTMI_CLK>,
-                               <&gcc GCC_USB20_SLEEP_CLK>,
-                               <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>;
-
-                       assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>,
-                                         <&gcc GCC_USB20_MASTER_CLK>;
-                       assigned-clock-rates = <19200000>, <60000000>;
-
-                       power-domains = <&gcc USB30_GDSC>;
-                       status = "disabled";
-
-                       dwc3@7600000 {
-                               compatible = "snps,dwc3";
-                               reg = <0x7600000 0xcc00>;
-                               interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>;
-                               phys = <&hsusb_phy2>;
-                               phy-names = "usb2-phy";
-                       };
-               };
-
-               usb3: usb@6af8800 {
-                       compatible = "qcom,msm8996-dwc3", "qcom,dwc3";
-                       reg = <0x6af8800 0x400>;
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
-
-                       clocks = <&gcc GCC_SYS_NOC_USB3_AXI_CLK>,
-                               <&gcc GCC_USB30_MASTER_CLK>,
-                               <&gcc GCC_AGGRE2_USB3_AXI_CLK>,
-                               <&gcc GCC_USB30_MOCK_UTMI_CLK>,
-                               <&gcc GCC_USB30_SLEEP_CLK>,
-                               <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>;
-
-                       assigned-clocks = <&gcc GCC_USB30_MOCK_UTMI_CLK>,
-                                         <&gcc GCC_USB30_MASTER_CLK>;
-                       assigned-clock-rates = <19200000>, <120000000>;
-
-                       power-domains = <&gcc USB30_GDSC>;
-                       status = "disabled";
-
-                       dwc3@6a00000 {
-                               compatible = "snps,dwc3";
-                               reg = <0x6a00000 0xcc00>;
-                               interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>;
-                               phys = <&hsusb_phy1>, <&ssusb_phy_0>;
-                               phy-names = "usb2-phy", "usb3-phy";
-                       };
-               };
-
-               vfe_smmu: iommu@da0000 {
-                       compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
-                       reg = <0xda0000 0x10000>;
-
-                       #global-interrupts = <1>;
-                       interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
-                       power-domains = <&mmcc MMAGIC_CAMSS_GDSC>;
-                       clocks = <&mmcc SMMU_VFE_AHB_CLK>,
-                                <&mmcc SMMU_VFE_AXI_CLK>;
-                       clock-names = "iface",
-                                     "bus";
-                       #iommu-cells = <1>;
+                       clock-names = "ref_clk_src", "ref_clk";
+                       clocks = <&rpmcc RPM_SMD_LN_BB_CLK>,
+                                <&gcc GCC_UFS_CLKREF_CLK>;
+                       resets = <&ufshc 0>;
+                       status = "disabled";
                };
 
                camss: camss@a00000 {
                        compatible = "qcom,msm8996-camss";
-                       reg = <0xa34000 0x1000>,
-                               <0xa00030 0x4>,
-                               <0xa35000 0x1000>,
-                               <0xa00038 0x4>,
-                               <0xa36000 0x1000>,
-                               <0xa00040 0x4>,
-                               <0xa30000 0x100>,
-                               <0xa30400 0x100>,
-                               <0xa30800 0x100>,
-                               <0xa30c00 0x100>,
-                               <0xa31000 0x500>,
-                               <0xa00020 0x10>,
-                               <0xa10000 0x1000>,
-                               <0xa14000 0x1000>;
+                       reg = <0x00a34000 0x1000>,
+                             <0x00a00030 0x4>,
+                             <0x00a35000 0x1000>,
+                             <0x00a00038 0x4>,
+                             <0x00a36000 0x1000>,
+                             <0x00a00040 0x4>,
+                             <0x00a30000 0x100>,
+                             <0x00a30400 0x100>,
+                             <0x00a30800 0x100>,
+                             <0x00a30c00 0x100>,
+                             <0x00a31000 0x500>,
+                             <0x00a00020 0x10>,
+                             <0x00a10000 0x1000>,
+                             <0x00a14000 0x1000>;
                        reg-names = "csiphy0",
                                "csiphy0_clk_mux",
                                "csiphy1",
                                "vfe1_stream",
                                "vfe_ahb",
                                "vfe_axi";
-                       vdda-supply = <&pm8994_l2>;
                        iommus = <&vfe_smmu 0>,
                                 <&vfe_smmu 1>,
                                 <&vfe_smmu 2>,
 
                adreno_smmu: iommu@b40000 {
                        compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
-                       reg = <0xb40000 0x10000>;
+                       reg = <0x00b40000 0x10000>;
 
                        #global-interrupts = <1>;
                        interrupts = <GIC_SPI 334 IRQ_TYPE_LEVEL_HIGH>,
                        power-domains = <&mmcc GPU_GDSC>;
                };
 
+               video-codec@c00000 {
+                       compatible = "qcom,msm8996-venus";
+                       reg = <0x00c00000 0xff000>;
+                       interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&mmcc VENUS_GDSC>;
+                       clocks = <&mmcc VIDEO_CORE_CLK>,
+                                <&mmcc VIDEO_AHB_CLK>,
+                                <&mmcc VIDEO_AXI_CLK>,
+                                <&mmcc VIDEO_MAXI_CLK>;
+                       clock-names = "core", "iface", "bus", "mbus";
+                       iommus = <&venus_smmu 0x00>,
+                                <&venus_smmu 0x01>,
+                                <&venus_smmu 0x0a>,
+                                <&venus_smmu 0x07>,
+                                <&venus_smmu 0x0e>,
+                                <&venus_smmu 0x0f>,
+                                <&venus_smmu 0x08>,
+                                <&venus_smmu 0x09>,
+                                <&venus_smmu 0x0b>,
+                                <&venus_smmu 0x0c>,
+                                <&venus_smmu 0x0d>,
+                                <&venus_smmu 0x10>,
+                                <&venus_smmu 0x11>,
+                                <&venus_smmu 0x21>,
+                                <&venus_smmu 0x28>,
+                                <&venus_smmu 0x29>,
+                                <&venus_smmu 0x2b>,
+                                <&venus_smmu 0x2c>,
+                                <&venus_smmu 0x2d>,
+                                <&venus_smmu 0x31>;
+                       memory-region = <&venus_region>;
+                       status = "okay";
+
+                       video-decoder {
+                               compatible = "venus-decoder";
+                               clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
+                               clock-names = "core";
+                               power-domains = <&mmcc VENUS_CORE0_GDSC>;
+                       };
+
+                       video-encoder {
+                               compatible = "venus-encoder";
+                               clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
+                               clock-names = "core";
+                               power-domains = <&mmcc VENUS_CORE1_GDSC>;
+                       };
+               };
+
                mdp_smmu: iommu@d00000 {
                        compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
-                       reg = <0xd00000 0x10000>;
+                       reg = <0x00d00000 0x10000>;
 
                        #global-interrupts = <1>;
                        interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
                        power-domains = <&mmcc MDSS_GDSC>;
                };
 
+               venus_smmu: iommu@d40000 {
+                       compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
+                       reg = <0x00d40000 0x20000>;
+                       #global-interrupts = <1>;
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
+                                    <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>;
+                       power-domains = <&mmcc MMAGIC_VIDEO_GDSC>;
+                       clocks = <&mmcc SMMU_VIDEO_AHB_CLK>,
+                                <&mmcc SMMU_VIDEO_AXI_CLK>;
+                       clock-names = "iface", "bus";
+                       #iommu-cells = <1>;
+                       status = "okay";
+               };
+
+               vfe_smmu: iommu@da0000 {
+                       compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
+                       reg = <0x00da0000 0x10000>;
+
+                       #global-interrupts = <1>;
+                       interrupts = <GIC_SPI 76 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 344 IRQ_TYPE_LEVEL_HIGH>;
+                       power-domains = <&mmcc MMAGIC_CAMSS_GDSC>;
+                       clocks = <&mmcc SMMU_VFE_AHB_CLK>,
+                                <&mmcc SMMU_VFE_AXI_CLK>;
+                       clock-names = "iface",
+                                     "bus";
+                       #iommu-cells = <1>;
+               };
+
                lpass_q6_smmu: iommu@1600000 {
                        compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
-                       reg = <0x1600000 0x20000>;
+                       reg = <0x01600000 0x20000>;
                        #iommu-cells = <1>;
                        power-domains = <&gcc HLOS1_VOTE_LPASS_CORE_GDSC>;
 
                        clock-names = "iface", "bus";
                };
 
-               agnoc@0 {
-                       power-domains = <&gcc AGGRE0_NOC_GDSC>;
-                       compatible = "simple-pm-bus";
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
+               stm@3002000 {
+                       compatible = "arm,coresight-stm", "arm,primecell";
+                       reg = <0x3002000 0x1000>,
+                             <0x8280000 0x180000>;
+                       reg-names = "stm-base", "stm-stimulus-base";
 
-                       pcie0: pcie@600000 {
-                               compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
-                               status = "disabled";
-                               power-domains = <&gcc PCIE0_GDSC>;
-                               bus-range = <0x00 0xff>;
-                               num-lanes = <1>;
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       out-ports {
+                               port {
+                                       stm_out: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel0_in>;
+                                       };
+                               };
+                       };
+               };
+
+               tpiu@3020000 {
+                       compatible = "arm,coresight-tpiu", "arm,primecell";
+                       reg = <0x3020000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               port {
+                                       tpiu_in: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_out1>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3021000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3021000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@7 {
+                                       reg = <7>;
+                                       funnel0_in: endpoint {
+                                               remote-endpoint =
+                                                 <&stm_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       funnel0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3022000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3022000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@6 {
+                                       reg = <6>;
+                                       funnel1_in: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       funnel1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in1>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3023000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3023000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+
+                       out-ports {
+                               port {
+                                       funnel2_out: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_in2>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@3025000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3025000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       merge_funnel_in0: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       merge_funnel_in1: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel1_out>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       merge_funnel_in2: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel2_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       merge_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&etf_in>;
+                                       };
+                               };
+                       };
+               };
+
+               replicator@3026000 {
+                       compatible = "arm,coresight-dynamic-replicator", "arm,primecell";
+                       reg = <0x3026000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               port {
+                                       replicator_in: endpoint {
+                                               remote-endpoint =
+                                                 <&etf_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       replicator_out0: endpoint {
+                                               remote-endpoint =
+                                                 <&etr_in>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       replicator_out1: endpoint {
+                                               remote-endpoint =
+                                                 <&tpiu_in>;
+                                       };
+                               };
+                       };
+               };
+
+               etf@3027000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0x3027000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               port {
+                                       etf_in: endpoint {
+                                               remote-endpoint =
+                                                 <&merge_funnel_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       etf_out: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_in>;
+                                       };
+                               };
+                       };
+               };
+
+               etr@3028000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0x3028000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+                       arm,scatter-gather;
+
+                       in-ports {
+                               port {
+                                       etr_in: endpoint {
+                                               remote-endpoint =
+                                                 <&replicator_out0>;
+                                       };
+                               };
+                       };
+               };
+
+               debug@3810000 {
+                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
+                       reg = <0x3810000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+                       clock-names = "apb_pclk";
+
+                       cpu = <&CPU0>;
+               };
+
+               etm@3840000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x3840000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU0>;
+
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel0_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               debug@3910000 {
+                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
+                       reg = <0x3910000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+                       clock-names = "apb_pclk";
+
+                       cpu = <&CPU1>;
+               };
+
+               etm@3940000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x3940000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       cpu = <&CPU1>;
+
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel0_in1>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@39b0000 { /* APSS Funnel 0 */
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x39b0000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       apss_funnel0_in0: endpoint {
+                                               remote-endpoint = <&etm0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       apss_funnel0_in1: endpoint {
+                                               remote-endpoint = <&etm1_out>;
+                                       };
+                               };
+                       };
+
+                       out-ports {
+                               port {
+                                       apss_funnel0_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_in0>;
+                                       };
+                               };
+                       };
+               };
+
+               debug@3a10000 {
+                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
+                       reg = <0x3a10000 0x1000>;
+
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+                       clock-names = "apb_pclk";
 
-                               reg = <0x00600000 0x2000>,
-                                     <0x0c000000 0xf1d>,
-                                     <0x0c000f20 0xa8>,
-                                     <0x0c100000 0x100000>;
-                               reg-names = "parf", "dbi", "elbi","config";
+                       cpu = <&CPU2>;
+               };
 
-                               phys = <&pciephy_0>;
-                               phy-names = "pciephy";
+               etm@3a40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x3a40000 0x1000>;
 
-                               #address-cells = <3>;
-                               #size-cells = <2>;
-                               ranges = <0x01000000 0x0 0x0c200000 0x0c200000 0x0 0x100000>,
-                                       <0x02000000 0x0 0x0c300000 0x0c300000 0x0 0xd00000>;
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
 
-                               interrupts = <GIC_SPI 405 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "msi";
-                               #interrupt-cells = <1>;
-                               interrupt-map-mask = <0 0 0 0x7>;
-                               interrupt-map = <0 0 0 1 &intc 0 244 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-                                               <0 0 0 2 &intc 0 245 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-                                               <0 0 0 3 &intc 0 247 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-                                               <0 0 0 4 &intc 0 248 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+                       cpu = <&CPU2>;
 
-                               pinctrl-names = "default", "sleep";
-                               pinctrl-0 = <&pcie0_clkreq_default &pcie0_perst_default &pcie0_wake_default>;
-                               pinctrl-1 = <&pcie0_clkreq_sleep &pcie0_perst_default &pcie0_wake_sleep>;
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel1_in0>;
+                                       };
+                               };
+                       };
+               };
 
+               debug@3b10000 {
+                       compatible = "arm,coresight-cpu-debug", "arm,primecell";
+                       reg = <0x3b10000 0x1000>;
 
-                               vdda-supply = <&pm8994_l28>;
+                       clocks = <&rpmcc RPM_QDSS_CLK>;
+                       clock-names = "apb_pclk";
 
-                               linux,pci-domain = <0>;
+                       cpu = <&CPU3>;
+               };
 
-                               clocks = <&gcc GCC_PCIE_0_PIPE_CLK>,
-                                       <&gcc GCC_PCIE_0_AUX_CLK>,
-                                       <&gcc GCC_PCIE_0_CFG_AHB_CLK>,
-                                       <&gcc GCC_PCIE_0_MSTR_AXI_CLK>,
-                                       <&gcc GCC_PCIE_0_SLV_AXI_CLK>;
+               etm@3b40000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0x3b40000 0x1000>;
 
-                               clock-names =  "pipe",
-                                               "aux",
-                                               "cfg",
-                                               "bus_master",
-                                               "bus_slave";
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
 
-                       };
+                       cpu = <&CPU3>;
 
-                       pcie1: pcie@608000 {
-                               compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
-                               power-domains = <&gcc PCIE1_GDSC>;
-                               bus-range = <0x00 0xff>;
-                               num-lanes = <1>;
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel1_in1>;
+                                       };
+                               };
+                       };
+               };
 
-                               status  = "disabled";
+               funnel@3bb0000 { /* APSS Funnel 1 */
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3bb0000 0x1000>;
 
-                               reg = <0x00608000 0x2000>,
-                                     <0x0d000000 0xf1d>,
-                                     <0x0d000f20 0xa8>,
-                                     <0x0d100000 0x100000>;
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
 
-                               reg-names = "parf", "dbi", "elbi","config";
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
 
-                               phys = <&pciephy_1>;
-                               phy-names = "pciephy";
+                               port@0 {
+                                       reg = <0>;
+                                       apss_funnel1_in0: endpoint {
+                                               remote-endpoint = <&etm2_out>;
+                                       };
+                               };
 
-                               #address-cells = <3>;
-                               #size-cells = <2>;
-                               ranges = <0x01000000 0x0 0x0d200000 0x0d200000 0x0 0x100000>,
-                                       <0x02000000 0x0 0x0d300000 0x0d300000 0x0 0xd00000>;
+                               port@1 {
+                                       reg = <1>;
+                                       apss_funnel1_in1: endpoint {
+                                               remote-endpoint = <&etm3_out>;
+                                       };
+                               };
+                       };
 
-                               interrupts = <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "msi";
-                               #interrupt-cells = <1>;
-                               interrupt-map-mask = <0 0 0 0x7>;
-                               interrupt-map = <0 0 0 1 &intc 0 272 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-                                               <0 0 0 2 &intc 0 273 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-                                               <0 0 0 3 &intc 0 274 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-                                               <0 0 0 4 &intc 0 275 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+                       out-ports {
+                               port {
+                                       apss_funnel1_out: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_merge_funnel_in1>;
+                                       };
+                               };
+                       };
+               };
 
-                               pinctrl-names = "default", "sleep";
-                               pinctrl-0 = <&pcie1_clkreq_default &pcie1_perst_default &pcie1_wake_default>;
-                               pinctrl-1 = <&pcie1_clkreq_sleep &pcie1_perst_default &pcie1_wake_sleep>;
+               funnel@3bc0000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0x3bc0000 0x1000>;
 
+                       clocks = <&rpmcc RPM_QDSS_CLK>, <&rpmcc RPM_QDSS_A_CLK>;
+                       clock-names = "apb_pclk", "atclk";
 
-                               vdda-supply = <&pm8994_l28>;
-                               linux,pci-domain = <1>;
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
 
-                               clocks = <&gcc GCC_PCIE_1_PIPE_CLK>,
-                                       <&gcc GCC_PCIE_1_AUX_CLK>,
-                                       <&gcc GCC_PCIE_1_CFG_AHB_CLK>,
-                                       <&gcc GCC_PCIE_1_MSTR_AXI_CLK>,
-                                       <&gcc GCC_PCIE_1_SLV_AXI_CLK>;
+                               port@0 {
+                                       reg = <0>;
+                                       apss_merge_funnel_in0: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel0_out>;
+                                       };
+                               };
 
-                               clock-names =  "pipe",
-                                               "aux",
-                                               "cfg",
-                                               "bus_master",
-                                               "bus_slave";
+                               port@1 {
+                                       reg = <1>;
+                                       apss_merge_funnel_in1: endpoint {
+                                               remote-endpoint =
+                                                 <&apss_funnel1_out>;
+                                       };
+                               };
                        };
 
-                       pcie2: pcie@610000 {
-                               compatible = "qcom,pcie-msm8996", "snps,dw-pcie";
-                               power-domains = <&gcc PCIE2_GDSC>;
-                               bus-range = <0x00 0xff>;
-                               num-lanes = <1>;
-                               status = "disabled";
-                               reg = <0x00610000 0x2000>,
-                                     <0x0e000000 0xf1d>,
-                                     <0x0e000f20 0xa8>,
-                                     <0x0e100000 0x100000>;
+                       out-ports {
+                               port {
+                                       apss_merge_funnel_out: endpoint {
+                                               remote-endpoint =
+                                                 <&funnel1_in>;
+                                       };
+                               };
+                       };
+               };
+               kryocc: clock-controller@6400000 {
+                       compatible = "qcom,apcc-msm8996";
+                       reg = <0x06400000 0x90000>;
+                       #clock-cells = <1>;
+               };
 
-                               reg-names = "parf", "dbi", "elbi","config";
+               usb3: usb@6af8800 {
+                       compatible = "qcom,msm8996-dwc3", "qcom,dwc3";
+                       reg = <0x06af8800 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
 
-                               phys = <&pciephy_2>;
-                               phy-names = "pciephy";
+                       clocks = <&gcc GCC_SYS_NOC_USB3_AXI_CLK>,
+                               <&gcc GCC_USB30_MASTER_CLK>,
+                               <&gcc GCC_AGGRE2_USB3_AXI_CLK>,
+                               <&gcc GCC_USB30_MOCK_UTMI_CLK>,
+                               <&gcc GCC_USB30_SLEEP_CLK>,
+                               <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>;
 
-                               #address-cells = <3>;
-                               #size-cells = <2>;
-                               ranges = <0x01000000 0x0 0x0e200000 0x0e200000 0x0 0x100000>,
-                                       <0x02000000 0x0 0x0e300000 0x0e300000 0x0 0x1d00000>;
+                       assigned-clocks = <&gcc GCC_USB30_MOCK_UTMI_CLK>,
+                                         <&gcc GCC_USB30_MASTER_CLK>;
+                       assigned-clock-rates = <19200000>, <120000000>;
 
-                               device_type = "pci";
+                       power-domains = <&gcc USB30_GDSC>;
+                       status = "disabled";
 
-                               interrupts = <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>;
-                               interrupt-names = "msi";
-                               #interrupt-cells = <1>;
-                               interrupt-map-mask = <0 0 0 0x7>;
-                               interrupt-map = <0 0 0 1 &intc 0 142 IRQ_TYPE_LEVEL_HIGH>, /* int_a */
-                                               <0 0 0 2 &intc 0 143 IRQ_TYPE_LEVEL_HIGH>, /* int_b */
-                                               <0 0 0 3 &intc 0 144 IRQ_TYPE_LEVEL_HIGH>, /* int_c */
-                                               <0 0 0 4 &intc 0 145 IRQ_TYPE_LEVEL_HIGH>; /* int_d */
+                       dwc3@6a00000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x06a00000 0xcc00>;
+                               interrupts = <0 131 IRQ_TYPE_LEVEL_HIGH>;
+                               phys = <&hsusb_phy1>, <&ssusb_phy_0>;
+                               phy-names = "usb2-phy", "usb3-phy";
+                               snps,dis_u2_susphy_quirk;
+                               snps,dis_enblslpm_quirk;
+                       };
+               };
 
-                               pinctrl-names = "default", "sleep";
-                               pinctrl-0 = <&pcie2_clkreq_default &pcie2_perst_default &pcie2_wake_default>;
-                               pinctrl-1 = <&pcie2_clkreq_sleep &pcie2_perst_default &pcie2_wake_sleep >;
+               usb3phy: phy@7410000 {
+                       compatible = "qcom,msm8996-qmp-usb3-phy";
+                       reg = <0x07410000 0x1c4>;
+                       #clock-cells = <1>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
 
-                               vdda-supply = <&pm8994_l28>;
+                       clocks = <&gcc GCC_USB3_PHY_AUX_CLK>,
+                               <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                               <&gcc GCC_USB3_CLKREF_CLK>;
+                       clock-names = "aux", "cfg_ahb", "ref";
 
-                               linux,pci-domain = <2>;
-                               clocks = <&gcc GCC_PCIE_2_PIPE_CLK>,
-                                       <&gcc GCC_PCIE_2_AUX_CLK>,
-                                       <&gcc GCC_PCIE_2_CFG_AHB_CLK>,
-                                       <&gcc GCC_PCIE_2_MSTR_AXI_CLK>,
-                                       <&gcc GCC_PCIE_2_SLV_AXI_CLK>;
+                       resets = <&gcc GCC_USB3_PHY_BCR>,
+                               <&gcc GCC_USB3PHY_PHY_BCR>;
+                       reset-names = "phy", "common";
+                       status = "disabled";
 
-                               clock-names =  "pipe",
-                                               "aux",
-                                               "cfg",
-                                               "bus_master",
-                                               "bus_slave";
+                       ssusb_phy_0: lane@7410200 {
+                               reg = <0x07410200 0x200>,
+                                     <0x07410400 0x130>,
+                                     <0x07410600 0x1a8>;
+                               #phy-cells = <0>;
+
+                               clock-output-names = "usb3_phy_pipe_clk_src";
+                               clocks = <&gcc GCC_USB3_PHY_PIPE_CLK>;
+                               clock-names = "pipe0";
                        };
                };
 
-               slimbam:dma@9184000
-               {
-                       compatible = "qcom,bam-v1.7.0";
-                       qcom,controlled-remotely;
-                       reg = <0x9184000 0x32000>;
-                       num-channels  = <31>;
-                       interrupts = <0 164 IRQ_TYPE_LEVEL_HIGH>;
-                       #dma-cells = <1>;
-                       qcom,ee = <1>;
-                       qcom,num-ees = <2>;
+               hsusb_phy1: phy@7411000 {
+                       compatible = "qcom,msm8996-qusb2-phy";
+                       reg = <0x07411000 0x180>;
+                       #phy-cells = <0>;
+
+                       clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                               <&gcc GCC_RX1_USB2_CLKREF_CLK>;
+                       clock-names = "cfg_ahb", "ref";
+
+                       resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+                       nvmem-cells = <&qusb2p_hstx_trim>;
+                       status = "disabled";
                };
 
-               slim_msm: slim@91c0000 {
-                       compatible = "qcom,slim-ngd-v1.5.0";
-                       reg = <0x91c0000 0x2C000>;
-                       reg-names = "ctrl";
-                       interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>;
-                       dmas =  <&slimbam 3>, <&slimbam 4>,
-                               <&slimbam 5>, <&slimbam 6>;
-                       dma-names = "rx", "tx", "tx2", "rx2";
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       ngd@1 {
-                               reg = <1>;
-                               #address-cells = <1>;
-                               #size-cells = <1>;
+               hsusb_phy2: phy@7412000 {
+                       compatible = "qcom,msm8996-qusb2-phy";
+                       reg = <0x07412000 0x180>;
+                       #phy-cells = <0>;
 
-                               tasha_ifd: tas-ifd {
-                                       compatible = "slim217,1a0";
-                                       reg  = <0 0>;
-                               };
+                       clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                               <&gcc GCC_RX2_USB2_CLKREF_CLK>;
+                       clock-names = "cfg_ahb", "ref";
 
-                               wcd9335: codec@1{
-                                       pinctrl-0 = <&cdc_reset_active &wcd_intr_default>;
-                                       pinctrl-names = "default";
+                       resets = <&gcc GCC_QUSB2PHY_SEC_BCR>;
+                       nvmem-cells = <&qusb2s_hstx_trim>;
+                       status = "disabled";
+               };
 
-                                       compatible = "slim217,1a0";
-                                       reg  = <1 0>;
+               sdhc2: sdhci@74a4900 {
+                        status = "disabled";
+                        compatible = "qcom,sdhci-msm-v4";
+                        reg = <0x074a4900 0x314>, <0x074a4000 0x800>;
+                        reg-names = "hc_mem", "core_mem";
 
-                                       interrupt-parent = <&msmgpio>;
-                                       interrupts = <54 IRQ_TYPE_LEVEL_HIGH>,
-                                                    <53 IRQ_TYPE_LEVEL_HIGH>;
-                                       interrupt-names  = "intr1", "intr2";
-                                       interrupt-controller;
-                                       #interrupt-cells = <1>;
-                                       reset-gpios = <&msmgpio 64 0>;
+                        interrupts = <0 125 IRQ_TYPE_LEVEL_HIGH>,
+                                     <0 221 IRQ_TYPE_LEVEL_HIGH>;
+                        interrupt-names = "hc_irq", "pwr_irq";
 
-                                       slim-ifc-dev  = <&tasha_ifd>;
+                        clock-names = "iface", "core", "xo";
+                        clocks = <&gcc GCC_SDCC2_AHB_CLK>,
+                        <&gcc GCC_SDCC2_APPS_CLK>,
+                        <&xo_board>;
+                        bus-width = <4>;
+                };
 
-                                       vdd-buck-supply = <&pm8994_s4>;
-                                       vdd-buck-sido-supply = <&pm8994_s4>;
-                                       vdd-tx-supply = <&pm8994_s4>;
-                                       vdd-rx-supply = <&pm8994_s4>;
-                                       vdd-io-supply = <&pm8994_s4>;
+               blsp1_uart1: serial@7570000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0x07570000 0x1000>;
+                       interrupts = <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP1_UART2_APPS_CLK>,
+                                <&gcc GCC_BLSP1_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       status = "disabled";
+               };
 
-                                       #sound-dai-cells = <1>;
-                               };
-                       };
+               blsp1_spi0: spi@7575000 {
+                       compatible = "qcom,spi-qup-v2.2.1";
+                       reg = <0x07575000 0x600>;
+                       interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP1_QUP1_SPI_APPS_CLK>,
+                                <&gcc GCC_BLSP1_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&blsp1_spi0_default>;
+                       pinctrl-1 = <&blsp1_spi0_sleep>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
                };
 
-               gpu@b00000 {
-                       compatible = "qcom,adreno-530.2", "qcom,adreno";
-                       #stream-id-cells = <16>;
+               blsp1_i2c2: i2c@7577000 {
+                       compatible = "qcom,i2c-qup-v2.2.1";
+                       reg = <0x07577000 0x1000>;
+                       interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP1_AHB_CLK>,
+                               <&gcc GCC_BLSP1_QUP3_I2C_APPS_CLK>;
+                       clock-names = "iface", "core";
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&blsp1_i2c2_default>;
+                       pinctrl-1 = <&blsp1_i2c2_sleep>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
 
-                       reg = <0xb00000 0x3f000>;
-                       reg-names = "kgsl_3d0_reg_memory";
+               blsp2_uart1: serial@75b0000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0x075b0000 0x1000>;
+                       interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP2_UART2_APPS_CLK>,
+                                <&gcc GCC_BLSP2_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       status = "disabled";
+               };
 
-                       interrupts = <0 300 IRQ_TYPE_LEVEL_HIGH>;
+               blsp2_uart2: serial@75b1000 {
+                       compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm";
+                       reg = <0x075b1000 0x1000>;
+                       interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP2_UART3_APPS_CLK>,
+                                <&gcc GCC_BLSP2_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       status = "disabled";
+               };
 
-                       clocks = <&mmcc GPU_GX_GFX3D_CLK>,
-                               <&mmcc GPU_AHB_CLK>,
-                               <&mmcc GPU_GX_RBBMTIMER_CLK>,
-                               <&gcc GCC_BIMC_GFX_CLK>,
-                               <&gcc GCC_MMSS_BIMC_GFX_CLK>;
+               blsp2_i2c0: i2c@75b5000 {
+                       compatible = "qcom,i2c-qup-v2.2.1";
+                       reg = <0x075b5000 0x1000>;
+                       interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP2_AHB_CLK>,
+                               <&gcc GCC_BLSP2_QUP1_I2C_APPS_CLK>;
+                       clock-names = "iface", "core";
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&blsp2_i2c0_default>;
+                       pinctrl-1 = <&blsp2_i2c0_sleep>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
 
-                       clock-names = "core",
-                               "iface",
-                               "rbbmtimer",
-                               "mem",
-                               "mem_iface";
+               blsp2_i2c1: i2c@75b6000 {
+                       compatible = "qcom,i2c-qup-v2.2.1";
+                       reg = <0x075b6000 0x1000>;
+                       interrupts = <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP2_AHB_CLK>,
+                               <&gcc GCC_BLSP2_QUP2_I2C_APPS_CLK>;
+                       clock-names = "iface", "core";
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&blsp2_i2c1_default>;
+                       pinctrl-1 = <&blsp2_i2c1_sleep>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
 
-                       power-domains = <&mmcc GPU_GDSC>;
-                       iommus = <&adreno_smmu 0>;
+               blsp2_spi5: spi@75ba000{
+                       compatible = "qcom,spi-qup-v2.2.1";
+                       reg = <0x075ba000 0x600>;
+                       interrupts = <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_BLSP2_QUP6_SPI_APPS_CLK>,
+                                <&gcc GCC_BLSP2_AHB_CLK>;
+                       clock-names = "core", "iface";
+                       pinctrl-names = "default", "sleep";
+                       pinctrl-0 = <&blsp2_spi5_default>;
+                       pinctrl-1 = <&blsp2_spi5_sleep>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       status = "disabled";
+               };
 
-                       nvmem-cells = <&gpu_speed_bin>;
-                       nvmem-cell-names = "speed_bin";
+               usb2: usb@76f8800 {
+                       compatible = "qcom,msm8996-dwc3", "qcom,dwc3";
+                       reg = <0x076f8800 0x400>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
 
-                       qcom,gpu-quirk-two-pass-use-wfi;
-                       qcom,gpu-quirk-fault-detect-mask;
+                       clocks = <&gcc GCC_PERIPH_NOC_USB20_AHB_CLK>,
+                               <&gcc GCC_USB20_MASTER_CLK>,
+                               <&gcc GCC_USB20_MOCK_UTMI_CLK>,
+                               <&gcc GCC_USB20_SLEEP_CLK>,
+                               <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>;
 
-                       operating-points-v2 = <&gpu_opp_table>;
+                       assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>,
+                                         <&gcc GCC_USB20_MASTER_CLK>;
+                       assigned-clock-rates = <19200000>, <60000000>;
 
-                       gpu_opp_table: opp-table {
-                               compatible  ="operating-points-v2";
+                       power-domains = <&gcc USB30_GDSC>;
+                       status = "disabled";
 
-                               /*
-                                * 624Mhz and 560Mhz are only available on speed
-                                * bin (1 << 0). All the rest are available on
-                                * all bins of the hardware
-                                */
-                               opp-624000000 {
-                                       opp-hz = /bits/ 64 <624000000>;
-                                       opp-supported-hw = <0x01>;
-                               };
-                               opp-560000000 {
-                                       opp-hz = /bits/ 64 <560000000>;
-                                       opp-supported-hw = <0x01>;
-                               };
-                               opp-510000000 {
-                                       opp-hz = /bits/ 64 <510000000>;
-                                       opp-supported-hw = <0xFF>;
-                               };
-                               opp-401800000 {
-                                       opp-hz = /bits/ 64 <401800000>;
-                                       opp-supported-hw = <0xFF>;
-                               };
-                               opp-315000000 {
-                                       opp-hz = /bits/ 64 <315000000>;
-                                       opp-supported-hw = <0xFF>;
-                               };
-                               opp-214000000 {
-                                       opp-hz = /bits/ 64 <214000000>;
-                                       opp-supported-hw = <0xFF>;
-                               };
-                               opp-133000000 {
-                                       opp-hz = /bits/ 64 <133000000>;
-                                       opp-supported-hw = <0xFF>;
+                       dwc3@7600000 {
+                               compatible = "snps,dwc3";
+                               reg = <0x07600000 0xcc00>;
+                               interrupts = <0 138 IRQ_TYPE_LEVEL_HIGH>;
+                               phys = <&hsusb_phy2>;
+                               phy-names = "usb2-phy";
+                               snps,dis_u2_susphy_quirk;
+                               snps,dis_enblslpm_quirk;
+                       };
+               };
+
+               slimbam: dma@9184000 {
+                       compatible = "qcom,bam-v1.7.0";
+                       qcom,controlled-remotely;
+                       reg = <0x09184000 0x32000>;
+                       num-channels  = <31>;
+                       interrupts = <0 164 IRQ_TYPE_LEVEL_HIGH>;
+                       #dma-cells = <1>;
+                       qcom,ee = <1>;
+                       qcom,num-ees = <2>;
+               };
+
+               slim_msm: slim@91c0000 {
+                       compatible = "qcom,slim-ngd-v1.5.0";
+                       reg = <0x091c0000 0x2C000>;
+                       reg-names = "ctrl";
+                       interrupts = <0 163 IRQ_TYPE_LEVEL_HIGH>;
+                       dmas =  <&slimbam 3>, <&slimbam 4>,
+                               <&slimbam 5>, <&slimbam 6>;
+                       dma-names = "rx", "tx", "tx2", "rx2";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       ngd@1 {
+                               reg = <1>;
+                               #address-cells = <1>;
+                               #size-cells = <1>;
+
+                               tasha_ifd: tas-ifd {
+                                       compatible = "slim217,1a0";
+                                       reg  = <0 0>;
                                };
-                       };
 
-                       zap-shader {
-                               memory-region = <&zap_shader_region>;
-                       };
-               };
+                               wcd9335: codec@1{
+                                       pinctrl-0 = <&cdc_reset_active &wcd_intr_default>;
+                                       pinctrl-names = "default";
 
-               mdss: mdss@900000 {
-                       compatible = "qcom,mdss";
+                                       compatible = "slim217,1a0";
+                                       reg  = <1 0>;
 
-                       reg = <0x900000 0x1000>,
-                             <0x9b0000 0x1040>,
-                             <0x9b8000 0x1040>;
-                       reg-names = "mdss_phys",
-                                   "vbif_phys",
-                                   "vbif_nrt_phys";
+                                       interrupt-parent = <&msmgpio>;
+                                       interrupts = <54 IRQ_TYPE_LEVEL_HIGH>,
+                                                    <53 IRQ_TYPE_LEVEL_HIGH>;
+                                       interrupt-names  = "intr1", "intr2";
+                                       interrupt-controller;
+                                       #interrupt-cells = <1>;
+                                       reset-gpios = <&msmgpio 64 0>;
 
-                       power-domains = <&mmcc MDSS_GDSC>;
-                       interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+                                       slim-ifc-dev  = <&tasha_ifd>;
 
-                       interrupt-controller;
-                       #interrupt-cells = <1>;
+                                       #sound-dai-cells = <1>;
+                               };
+                       };
+               };
 
-                       clocks = <&mmcc MDSS_AHB_CLK>;
-                       clock-names = "iface";
+               adsp_pil: remoteproc@9300000 {
+                       compatible = "qcom,msm8996-adsp-pil";
+                       reg = <0x09300000 0x80000>;
 
-                       #address-cells = <1>;
-                       #size-cells = <1>;
-                       ranges;
+                       interrupts-extended = <&intc 0 162 IRQ_TYPE_EDGE_RISING>,
+                                             <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready",
+                                         "handover", "stop-ack";
 
-                       mdp: mdp@901000 {
-                               compatible = "qcom,mdp5";
-                               reg = <0x901000 0x90000>;
-                               reg-names = "mdp_phys";
+                       clocks = <&xo_board>;
+                       clock-names = "xo";
 
-                               interrupt-parent = <&mdss>;
-                               interrupts = <0 IRQ_TYPE_LEVEL_HIGH>;
+                       memory-region = <&adsp_region>;
 
-                               clocks = <&mmcc MDSS_AHB_CLK>,
-                                        <&mmcc MDSS_AXI_CLK>,
-                                        <&mmcc MDSS_MDP_CLK>,
-                                        <&mmcc SMMU_MDP_AXI_CLK>,
-                                        <&mmcc MDSS_VSYNC_CLK>;
-                               clock-names = "iface",
-                                             "bus",
-                                             "core",
-                                             "iommu",
-                                             "vsync";
+                       qcom,smem-states = <&smp2p_adsp_out 0>;
+                       qcom,smem-state-names = "stop";
 
-                               iommus = <&mdp_smmu 0>;
+                       smd-edge {
+                               interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
 
-                               ports {
+                               label = "lpass";
+                               mboxes = <&apcs_glb 8>;
+                               qcom,smd-edge = <1>;
+                               qcom,remote-pid = <2>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               apr {
+                                       power-domains = <&gcc HLOS1_VOTE_LPASS_ADSP_GDSC>;
+                                       compatible = "qcom,apr-v2";
+                                       qcom,smd-channels = "apr_audio_svc";
+                                       qcom,apr-domain = <APR_DOMAIN_ADSP>;
                                        #address-cells = <1>;
                                        #size-cells = <0>;
 
-                                       port@0 {
-                                               reg = <0>;
-                                               mdp5_intf3_out: endpoint {
-                                                       remote-endpoint = <&hdmi_in>;
+                                       q6core {
+                                               reg = <APR_SVC_ADSP_CORE>;
+                                               compatible = "qcom,q6core";
+                                       };
+
+                                       q6afe: q6afe {
+                                               compatible = "qcom,q6afe";
+                                               reg = <APR_SVC_AFE>;
+                                               q6afedai: dais {
+                                                       compatible = "qcom,q6afe-dais";
+                                                       #address-cells = <1>;
+                                                       #size-cells = <0>;
+                                                       #sound-dai-cells = <1>;
+                                                       hdmi@1 {
+                                                               reg = <1>;
+                                                       };
                                                };
                                        };
-                               };
-                       };
 
-                       hdmi: hdmi-tx@9a0000 {
-                               compatible = "qcom,hdmi-tx-8996";
-                               reg =   <0x009a0000 0x50c>,
-                                       <0x00070000 0x6158>,
-                                       <0x009e0000 0xfff>;
-                               reg-names = "core_physical",
-                                           "qfprom_physical",
-                                           "hdcp_physical";
+                                       q6asm: q6asm {
+                                               compatible = "qcom,q6asm";
+                                               reg = <APR_SVC_ASM>;
+                                               q6asmdai: dais {
+                                                       compatible = "qcom,q6asm-dais";
+                                                       #sound-dai-cells = <1>;
+                                                       iommus = <&lpass_q6_smmu 1>;
+                                               };
+                                       };
 
-                               interrupt-parent = <&mdss>;
-                               interrupts = <8 IRQ_TYPE_LEVEL_HIGH>;
+                                       q6adm: q6adm {
+                                               compatible = "qcom,q6adm";
+                                               reg = <APR_SVC_ADM>;
+                                               q6routing: routing {
+                                                       compatible = "qcom,q6adm-routing";
+                                                       #sound-dai-cells = <0>;
+                                               };
+                                       };
+                               };
 
-                               clocks = <&mmcc MDSS_MDP_CLK>,
-                                        <&mmcc MDSS_AHB_CLK>,
-                                        <&mmcc MDSS_HDMI_CLK>,
-                                        <&mmcc MDSS_HDMI_AHB_CLK>,
-                                        <&mmcc MDSS_EXTPCLK_CLK>;
-                               clock-names =
-                                       "mdp_core",
-                                       "iface",
-                                       "core",
-                                       "alt_iface",
-                                       "extp";
+                       };
+               };
 
-                               phys = <&hdmi_phy>;
-                               phy-names = "hdmi_phy";
-                               #sound-dai-cells = <1>;
+               apcs_glb: mailbox@9820000 {
+                       compatible = "qcom,msm8996-apcs-hmss-global";
+                       reg = <0x09820000 0x1000>;
 
-                               ports {
-                                       #address-cells = <1>;
-                                       #size-cells = <0>;
+                       #mbox-cells = <1>;
+               };
 
-                                       port@0 {
-                                               reg = <0>;
-                                               hdmi_in: endpoint {
-                                                       remote-endpoint = <&mdp5_intf3_out>;
-                                               };
-                                       };
-                               };
+               timer@9840000 {
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges;
+                       compatible = "arm,armv7-timer-mem";
+                       reg = <0x09840000 0x1000>;
+                       clock-frequency = <19200000>;
+
+                       frame@9850000 {
+                               frame-number = <0>;
+                               interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 30 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x09850000 0x1000>,
+                                     <0x09860000 0x1000>;
                        };
 
-                       hdmi_phy: hdmi-phy@9a0600 {
-                               #phy-cells = <0>;
-                               compatible = "qcom,hdmi-phy-8996";
-                               reg = <0x9a0600 0x1c4>,
-                                     <0x9a0a00 0x124>,
-                                     <0x9a0c00 0x124>,
-                                     <0x9a0e00 0x124>,
-                                     <0x9a1000 0x124>,
-                                     <0x9a1200 0x0c8>;
-                               reg-names = "hdmi_pll",
-                                           "hdmi_tx_l0",
-                                           "hdmi_tx_l1",
-                                           "hdmi_tx_l2",
-                                           "hdmi_tx_l3",
-                                           "hdmi_phy";
+                       frame@9870000 {
+                               frame-number = <1>;
+                               interrupts = <GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x09870000 0x1000>;
+                               status = "disabled";
+                       };
 
-                               clocks = <&mmcc MDSS_AHB_CLK>,
-                                        <&gcc GCC_HDMI_CLKREF_CLK>;
-                               clock-names = "iface",
-                                             "ref";
+                       frame@9880000 {
+                               frame-number = <2>;
+                               interrupts = <GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x09880000 0x1000>;
+                               status = "disabled";
                        };
-               };
 
-               venus_smmu: arm,smmu-venus@d40000 {
-                       compatible = "qcom,msm8996-smmu-v2", "qcom,smmu-v2";
-                       reg = <0xd40000 0x20000>;
-                       #global-interrupts = <1>;
-                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 335 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 336 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>,
-                                    <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>;
-                       power-domains = <&mmcc MMAGIC_VIDEO_GDSC>;
-                       clocks = <&mmcc SMMU_VIDEO_AHB_CLK>,
-                                <&mmcc SMMU_VIDEO_AXI_CLK>;
-                       clock-names = "iface", "bus";
-                       #iommu-cells = <1>;
-                       status = "okay";
-               };
+                       frame@9890000 {
+                               frame-number = <3>;
+                               interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x09890000 0x1000>;
+                               status = "disabled";
+                       };
 
-               video-codec@c00000 {
-                       compatible = "qcom,msm8996-venus";
-                       reg = <0x00c00000 0xff000>;
-                       interrupts = <GIC_SPI 287 IRQ_TYPE_LEVEL_HIGH>;
-                       power-domains = <&mmcc VENUS_GDSC>;
-                       clocks = <&mmcc VIDEO_CORE_CLK>,
-                                <&mmcc VIDEO_AHB_CLK>,
-                                <&mmcc VIDEO_AXI_CLK>,
-                                <&mmcc VIDEO_MAXI_CLK>;
-                       clock-names = "core", "iface", "bus", "mbus";
-                       iommus = <&venus_smmu 0x00>,
-                                <&venus_smmu 0x01>,
-                                <&venus_smmu 0x0a>,
-                                <&venus_smmu 0x07>,
-                                <&venus_smmu 0x0e>,
-                                <&venus_smmu 0x0f>,
-                                <&venus_smmu 0x08>,
-                                <&venus_smmu 0x09>,
-                                <&venus_smmu 0x0b>,
-                                <&venus_smmu 0x0c>,
-                                <&venus_smmu 0x0d>,
-                                <&venus_smmu 0x10>,
-                                <&venus_smmu 0x11>,
-                                <&venus_smmu 0x21>,
-                                <&venus_smmu 0x28>,
-                                <&venus_smmu 0x29>,
-                                <&venus_smmu 0x2b>,
-                                <&venus_smmu 0x2c>,
-                                <&venus_smmu 0x2d>,
-                                <&venus_smmu 0x31>;
-                       memory-region = <&venus_region>;
-                       status = "okay";
+                       frame@98a0000 {
+                               frame-number = <4>;
+                               interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x098a0000 0x1000>;
+                               status = "disabled";
+                       };
 
-                       video-decoder {
-                               compatible = "venus-decoder";
-                               clocks = <&mmcc VIDEO_SUBCORE0_CLK>;
-                               clock-names = "core";
-                               power-domains = <&mmcc VENUS_CORE0_GDSC>;
+                       frame@98b0000 {
+                               frame-number = <5>;
+                               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x098b0000 0x1000>;
+                               status = "disabled";
                        };
 
-                       video-encoder {
-                               compatible = "venus-encoder";
-                               clocks = <&mmcc VIDEO_SUBCORE1_CLK>;
-                               clock-names = "core";
-                               power-domains = <&mmcc VENUS_CORE1_GDSC>;
+                       frame@98c0000 {
+                               frame-number = <6>;
+                               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0x098c0000 0x1000>;
+                               status = "disabled";
                        };
                };
+
+               saw3: syscon@9a10000 {
+                       compatible = "syscon";
+                       reg = <0x09a10000 0x1000>;
+               };
+
+               intc: interrupt-controller@9bc0000 {
+                       compatible = "qcom,msm8996-gic-v3", "arm,gic-v3";
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       #redistributor-regions = <1>;
+                       redistributor-stride = <0x0 0x40000>;
+                       reg = <0x09bc0000 0x10000>,
+                             <0x09c00000 0x100000>;
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               };
        };
 
        sound: sound {
        };
 
-       adsp-pil {
-               compatible = "qcom,msm8996-adsp-pil";
+       thermal-zones {
+               cpu0-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-               interrupts-extended = <&intc 0 162 IRQ_TYPE_EDGE_RISING>,
-                                     <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
-                                     <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
-                                     <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
-                                     <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
-               interrupt-names = "wdog", "fatal", "ready",
-                                 "handover", "stop-ack";
+                       thermal-sensors = <&tsens0 3>;
 
-               clocks = <&xo_board>;
-               clock-names = "xo";
+                       trips {
+                               cpu0_alert0: trip-point@0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
 
-               memory-region = <&adsp_region>;
+                               cpu0_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
 
-               qcom,smem-states = <&adsp_smp2p_out 0>;
-               qcom,smem-state-names = "stop";
+               cpu1-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-               smd-edge {
-                       interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+                       thermal-sensors = <&tsens0 5>;
 
-                       label = "lpass";
-                       mboxes = <&apcs_glb 8>;
-                       qcom,smd-edge = <1>;
-                       qcom,remote-pid = <2>;
-                       #address-cells = <1>;
-                       #size-cells = <0>;
-                       apr {
-                               power-domains = <&gcc HLOS1_VOTE_LPASS_ADSP_GDSC>;
-                               compatible = "qcom,apr-v2";
-                               qcom,smd-channels = "apr_audio_svc";
-                               qcom,apr-domain = <APR_DOMAIN_ADSP>;
-                               #address-cells = <1>;
-                               #size-cells = <0>;
+                       trips {
+                               cpu1_alert0: trip-point@0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
 
-                               q6core {
-                                       reg = <APR_SVC_ADSP_CORE>;
-                                       compatible = "qcom,q6core";
-                               };
-
-                               q6afe: q6afe {
-                                       compatible = "qcom,q6afe";
-                                       reg = <APR_SVC_AFE>;
-                                       q6afedai: dais {
-                                               compatible = "qcom,q6afe-dais";
-                                               #address-cells = <1>;
-                                               #size-cells = <0>;
-                                               #sound-dai-cells = <1>;
-                                               hdmi@1 {
-                                                       reg = <1>;
-                                               };
-                                       };
+                               cpu1_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
                                };
+                       };
+               };
 
-                               q6asm: q6asm {
-                                       compatible = "qcom,q6asm";
-                                       reg = <APR_SVC_ASM>;
-                                       q6asmdai: dais {
-                                               compatible = "qcom,q6asm-dais";
-                                               #sound-dai-cells = <1>;
-                                               iommus = <&lpass_q6_smmu 1>;
-                                       };
+               cpu2-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 8>;
+
+                       trips {
+                               cpu2_alert0: trip-point@0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
                                };
 
-                               q6adm: q6adm {
-                                       compatible = "qcom,q6adm";
-                                       reg = <APR_SVC_ADM>;
-                                       q6routing: routing {
-                                               compatible = "qcom,q6adm-routing";
-                                               #sound-dai-cells = <0>;
-                                       };
+                               cpu2_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
                                };
                        };
+               };
+
+               cpu3-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 10>;
+
+                       trips {
+                               cpu3_alert0: trip-point@0 {
+                                       temperature = <75000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
 
+                               cpu3_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
                };
-       };
 
-       adsp-smp2p {
-               compatible = "qcom,smp2p";
-               qcom,smem = <443>, <429>;
+               gpu-thermal-top {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-               interrupts = <0 158 IRQ_TYPE_EDGE_RISING>;
+                       thermal-sensors = <&tsens1 6>;
 
-               mboxes = <&apcs_glb 10>;
+                       trips {
+                               gpu1_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
 
-               qcom,local-pid = <0>;
-               qcom,remote-pid = <2>;
+               gpu-thermal-bottom {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-               adsp_smp2p_out: master-kernel {
-                       qcom,entry-name = "master-kernel";
-                       #qcom,smem-state-cells = <1>;
+                       thermal-sensors = <&tsens1 7>;
+
+                       trips {
+                               gpu2_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
                };
 
-               adsp_smp2p_in: slave-kernel {
-                       qcom,entry-name = "slave-kernel";
+               m4m-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
+                       thermal-sensors = <&tsens0 1>;
+
+                       trips {
+                               m4m_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
                };
-       };
 
-       modem-smp2p {
-               compatible = "qcom,smp2p";
-               qcom,smem = <435>, <428>;
+               l3-or-venus-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-               interrupts = <GIC_SPI 451 IRQ_TYPE_EDGE_RISING>;
+                       thermal-sensors = <&tsens0 2>;
 
-               mboxes = <&apcs_glb 14>;
+                       trips {
+                               l3_or_venus_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
 
-               qcom,local-pid = <0>;
-               qcom,remote-pid = <1>;
+               cluster0-l2-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-               modem_smp2p_out: master-kernel {
-                       qcom,entry-name = "master-kernel";
-                       #qcom,smem-state-cells = <1>;
+                       thermal-sensors = <&tsens0 7>;
+
+                       trips {
+                               cluster0_l2_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
                };
 
-               modem_smp2p_in: slave-kernel {
-                       qcom,entry-name = "slave-kernel";
+               cluster1-l2-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
+                       thermal-sensors = <&tsens0 12>;
+
+                       trips {
+                               cluster1_l2_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
                };
-       };
 
-       smp2p-slpi {
-               compatible = "qcom,smp2p";
-               qcom,smem = <481>, <430>;
+               camera-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-               interrupts = <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>;
+                       thermal-sensors = <&tsens1 1>;
 
-               mboxes = <&apcs_glb 26>;
+                       trips {
+                               camera_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
 
-               qcom,local-pid = <0>;
-               qcom,remote-pid = <3>;
+               q6-dsp-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
 
-               slpi_smp2p_in: slave-kernel {
-                       qcom,entry-name = "slave-kernel";
-                       interrupt-controller;
-                       #interrupt-cells = <2>;
+                       thermal-sensors = <&tsens1 2>;
+
+                       trips {
+                               q6_dsp_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
                };
 
-               slpi_smp2p_out: master-kernel {
-                       qcom,entry-name = "master-kernel";
-                       #qcom,smem-state-cells = <1>;
+               mem-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 3>;
+
+                       trips {
+                               mem_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               modemtx-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 4>;
+
+                       trips {
+                               modemtx_alert0: trip-point@0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
                };
        };
 
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>;
+       };
 };
 #include "msm8996-pins.dtsi"
index 6138b58..6ab830d 100644 (file)
        cpu-idle-states = <&BIG_CPU_SLEEP_1>;
 };
 
+&pm8005_lsid1 {
+       pm8005-regulators {
+               compatible = "qcom,pm8005-regulators";
+
+               vdd_s1-supply = <&vph_pwr>;
+
+               pm8005_s1: s1 { /* VDD_GFX supply */
+                       regulator-min-microvolt = <524000>;
+                       regulator-max-microvolt = <1100000>;
+                       regulator-enable-ramp-delay = <500>;
+
+                       /* hack until we rig up the gpu consumer */
+                       regulator-always-on;
+               };
+       };
+};
+
 &qusb2phy {
        status = "okay";
 
        vdda-phy-supply = <&vreg_l1a_0p875>;
        vdda-pll-supply = <&vreg_l2a_1p2>;
 };
+
+&wifi {
+       status = "okay";
+
+       vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
+       vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+       vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+       vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+};
+
+/* PINCTRL - board-specific pinctrl */
+&blsp1_uart3_on {
+       rx {
+               /delete-property/ bias-disable;
+               /*
+                * Configure a pull-up on 45 (RX). This is needed to
+                * avoid garbage data when the TX pin of the Bluetooth
+                * module is in tri-state (module powered off or not
+                * driving the signal yet).
+                */
+               bias-pull-up;
+       };
+
+       cts {
+               /delete-property/ bias-disable;
+               /*
+                * Configure a pull-down on 47 (CTS) to match the pull
+                * of the Bluetooth module.
+                */
+               bias-pull-down;
+       };
+};
index 5f101a2..0e0b9bc 100644 (file)
@@ -9,6 +9,7 @@
 / {
        aliases {
                serial0 = &blsp2_uart1;
+               serial1 = &blsp1_uart3;
        };
 
        chosen {
        };
 };
 
+&remoteproc_adsp {
+       status = "okay";
+};
+
+&remoteproc_slpi {
+       status = "okay";
+};
+
 &tlmm {
        gpio-reserved-ranges = <0 4>, <81 4>;
 };
        vdda-phy-supply = <&vreg_l1a_0p875>;
        vdda-pll-supply = <&vreg_l2a_1p2>;
 };
+
+&wifi {
+       status = "okay";
+
+       vdd-0.8-cx-mx-supply = <&vreg_l5a_0p8>;
+       vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
+       vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
+       vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+};
+
+/* PINCTRL - board-specific pinctrl */
+&blsp1_uart3_on {
+       rx {
+               /delete-property/ bias-disable;
+               /*
+                * Configure a pull-up on 45 (RX). This is needed to
+                * avoid garbage data when the TX pin of the Bluetooth
+                * module is in tri-state (module powered off or not
+                * driving the signal yet).
+                */
+               bias-pull-up;
+       };
+
+       cts {
+               /delete-property/ bias-disable;
+               /*
+                * Configure a pull-down on 47 (CTS) to match the pull
+                * of the Bluetooth module.
+                */
+               bias-pull-down;
+       };
+};
index e32d3ab..7c222cb 100644 (file)
        };
 
        blsp1_uart3_on: blsp1_uart3_on {
-               mux {
-                       pins = "gpio45", "gpio46", "gpio47", "gpio48";
+               tx {
+                       pins = "gpio45";
                        function = "blsp_uart3_a";
+                       drive-strength = <2>;
+                       bias-disable;
                };
 
-               config {
-                       pins = "gpio45", "gpio46", "gpio47", "gpio48";
+               rx {
+                       pins = "gpio46";
+                       function = "blsp_uart3_a";
+                       drive-strength = <2>;
+                       bias-disable;
+               };
+
+               cts {
+                       pins = "gpio47";
+                       function = "blsp_uart3_a";
+                       drive-strength = <2>;
+                       bias-disable;
+               };
+
+               rfr {
+                       pins = "gpio48";
+                       function = "blsp_uart3_a";
                        drive-strength = <2>;
                        bias-disable;
                };
index fc7838e..91f7f2d 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/clock/qcom,gcc-msm8998.h>
+#include <dt-bindings/clock/qcom,gpucc-msm8998.h>
 #include <dt-bindings/clock/qcom,rpmcc.h>
 #include <dt-bindings/power/qcom-rpmpd.h>
 #include <dt-bindings/gpio/gpio.h>
                #size-cells = <2>;
                ranges;
 
-               memory@85800000 {
-                       reg = <0x0 0x85800000 0x0 0x800000>;
+               hyp_mem: memory@85800000 {
+                       reg = <0x0 0x85800000 0x0 0x600000>;
+                       no-map;
+               };
+
+               xbl_mem: memory@85e00000 {
+                       reg = <0x0 0x85e00000 0x0 0x100000>;
                        no-map;
                };
 
                        no-map;
                };
 
-               memory@86200000 {
+               tz_mem: memory@86200000 {
                        reg = <0x0 0x86200000 0x0 0x2d00000>;
                        no-map;
                };
 
-               rmtfs {
+               rmtfs_mem: memory@88f00000 {
                        compatible = "qcom,rmtfs-mem";
-
-                       size = <0x0 0x200000>;
-                       alloc-ranges = <0x0 0xa0000000 0x0 0x2000000>;
+                       reg = <0x0 0x88f00000 0x0 0x200000>;
                        no-map;
 
                        qcom,client-id = <1>;
                        qcom,vmid = <15>;
                };
+
+               spss_mem: memory@8ab00000 {
+                       reg = <0x0 0x8ab00000 0x0 0x700000>;
+                       no-map;
+               };
+
+               adsp_mem: memory@8b200000 {
+                       reg = <0x0 0x8b200000 0x0 0x1a00000>;
+                       no-map;
+               };
+
+               mpss_mem: memory@8cc00000 {
+                       reg = <0x0 0x8cc00000 0x0 0x7000000>;
+                       no-map;
+               };
+
+               venus_mem: memory@93c00000 {
+                       reg = <0x0 0x93c00000 0x0 0x500000>;
+                       no-map;
+               };
+
+               mba_mem: memory@94100000 {
+                       reg = <0x0 0x94100000 0x0 0x200000>;
+                       no-map;
+               };
+
+               slpi_mem: memory@94300000 {
+                       reg = <0x0 0x94300000 0x0 0xf00000>;
+                       no-map;
+               };
+
+               ipa_fw_mem: memory@95200000 {
+                       reg = <0x0 0x95200000 0x0 0x10000>;
+                       no-map;
+               };
+
+               ipa_gsi_mem: memory@95210000 {
+                       reg = <0x0 0x95210000 0x0 0x5000>;
+                       no-map;
+               };
+
+               gpu_mem: memory@95600000 {
+                       reg = <0x0 0x95600000 0x0 0x100000>;
+                       no-map;
+               };
+
+               wlan_msa_mem: memory@95700000 {
+                       reg = <0x0 0x95700000 0x0 0x100000>;
+                       no-map;
+               };
        };
 
        clocks {
                        reg = <0x010ab000 0x1000>, /* TM */
                              <0x010aa000 0x1000>; /* SROT */
                        #qcom,sensors = <14>;
-                       interrupts = <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "uplow";
+                       interrupts = <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow", "critical";
                        #thermal-sensor-cells = <1>;
                };
 
                        reg = <0x010ae000 0x1000>, /* TM */
                              <0x010ad000 0x1000>; /* SROT */
                        #qcom,sensors = <8>;
-                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
-                       interrupt-names = "uplow";
+                       interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow", "critical";
                        #thermal-sensor-cells = <1>;
                };
 
                                <GIC_SPI 369 IRQ_TYPE_EDGE_RISING>;
                };
 
+               anoc2_smmu: iommu@16c0000 {
+                       compatible = "qcom,msm8998-smmu-v2", "qcom,smmu-v2";
+                       reg = <0x016c0000 0x40000>;
+                       #iommu-cells = <1>;
+
+                       #global-interrupts = <0>;
+                       interrupts =
+                               <GIC_SPI 373 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 374 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 375 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 376 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 377 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 378 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 462 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>,
+                               <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>;
+               };
+
                pcie0: pci@1c00000 {
                        compatible = "qcom,pcie-msm8996";
                        reg =   <0x01c00000 0x2000>,
 
                tcsr_mutex_regs: syscon@1f40000 {
                        compatible = "syscon";
-                       reg = <0x01f40000 0x20000>;
+                       reg = <0x01f40000 0x40000>;
                };
 
                tlmm: pinctrl@3400000 {
                        #interrupt-cells = <0x2>;
                };
 
+               remoteproc_mss: remoteproc@4080000 {
+                       compatible = "qcom,msm8998-mss-pil";
+                       reg = <0x04080000 0x100>, <0x04180000 0x20>;
+                       reg-names = "qdsp6", "rmb";
+
+                       interrupts-extended =
+                               <&intc GIC_SPI 448 IRQ_TYPE_EDGE_RISING>,
+                               <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                               <&modem_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                               <&modem_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                               <&modem_smp2p_in 3 IRQ_TYPE_EDGE_RISING>,
+                               <&modem_smp2p_in 7 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready",
+                                         "handover", "stop-ack",
+                                         "shutdown-ack";
+
+                       clocks = <&gcc GCC_MSS_CFG_AHB_CLK>,
+                                <&gcc GCC_BIMC_MSS_Q6_AXI_CLK>,
+                                <&gcc GCC_BOOT_ROM_AHB_CLK>,
+                                <&gcc GCC_MSS_GPLL0_DIV_CLK_SRC>,
+                                <&gcc GCC_MSS_SNOC_AXI_CLK>,
+                                <&gcc GCC_MSS_MNOC_BIMC_AXI_CLK>,
+                                <&rpmcc RPM_SMD_QDSS_CLK>,
+                                <&rpmcc RPM_SMD_XO_CLK_SRC>;
+                       clock-names = "iface", "bus", "mem", "gpll0_mss",
+                                     "snoc_axi", "mnoc_axi", "qdss", "xo";
+
+                       qcom,smem-states = <&modem_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       resets = <&gcc GCC_MSS_RESTART>;
+                       reset-names = "mss_restart";
+
+                       qcom,halt-regs = <&tcsr_mutex_regs 0x23000 0x25000 0x24000>;
+
+                       power-domains = <&rpmpd MSM8998_VDDCX>,
+                                       <&rpmpd MSM8998_VDDMX>;
+                       power-domain-names = "cx", "mx";
+
+                       mba {
+                               memory-region = <&mba_mem>;
+                       };
+
+                       mpss {
+                               memory-region = <&mpss_mem>;
+                       };
+
+                       glink-edge {
+                               interrupts = <GIC_SPI 452 IRQ_TYPE_EDGE_RISING>;
+                               label = "modem";
+                               qcom,remote-pid = <1>;
+                               mboxes = <&apcs_glb 15>;
+                       };
+               };
+
+               gpucc: clock-controller@5065000 {
+                       compatible = "qcom,msm8998-gpucc";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+                       reg = <0x05065000 0x9000>;
+
+                       clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+                                <&gcc GPLL0_OUT_MAIN>;
+                       clock-names = "xo",
+                                     "gpll0";
+               };
+
+               remoteproc_slpi: remoteproc@5800000 {
+                       compatible = "qcom,msm8998-slpi-pas";
+                       reg = <0x05800000 0x4040>;
+
+                       interrupts-extended = <&intc GIC_SPI 390 IRQ_TYPE_EDGE_RISING>,
+                                             <&slpi_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&slpi_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&slpi_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&slpi_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready",
+                                         "handover", "stop-ack";
+
+                       px-supply = <&vreg_lvs2a_1p8>;
+
+                       clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
+                                <&rpmcc RPM_SMD_AGGR2_NOC_CLK>;
+                       clock-names = "xo", "aggre2";
+
+                       memory-region = <&slpi_mem>;
+
+                       qcom,smem-states = <&slpi_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       power-domains = <&rpmpd MSM8998_SSCCX>;
+                       power-domain-names = "ssc_cx";
+
+                       status = "disabled";
+
+                       glink-edge {
+                               interrupts = <GIC_SPI 179 IRQ_TYPE_EDGE_RISING>;
+                               label = "dsps";
+                               qcom,remote-pid = <3>;
+                               mboxes = <&apcs_glb 27>;
+                       };
+               };
+
                stm: stm@6002000 {
                        compatible = "arm,coresight-stm", "arm,primecell";
                        reg = <0x06002000 0x1000>,
                        #size-cells = <0>;
                };
 
+               remoteproc_adsp: remoteproc@17300000 {
+                       compatible = "qcom,msm8998-adsp-pas";
+                       reg = <0x17300000 0x4040>;
+
+                       interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
+                                             <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready",
+                                         "handover", "stop-ack";
+
+                       clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>;
+                       clock-names = "xo";
+
+                       memory-region = <&adsp_mem>;
+
+                       qcom,smem-states = <&adsp_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       power-domains = <&rpmpd MSM8998_VDDCX>;
+                       power-domain-names = "cx";
+
+                       status = "disabled";
+
+                       glink-edge {
+                               interrupts = <GIC_SPI 157 IRQ_TYPE_EDGE_RISING>;
+                               label = "lpass";
+                               qcom,remote-pid = <2>;
+                               mboxes = <&apcs_glb 9>;
+                       };
+               };
+
                apcs_glb: mailbox@17911000 {
                        compatible = "qcom,msm8998-apcs-hmss-global";
                        reg = <0x17911000 0x1000>;
                        redistributor-stride = <0x0 0x20000>;
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
                };
+
+               wifi: wifi@18800000 {
+                       compatible = "qcom,wcn3990-wifi";
+                       status = "disabled";
+                       reg = <0x18800000 0x800000>;
+                       reg-names = "membase";
+                       memory-region = <&wlan_msa_mem>;
+                       clocks = <&rpmcc RPM_SMD_RF_CLK2_PIN>;
+                       clock-names = "cxo_ref_clk_pin";
+                       interrupts =
+                               <GIC_SPI 413 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 414 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 415 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 418 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>;
+                       iommus = <&anoc2_smmu 0x1900>,
+                                <&anoc2_smmu 0x1901>;
+                       qcom,snoc-host-cap-8bit-quirk;
+               };
        };
 };
 
diff --git a/arch/arm64/boot/dts/qcom/pm6150.dtsi b/arch/arm64/boot/dts/qcom/pm6150.dtsi
new file mode 100644 (file)
index 0000000..2353463
--- /dev/null
@@ -0,0 +1,72 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+#include <dt-bindings/iio/qcom,spmi-vadc.h>
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+#include <dt-bindings/thermal/thermal.h>
+
+&spmi_bus {
+       pm6150_lsid0: pmic@0 {
+               compatible = "qcom,pm6150", "qcom,spmi-pmic";
+               reg = <0x0 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pm6150_pon: pon@800 {
+                       compatible = "qcom,pm8998-pon";
+                       reg = <0x800>;
+                       mode-bootloader = <0x2>;
+                       mode-recovery = <0x1>;
+
+                       pwrkey {
+                               compatible = "qcom,pm8941-pwrkey";
+                               interrupts = <0x0 0x8 0 IRQ_TYPE_EDGE_BOTH>;
+                               debounce = <15625>;
+                               bias-pull-up;
+                               linux,code = <KEY_POWER>;
+                       };
+               };
+
+               pm6150_temp: temp-alarm@2400 {
+                       compatible = "qcom,spmi-temp-alarm";
+                       reg = <0x2400>;
+                       interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_RISING>;
+                       io-channels = <&pm6150_adc ADC5_DIE_TEMP>;
+                       io-channel-names = "thermal";
+                       #thermal-sensor-cells = <0>;
+               };
+
+               pm6150_adc: adc@3100 {
+                       compatible = "qcom,spmi-adc5";
+                       reg = <0x3100>;
+                       interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       #io-channel-cells = <1>;
+
+                       adc-chan@6 {
+                               reg = <ADC5_DIE_TEMP>;
+                               label = "die_temp";
+                       };
+               };
+
+               pm6150_gpio: gpios@c000 {
+                       compatible = "qcom,pm6150-gpio", "qcom,spmi-gpio";
+                       reg = <0xc000>;
+                       gpio-controller;
+                       gpio-ranges = <&pm6150_gpio 0 0 10>;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       pm6150_lsid1: pmic@1 {
+               compatible = "qcom,pm6150", "qcom,spmi-pmic";
+               reg = <0x1 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
diff --git a/arch/arm64/boot/dts/qcom/pm6150l.dtsi b/arch/arm64/boot/dts/qcom/pm6150l.dtsi
new file mode 100644 (file)
index 0000000..f84027b
--- /dev/null
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: BSD-3-Clause
+// Copyright (c) 2019, The Linux Foundation. All rights reserved.
+
+#include <dt-bindings/interrupt-controller/irq.h>
+#include <dt-bindings/spmi/spmi.h>
+
+&spmi_bus {
+       pm6150l_lsid4: pmic@4 {
+               compatible = "qcom,pm6150l", "qcom,spmi-pmic";
+               reg = <0x4 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               pm6150l_gpio: gpios@c000 {
+                       compatible = "qcom,pm6150l-gpio", "qcom,spmi-gpio";
+                       reg = <0xc000>;
+                       gpio-controller;
+                       gpio-ranges = <&pm6150l_gpio 0 0 12>;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       pm6150l_lsid5: pmic@5 {
+               compatible = "qcom,pm6150l", "qcom,spmi-pmic";
+               reg = <0x5 SPMI_USID>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+       };
+};
index 297b57b..0abd1ab 100644 (file)
@@ -4,17 +4,23 @@
 
 &spmi_bus {
 
-       pmic@4 {
+       pm8004_lsid4: pmic@4 {
                compatible = "qcom,pm8004", "qcom,spmi-pmic";
                reg = <0x4 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
+               status = "disabled";
        };
 
-       pmic@5 {
+       pm8004_lsid5: pmic@5 {
                compatible = "qcom,pm8004", "qcom,spmi-pmic";
                reg = <0x5 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
+               status = "disabled";
+
+               pm8004_spmi_regulators: regulators {
+                       compatible = "qcom,pm8004-regulators";
+               };
        };
 };
index 9dd2df1..0bcdf04 100644 (file)
                #address-cells = <1>;
                #size-cells = <0>;
 
+               pm8916_vib: vibrator@c000 {
+                       compatible = "qcom,pm8916-vib";
+                       reg = <0xc000>;
+                       status = "disabled";
+               };
+
                wcd_codec: codec@f000 {
                        compatible = "qcom,pm8916-wcd-analog-codec";
                        reg = <0xf000 0x200>;
index 76b5a3e..7e4f777 100644 (file)
@@ -85,5 +85,9 @@
                reg = <0x1 SPMI_USID>;
                #address-cells = <1>;
                #size-cells = <0>;
+
+               pm8994_spmi_regulators: regulators {
+                       compatible = "qcom,pm8994-regulators";
+               };
        };
 };
index 501a733..522d3ef 100644 (file)
@@ -73,6 +73,7 @@
                regulator-always-on;
                regulator-boot-on;
                regulator-name = "vdd_apc";
+               regulator-initial-mode = <1>;
                regulator-min-microvolt = <1048000>;
                regulator-max-microvolt = <1384000>;
        };
index f5f0c4c..4ee1e3d 100644 (file)
                        cpu-idle-states = <&CPU_SLEEP_0>;
                        next-level-cache = <&L2_0>;
                        #cooling-cells = <2>;
+                       clocks = <&apcs_glb>;
+                       operating-points-v2 = <&cpu_opp_table>;
+                       power-domains = <&cpr>;
+                       power-domain-names = "cpr";
                };
 
                CPU1: cpu@101 {
                        cpu-idle-states = <&CPU_SLEEP_0>;
                        next-level-cache = <&L2_0>;
                        #cooling-cells = <2>;
+                       clocks = <&apcs_glb>;
+                       operating-points-v2 = <&cpu_opp_table>;
+                       power-domains = <&cpr>;
+                       power-domain-names = "cpr";
                };
 
                CPU2: cpu@102 {
                        cpu-idle-states = <&CPU_SLEEP_0>;
                        next-level-cache = <&L2_0>;
                        #cooling-cells = <2>;
+                       clocks = <&apcs_glb>;
+                       operating-points-v2 = <&cpu_opp_table>;
+                       power-domains = <&cpr>;
+                       power-domain-names = "cpr";
                };
 
                CPU3: cpu@103 {
                        cpu-idle-states = <&CPU_SLEEP_0>;
                        next-level-cache = <&L2_0>;
                        #cooling-cells = <2>;
+                       clocks = <&apcs_glb>;
+                       operating-points-v2 = <&cpu_opp_table>;
+                       power-domains = <&cpr>;
+                       power-domain-names = "cpr";
                };
 
                L2_0: l2-cache {
                };
        };
 
+       cpu_opp_table: cpu-opp-table {
+               compatible = "operating-points-v2-kryo-cpu";
+               opp-shared;
+
+               opp-1094400000 {
+                       opp-hz = /bits/ 64 <1094400000>;
+                       required-opps = <&cpr_opp1>;
+               };
+               opp-1248000000 {
+                       opp-hz = /bits/ 64 <1248000000>;
+                       required-opps = <&cpr_opp2>;
+               };
+               opp-1401600000 {
+                       opp-hz = /bits/ 64 <1401600000>;
+                       required-opps = <&cpr_opp3>;
+               };
+       };
+
+       cpr_opp_table: cpr-opp-table {
+               compatible = "operating-points-v2-qcom-level";
+
+               cpr_opp1: opp1 {
+                       opp-level = <1>;
+                       qcom,opp-fuse-level = <1>;
+               };
+               cpr_opp2: opp2 {
+                       opp-level = <2>;
+                       qcom,opp-fuse-level = <2>;
+               };
+               cpr_opp3: opp3 {
+                       opp-level = <3>;
+                       qcom,opp-fuse-level = <3>;
+               };
+       };
+
        firmware {
                scm: scm {
                        compatible = "qcom,scm-qcs404", "qcom,scm";
                        tsens_caldata: caldata@d0 {
                                reg = <0x1f8 0x14>;
                        };
+                       cpr_efuse_speedbin: speedbin@13c {
+                               reg = <0x13c 0x4>;
+                               bits = <2 3>;
+                       };
+                       cpr_efuse_quot_offset1: qoffset1@231 {
+                               reg = <0x231 0x4>;
+                               bits = <4 7>;
+                       };
+                       cpr_efuse_quot_offset2: qoffset2@232 {
+                               reg = <0x232 0x4>;
+                               bits = <3 7>;
+                       };
+                       cpr_efuse_quot_offset3: qoffset3@233 {
+                               reg = <0x233 0x4>;
+                               bits = <2 7>;
+                       };
+                       cpr_efuse_init_voltage1: ivoltage1@229 {
+                               reg = <0x229 0x4>;
+                               bits = <4 6>;
+                       };
+                       cpr_efuse_init_voltage2: ivoltage2@22a {
+                               reg = <0x22a 0x4>;
+                               bits = <2 6>;
+                       };
+                       cpr_efuse_init_voltage3: ivoltage3@22b {
+                               reg = <0x22b 0x4>;
+                               bits = <0 6>;
+                       };
+                       cpr_efuse_quot1: quot1@22b {
+                               reg = <0x22b 0x4>;
+                               bits = <6 12>;
+                       };
+                       cpr_efuse_quot2: quot2@22d {
+                               reg = <0x22d 0x4>;
+                               bits = <2 12>;
+                       };
+                       cpr_efuse_quot3: quot3@230 {
+                               reg = <0x230 0x4>;
+                               bits = <0 12>;
+                       };
+                       cpr_efuse_ring1: ring1@228 {
+                               reg = <0x228 0x4>;
+                               bits = <0 3>;
+                       };
+                       cpr_efuse_ring2: ring2@228 {
+                               reg = <0x228 0x4>;
+                               bits = <4 3>;
+                       };
+                       cpr_efuse_ring3: ring3@229 {
+                               reg = <0x229 0x4>;
+                               bits = <0 3>;
+                       };
+                       cpr_efuse_revision: revision@218 {
+                               reg = <0x218 0x4>;
+                               bits = <3 3>;
+                       };
                };
 
                rng: rng@e3000 {
                        compatible = "qcom,qcs404-apcs-apps-global", "syscon";
                        reg = <0x0b011000 0x1000>;
                        #mbox-cells = <1>;
+                       clocks = <&apcs_hfpll>, <&gcc GCC_GPLL0_AO_OUT_MAIN>;
+                       clock-names = "pll", "aux";
+                       #clock-cells = <0>;
+               };
+
+               apcs_hfpll: clock-controller@b016000 {
+                       compatible = "qcom,hfpll";
+                       reg = <0x0b016000 0x30>;
+                       #clock-cells = <0>;
+                       clock-output-names = "apcs_hfpll";
+                       clocks = <&xo_board>;
+                       clock-names = "xo";
                };
 
                watchdog@b017000 {
-                       compatible = "qcom,kpss-wdt";
+                       compatible = "qcom,apss-wdt-qcs404", "qcom,kpss-wdt";
                        reg = <0x0b017000 0x1000>;
                        clocks = <&sleep_clk>;
                };
 
+               cpr: power-controller@b018000 {
+                       compatible = "qcom,qcs404-cpr", "qcom,cpr";
+                       reg = <0x0b018000 0x1000>;
+                       interrupts = <0 15 IRQ_TYPE_EDGE_RISING>;
+                       clocks = <&xo_board>;
+                       clock-names = "ref";
+                       vdd-apc-supply = <&pms405_s3>;
+                       #power-domain-cells = <0>;
+                       operating-points-v2 = <&cpr_opp_table>;
+                       acc-syscon = <&tcsr>;
+
+                       nvmem-cells = <&cpr_efuse_quot_offset1>,
+                               <&cpr_efuse_quot_offset2>,
+                               <&cpr_efuse_quot_offset3>,
+                               <&cpr_efuse_init_voltage1>,
+                               <&cpr_efuse_init_voltage2>,
+                               <&cpr_efuse_init_voltage3>,
+                               <&cpr_efuse_quot1>,
+                               <&cpr_efuse_quot2>,
+                               <&cpr_efuse_quot3>,
+                               <&cpr_efuse_ring1>,
+                               <&cpr_efuse_ring2>,
+                               <&cpr_efuse_ring3>,
+                               <&cpr_efuse_revision>;
+                       nvmem-cell-names = "cpr_quotient_offset1",
+                               "cpr_quotient_offset2",
+                               "cpr_quotient_offset3",
+                               "cpr_init_voltage1",
+                               "cpr_init_voltage2",
+                               "cpr_init_voltage3",
+                               "cpr_quotient1",
+                               "cpr_quotient2",
+                               "cpr_quotient3",
+                               "cpr_ring_osc1",
+                               "cpr_ring_osc2",
+                               "cpr_ring_osc3",
+                               "cpr_fuse_revision";
+               };
+
                timer@b120000 {
                        #address-cells = <1>;
                        #size-cells = <1>;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-idp.dts b/arch/arm64/boot/dts/qcom/sc7180-idp.dts
new file mode 100644 (file)
index 0000000..388f50a
--- /dev/null
@@ -0,0 +1,430 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * SC7180 IDP board device tree source
+ *
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+/dts-v1/;
+
+#include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include "sc7180.dtsi"
+#include "pm6150.dtsi"
+#include "pm6150l.dtsi"
+
+/ {
+       model = "Qualcomm Technologies, Inc. SC7180 IDP";
+       compatible = "qcom,sc7180-idp", "qcom,sc7180";
+
+       aliases {
+               hsuart0 = &uart3;
+               serial0 = &uart8;
+       };
+
+       chosen {
+               stdout-path = "serial0:115200n8";
+       };
+};
+
+&apps_rsc {
+       pm6150-rpmh-regulators {
+               compatible = "qcom,pm6150-rpmh-regulators";
+               qcom,pmic-id = "a";
+
+               vreg_s1a_1p1: smps1 {
+                       regulator-min-microvolt = <1128000>;
+                       regulator-max-microvolt = <1128000>;
+               };
+
+               vreg_s4a_1p0: smps4 {
+                       regulator-min-microvolt = <824000>;
+                       regulator-max-microvolt = <1120000>;
+               };
+
+               vreg_s5a_2p0: smps5 {
+                       regulator-min-microvolt = <1744000>;
+                       regulator-max-microvolt = <2040000>;
+               };
+
+               vreg_l1a_1p2: ldo1 {
+                       regulator-min-microvolt = <1178000>;
+                       regulator-max-microvolt = <1256000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l2a_1p0: ldo2 {
+                       regulator-min-microvolt = <944000>;
+                       regulator-max-microvolt = <1056000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l3a_1p0: ldo3 {
+                       regulator-min-microvolt = <968000>;
+                       regulator-max-microvolt = <1064000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l4a_0p8: ldo4 {
+                       regulator-min-microvolt = <824000>;
+                       regulator-max-microvolt = <928000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l5a_2p7: ldo5 {
+                       regulator-min-microvolt = <2496000>;
+                       regulator-max-microvolt = <3000000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l6a_0p6: ldo6 {
+                       regulator-min-microvolt = <568000>;
+                       regulator-max-microvolt = <648000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l9a_0p6: ldo9 {
+                       regulator-min-microvolt = <488000>;
+                       regulator-max-microvolt = <800000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l10a_1p8: ldo10 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1832000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l11a_1p8: ldo11 {
+                       regulator-min-microvolt = <1696000>;
+                       regulator-max-microvolt = <1904000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l12a_1p8: ldo12 {
+                       regulator-min-microvolt = <1696000>;
+                       regulator-max-microvolt = <1952000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l13a_1p8: ldo13 {
+                       regulator-min-microvolt = <1696000>;
+                       regulator-max-microvolt = <1904000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l14a_1p8: ldo14 {
+                       regulator-min-microvolt = <1728000>;
+                       regulator-max-microvolt = <1832000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l15a_1p8: ldo15 {
+                       regulator-min-microvolt = <1696000>;
+                       regulator-max-microvolt = <1904000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l16a_2p7: ldo16 {
+                       regulator-min-microvolt = <2496000>;
+                       regulator-max-microvolt = <3304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l17a_3p0: ldo17 {
+                       regulator-min-microvolt = <2920000>;
+                       regulator-max-microvolt = <3232000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l18a_2p8: ldo18 {
+                       regulator-min-microvolt = <2496000>;
+                       regulator-max-microvolt = <3304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l19a_2p9: ldo19 {
+                       regulator-min-microvolt = <2696000>;
+                       regulator-max-microvolt = <3304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+       };
+
+       pm6150l-rpmh-regulators {
+               compatible = "qcom,pm6150l-rpmh-regulators";
+               qcom,pmic-id = "c";
+
+               vreg_s8c_1p3: smps8 {
+                       regulator-min-microvolt = <1120000>;
+                       regulator-max-microvolt = <1408000>;
+               };
+
+               vreg_l1c_1p8: ldo1 {
+                       regulator-min-microvolt = <1616000>;
+                       regulator-max-microvolt = <1984000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l2c_1p3: ldo2 {
+                       regulator-min-microvolt = <1168000>;
+                       regulator-max-microvolt = <1304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l3c_1p2: ldo3 {
+                       regulator-min-microvolt = <1144000>;
+                       regulator-max-microvolt = <1304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l4c_1p8: ldo4 {
+                       regulator-min-microvolt = <1648000>;
+                       regulator-max-microvolt = <3304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l5c_1p8: ldo5 {
+                       regulator-min-microvolt = <1648000>;
+                       regulator-max-microvolt = <3304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l6c_2p9: ldo6 {
+                       regulator-min-microvolt = <2696000>;
+                       regulator-max-microvolt = <3304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l7c_3p0: ldo7 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3312000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l8c_1p8: ldo8 {
+                       regulator-min-microvolt = <1800000>;
+                       regulator-max-microvolt = <1904000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l9c_2p9: ldo9 {
+                       regulator-min-microvolt = <2952000>;
+                       regulator-max-microvolt = <3304000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l10c_3p3: ldo10 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3400000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_l11c_3p3: ldo11 {
+                       regulator-min-microvolt = <3000000>;
+                       regulator-max-microvolt = <3400000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_LPM>;
+               };
+
+               vreg_bob: bob {
+                       regulator-min-microvolt = <3008000>;
+                       regulator-max-microvolt = <3960000>;
+                       regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>;
+               };
+       };
+};
+
+&qspi {
+       status = "okay";
+       pinctrl-names = "default";
+       pinctrl-0 = <&qspi_clk &qspi_cs0 &qspi_data01>;
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <25000000>;
+               spi-tx-bus-width = <2>;
+               spi-rx-bus-width = <2>;
+       };
+};
+
+&qupv3_id_0 {
+       status = "okay";
+};
+
+&qupv3_id_1 {
+       status = "okay";
+};
+
+&uart3 {
+       status = "okay";
+};
+
+&uart8 {
+       status = "okay";
+};
+
+&usb_1 {
+       status = "okay";
+};
+
+&usb_1_dwc3 {
+       dr_mode = "host";
+};
+
+&usb_1_hsphy {
+       status = "okay";
+       vdd-supply = <&vreg_l4a_0p8>;
+       vdda-pll-supply = <&vreg_l11a_1p8>;
+       vdda-phy-dpdm-supply = <&vreg_l17a_3p0>;
+       qcom,imp-res-offset-value = <8>;
+       qcom,hstx-trim-value = <QUSB2_V2_HSTX_TRIM_21_6_MA>;
+       qcom,preemphasis-level = <QUSB2_V2_PREEMPHASIS_5_PERCENT>;
+       qcom,preemphasis-width = <QUSB2_V2_PREEMPHASIS_WIDTH_HALF_BIT>;
+};
+
+&usb_1_qmpphy {
+       status = "okay";
+       vdda-phy-supply = <&vreg_l3c_1p2>;
+       vdda-pll-supply = <&vreg_l4a_0p8>;
+};
+
+/* PINCTRL - additions to nodes defined in sc7180.dtsi */
+
+&qspi_clk {
+       pinconf {
+               pins = "gpio63";
+               bias-disable;
+       };
+};
+
+&qspi_cs0 {
+       pinconf {
+               pins = "gpio68";
+               bias-disable;
+       };
+};
+
+&qspi_data01 {
+       pinconf {
+               pins = "gpio64", "gpio65";
+
+               /* High-Z when no transfers; nice to park the lines */
+               bias-pull-up;
+       };
+};
+
+&qup_i2c2_default {
+       pinconf {
+               pins = "gpio15", "gpio16";
+               drive-strength = <2>;
+
+               /* Has external pullup */
+               bias-disable;
+       };
+};
+
+&qup_i2c4_default {
+       pinconf {
+               pins = "gpio115", "gpio116";
+               drive-strength = <2>;
+
+               /* Has external pullup */
+               bias-disable;
+       };
+};
+
+&qup_i2c7_default {
+       pinconf {
+               pins = "gpio6", "gpio7";
+               drive-strength = <2>;
+
+               /* Has external pullup */
+               bias-disable;
+       };
+};
+
+&qup_i2c9_default {
+       pinconf {
+               pins = "gpio46", "gpio47";
+               drive-strength = <2>;
+
+               /* Has external pullup */
+               bias-disable;
+       };
+};
+
+&qup_uart3_default {
+       pinconf-cts {
+               /*
+                * Configure a pull-down on 38 (CTS) to match the pull of
+                * the Bluetooth module.
+                */
+               pins = "gpio38";
+               bias-pull-down;
+               output-high;
+       };
+
+       pinconf-rts {
+               /* We'll drive 39 (RTS), so no pull */
+               pins = "gpio39";
+               drive-strength = <2>;
+               bias-disable;
+       };
+
+       pinconf-tx {
+               /* We'll drive 40 (TX), so no pull */
+               pins = "gpio40";
+               drive-strength = <2>;
+               bias-disable;
+               output-high;
+       };
+
+       pinconf-rx {
+               /*
+                * Configure a pull-up on 41 (RX). This is needed to avoid
+                * garbage data when the TX pin of the Bluetooth module is
+                * in tri-state (module powered off or not driving the
+                * signal yet).
+                */
+               pins = "gpio41";
+               bias-pull-up;
+       };
+};
+
+&qup_uart8_default {
+       pinconf-tx {
+               pins = "gpio44";
+               drive-strength = <2>;
+               bias-disable;
+       };
+
+       pinconf-rx {
+               pins = "gpio45";
+               drive-strength = <2>;
+               bias-pull-up;
+       };
+};
+
+&qup_spi0_default {
+       pinconf {
+               pins = "gpio34", "gpio35", "gpio36", "gpio37";
+               drive-strength = <2>;
+               bias-disable;
+       };
+};
+
+&qup_spi6_default {
+       pinconf {
+               pins = "gpio59", "gpio60", "gpio61", "gpio62";
+               drive-strength = <2>;
+               bias-disable;
+       };
+};
+
+&qup_spi10_default {
+       pinconf {
+               pins = "gpio86", "gpio87", "gpio88", "gpio89";
+               drive-strength = <2>;
+               bias-disable;
+       };
+};
+
diff --git a/arch/arm64/boot/dts/qcom/sc7180.dtsi b/arch/arm64/boot/dts/qcom/sc7180.dtsi
new file mode 100644 (file)
index 0000000..8011c5f
--- /dev/null
@@ -0,0 +1,2187 @@
+// SPDX-License-Identifier: BSD-3-Clause
+/*
+ * SC7180 SoC device tree source
+ *
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#include <dt-bindings/clock/qcom,gcc-sc7180.h>
+#include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/phy/phy-qcom-qusb2.h>
+#include <dt-bindings/power/qcom-aoss-qmp.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
+#include <dt-bindings/reset/qcom,sdm845-aoss.h>
+#include <dt-bindings/reset/qcom,sdm845-pdc.h>
+#include <dt-bindings/soc/qcom,rpmh-rsc.h>
+#include <dt-bindings/thermal/thermal.h>
+
+/ {
+       interrupt-parent = <&intc>;
+
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       chosen { };
+
+       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;
+               spi0 = &spi0;
+               spi1 = &spi1;
+               spi3 = &spi3;
+               spi5 = &spi5;
+               spi6 = &spi6;
+               spi8 = &spi8;
+               spi10 = &spi10;
+               spi11 = &spi11;
+       };
+
+       clocks {
+               xo_board: xo-board {
+                       compatible = "fixed-clock";
+                       clock-frequency = <38400000>;
+                       #clock-cells = <0>;
+               };
+
+               sleep_clk: sleep-clk {
+                       compatible = "fixed-clock";
+                       clock-frequency = <32764>;
+                       #clock-cells = <0>;
+               };
+       };
+
+       reserved_memory: reserved-memory {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               aop_cmd_db_mem: memory@80820000 {
+                       reg = <0x0 0x80820000 0x0 0x20000>;
+                       compatible = "qcom,cmd-db";
+               };
+
+               smem_mem: memory@80900000 {
+                       reg = <0x0 0x80900000 0x0 0x200000>;
+                       no-map;
+               };
+       };
+
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               CPU0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_0>;
+                       #cooling-cells = <2>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
+                       L2_0: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                               L3_0: l3-cache {
+                                       compatible = "cache";
+                               };
+                       };
+               };
+
+               CPU1: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x100>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_100>;
+                       #cooling-cells = <2>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
+                       L2_100: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU2: cpu@200 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x200>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_200>;
+                       #cooling-cells = <2>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
+                       L2_200: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU3: cpu@300 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x300>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_300>;
+                       #cooling-cells = <2>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
+                       L2_300: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU4: cpu@400 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x400>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_400>;
+                       #cooling-cells = <2>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
+                       L2_400: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU5: cpu@500 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x500>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_500>;
+                       #cooling-cells = <2>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
+                       L2_500: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU6: cpu@600 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x600>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_600>;
+                       #cooling-cells = <2>;
+                       qcom,freq-domain = <&cpufreq_hw 1>;
+                       L2_600: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+
+               CPU7: cpu@700 {
+                       device_type = "cpu";
+                       compatible = "arm,armv8";
+                       reg = <0x0 0x700>;
+                       enable-method = "psci";
+                       next-level-cache = <&L2_700>;
+                       #cooling-cells = <2>;
+                       qcom,freq-domain = <&cpufreq_hw 1>;
+                       L2_700: l2-cache {
+                               compatible = "cache";
+                               next-level-cache = <&L3_0>;
+                       };
+               };
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               /* We expect the bootloader to fill in the size */
+               reg = <0 0x80000000 0 0>;
+       };
+
+       pmu {
+               compatible = "arm,armv8-pmuv3";
+               interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       firmware {
+               scm {
+                       compatible = "qcom,scm-sc7180", "qcom,scm";
+               };
+       };
+
+       tcsr_mutex: hwlock {
+               compatible = "qcom,tcsr-mutex";
+               syscon = <&tcsr_mutex_regs 0 0x1000>;
+               #hwlock-cells = <1>;
+       };
+
+       smem {
+               compatible = "qcom,smem";
+               memory-region = <&smem_mem>;
+               hwlocks = <&tcsr_mutex 3>;
+       };
+
+       smp2p-cdsp {
+               compatible = "qcom,smp2p";
+               qcom,smem = <94>, <432>;
+
+               interrupts = <GIC_SPI 576 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apss_shared 6>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <5>;
+
+               cdsp_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               cdsp_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-lpass {
+               compatible = "qcom,smp2p";
+               qcom,smem = <443>, <429>;
+
+               interrupts = <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apss_shared 10>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <2>;
+
+               adsp_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               adsp_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-mpss {
+               compatible = "qcom,smp2p";
+               qcom,smem = <435>, <428>;
+               interrupts = <GIC_SPI 451 IRQ_TYPE_EDGE_RISING>;
+               mboxes = <&apss_shared 14>;
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <1>;
+
+               modem_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               modem_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       psci {
+               compatible = "arm,psci-1.0";
+               method = "smc";
+       };
+
+       soc: soc {
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges = <0 0 0 0 0x10 0>;
+               dma-ranges = <0 0 0 0 0x10 0>;
+               compatible = "simple-bus";
+
+               gcc: clock-controller@100000 {
+                       compatible = "qcom,gcc-sc7180";
+                       reg = <0 0x00100000 0 0x1f0000>;
+                       clocks = <&rpmhcc RPMH_CXO_CLK>,
+                                <&rpmhcc RPMH_CXO_CLK_A>;
+                       clock-names = "bi_tcxo", "bi_tcxo_ao";
+                       #clock-cells = <1>;
+                       #reset-cells = <1>;
+                       #power-domain-cells = <1>;
+               };
+
+               qfprom@784000 {
+                       compatible = "qcom,qfprom";
+                       reg = <0 0x00784000 0 0x8ff>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+
+                       qusb2p_hstx_trim: hstx-trim-primary@25b {
+                               reg = <0x25b 0x1>;
+                               bits = <1 3>;
+                       };
+               };
+
+               qupv3_id_0: geniqup@8c0000 {
+                       compatible = "qcom,geni-se-qup";
+                       reg = <0 0x008c0000 0 0x6000>;
+                       clock-names = "m-ahb", "s-ahb";
+                       clocks = <&gcc GCC_QUPV3_WRAP_0_M_AHB_CLK>,
+                                <&gcc GCC_QUPV3_WRAP_0_S_AHB_CLK>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       status = "disabled";
+
+                       i2c0: i2c@880000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00880000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c0_default>;
+                               interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi0: spi@880000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0 0x00880000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi0_default>;
+                               interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart0: serial@880000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00880000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart0_default>;
+                               interrupts = <GIC_SPI 601 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c1: i2c@884000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00884000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c1_default>;
+                               interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi1: spi@884000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0 0x00884000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi1_default>;
+                               interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart1: serial@884000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00884000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart1_default>;
+                               interrupts = <GIC_SPI 602 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c2: i2c@888000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00888000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c2_default>;
+                               interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart2: serial@888000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00888000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart2_default>;
+                               interrupts = <GIC_SPI 603 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c3: i2c@88c000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x0088c000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c3_default>;
+                               interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi3: spi@88c000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0 0x0088c000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi3_default>;
+                               interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart3: serial@88c000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x0088c000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart3_default>;
+                               interrupts = <GIC_SPI 604 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c4: i2c@890000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00890000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c4_default>;
+                               interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart4: serial@890000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00890000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart4_default>;
+                               interrupts = <GIC_SPI 605 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c5: i2c@894000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00894000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c5_default>;
+                               interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi5: spi@894000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0 0x00894000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi5_default>;
+                               interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart5: serial@894000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00894000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP0_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart5_default>;
+                               interrupts = <GIC_SPI 606 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+               };
+
+               qupv3_id_1: geniqup@ac0000 {
+                       compatible = "qcom,geni-se-qup";
+                       reg = <0 0x00ac0000 0 0x6000>;
+                       clock-names = "m-ahb", "s-ahb";
+                       clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>,
+                                <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       status = "disabled";
+
+                       i2c6: i2c@a80000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00a80000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c6_default>;
+                               interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi6: spi@a80000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0 0x00a80000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi6_default>;
+                               interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart6: serial@a80000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00a80000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart6_default>;
+                               interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c7: i2c@a84000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00a84000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c7_default>;
+                               interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart7: serial@a84000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00a84000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart7_default>;
+                               interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c8: i2c@a88000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00a88000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c8_default>;
+                               interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi8: spi@a88000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0 0x00a88000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi8_default>;
+                               interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart8: serial@a88000 {
+                               compatible = "qcom,geni-debug-uart";
+                               reg = <0 0x00a88000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart8_default>;
+                               interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c9: i2c@a8c000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00a8c000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c9_default>;
+                               interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart9: serial@a8c000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00a8c000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart9_default>;
+                               interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c10: i2c@a90000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00a90000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c10_default>;
+                               interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi10: spi@a90000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0 0x00a90000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi10_default>;
+                               interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart10: serial@a90000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00a90000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart10_default>;
+                               interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+
+                       i2c11: i2c@a94000 {
+                               compatible = "qcom,geni-i2c";
+                               reg = <0 0x00a94000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_i2c11_default>;
+                               interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       spi11: spi@a94000 {
+                               compatible = "qcom,geni-spi";
+                               reg = <0 0x00a94000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_spi11_default>;
+                               interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+                               status = "disabled";
+                       };
+
+                       uart11: serial@a94000 {
+                               compatible = "qcom,geni-uart";
+                               reg = <0 0x00a94000 0 0x4000>;
+                               clock-names = "se";
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>;
+                               pinctrl-names = "default";
+                               pinctrl-0 = <&qup_uart11_default>;
+                               interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>;
+                               status = "disabled";
+                       };
+               };
+
+               tcsr_mutex_regs: syscon@1f40000 {
+                       compatible = "syscon";
+                       reg = <0 0x01f40000 0 0x40000>;
+               };
+
+               tlmm: pinctrl@3500000 {
+                       compatible = "qcom,sc7180-pinctrl";
+                       reg = <0 0x03500000 0 0x300000>,
+                             <0 0x03900000 0 0x300000>,
+                             <0 0x03d00000 0 0x300000>;
+                       reg-names = "west", "north", "south";
+                       interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>;
+                       gpio-controller;
+                       #gpio-cells = <2>;
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+                       gpio-ranges = <&tlmm 0 0 120>;
+                       wakeup-parent = <&pdc>;
+
+                       qspi_clk: qspi-clk {
+                               pinmux {
+                                       pins = "gpio63";
+                                       function = "qspi_clk";
+                               };
+                       };
+
+                       qspi_cs0: qspi-cs0 {
+                               pinmux {
+                                       pins = "gpio68";
+                                       function = "qspi_cs";
+                               };
+                       };
+
+                       qspi_cs1: qspi-cs1 {
+                               pinmux {
+                                       pins = "gpio72";
+                                       function = "qspi_cs";
+                               };
+                       };
+
+                       qspi_data01: qspi-data01 {
+                               pinmux-data {
+                                       pins = "gpio64", "gpio65";
+                                       function = "qspi_data";
+                               };
+                       };
+
+                       qspi_data12: qspi-data12 {
+                               pinmux-data {
+                                       pins = "gpio66", "gpio67";
+                                       function = "qspi_data";
+                               };
+                       };
+
+                       qup_i2c0_default: qup-i2c0-default {
+                               pinmux {
+                                       pins = "gpio34", "gpio35";
+                                       function = "qup00";
+                               };
+                       };
+
+                       qup_i2c1_default: qup-i2c1-default {
+                               pinmux {
+                                       pins = "gpio0", "gpio1";
+                                       function = "qup01";
+                               };
+                       };
+
+                       qup_i2c2_default: qup-i2c2-default {
+                               pinmux {
+                                       pins = "gpio15", "gpio16";
+                                       function = "qup02_i2c";
+                               };
+                       };
+
+                       qup_i2c3_default: qup-i2c3-default {
+                               pinmux {
+                                       pins = "gpio38", "gpio39";
+                                       function = "qup03";
+                               };
+                       };
+
+                       qup_i2c4_default: qup-i2c4-default {
+                               pinmux {
+                                       pins = "gpio115", "gpio116";
+                                       function = "qup04_i2c";
+                               };
+                       };
+
+                       qup_i2c5_default: qup-i2c5-default {
+                               pinmux {
+                                       pins = "gpio25", "gpio26";
+                                       function = "qup05";
+                               };
+                       };
+
+                       qup_i2c6_default: qup-i2c6-default {
+                               pinmux {
+                                       pins = "gpio59", "gpio60";
+                                       function = "qup10";
+                               };
+                       };
+
+                       qup_i2c7_default: qup-i2c7-default {
+                               pinmux {
+                                       pins = "gpio6", "gpio7";
+                                       function = "qup11_i2c";
+                               };
+                       };
+
+                       qup_i2c8_default: qup-i2c8-default {
+                               pinmux {
+                                       pins = "gpio42", "gpio43";
+                                       function = "qup12";
+                               };
+                       };
+
+                       qup_i2c9_default: qup-i2c9-default {
+                               pinmux {
+                                       pins = "gpio46", "gpio47";
+                                       function = "qup13_i2c";
+                               };
+                       };
+
+                       qup_i2c10_default: qup-i2c10-default {
+                               pinmux {
+                                       pins = "gpio86", "gpio87";
+                                       function = "qup14";
+                               };
+                       };
+
+                       qup_i2c11_default: qup-i2c11-default {
+                               pinmux {
+                                       pins = "gpio53", "gpio54";
+                                       function = "qup15";
+                               };
+                       };
+
+                       qup_spi0_default: qup-spi0-default {
+                               pinmux {
+                                       pins = "gpio34", "gpio35",
+                                              "gpio36", "gpio37";
+                                       function = "qup00";
+                               };
+                       };
+
+                       qup_spi1_default: qup-spi1-default {
+                               pinmux {
+                                       pins = "gpio0", "gpio1",
+                                              "gpio2", "gpio3";
+                                       function = "qup01";
+                               };
+                       };
+
+                       qup_spi3_default: qup-spi3-default {
+                               pinmux {
+                                       pins = "gpio38", "gpio39",
+                                              "gpio40", "gpio41";
+                                       function = "qup03";
+                               };
+                       };
+
+                       qup_spi5_default: qup-spi5-default {
+                               pinmux {
+                                       pins = "gpio25", "gpio26",
+                                              "gpio27", "gpio28";
+                                       function = "qup05";
+                               };
+                       };
+
+                       qup_spi6_default: qup-spi6-default {
+                               pinmux {
+                                       pins = "gpio59", "gpio60",
+                                              "gpio61", "gpio62";
+                                       function = "qup10";
+                               };
+                       };
+
+                       qup_spi8_default: qup-spi8-default {
+                               pinmux {
+                                       pins = "gpio42", "gpio43",
+                                              "gpio44", "gpio45";
+                                       function = "qup12";
+                               };
+                       };
+
+                       qup_spi10_default: qup-spi10-default {
+                               pinmux {
+                                       pins = "gpio86", "gpio87",
+                                              "gpio88", "gpio89";
+                                       function = "qup14";
+                               };
+                       };
+
+                       qup_spi11_default: qup-spi11-default {
+                               pinmux {
+                                       pins = "gpio53", "gpio54",
+                                              "gpio55", "gpio56";
+                                       function = "qup15";
+                               };
+                       };
+
+                       qup_uart0_default: qup-uart0-default {
+                               pinmux {
+                                       pins = "gpio34", "gpio35",
+                                              "gpio36", "gpio37";
+                                       function = "qup00";
+                               };
+                       };
+
+                       qup_uart1_default: qup-uart1-default {
+                               pinmux {
+                                       pins = "gpio0", "gpio1",
+                                              "gpio2", "gpio3";
+                                       function = "qup01";
+                               };
+                       };
+
+                       qup_uart2_default: qup-uart2-default {
+                               pinmux {
+                                       pins = "gpio15", "gpio16";
+                                       function = "qup02_uart";
+                               };
+                       };
+
+                       qup_uart3_default: qup-uart3-default {
+                               pinmux {
+                                       pins = "gpio38", "gpio39",
+                                              "gpio40", "gpio41";
+                                       function = "qup03";
+                               };
+                       };
+
+                       qup_uart4_default: qup-uart4-default {
+                               pinmux {
+                                       pins = "gpio115", "gpio116";
+                                       function = "qup04_uart";
+                               };
+                       };
+
+                       qup_uart5_default: qup-uart5-default {
+                               pinmux {
+                                       pins = "gpio25", "gpio26",
+                                              "gpio27", "gpio28";
+                                       function = "qup05";
+                               };
+                       };
+
+                       qup_uart6_default: qup-uart6-default {
+                               pinmux {
+                                       pins = "gpio59", "gpio60",
+                                              "gpio61", "gpio62";
+                                       function = "qup10";
+                               };
+                       };
+
+                       qup_uart7_default: qup-uart7-default {
+                               pinmux {
+                                       pins = "gpio6", "gpio7";
+                                       function = "qup11_uart";
+                               };
+                       };
+
+                       qup_uart8_default: qup-uart8-default {
+                               pinmux {
+                                       pins = "gpio44", "gpio45";
+                                       function = "qup12";
+                               };
+                       };
+
+                       qup_uart9_default: qup-uart9-default {
+                               pinmux {
+                                       pins = "gpio46", "gpio47";
+                                       function = "qup13_uart";
+                               };
+                       };
+
+                       qup_uart10_default: qup-uart10-default {
+                               pinmux {
+                                       pins = "gpio86", "gpio87",
+                                              "gpio88", "gpio89";
+                                       function = "qup14";
+                               };
+                       };
+
+                       qup_uart11_default: qup-uart11-default {
+                               pinmux {
+                                       pins = "gpio53", "gpio54",
+                                              "gpio55", "gpio56";
+                                       function = "qup15";
+                               };
+                       };
+               };
+
+               qspi: spi@88dc000 {
+                       compatible = "qcom,qspi-v1";
+                       reg = <0 0x088dc000 0 0x600>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       interrupts = <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&gcc GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
+                                <&gcc GCC_QSPI_CORE_CLK>;
+                       clock-names = "iface", "core";
+                       status = "disabled";
+               };
+
+               usb_1_hsphy: phy@88e3000 {
+                       compatible = "qcom,sc7180-qusb2-phy";
+                       reg = <0 0x088e3000 0 0x400>;
+                       status = "disabled";
+                       #phy-cells = <0>;
+                       clocks = <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                                <&rpmhcc RPMH_CXO_CLK>;
+                       clock-names = "cfg_ahb", "ref";
+                       resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>;
+
+                       nvmem-cells = <&qusb2p_hstx_trim>;
+               };
+
+               usb_1_qmpphy: phy-wrapper@88e9000 {
+                       compatible = "qcom,sc7180-qmp-usb3-phy";
+                       reg = <0 0x088e9000 0 0x18c>,
+                             <0 0x088e8000 0 0x38>;
+                       reg-names = "reg-base", "dp_com";
+                       status = "disabled";
+                       #clock-cells = <1>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+
+                       clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>,
+                                <&gcc GCC_USB_PHY_CFG_AHB2PHY_CLK>,
+                                <&gcc GCC_USB3_PRIM_CLKREF_CLK>,
+                                <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>;
+                       clock-names = "aux", "cfg_ahb", "ref", "com_aux";
+
+                       resets = <&gcc GCC_USB3_DP_PHY_PRIM_BCR>,
+                                <&gcc GCC_USB3_PHY_PRIM_BCR>;
+                       reset-names = "phy", "common";
+
+                       usb_1_ssphy: phy@88e9200 {
+                               reg = <0 0x088e9200 0 0x128>,
+                                     <0 0x088e9400 0 0x200>,
+                                     <0 0x088e9c00 0 0x218>,
+                                     <0 0x088e9600 0 0x128>,
+                                     <0 0x088e9800 0 0x200>,
+                                     <0 0x088e9a00 0 0x18>;
+                               #clock-cells = <0>;
+                               #phy-cells = <0>;
+                               clocks = <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>;
+                               clock-names = "pipe0";
+                               clock-output-names = "usb3_phy_pipe_clk_src";
+                       };
+               };
+
+               system-cache-controller@9200000 {
+                       compatible = "qcom,sc7180-llcc";
+                       reg = <0 0x09200000 0 0x200000>, <0 0x09600000 0 0x50000>;
+                       reg-names = "llcc_base", "llcc_broadcast_base";
+                       interrupts = <GIC_SPI 582 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               usb_1: usb@a6f8800 {
+                       compatible = "qcom,sc7180-dwc3", "qcom,dwc3";
+                       reg = <0 0x0a6f8800 0 0x400>;
+                       status = "disabled";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       dma-ranges;
+
+                       clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>,
+                                <&gcc GCC_USB30_PRIM_MASTER_CLK>,
+                                <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>,
+                                <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+                                <&gcc GCC_USB30_PRIM_SLEEP_CLK>;
+                       clock-names = "cfg_noc", "core", "iface", "mock_utmi",
+                                     "sleep";
+
+                       assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>,
+                                         <&gcc GCC_USB30_PRIM_MASTER_CLK>;
+                       assigned-clock-rates = <19200000>, <150000000>;
+
+                       interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "hs_phy_irq", "ss_phy_irq",
+                                         "dm_hs_phy_irq", "dp_hs_phy_irq";
+
+                       power-domains = <&gcc USB30_PRIM_GDSC>;
+
+                       resets = <&gcc GCC_USB30_PRIM_BCR>;
+
+                       usb_1_dwc3: dwc3@a600000 {
+                               compatible = "snps,dwc3";
+                               reg = <0 0x0a600000 0 0xe000>;
+                               interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+                               iommus = <&apps_smmu 0x540 0>;
+                               snps,dis_u2_susphy_quirk;
+                               snps,dis_enblslpm_quirk;
+                               phys = <&usb_1_hsphy>, <&usb_1_ssphy>;
+                               phy-names = "usb2-phy", "usb3-phy";
+                       };
+               };
+
+               pdc: interrupt-controller@b220000 {
+                       compatible = "qcom,sc7180-pdc", "qcom,pdc";
+                       reg = <0 0x0b220000 0 0x30000>;
+                       qcom,pdc-ranges = <0 480 15>, <17 497 98>,
+                                         <119 634 4>, <124 639 1>;
+                       #interrupt-cells = <2>;
+                       interrupt-parent = <&intc>;
+                       interrupt-controller;
+               };
+
+               pdc_reset: reset-controller@b2e0000 {
+                       compatible = "qcom,sc7180-pdc-global", "qcom,sdm845-pdc-global";
+                       reg = <0 0x0b2e0000 0 0x20000>;
+                       #reset-cells = <1>;
+               };
+
+               tsens0: thermal-sensor@c263000 {
+                       compatible = "qcom,sc7180-tsens","qcom,tsens-v2";
+                       reg = <0 0x0c263000 0 0x1ff>, /* TM */
+                               <0 0x0c222000 0 0x1ff>; /* SROT */
+                       #qcom,sensors = <15>;
+                       interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow","critical";
+                       #thermal-sensor-cells = <1>;
+               };
+
+               tsens1: thermal-sensor@c265000 {
+                       compatible = "qcom,sc7180-tsens","qcom,tsens-v2";
+                       reg = <0 0x0c265000 0 0x1ff>, /* TM */
+                               <0 0x0c223000 0 0x1ff>; /* SROT */
+                       #qcom,sensors = <10>;
+                       interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow","critical";
+                       #thermal-sensor-cells = <1>;
+               };
+
+               aoss_reset: reset-controller@c2a0000 {
+                       compatible = "qcom,sc7180-aoss-cc", "qcom,sdm845-aoss-cc";
+                       reg = <0 0x0c2a0000 0 0x31000>;
+                       #reset-cells = <1>;
+               };
+
+               aoss_qmp: qmp@c300000 {
+                       compatible = "qcom,sc7180-aoss-qmp";
+                       reg = <0 0x0c300000 0 0x100000>;
+                       interrupts = <GIC_SPI 389 IRQ_TYPE_EDGE_RISING>;
+                       mboxes = <&apss_shared 0>;
+
+                       #clock-cells = <0>;
+                       #power-domain-cells = <1>;
+               };
+
+               spmi_bus: spmi@c440000 {
+                       compatible = "qcom,spmi-pmic-arb";
+                       reg = <0 0x0c440000 0 0x1100>,
+                             <0 0x0c600000 0 0x2000000>,
+                             <0 0x0e600000 0 0x100000>,
+                             <0 0x0e700000 0 0xa0000>,
+                             <0 0x0c40a000 0 0x26000>;
+                       reg-names = "core", "chnls", "obsrvr", "intr", "cnfg";
+                       interrupt-names = "periph_irq";
+                       interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>;
+                       qcom,ee = <0>;
+                       qcom,channel = <0>;
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       interrupt-controller;
+                       #interrupt-cells = <4>;
+                       cell-index = <0>;
+               };
+
+               apps_smmu: iommu@15000000 {
+                       compatible = "qcom,sc7180-smmu-500", "arm,mmu-500";
+                       reg = <0 0x15000000 0 0x100000>;
+                       #iommu-cells = <2>;
+                       #global-interrupts = <1>;
+                       interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 104 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 105 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 106 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 107 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 108 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 111 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 185 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 187 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 188 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 192 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>,
+                                    <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>,
+                                    <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 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>,
+                                    <GIC_SPI 406 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 411 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 412 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               intc: interrupt-controller@17a00000 {
+                       compatible = "arm,gic-v3";
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       #interrupt-cells = <3>;
+                       interrupt-controller;
+                       reg = <0 0x17a00000 0 0x10000>,     /* GICD */
+                             <0 0x17a60000 0 0x100000>;    /* GICR * 8 */
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+
+                       msi-controller@17a40000 {
+                               compatible = "arm,gic-v3-its";
+                               msi-controller;
+                               #msi-cells = <1>;
+                               reg = <0 0x17a40000 0 0x20000>;
+                               status = "disabled";
+                       };
+               };
+
+               apss_shared: mailbox@17c00000 {
+                       compatible = "qcom,sc7180-apss-shared";
+                       reg = <0 0x17c00000 0 0x10000>;
+                       #mbox-cells = <1>;
+               };
+
+               watchdog@17c10000 {
+                       compatible = "qcom,apss-wdt-sc7180", "qcom,kpss-wdt";
+                       reg = <0 0x17c10000 0 0x1000>;
+                       clocks = <&sleep_clk>;
+               };
+
+               timer@17c20000{
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       compatible = "arm,armv7-timer-mem";
+                       reg = <0 0x17c20000 0 0x1000>;
+
+                       frame@17c21000 {
+                               frame-number = <0>;
+                               interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+                                            <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0 0x17c21000 0 0x1000>,
+                                     <0 0x17c22000 0 0x1000>;
+                       };
+
+                       frame@17c23000 {
+                               frame-number = <1>;
+                               interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0 0x17c23000 0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c25000 {
+                               frame-number = <2>;
+                               interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0 0x17c25000 0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c27000 {
+                               frame-number = <3>;
+                               interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0 0x17c27000 0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c29000 {
+                               frame-number = <4>;
+                               interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0 0x17c29000 0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c2b000 {
+                               frame-number = <5>;
+                               interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0 0x17c2b000 0 0x1000>;
+                               status = "disabled";
+                       };
+
+                       frame@17c2d000 {
+                               frame-number = <6>;
+                               interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
+                               reg = <0 0x17c2d000 0 0x1000>;
+                               status = "disabled";
+                       };
+               };
+
+               apps_rsc: rsc@18200000 {
+                       compatible = "qcom,rpmh-rsc";
+                       reg = <0 0x18200000 0 0x10000>,
+                             <0 0x18210000 0 0x10000>,
+                             <0 0x18220000 0 0x10000>;
+                       reg-names = "drv-0", "drv-1", "drv-2";
+                       interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                       qcom,tcs-offset = <0xd00>;
+                       qcom,drv-id = <2>;
+                       qcom,tcs-config = <ACTIVE_TCS  2>,
+                                         <SLEEP_TCS   3>,
+                                         <WAKE_TCS    3>,
+                                         <CONTROL_TCS 1>;
+
+                       rpmhcc: clock-controller {
+                               compatible = "qcom,sc7180-rpmh-clk";
+                               clocks = <&xo_board>;
+                               clock-names = "xo";
+                               #clock-cells = <1>;
+                       };
+
+                       rpmhpd: power-controller {
+                               compatible = "qcom,sc7180-rpmhpd";
+                               #power-domain-cells = <1>;
+                               operating-points-v2 = <&rpmhpd_opp_table>;
+
+                               rpmhpd_opp_table: opp-table {
+                                       compatible = "operating-points-v2";
+
+                                       rpmhpd_opp_ret: opp1 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
+                                       };
+
+                                       rpmhpd_opp_min_svs: opp2 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+                                       };
+
+                                       rpmhpd_opp_low_svs: opp3 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+                                       };
+
+                                       rpmhpd_opp_svs: opp4 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+                                       };
+
+                                       rpmhpd_opp_svs_l1: opp5 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+                                       };
+
+                                       rpmhpd_opp_svs_l2: opp6 {
+                                               opp-level = <224>;
+                                       };
+
+                                       rpmhpd_opp_nom: opp7 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+                                       };
+
+                                       rpmhpd_opp_nom_l1: opp8 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+                                       };
+
+                                       rpmhpd_opp_nom_l2: opp9 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
+                                       };
+
+                                       rpmhpd_opp_turbo: opp10 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+                                       };
+
+                                       rpmhpd_opp_turbo_l1: opp11 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+                                       };
+                               };
+                       };
+               };
+
+               cpufreq_hw: cpufreq@18323000 {
+                       compatible = "qcom,cpufreq-hw";
+                       reg = <0 0x18323000 0 0x1400>, <0 0x18325800 0 0x1400>;
+                       reg-names = "freq-domain0", "freq-domain1";
+
+                       clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>;
+                       clock-names = "xo", "alternate";
+
+                       #freq-domain-cells = <1>;
+               };
+       };
+
+       thermal-zones {
+               cpu0-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 1>;
+
+                       trips {
+                               cpu0_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu0_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu0_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu0_alert0>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu0_alert1>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu1-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 2>;
+
+                       trips {
+                               cpu1_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu1_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu1_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu1_alert0>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu1_alert1>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu2-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 3>;
+
+                       trips {
+                               cpu2_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu2_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu2_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu2_alert0>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu2_alert1>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu3-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 4>;
+
+                       trips {
+                               cpu3_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu3_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu3_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu3_alert0>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu3_alert1>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu4-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 5>;
+
+                       trips {
+                               cpu4_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu4_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu4_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu4_alert0>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu4_alert1>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu5-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 6>;
+
+                       trips {
+                               cpu5_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu5_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu5_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu5_alert0>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu5_alert1>;
+                                       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>,
+                                                        <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu6-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 9>;
+
+                       trips {
+                               cpu6_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu6_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu6_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu6_alert0>;
+                                       cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu6_alert1>;
+                                       cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu7-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 10>;
+
+                       trips {
+                               cpu7_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu7_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu7_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu7_alert0>;
+                                       cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu7_alert1>;
+                                       cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu8-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 11>;
+
+                       trips {
+                               cpu8_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu8_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu8_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu8_alert0>;
+                                       cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu8_alert1>;
+                                       cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               cpu9-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 12>;
+
+                       trips {
+                               cpu9_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu9_alert1: trip-point1 {
+                                       temperature = <95000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               cpu9_crit: cpu_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <1000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&cpu9_alert0>;
+                                       cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                               map1 {
+                                       trip = <&cpu9_alert1>;
+                                       cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>,
+                                                        <&CPU7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
+               };
+
+               aoss0-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 0>;
+
+                       trips {
+                               aoss0_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               cpuss0-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 7>;
+
+                       trips {
+                               cpuss0_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                               cpuss0_crit: cluster0_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               cpuss1-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 8>;
+
+                       trips {
+                               cpuss1_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                               cpuss1_crit: cluster0_crit {
+                                       temperature = <110000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+               };
+
+               gpuss0-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 13>;
+
+                       trips {
+                               gpuss0_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               gpuss1-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens0 14>;
+
+                       trips {
+                               gpuss1_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               aoss1-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 0>;
+
+                       trips {
+                               aoss1_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               cwlan-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 1>;
+
+                       trips {
+                               cwlan_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               audio-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 2>;
+
+                       trips {
+                               audio_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               ddr-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 3>;
+
+                       trips {
+                               ddr_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               q6-hvx-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 4>;
+
+                       trips {
+                               q6_hvx_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               camera-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 5>;
+
+                       trips {
+                               camera_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               mdm-core-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 6>;
+
+                       trips {
+                               mdm_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               mdm-dsp-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 7>;
+
+                       trips {
+                               mdm_dsp_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               npu-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 8>;
+
+                       trips {
+                               npu_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+
+               video-thermal {
+                       polling-delay-passive = <250>;
+                       polling-delay = <1000>;
+
+                       thermal-sensors = <&tsens1 9>;
+
+                       trips {
+                               video_alert0: trip-point0 {
+                                       temperature = <90000>;
+                                       hysteresis = <2000>;
+                                       type = "hot";
+                               };
+                       };
+               };
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 1 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 2 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 3 IRQ_TYPE_LEVEL_LOW>,
+                            <GIC_PPI 0 IRQ_TYPE_LEVEL_LOW>;
+       };
+};
index 9a4ff57..7b53b3c 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 */
@@ -651,6 +650,20 @@ ap_ts_i2c: &i2c14 {
        status = "okay";
 };
 
+&spi5 {
+       status = "okay";
+
+       tpm@0 {
+               compatible = "google,cr50";
+               reg = <0>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&h1_ap_int_odl>;
+               spi-max-frequency = <800000>;
+               interrupt-parent = <&tlmm>;
+               interrupts = <129 IRQ_TYPE_EDGE_RISING>;
+       };
+};
+
 &spi10 {
        status = "okay";
 
index d100f46..eb77aaa 100644 (file)
 &adsp_pas {
        status = "okay";
 
-       firmware-name = "qcom/db845c/adsp.mdt";
+       firmware-name = "qcom/sdm845/adsp.mdt";
 };
 
 &apps_rsc {
 
 &cdsp_pas {
        status = "okay";
-       firmware-name = "qcom/db845c/cdsp.mdt";
+       firmware-name = "qcom/sdm845/cdsp.mdt";
 };
 
 &gcc {
                           <GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
 };
 
+&gpu {
+       zap-shader {
+               memory-region = <&gpu_mem>;
+               firmware-name = "qcom/sdm845/a630_zap.mbn";
+       };
+};
+
+&mss_pil {
+       status = "okay";
+       firmware-name = "qcom/sdm845/mba.mbn", "qcom/sdm845/modem.mbn";
+};
+
 &pm8998_gpio {
        vol_up_pin_a: vol-up-active {
                pins = "gpio6";
        vdd-1.8-xo-supply = <&vreg_l7a_1p8>;
        vdd-1.3-rfa-supply = <&vreg_l17a_1p3>;
        vdd-3.3-ch0-supply = <&vreg_l25a_3p3>;
+
+       qcom,snoc-host-cap-8bit-quirk;
 };
 
 /* PINCTRL - additions to nodes defined in sdm845.dtsi */
index c57548b..09ad37b 100644 (file)
                           <GCC_LPASS_SWAY_CLK>;
 };
 
+&gpu {
+       zap-shader {
+               memory-region = <&gpu_mem>;
+               firmware-name = "qcom/sdm845/a630_zap.mbn";
+       };
+};
+
 &i2c10 {
        status = "okay";
        clock-frequency = <400000>;
index ddb1f23..d42302b 100644 (file)
                        };
                };
 
-               cache-controller@1100000 {
+               system-cache-controller@1100000 {
                        compatible = "qcom,sdm845-llcc";
                        reg = <0 0x01100000 0 0x200000>, <0 0x01300000 0 0x50000>;
                        reg-names = "llcc_base", "llcc_broadcast_base";
                        lanes-per-direction = <2>;
                        power-domains = <&gcc UFS_PHY_GDSC>;
                        #reset-cells = <1>;
+                       resets = <&gcc GCC_UFS_PHY_BCR>;
+                       reset-names = "rst";
 
                        iommus = <&apps_smmu 0x100 0xf>;
 
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        gpio-ranges = <&tlmm 0 0 150>;
+                       wakeup-parent = <&pdc_intc>;
 
                        qspi_clk: qspi-clk {
                                pinmux {
                        };
                };
 
-               gpu@5000000 {
+               gpu: gpu@5000000 {
                        compatible = "qcom,adreno-630.2", "qcom,adreno";
                        #stream-id-cells = <16>;
 
 
                        qcom,gmu = <&gmu>;
 
-                       zap_shader: zap-shader {
-                               memory-region = <&gpu_mem>;
-                       };
-
                        gpu_opp_table: opp-table {
                                compatible = "operating-points-v2";
 
                        #power-domain-cells = <1>;
                };
 
+               pdc_intc: interrupt-controller@b220000 {
+                       compatible = "qcom,sdm845-pdc", "qcom,pdc";
+                       reg = <0 0x0b220000 0 0x30000>;
+                       qcom,pdc-ranges = <0 480 94>, <94 609 15>, <115 630 7>;
+                       #interrupt-cells = <2>;
+                       interrupt-parent = <&intc>;
+                       interrupt-controller;
+               };
+
                pdc_reset: reset-controller@b2e0000 {
                        compatible = "qcom,sdm845-pdc-global";
                        reg = <0 0x0b2e0000 0 0x20000>;
                        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";
+                       interrupts = <GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow", "critical";
                        #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";
+                       interrupts = <GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "uplow", "critical";
                        #thermal-sensor-cells = <1>;
                };
 
                              <0 0x17a60000 0 0x100000>;    /* GICR * 8 */
                        interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
 
-                       gic-its@17a40000 {
+                       msi-controller@17a40000 {
                                compatible = "arm,gic-v3-its";
                                msi-controller;
                                #msi-cells = <1>;
index 13dc619..b255be3 100644 (file)
                           <GCC_QSPI_CNOC_PERIPH_AHB_CLK>;
 };
 
+&gpu {
+       zap-shader {
+               memory-region = <&gpu_mem>;
+               firmware-name = "qcom/LENOVO/81JL/qcdxkmsuc850.mbn";
+       };
+};
+
 &i2c1 {
        status = "okay";
        clock-frequency = <400000>;
index aa5de42..8ab1661 100644 (file)
@@ -7,6 +7,7 @@
 /dts-v1/;
 
 #include <dt-bindings/regulator/qcom,rpmh-regulator.h>
+#include <dt-bindings/gpio/gpio.h>
 #include "sm8150.dtsi"
 #include "pm8150.dtsi"
 #include "pm8150b.dtsi"
        };
 };
 
+&remoteproc_adsp {
+       status = "okay";
+};
+
+&remoteproc_cdsp {
+       status = "okay";
+};
+
+&remoteproc_slpi {
+       status = "okay";
+};
+
 &tlmm {
        gpio-reserved-ranges = <0 4>, <126 4>;
 };
 &uart2 {
        status = "okay";
 };
+
+&ufs_mem_hc {
+       status = "okay";
+
+       reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>;
+
+       vcc-supply = <&vreg_l10a_2p5>;
+       vcc-max-microamp = <750000>;
+       vccq-supply = <&vreg_l9a_1p2>;
+       vccq-max-microamp = <700000>;
+       vccq2-supply = <&vreg_s4a_1p8>;
+       vccq2-max-microamp = <750000>;
+};
+
+&ufs_mem_phy {
+       status = "okay";
+
+       vdda-phy-supply = <&vdda_ufs_2ln_core_1>;
+       vdda-max-microamp = <90200>;
+       vdda-pll-supply = <&vreg_l3c_1p2>;
+       vdda-pll-max-microamp = <19000>;
+};
index 8f23fca..141c21d 100644 (file)
@@ -5,8 +5,11 @@
  */
 
 #include <dt-bindings/interrupt-controller/arm-gic.h>
+#include <dt-bindings/power/qcom-aoss-qmp.h>
+#include <dt-bindings/power/qcom-rpmpd.h>
 #include <dt-bindings/soc/qcom,rpmh-rsc.h>
 #include <dt-bindings/clock/qcom,rpmh.h>
+#include <dt-bindings/clock/qcom,gcc-sm8150.h>
 
 / {
        interrupt-parent = <&intc>;
@@ -42,6 +45,7 @@
                        reg = <0x0 0x0>;
                        enable-method = "psci";
                        next-level-cache = <&L2_0>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
                        L2_0: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
@@ -57,6 +61,7 @@
                        reg = <0x0 0x100>;
                        enable-method = "psci";
                        next-level-cache = <&L2_100>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
                        L2_100: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
@@ -70,6 +75,7 @@
                        reg = <0x0 0x200>;
                        enable-method = "psci";
                        next-level-cache = <&L2_200>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
                        L2_200: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
@@ -82,6 +88,7 @@
                        reg = <0x0 0x300>;
                        enable-method = "psci";
                        next-level-cache = <&L2_300>;
+                       qcom,freq-domain = <&cpufreq_hw 0>;
                        L2_300: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
                        reg = <0x0 0x400>;
                        enable-method = "psci";
                        next-level-cache = <&L2_400>;
+                       qcom,freq-domain = <&cpufreq_hw 1>;
                        L2_400: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
                        reg = <0x0 0x500>;
                        enable-method = "psci";
                        next-level-cache = <&L2_500>;
+                       qcom,freq-domain = <&cpufreq_hw 1>;
                        L2_500: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
                        reg = <0x0 0x600>;
                        enable-method = "psci";
                        next-level-cache = <&L2_600>;
+                       qcom,freq-domain = <&cpufreq_hw 1>;
                        L2_600: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
                        reg = <0x0 0x700>;
                        enable-method = "psci";
                        next-level-cache = <&L2_700>;
+                       qcom,freq-domain = <&cpufreq_hw 2>;
                        L2_700: l2-cache {
                                compatible = "cache";
                                next-level-cache = <&L3_0>;
                hwlocks = <&tcsr_mutex 3>;
        };
 
+       smp2p-cdsp {
+               compatible = "qcom,smp2p";
+               qcom,smem = <94>, <432>;
+
+               interrupts = <GIC_SPI 576 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apss_shared 6>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <5>;
+
+               cdsp_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               cdsp_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-lpass {
+               compatible = "qcom,smp2p";
+               qcom,smem = <443>, <429>;
+
+               interrupts = <GIC_SPI 158 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apss_shared 10>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <2>;
+
+               adsp_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               adsp_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-mpss {
+               compatible = "qcom,smp2p";
+               qcom,smem = <435>, <428>;
+
+               interrupts = <GIC_SPI 451 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apss_shared 14>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <1>;
+
+               modem_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               modem_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
+       smp2p-slpi {
+               compatible = "qcom,smp2p";
+               qcom,smem = <481>, <430>;
+
+               interrupts = <GIC_SPI 172 IRQ_TYPE_EDGE_RISING>;
+
+               mboxes = <&apss_shared 26>;
+
+               qcom,local-pid = <0>;
+               qcom,remote-pid = <3>;
+
+               slpi_smp2p_out: master-kernel {
+                       qcom,entry-name = "master-kernel";
+                       #qcom,smem-state-cells = <1>;
+               };
+
+               slpi_smp2p_in: slave-kernel {
+                       qcom,entry-name = "slave-kernel";
+
+                       interrupt-controller;
+                       #interrupt-cells = <2>;
+               };
+       };
+
        soc: soc@0 {
                #address-cells = <2>;
                #size-cells = <2>;
                        compatible = "qcom,geni-se-qup";
                        reg = <0x0 0x00ac0000 0x0 0x6000>;
                        clock-names = "m-ahb", "s-ahb";
-                       clocks = <&gcc 123>,
-                                <&gcc 124>;
+                       clocks = <&gcc GCC_QUPV3_WRAP_1_M_AHB_CLK>,
+                                <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>;
                        #address-cells = <2>;
                        #size-cells = <2>;
                        ranges;
                                compatible = "qcom,geni-debug-uart";
                                reg = <0x0 0x00a90000 0x0 0x4000>;
                                clock-names = "se";
-                               clocks = <&gcc 105>;
+                               clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>;
                                interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>;
                                status = "disabled";
                        };
                };
 
+               ufs_mem_hc: ufshc@1d84000 {
+                       compatible = "qcom,sm8150-ufshc", "qcom,ufshc",
+                                    "jedec,ufs-2.0";
+                       reg = <0 0x01d84000 0 0x2500>;
+                       interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>;
+                       phys = <&ufs_mem_phy_lanes>;
+                       phy-names = "ufsphy";
+                       lanes-per-direction = <2>;
+                       #reset-cells = <1>;
+                       resets = <&gcc GCC_UFS_PHY_BCR>;
+                       reset-names = "rst";
+
+                       clock-names =
+                               "core_clk",
+                               "bus_aggr_clk",
+                               "iface_clk",
+                               "core_clk_unipro",
+                               "ref_clk",
+                               "tx_lane0_sync_clk",
+                               "rx_lane0_sync_clk",
+                               "rx_lane1_sync_clk";
+                       clocks =
+                               <&gcc GCC_UFS_PHY_AXI_CLK>,
+                               <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>,
+                               <&gcc GCC_UFS_PHY_AHB_CLK>,
+                               <&gcc GCC_UFS_PHY_UNIPRO_CORE_CLK>,
+                               <&rpmhcc RPMH_CXO_CLK>,
+                               <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>,
+                               <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>,
+                               <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>;
+                       freq-table-hz =
+                               <37500000 300000000>,
+                               <0 0>,
+                               <0 0>,
+                               <37500000 300000000>,
+                               <0 0>,
+                               <0 0>,
+                               <0 0>,
+                               <0 0>;
+
+                       status = "disabled";
+               };
+
+               ufs_mem_phy: phy@1d87000 {
+                       compatible = "qcom,sm8150-qmp-ufs-phy";
+                       reg = <0 0x01d87000 0 0x1c0>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       clock-names = "ref",
+                                     "ref_aux";
+                       clocks = <&gcc GCC_UFS_MEM_CLKREF_CLK>,
+                                <&gcc GCC_UFS_PHY_PHY_AUX_CLK>;
+
+                       resets = <&ufs_mem_hc 0>;
+                       reset-names = "ufsphy";
+                       status = "disabled";
+
+                       ufs_mem_phy_lanes: lanes@1d87400 {
+                               reg = <0 0x01d87400 0 0x108>,
+                                     <0 0x01d87600 0 0x1e0>,
+                                     <0 0x01d87c00 0 0x1dc>,
+                                     <0 0x01d87800 0 0x108>,
+                                     <0 0x01d87a00 0 0x1e0>;
+                               #phy-cells = <0>;
+                       };
+               };
+
                tcsr_mutex_regs: syscon@1f40000 {
                        compatible = "syscon";
                        reg = <0x0 0x01f40000 0x0 0x40000>;
                };
 
+               remoteproc_slpi: remoteproc@2400000 {
+                       compatible = "qcom,sm8150-slpi-pas";
+                       reg = <0x0 0x02400000 0x0 0x4040>;
+
+                       interrupts-extended = <&intc GIC_SPI 494 IRQ_TYPE_EDGE_RISING>,
+                                             <&slpi_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&slpi_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&slpi_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&slpi_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready",
+                                         "handover", "stop-ack";
+
+                       clocks = <&rpmhcc RPMH_CXO_CLK>;
+                       clock-names = "xo";
+
+                       power-domains = <&aoss_qmp AOSS_QMP_LS_SLPI>,
+                                       <&rpmhpd 3>,
+                                       <&rpmhpd 2>;
+                       power-domain-names = "load_state", "lcx", "lmx";
+
+                       memory-region = <&slpi_mem>;
+
+                       qcom,smem-states = <&slpi_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       status = "disabled";
+
+                       glink-edge {
+                               interrupts = <GIC_SPI 170 IRQ_TYPE_EDGE_RISING>;
+                               label = "dsps";
+                               qcom,remote-pid = <3>;
+                               mboxes = <&apss_shared 24>;
+                       };
+               };
+
                tlmm: pinctrl@3100000 {
                        compatible = "qcom,sm8150-pinctrl";
                        reg = <0x0 0x03100000 0x0 0x300000>,
                        #interrupt-cells = <2>;
                };
 
+               remoteproc_mpss: remoteproc@4080000 {
+                       compatible = "qcom,sm8150-mpss-pas";
+                       reg = <0x0 0x04080000 0x0 0x4040>;
+
+                       interrupts-extended = <&intc GIC_SPI 266 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 3 IRQ_TYPE_EDGE_RISING>,
+                                             <&modem_smp2p_in 7 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready", "handover",
+                                         "stop-ack", "shutdown-ack";
+
+                       clocks = <&rpmhcc RPMH_CXO_CLK>;
+                       clock-names = "xo";
+
+                       power-domains = <&aoss_qmp AOSS_QMP_LS_MODEM>,
+                                       <&rpmhpd 7>,
+                                       <&rpmhpd 0>;
+                       power-domain-names = "load_state", "cx", "mss";
+
+                       memory-region = <&mpss_mem>;
+
+                       qcom,smem-states = <&modem_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       glink-edge {
+                               interrupts = <GIC_SPI 449 IRQ_TYPE_EDGE_RISING>;
+                               label = "modem";
+                               qcom,remote-pid = <1>;
+                               mboxes = <&apss_shared 12>;
+                       };
+               };
+
+               remoteproc_cdsp: remoteproc@8300000 {
+                       compatible = "qcom,sm8150-cdsp-pas";
+                       reg = <0x0 0x08300000 0x0 0x4040>;
+
+                       interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>,
+                                             <&cdsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&cdsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&cdsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&cdsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready",
+                                         "handover", "stop-ack";
+
+                       clocks = <&rpmhcc RPMH_CXO_CLK>;
+                       clock-names = "xo";
+
+                       power-domains = <&aoss_qmp AOSS_QMP_LS_CDSP>,
+                                       <&rpmhpd 7>;
+                       power-domain-names = "load_state", "cx";
+
+                       memory-region = <&cdsp_mem>;
+
+                       qcom,smem-states = <&cdsp_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       status = "disabled";
+
+                       glink-edge {
+                               interrupts = <GIC_SPI 574 IRQ_TYPE_EDGE_RISING>;
+                               label = "cdsp";
+                               qcom,remote-pid = <5>;
+                               mboxes = <&apss_shared 4>;
+                       };
+               };
+
                aoss_qmp: power-controller@c300000 {
                        compatible = "qcom,sm8150-aoss-qmp";
                        reg = <0x0 0x0c300000 0x0 0x100000>;
                        cell-index = <0>;
                };
 
+               remoteproc_adsp: remoteproc@17300000 {
+                       compatible = "qcom,sm8150-adsp-pas";
+                       reg = <0x0 0x17300000 0x0 0x4040>;
+
+                       interrupts-extended = <&intc GIC_SPI 162 IRQ_TYPE_EDGE_RISING>,
+                                             <&adsp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>,
+                                             <&adsp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>,
+                                             <&adsp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>,
+                                             <&adsp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "wdog", "fatal", "ready",
+                                         "handover", "stop-ack";
+
+                       clocks = <&rpmhcc RPMH_CXO_CLK>;
+                       clock-names = "xo";
+
+                       power-domains = <&aoss_qmp AOSS_QMP_LS_LPASS>,
+                                       <&rpmhpd 7>;
+                       power-domain-names = "load_state", "cx";
+
+                       memory-region = <&adsp_mem>;
+
+                       qcom,smem-states = <&adsp_smp2p_out 0>;
+                       qcom,smem-state-names = "stop";
+
+                       status = "disabled";
+
+                       glink-edge {
+                               interrupts = <GIC_SPI 156 IRQ_TYPE_EDGE_RISING>;
+                               label = "lpass";
+                               qcom,remote-pid = <2>;
+                               mboxes = <&apss_shared 8>;
+                       };
+               };
+
                intc: interrupt-controller@17a00000 {
                        compatible = "arm,gic-v3";
                        interrupt-controller;
                        #mbox-cells = <1>;
                };
 
+               watchdog@17c10000 {
+                       compatible = "qcom,apss-wdt-sm8150", "qcom,kpss-wdt";
+                       reg = <0 0x17c10000 0 0x1000>;
+                       clocks = <&sleep_clk>;
+               };
+
                timer@17c20000 {
                        #address-cells = <2>;
                        #size-cells = <2>;
                                clock-names = "xo";
                                clocks = <&xo_board>;
                        };
+
+                       rpmhpd: power-controller {
+                               compatible = "qcom,sm8150-rpmhpd";
+                               #power-domain-cells = <1>;
+                               operating-points-v2 = <&rpmhpd_opp_table>;
+
+                               rpmhpd_opp_table: opp-table {
+                                       compatible = "operating-points-v2";
+
+                                       rpmhpd_opp_ret: opp1 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>;
+                                       };
+
+                                       rpmhpd_opp_min_svs: opp2 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>;
+                                       };
+
+                                       rpmhpd_opp_low_svs: opp3 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>;
+                                       };
+
+                                       rpmhpd_opp_svs: opp4 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_SVS>;
+                                       };
+
+                                       rpmhpd_opp_svs_l1: opp5 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>;
+                                       };
+
+                                       rpmhpd_opp_svs_l2: opp6 {
+                                               opp-level = <224>;
+                                       };
+
+                                       rpmhpd_opp_nom: opp7 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_NOM>;
+                                       };
+
+                                       rpmhpd_opp_nom_l1: opp8 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>;
+                                       };
+
+                                       rpmhpd_opp_nom_l2: opp9 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>;
+                                       };
+
+                                       rpmhpd_opp_turbo: opp10 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_TURBO>;
+                                       };
+
+                                       rpmhpd_opp_turbo_l1: opp11 {
+                                               opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>;
+                                       };
+                               };
+                       };
+               };
+
+               cpufreq_hw: cpufreq@18323000 {
+                       compatible = "qcom,cpufreq-hw";
+                       reg = <0 0x18323000 0 0x1400>, <0 0x18325800 0 0x1400>,
+                             <0 0x18327800 0 0x1400>;
+                       reg-names = "freq-domain0", "freq-domain1",
+                                   "freq-domain2";
+
+                       clocks = <&rpmhcc RPMH_CXO_CLK>, <&gcc GPLL0>;
+                       clock-names = "xo", "alternate";
+
+                       #freq-domain-cells = <1>;
                };
        };
 
index 8fdbd22..2153842 100644 (file)
@@ -3,22 +3,21 @@ 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
-dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-salvator-xs.dtb
-dtb-$(CONFIG_ARCH_R8A7795) += r8a7795-es1-salvator-x.dtb r8a7795-es1-h3ulcb.dtb
-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_R8A774C0) += r8a774c0-cat874.dtb r8a774c0-ek874.dtb \
+                              r8a774c0-ek874-idk-2121wr.dtb
+dtb-$(CONFIG_ARCH_R8A7795) += r8a77950-salvator-x.dtb
+dtb-$(CONFIG_ARCH_R8A7795) += r8a77950-ulcb.dtb r8a77950-ulcb-kf.dtb
+dtb-$(CONFIG_ARCH_R8A7795) += r8a77951-salvator-x.dtb r8a77951-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A7795) += r8a77951-ulcb.dtb r8a77951-ulcb-kf.dtb
+dtb-$(CONFIG_ARCH_R8A77950) += r8a77950-salvator-x.dtb
+dtb-$(CONFIG_ARCH_R8A77950) += r8a77950-ulcb.dtb r8a77950-ulcb-kf.dtb
+dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-salvator-x.dtb r8a77951-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77951) += r8a77951-ulcb.dtb r8a77951-ulcb-kf.dtb
+dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-salvator-x.dtb r8a77960-salvator-xs.dtb
+dtb-$(CONFIG_ARCH_R8A77960) += r8a77960-ulcb.dtb r8a77960-ulcb-kf.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
+dtb-$(CONFIG_ARCH_R8A77965) += r8a77965-ulcb.dtb r8a77965-ulcb-kf.dtb
 dtb-$(CONFIG_ARCH_R8A77970) += r8a77970-eagle.dtb r8a77970-v3msk.dtb
 dtb-$(CONFIG_ARCH_R8A77980) += r8a77980-condor.dtb r8a77980-v3hsk.dtb
 dtb-$(CONFIG_ARCH_R8A77990) += r8a77990-ebisu.dtb
index 2c942a7..bd05690 100644 (file)
 
                gpios = <&gpio6 30 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        wlan_en_reg: regulator-wlan_en {
index 34a9f47..8f950da 100644 (file)
                        #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>;
+                       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 R8A774A1_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,r8a774a1-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>;
+                       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 R8A774A1_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a774a1-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>;
+                       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 R8A774A1_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a774a1",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a774a1",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a774a1",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a774a1",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a774a1",
                                     "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>;
+                       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",
                        #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>;
+                       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>,
                        #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>;
+                       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>,
index fe78387..c40ea30 100644 (file)
                        #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>;
+                       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>;
                        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>;
+                       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>;
                        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>;
+                       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>;
                        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>;
+                       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",
                        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>;
+                       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",
                        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>;
+                       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",
                        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>;
+                       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",
                        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>;
+                       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",
                        #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>;
+                       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>,
                        #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>;
+                       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>,
index c99b1de..26aee00 100644 (file)
 
                gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        wlan_en_reg: fixedregulator {
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dts b/arch/arm64/boot/dts/renesas/r8a774c0-ek874-idk-2121wr.dts
new file mode 100644 (file)
index 0000000..a7b27d0
--- /dev/null
@@ -0,0 +1,116 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Device Tree Source for the Silicon Linux RZ/G2E evaluation kit (EK874),
+ * connected to an Advantech IDK-2121WR 21.5" LVDS panel
+ *
+ * Copyright (C) 2019 Renesas Electronics Corp.
+ */
+
+#include "r8a774c0-ek874.dts"
+
+/ {
+       backlight: backlight {
+               compatible = "pwm-backlight";
+               pwms = <&pwm5 0 50000>;
+
+               brightness-levels = <0 4 8 16 32 64 128 255>;
+               default-brightness-level = <6>;
+
+               power-supply = <&reg_12p0v>;
+               enable-gpios = <&gpio6 12 GPIO_ACTIVE_HIGH>;
+       };
+
+       panel-lvds {
+               compatible = "advantech,idk-2121wr", "panel-lvds";
+
+               width-mm = <476>;
+               height-mm = <268>;
+
+               data-mapping = "vesa-24";
+
+               panel-timing {
+                       clock-frequency = <148500000>;
+                       hactive = <1920>;
+                       vactive = <1080>;
+                       hsync-len = <44>;
+                       hfront-porch = <88>;
+                       hback-porch = <148>;
+                       vfront-porch = <4>;
+                       vback-porch = <36>;
+                       vsync-len = <5>;
+               };
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               dual-lvds-odd-pixels;
+                               panel_in0: endpoint {
+                                       remote-endpoint = <&lvds0_out>;
+                               };
+                       };
+
+                       port@1 {
+                               reg = <1>;
+                               dual-lvds-even-pixels;
+                               panel_in1: endpoint {
+                                       remote-endpoint = <&lvds1_out>;
+                               };
+                       };
+               };
+       };
+};
+
+&gpio0 {
+       /*
+        * When GP0_17 is low LVDS[01] are connected to the LVDS connector
+        * When GP0_17 is high LVDS[01] are connected to the LT8918L
+        */
+       lvds-connector-en-gpio{
+               gpio-hog;
+               gpios = <17 GPIO_ACTIVE_HIGH>;
+               output-low;
+               line-name = "lvds-connector-en-gpio";
+       };
+};
+
+&lvds0 {
+       ports {
+               port@1 {
+                       lvds0_out: endpoint {
+                               remote-endpoint = <&panel_in0>;
+                       };
+               };
+       };
+};
+
+&lvds1 {
+       status = "okay";
+
+       clocks = <&cpg CPG_MOD 727>, <&x13_clk>, <&extal_clk>;
+       clock-names = "fck", "dclkin.0", "extal";
+
+       ports {
+               port@1 {
+                       lvds1_out: endpoint {
+                               remote-endpoint = <&panel_in1>;
+                       };
+               };
+       };
+};
+
+&pfc {
+       pwm5_pins: pwm5 {
+               groups = "pwm5_a";
+               function = "pwm5";
+       };
+};
+
+&pwm5 {
+       pinctrl-0 = <&pwm5_pins>;
+       pinctrl-names = "default";
+
+       status = "okay";
+};
index c7bdc36..a53cd5f 100644 (file)
                        #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>;
+                       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 R8A774C0_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,r8a774c0-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>;
+                       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 R8A774C0_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a774c0-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>;
+                       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 R8A774C0_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a774c0",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a774c0",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a774c0",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a774c0",
                                     "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>;
+                       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",
                        #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>;
+                       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 0x40000000>;
                        interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
@@ -6,11 +6,11 @@
  */
 
 /dts-v1/;
-#include "r8a7795-es1.dtsi"
+#include "r8a77950.dtsi"
 #include "salvator-x.dtsi"
 
 / {
-       model = "Renesas Salvator-X board based on r8a7795 ES1.x";
+       model = "Renesas Salvator-X board based on r8a77950";
        compatible = "renesas,salvator-x", "renesas,r8a7795";
 
        memory@48000000 {
@@ -6,11 +6,11 @@
  * Copyright (C) 2017 Cogent Embedded, Inc.
  */
 
-#include "r8a7795-h3ulcb.dts"
+#include "r8a77950-ulcb.dts"
 #include "ulcb-kf.dtsi"
 
 / {
-       model = "Renesas H3ULCB Kingfisher board based on r8a7795 ES2.0+";
+       model = "Renesas H3ULCB Kingfisher board based on r8a77950";
        compatible = "shimafuji,kingfisher", "renesas,h3ulcb",
                     "renesas,r8a7795";
 };
@@ -7,11 +7,11 @@
  */
 
 /dts-v1/;
-#include "r8a7795-es1.dtsi"
+#include "r8a77950.dtsi"
 #include "ulcb.dtsi"
 
 / {
-       model = "Renesas H3ULCB board based on r8a7795 ES1.x";
+       model = "Renesas H3ULCB board based on r8a77950";
        compatible = "renesas,h3ulcb", "renesas,r8a7795";
 
        memory@48000000 {
similarity index 98%
rename from arch/arm64/boot/dts/renesas/r8a7795-es1.dtsi
rename to arch/arm64/boot/dts/renesas/r8a77950.dtsi
index 14d8513..1521649 100644 (file)
@@ -1,11 +1,11 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the R-Car H3 (R8A77950) ES1.x SoC
+ * Device Tree Source for the R-Car H3 (R8A77950) SoC
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
 
-#include "r8a7795.dtsi"
+#include "r8a77951.dtsi"
 
 &audma0 {
        iommus = <&ipmmu_mp1 0>, <&ipmmu_mp1 1>,
@@ -6,11 +6,11 @@
  */
 
 /dts-v1/;
-#include "r8a7795.dtsi"
+#include "r8a77951.dtsi"
 #include "salvator-x.dtsi"
 
 / {
-       model = "Renesas Salvator-X board based on r8a7795 ES2.0+";
+       model = "Renesas Salvator-X board based on r8a77951";
        compatible = "renesas,salvator-x", "renesas,r8a7795";
 
        memory@48000000 {
@@ -1,16 +1,16 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the Salvator-X 2nd version board with R-Car H3 ES2.0
+ * Device Tree Source for the Salvator-X 2nd version board with R-Car H3 ES2.0+
  *
  * Copyright (C) 2015-2017 Renesas Electronics Corp.
  */
 
 /dts-v1/;
-#include "r8a7795.dtsi"
+#include "r8a77951.dtsi"
 #include "salvator-xs.dtsi"
 
 / {
-       model = "Renesas Salvator-X 2nd version board based on r8a7795 ES2.0+";
+       model = "Renesas Salvator-X 2nd version board based on r8a77951";
        compatible = "renesas,salvator-xs", "renesas,r8a7795";
 
        memory@48000000 {
         * - On Salvator-X[S], GP6_3[01] are connected to ADV7482 as irq pins
         *   (when SW31 is the default setting on Salvator-XS).
         * - If SW31 is the default setting, you cannot use USB2.0 ch3 on
-        *   r8a7795 with Salvator-XS.
+        *   r8a77951 with Salvator-XS.
         *   Hence the SW31 setting must be changed like 2) below.
         *   1) Default setting of SW31: ON-ON-OFF-OFF-OFF-OFF:
         *      - Connect GP6_3[01] to ADV7842.
@@ -6,11 +6,11 @@
  * Copyright (C) 2017 Cogent Embedded, Inc.
  */
 
-#include "r8a7795-es1-h3ulcb.dts"
+#include "r8a77951-ulcb.dts"
 #include "ulcb-kf.dtsi"
 
 / {
-       model = "Renesas H3ULCB Kingfisher board based on r8a7795 ES1.x";
+       model = "Renesas H3ULCB Kingfisher board based on r8a77951";
        compatible = "shimafuji,kingfisher", "renesas,h3ulcb",
                     "renesas,r8a7795";
 };
@@ -7,11 +7,11 @@
  */
 
 /dts-v1/;
-#include "r8a7795.dtsi"
+#include "r8a77951.dtsi"
 #include "ulcb.dtsi"
 
 / {
-       model = "Renesas H3ULCB board based on r8a7795 ES2.0+";
+       model = "Renesas H3ULCB board based on r8a77951";
        compatible = "renesas,h3ulcb", "renesas,r8a7795";
 
        memory@48000000 {
similarity index 94%
rename from arch/arm64/boot/dts/renesas/r8a7795.dtsi
rename to arch/arm64/boot/dts/renesas/r8a77951.dtsi
index fde6ec1..a8729eb 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Device Tree Source for the R-Car H3 (R8A77950) SoC
+ * Device Tree Source for the R-Car H3 (R8A77951) SoC
  *
  * Copyright (C) 2015 Renesas Electronics Corp.
  */
                        #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>;
+                       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 R8A7795_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,r8a7795-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>;
+                       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 R8A7795_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7795-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>;
+                       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 R8A7795_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7795-usb-dmac",
                                     "renesas,usb-dmac";
                        reg = <0 0xe6460000 0 0x100>;
-                       interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "ch0", "ch1";
                        clocks = <&cpg CPG_MOD 326>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7795-usb-dmac",
                                     "renesas,usb-dmac";
                        reg = <0 0xe6470000 0 0x100>;
-                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "ch0", "ch1";
                        clocks = <&cpg CPG_MOD 329>;
                        power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a7795",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a7795",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a7795",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a7795",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a7795",
                                     "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>;
+                       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",
                        #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>;
+                       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 0x40000000>;
                        interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
                        #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>;
+                       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 0x40000000>;
                        interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
@@ -6,11 +6,11 @@
  */
 
 /dts-v1/;
-#include "r8a7796.dtsi"
+#include "r8a77960.dtsi"
 #include "salvator-x.dtsi"
 
 / {
-       model = "Renesas Salvator-X board based on r8a7796";
+       model = "Renesas Salvator-X board based on r8a77960";
        compatible = "renesas,salvator-x", "renesas,r8a7796";
 
        memory@48000000 {
@@ -6,11 +6,11 @@
  */
 
 /dts-v1/;
-#include "r8a7796.dtsi"
+#include "r8a77960.dtsi"
 #include "salvator-xs.dtsi"
 
 / {
-       model = "Renesas Salvator-X 2nd version board based on r8a7796";
+       model = "Renesas Salvator-X 2nd version board based on r8a77960";
        compatible = "renesas,salvator-xs", "renesas,r8a7796";
 
        memory@48000000 {
@@ -6,11 +6,11 @@
  * Copyright (C) 2017 Cogent Embedded, Inc.
  */
 
-#include "r8a7796-m3ulcb.dts"
+#include "r8a77960-ulcb.dts"
 #include "ulcb-kf.dtsi"
 
 / {
-       model = "Renesas M3ULCB Kingfisher board based on r8a7796";
+       model = "Renesas M3ULCB Kingfisher board based on r8a77960";
        compatible = "shimafuji,kingfisher", "renesas,m3ulcb",
                     "renesas,r8a7796";
 };
@@ -7,11 +7,11 @@
  */
 
 /dts-v1/;
-#include "r8a7796.dtsi"
+#include "r8a77960.dtsi"
 #include "ulcb.dtsi"
 
 / {
-       model = "Renesas M3ULCB board based on r8a7796";
+       model = "Renesas M3ULCB board based on r8a77960";
        compatible = "renesas,m3ulcb", "renesas,r8a7796";
 
        memory@48000000 {
similarity index 94%
rename from arch/arm64/boot/dts/renesas/r8a7796.dtsi
rename to arch/arm64/boot/dts/renesas/r8a77960.dtsi
index b9db882..60f156c 100644 (file)
                        #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>;
+                       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 R8A7796_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,r8a7796-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>;
+                       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 R8A7796_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a7796-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>;
+                       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 R8A7796_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a7796",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a7796",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a7796",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a7796",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a7796",
                                     "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>;
+                       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",
                        #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>;
+                       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>,
                        #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>;
+                       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>,
index 64466c8..be3824b 100644 (file)
                ranges;
 
                rwdt: watchdog@e6020000 {
+                       compatible = "renesas,r8a77961-wdt",
+                                    "renesas,rcar-gen3-wdt";
                        reg = <0 0xe6020000 0 0x0c>;
-                       /* placeholder */
+                       clocks = <&cpg CPG_MOD 402>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 402>;
+                       status = "disabled";
+               };
+
+               gpio0: gpio@e6050000 {
+                       compatible = "renesas,gpio-r8a77961",
+                                    "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 R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 912>;
+               };
+
+               gpio1: gpio@e6051000 {
+                       compatible = "renesas,gpio-r8a77961",
+                                    "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 R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 911>;
                };
 
                gpio2: gpio@e6052000 {
+                       compatible = "renesas,gpio-r8a77961",
+                                    "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;
-                       /* placeholder */
+                       clocks = <&cpg CPG_MOD 910>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 910>;
                };
 
                gpio3: gpio@e6053000 {
+                       compatible = "renesas,gpio-r8a77961",
+                                    "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;
-                       /* placeholder */
+                       clocks = <&cpg CPG_MOD 909>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 909>;
                };
 
                gpio4: gpio@e6054000 {
+                       compatible = "renesas,gpio-r8a77961",
+                                    "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;
-                       /* placeholder */
+                       clocks = <&cpg CPG_MOD 908>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 908>;
                };
 
                gpio5: gpio@e6055000 {
+                       compatible = "renesas,gpio-r8a77961",
+                                    "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;
-                       /* placeholder */
+                       clocks = <&cpg CPG_MOD 907>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 907>;
                };
 
                gpio6: gpio@e6055400 {
+                       compatible = "renesas,gpio-r8a77961",
+                                    "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;
-                       /* placeholder */
+                       clocks = <&cpg CPG_MOD 906>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 906>;
+               };
+
+               gpio7: gpio@e6055800 {
+                       compatible = "renesas,gpio-r8a77961",
+                                    "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 R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 905>;
                };
 
                pfc: pin-controller@e6060000 {
                        /* placeholder */
                };
 
+               i2c0: i2c@e6500000 {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       compatible = "renesas,i2c-r8a77961",
+                                    "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 R8A77961_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-r8a77961",
+                                    "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 R8A77961_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-r8a77961",
+                                    "renesas,rcar-gen3-i2c";
                        reg = <0 0xe6510000 0 0x40>;
-                       /* placeholder */
+                       interrupts = <GIC_SPI 286 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 929>;
+                       power-domains = <&sysc R8A77961_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-r8a77961",
+                                    "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 R8A77961_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-r8a77961",
+                                    "renesas,rcar-gen3-i2c";
                        reg = <0 0xe66d8000 0 0x40>;
-                       /* placeholder */
+                       interrupts = <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 927>;
+                       power-domains = <&sysc R8A77961_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-r8a77961",
+                                    "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 R8A77961_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-r8a77961",
+                                    "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 R8A77961_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-r8a77961",
+                                    "renesas,rcar-gen3-iic",
+                                    "renesas,rmobile-iic";
                        reg = <0 0xe60b0000 0 0x425>;
-                       /* placeholder */
+                       interrupts = <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 926>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 926>;
+                       dmas = <&dmac0 0x11>, <&dmac0 0x10>;
+                       dma-names = "tx", "rx";
+                       status = "disabled";
                };
 
+
                hscif1: serial@e6550000 {
                        reg = <0 0xe6550000 0 0x60>;
                        /* placeholder */
                        /* placeholder */
                };
 
+               dmac0: dma-controller@e6700000 {
+                       compatible = "renesas,dmac-r8a77961",
+                                    "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 R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 219>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               dmac1: dma-controller@e7300000 {
+                       compatible = "renesas,dmac-r8a77961",
+                                    "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 R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 218>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
+               dmac2: dma-controller@e7310000 {
+                       compatible = "renesas,dmac-r8a77961",
+                                    "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 R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 217>;
+                       #dma-cells = <1>;
+                       dma-channels = <16>;
+               };
+
                avb: ethernet@e6800000 {
+                       compatible = "renesas,etheravb-r8a77961",
+                                    "renesas,etheravb-rcar-gen3";
                        reg = <0 0xe6800000 0 0x800>, <0 0xe6a00000 0 0x10000>;
+                       interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 48 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 61 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 63 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupt-names = "ch0", "ch1", "ch2", "ch3",
+                                         "ch4", "ch5", "ch6", "ch7",
+                                         "ch8", "ch9", "ch10", "ch11",
+                                         "ch12", "ch13", "ch14", "ch15",
+                                         "ch16", "ch17", "ch18", "ch19",
+                                         "ch20", "ch21", "ch22", "ch23",
+                                         "ch24";
+                       clocks = <&cpg CPG_MOD 812>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 812>;
+                       phy-mode = "rgmii";
                        #address-cells = <1>;
                        #size-cells = <0>;
-                       /* placeholder */
+                       status = "disabled";
                };
 
                pwm1: pwm@e6e31000 {
                };
 
                sdhi0: sd@ee100000 {
+                       compatible = "renesas,sdhi-r8a77961",
+                                    "renesas,rcar-gen3-sdhi";
                        reg = <0 0xee100000 0 0x2000>;
-                       /* placeholder */
+                       interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 314>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 314>;
+                       status = "disabled";
+               };
+
+               sdhi1: sd@ee120000 {
+                       compatible = "renesas,sdhi-r8a77961",
+                                    "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 R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 313>;
+                       status = "disabled";
                };
 
                sdhi2: sd@ee140000 {
+                       compatible = "renesas,sdhi-r8a77961",
+                                    "renesas,rcar-gen3-sdhi";
                        reg = <0 0xee140000 0 0x2000>;
-                       /* placeholder */
+                       interrupts = <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 312>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 312>;
+                       status = "disabled";
                };
 
                sdhi3: sd@ee160000 {
+                       compatible = "renesas,sdhi-r8a77961",
+                                    "renesas,rcar-gen3-sdhi";
                        reg = <0 0xee160000 0 0x2000>;
-                       /* placeholder */
+                       interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>;
+                       clocks = <&cpg CPG_MOD 311>;
+                       max-frequency = <200000000>;
+                       power-domains = <&sysc R8A77961_PD_ALWAYS_ON>;
+                       resets = <&cpg 311>;
+                       status = "disabled";
                };
 
                gic: interrupt-controller@f1010000 {
@@ -6,7 +6,7 @@
  * Copyright (C) 2018 Cogent Embedded, Inc.
  */
 
-#include "r8a77965-m3nulcb.dts"
+#include "r8a77965-ulcb.dts"
 #include "ulcb-kf.dtsi"
 
 / {
index bdbe197..c17d90b 100644 (file)
                        #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>;
+                       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 R8A77965_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,r8a77965-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>;
+                       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 R8A77965_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a77965-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>;
+                       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 R8A77965_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a77965",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a77965",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a77965",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a77965",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a77965",
                                     "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>;
+                       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",
                        #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>;
+                       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>,
                        #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>;
+                       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>,
index 0d0558e..664a73a 100644 (file)
 
                thermal: thermal@e6190000 {
                        compatible = "renesas,thermal-r8a77970";
-                       reg =  <0 0xe6190000 0 0x10
-                               0 0xe6190100 0 0x120>;
+                       reg = <0 0xe6190000 0 0x10>,
+                             <0 0xe6190100 0 0x120>;
                        interrupts = <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>;
                        #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>;
+                       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 R8A77970_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,dmac-r8a77970",
                                     "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>;
+                       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>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7";
                        compatible = "renesas,dmac-r8a77970",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe7310000 0 0x10000>;
-                       interrupts = <GIC_SPI 307 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>;
+                       interrupts = <GIC_SPI 307 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";
index 4d86669..b340fb4 100644 (file)
                        #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>;
+                       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 R8A77980_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,dmac-r8a77980",
                                     "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 353 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
+                       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 353 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 359 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 360 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        compatible = "renesas,dmac-r8a77980",
                                     "renesas,rcar-dmac";
                        reg = <0 0xe7310000 0 0x10000>;
-                       interrupts = <GIC_SPI 307 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
-                                     GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 366 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH
-                                     GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>;
+                       interrupts = <GIC_SPI 307 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>,
+                                    <GIC_SPI 361 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 362 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 364 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 365 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 366 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 367 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 368 IRQ_TYPE_LEVEL_HIGH>;
                        interrupt-names = "error",
                                          "ch0", "ch1", "ch2", "ch3",
                                          "ch4", "ch5", "ch6", "ch7",
                        #size-cells = <2>;
                        bus-range = <0x00 0xff>;
                        device_type = "pci";
-                       ranges = <
-                               0x01000000 0 0x00000000 0 0xfe100000 0 0x0100000
-                               0x02000000 0 0xfe200000 0 0xfe200000 0 0x0200000
-                               0x02000000 0 0x30000000 0 0x30000000 0 0x8000000
-                               0x42000000 0 0x38000000 0 0x38000000 0 0x8000000
-                       >;
-                       dma-ranges = <0x42000000 0 0x40000000 0 0x40000000
-                                     0 0x80000000>;
+                       ranges = <0x01000000 0 0x00000000 0 0xfe100000 0 0x0100000>,
+                                <0x02000000 0 0xfe200000 0 0xfe200000 0 0x0200000>,
+                                <0x02000000 0 0x30000000 0 0x30000000 0 0x8000000>,
+                                <0x42000000 0 0x38000000 0 0x38000000 0 0x8000000>;
+                       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>;
+                       interrupt-map = <0 0 0 0 &gic GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>;
                        clocks = <&cpg CPG_MOD 319>, <&pcie_bus_clk>;
                        clock-names = "pcie", "pcie_bus";
                        power-domains = <&sysc R8A77980_PD_ALWAYS_ON>;
index b38f9d4..4fd2b14 100644 (file)
 
                gpios = <&gpio5 18 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi1: regulator-vcc-sdhi1 {
 
                gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vga {
        /* audio_clkout0/1/2/3 */
        #clock-cells = <1>;
        clock-frequency = <12288000 11289600>;
-       clkout-lr-synchronous;
 
        status = "okay";
 
index 67a6824..32d91f2 100644 (file)
                        #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>;
+                       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 R8A77990_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,r8a77990-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>;
+                       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 R8A77990_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a77990-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>;
+                       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 R8A77990_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a77990",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a77990",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a77990",
                                     "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>;
+                       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",
                        compatible = "renesas,dmac-r8a77990",
                                     "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>;
+                       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",
                        #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>;
+                       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 0x40000000>;
                        interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>,
index e6ee2b7..9503007 100644 (file)
                        #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>;
+                       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 R8A77995_PD_ALWAYS_ON>;
                        resets = <&cpg 407>;
                        compatible = "renesas,r8a77995-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>;
+                       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 R8A77995_PD_ALWAYS_ON>;
                        compatible = "renesas,r8a77995-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>;
+                       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 R8A77995_PD_ALWAYS_ON>;
                        compatible = "renesas,dmac-r8a77995",
                                     "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>;
+                       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>;
                        interrupt-names = "error",
                                        "ch0", "ch1", "ch2", "ch3",
                                        "ch4", "ch5", "ch6", "ch7";
                        compatible = "renesas,dmac-r8a77995",
                                     "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>;
+                       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>;
                        interrupt-names = "error",
                                        "ch0", "ch1", "ch2", "ch3",
                                        "ch4", "ch5", "ch6", "ch7";
                        compatible = "renesas,dmac-r8a77995",
                                     "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>;
+                       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>;
                        interrupt-names = "error",
                                        "ch0", "ch1", "ch2", "ch3",
                                        "ch4", "ch5", "ch6", "ch7";
index 21e0105..98bbcaf 100644 (file)
 
                gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vcc_sdhi3: regulator-vcc-sdhi3 {
 
                gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        vga {
index 3ef8917..ff88af8 100644 (file)
 
                gpios = <&gpio5 1 GPIO_ACTIVE_HIGH>;
                gpios-states = <1>;
-               states = <3300000 1
-                         1800000 0>;
+               states = <3300000 1>, <1800000 0>;
        };
 
        x12_clk: x12 {
index 48fb631..60d9437 100644 (file)
@@ -33,6 +33,8 @@ 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-v2.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-rockpro64.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire.dtb
 dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399-sapphire-excavator.dtb
+dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb
index 936ed7d..0a68025 100644 (file)
        status = "okay";
 };
 
+&dsi {
+       status = "okay";
+
+       ports {
+               mipi_out: port@1 {
+                       reg = <1>;
+
+                       mipi_out_panel: endpoint {
+                               remote-endpoint = <&mipi_in_panel>;
+                       };
+               };
+       };
+
+       panel@0 {
+               compatible = "xinpeng,xpp055c272";
+               reg = <0>;
+               backlight = <&backlight>;
+               iovcc-supply = <&vcc_1v8>;
+               vci-supply = <&vcc3v3_lcd>;
+
+               port {
+                       mipi_in_panel: endpoint {
+                               remote-endpoint = <&mipi_out_panel>;
+                       };
+               };
+       };
+};
+
+&dsi_dphy {
+       status = "okay";
+};
+
 &emmc {
        bus-width = <8>;
        cap-mmc-highspeed;
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&vdd_log>;
+       status = "okay";
+};
+
 &i2c0 {
        status = "okay";
 
        status = "okay";
 };
 
+&tsadc {
+       rockchip,hw-tshut-mode = <1>;
+       rockchip,hw-tshut-polarity = <1>;
+       status = "okay";
+};
+
 &u2phy {
        status = "okay";
 
index 8812b70..75908c5 100644 (file)
@@ -10,6 +10,7 @@
 #include <dt-bindings/pinctrl/rockchip.h>
 #include <dt-bindings/power/px30-power.h>
 #include <dt-bindings/soc/rockchip,boot-mode.h>
+#include <dt-bindings/thermal/thermal.h>
 
 / {
        compatible = "rockchip,px30";
                compatible = "operating-points-v2";
                opp-shared;
 
-               opp-408000000 {
-                       opp-hz = /bits/ 64 <408000000>;
-                       opp-microvolt = <950000 950000 1350000>;
-                       clock-latency-ns = <40000>;
-                       opp-suspend;
-               };
                opp-600000000 {
                        opp-hz = /bits/ 64 <600000000>;
                        opp-microvolt = <950000 950000 1350000>;
                        clock-latency-ns = <40000>;
+                       opp-suspend;
                };
                opp-816000000 {
                        opp-hz = /bits/ 64 <816000000>;
                             <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
        };
 
+       thermal_zones: thermal-zones {
+               soc_thermal: soc-thermal {
+                       polling-delay-passive = <20>;
+                       polling-delay = <1000>;
+                       sustainable-power = <750>;
+                       thermal-sensors = <&tsadc 0>;
+
+                       trips {
+                               threshold: trip-point-0 {
+                                       temperature = <70000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               target: trip-point-1 {
+                                       temperature = <85000>;
+                                       hysteresis = <2000>;
+                                       type = "passive";
+                               };
+
+                               soc_crit: soc-crit {
+                                       temperature = <115000>;
+                                       hysteresis = <2000>;
+                                       type = "critical";
+                               };
+                       };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&target>;
+                                       cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                                       contribution = <4096>;
+                               };
+
+                               map1 {
+                                       trip = <&target>;
+                                       cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                                       contribution = <4096>;
+                               };
+                       };
+               };
+
+               gpu_thermal: gpu-thermal {
+                       polling-delay-passive = <100>; /* milliseconds */
+                       polling-delay = <1000>; /* milliseconds */
+                       thermal-sensors = <&tsadc 1>;
+               };
+       };
+
        xin24m: xin24m {
                compatible = "fixed-clock";
                #clock-cells = <0>;
                        compatible = "rockchip,px30-io-voltage-domain";
                        status = "disabled";
                };
+
+               lvds: lvds {
+                       compatible = "rockchip,px30-lvds";
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+                       phys = <&dsi_dphy>;
+                       phy-names = "dphy";
+                       rockchip,grf = <&grf>;
+                       rockchip,output = "lvds";
+                       status = "disabled";
+
+                       port@0 {
+                               reg = <0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               lvds_vopb_in: endpoint@0 {
+                                       reg = <0>;
+                                       remote-endpoint = <&vopb_out_lvds>;
+                               };
+
+                               lvds_vopl_in: endpoint@1 {
+                                       reg = <1>;
+                                       remote-endpoint = <&vopl_out_lvds>;
+                               };
+                       };
+               };
        };
 
        uart1: serial@ff158000 {
                };
        };
 
+       tsadc: tsadc@ff280000 {
+               compatible = "rockchip,px30-tsadc";
+               reg = <0x0 0xff280000 0x0 0x100>;
+               interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;
+               assigned-clocks = <&cru SCLK_TSADC>;
+               assigned-clock-rates = <50000>;
+               clocks = <&cru SCLK_TSADC>, <&cru PCLK_TSADC>;
+               clock-names = "tsadc", "apb_pclk";
+               resets = <&cru SRST_TSADC>;
+               reset-names = "tsadc-apb";
+               rockchip,grf = <&grf>;
+               rockchip,hw-tshut-temp = <120000>;
+               pinctrl-names = "init", "default", "sleep";
+               pinctrl-0 = <&tsadc_otp_gpio>;
+               pinctrl-1 = <&tsadc_otp_out>;
+               pinctrl-2 = <&tsadc_otp_gpio>;
+               #thermal-sensor-cells = <1>;
+               status = "disabled";
+       };
+
        saradc: saradc@ff288000 {
                compatible = "rockchip,px30-saradc", "rockchip,rk3399-saradc";
                reg = <0x0 0xff288000 0x0 0x100>;
                };
        };
 
+       dsi_dphy: phy@ff2e0000 {
+               compatible = "rockchip,px30-dsi-dphy";
+               reg = <0x0 0xff2e0000 0x0 0x10000>;
+               clocks = <&pmucru SCLK_MIPIDSIPHY_REF>, <&cru PCLK_MIPIDSIPHY>;
+               clock-names = "ref", "pclk";
+               resets = <&cru SRST_MIPIDSIPHY_P>;
+               reset-names = "apb";
+               #phy-cells = <0>;
+               power-domains = <&power PX30_PD_VO>;
+               status = "disabled";
+       };
+
        usb20_otg: usb@ff300000 {
                compatible = "rockchip,px30-usb", "rockchip,rk3066-usb",
                             "snps,dwc2";
                status = "disabled";
        };
 
-       sdmmc: dwmmc@ff370000 {
+       sdmmc: mmc@ff370000 {
                compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff370000 0x0 0x4000>;
                interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDMMC>, <&cru SCLK_SDMMC>,
                         <&cru SCLK_SDMMC_DRV>, <&cru SCLK_SDMMC_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                max-frequency = <150000000>;
                pinctrl-names = "default";
                status = "disabled";
        };
 
-       sdio: dwmmc@ff380000 {
+       sdio: mmc@ff380000 {
                compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff380000 0x0 0x4000>;
                interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_SDIO>, <&cru SCLK_SDIO>,
                         <&cru SCLK_SDIO_DRV>, <&cru SCLK_SDIO_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                max-frequency = <150000000>;
                pinctrl-names = "default";
                status = "disabled";
        };
 
-       emmc: dwmmc@ff390000 {
+       emmc: mmc@ff390000 {
                compatible = "rockchip,px30-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff390000 0x0 0x4000>;
                interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>;
                clocks = <&cru HCLK_EMMC>, <&cru SCLK_EMMC>,
                         <&cru SCLK_EMMC_DRV>, <&cru SCLK_EMMC_SAMPLE>;
-               clock-names = "biu", "ciu", "ciu-drv", "ciu-sample";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                max-frequency = <150000000>;
                pinctrl-names = "default";
                status = "disabled";
        };
 
+       gpu: gpu@ff400000 {
+               compatible = "rockchip,px30-mali", "arm,mali-bifrost";
+               reg = <0x0 0xff400000 0x0 0x4000>;
+               interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "job", "mmu", "gpu";
+               clocks = <&cru SCLK_GPU>;
+               #cooling-cells = <2>;
+               power-domains = <&power PX30_PD_GPU>;
+               status = "disabled";
+       };
+
+       dsi: dsi@ff450000 {
+               compatible = "rockchip,px30-mipi-dsi";
+               reg = <0x0 0xff450000 0x0 0x10000>;
+               interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+               clocks = <&cru PCLK_MIPI_DSI>;
+               clock-names = "pclk";
+               phys = <&dsi_dphy>;
+               phy-names = "dphy";
+               power-domains = <&power PX30_PD_VO>;
+               resets = <&cru SRST_MIPIDSI_HOST_P>;
+               reset-names = "apb";
+               rockchip,grf = <&grf>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               status = "disabled";
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       port@0 {
+                               reg = <0>;
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               dsi_in_vopb: endpoint@0 {
+                                       reg = <0>;
+                                       remote-endpoint = <&vopb_out_dsi>;
+                               };
+
+                               dsi_in_vopl: endpoint@1 {
+                                       reg = <1>;
+                                       remote-endpoint = <&vopl_out_dsi>;
+                               };
+                       };
+               };
+       };
+
        vopb: vop@ff460000 {
                compatible = "rockchip,px30-vop-big";
                reg = <0x0 0xff460000 0x0 0xefc>;
                vopb_out: port {
                        #address-cells = <1>;
                        #size-cells = <0>;
+
+                       vopb_out_dsi: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&dsi_in_vopb>;
+                       };
+
+                       vopb_out_lvds: endpoint@1 {
+                               reg = <1>;
+                               remote-endpoint = <&lvds_vopb_in>;
+                       };
                };
        };
 
                vopl_out: port {
                        #address-cells = <1>;
                        #size-cells = <0>;
+
+                       vopl_out_dsi: endpoint@0 {
+                               reg = <0>;
+                               remote-endpoint = <&dsi_in_vopl>;
+                       };
+
+                       vopl_out_lvds: endpoint@1 {
+                               reg = <1>;
+                               remote-endpoint = <&lvds_vopl_in>;
+                       };
                };
        };
 
index 8bdc66c..116f190 100644 (file)
                status = "disabled";
        };
 
-       sdmmc: dwmmc@ff480000 {
+       sdmmc: mmc@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";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                max-frequency = <150000000>;
                pinctrl-names = "default";
                status = "disabled";
        };
 
-       emmc: dwmmc@ff490000 {
+       emmc: mmc@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";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                max-frequency = <150000000>;
                status = "disabled";
        };
 
-       sdio: dwmmc@ff4a0000 {
+       sdio: mmc@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";
+               clock-names = "biu", "ciu", "ciu-drive", "ciu-sample";
                fifo-depth = <0x100>;
                max-frequency = <150000000>;
                pinctrl-names = "default";
index 91306eb..1f53ead 100644 (file)
@@ -41,6 +41,7 @@
                        reg = <0x0 0x0>;
                        clocks = <&cru ARMCLK>;
                        #cooling-cells = <2>;
+                       cpu-idle-states = <&CPU_SLEEP>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
@@ -53,6 +54,7 @@
                        reg = <0x0 0x1>;
                        clocks = <&cru ARMCLK>;
                        #cooling-cells = <2>;
+                       cpu-idle-states = <&CPU_SLEEP>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
@@ -65,6 +67,7 @@
                        reg = <0x0 0x2>;
                        clocks = <&cru ARMCLK>;
                        #cooling-cells = <2>;
+                       cpu-idle-states = <&CPU_SLEEP>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                        reg = <0x0 0x3>;
                        clocks = <&cru ARMCLK>;
                        #cooling-cells = <2>;
+                       cpu-idle-states = <&CPU_SLEEP>;
                        dynamic-power-coefficient = <120>;
                        enable-method = "psci";
                        next-level-cache = <&l2>;
                        operating-points-v2 = <&cpu0_opp_table>;
                };
 
+               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-cache0 {
                        compatible = "cache";
                };
                };
        };
 
-       sdmmc: dwmmc@ff500000 {
+       sdmmc: mmc@ff500000 {
                compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff500000 0x0 0x4000>;
                interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       sdio: dwmmc@ff510000 {
+       sdio: mmc@ff510000 {
                compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff510000 0x0 0x4000>;
                interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>;
                status = "disabled";
        };
 
-       emmc: dwmmc@ff520000 {
+       emmc: mmc@ff520000 {
                compatible = "rockchip,rk3328-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff520000 0x0 0x4000>;
                interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>;
index 8251f3c..cbde279 100644 (file)
        status = "okay";
 };
 
-&uart0 {
-       pinctrl-names = "default";
-       pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
-       status = "okay";
-};
-
 &usb_otg {
        dr_mode = "otg";
        status = "okay";
index fd86188..a0df61c 100644 (file)
                #clock-cells = <0>;
        };
 
-       sdmmc: dwmmc@ff0c0000 {
+       sdmmc: mmc@ff0c0000 {
                compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff0c0000 0x0 0x4000>;
                max-frequency = <150000000>;
                status = "disabled";
        };
 
-       sdio0: dwmmc@ff0d0000 {
+       sdio0: mmc@ff0d0000 {
                compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff0d0000 0x0 0x4000>;
                max-frequency = <150000000>;
                status = "disabled";
        };
 
-       emmc: dwmmc@ff0f0000 {
+       emmc: mmc@ff0f0000 {
                compatible = "rockchip,rk3368-dw-mshc", "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xff0f0000 0x0 0x4000>;
                max-frequency = <150000000>;
index c706db0..d63faf3 100644 (file)
                regulator-name = "vdd_log";
                regulator-always-on;
                regulator-boot-on;
-               regulator-min-microvolt = <800000>;
+               regulator-min-microvolt = <430000>;
                regulator-max-microvolt = <1400000>;
                vin-supply = <&vcc_sys>;
        };
        keep-power-in-suspend;
        mmc-pwrseq = <&sdio_pwrseq>;
        non-removable;
-       num-slots = <1>;
        pinctrl-names = "default";
        pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
        sd-uhs-sdr104;
        vqmmc-supply = &vcc1v8_s3;      /* IO line */
        vmmc-supply = &vcc_sdio;        /* card's power */
 
+       #address-cells = <1>;
+       #size-cells = <0>;
        status = "okay";
 
        brcmf: wifi@1 {
+               reg = <1>;
                compatible = "brcm,bcm4329-fmac";
                interrupt-parent = <&gpio0>;
                interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
index 9dd3b17..e6c1c94 100644 (file)
@@ -18,7 +18,7 @@
                     "google,bob", "google,gru", "rockchip,rk3399";
 
        edp_panel: edp-panel {
-               compatible = "boe,nv101wxmn51", "simple-panel";
+               compatible = "boe,nv101wxmn51";
                backlight = <&backlight>;
                power-supply = <&pp3300_disp>;
 
index b806686..2bbef9f 100644 (file)
@@ -39,7 +39,7 @@
        };
 
        edp_panel: edp-panel {
-               compatible = "sharp,lq123p1jx31", "simple-panel";
+               compatible = "sharp,lq123p1jx31";
                backlight = <&backlight>;
                power-supply = <&pp3300_disp>;
 
index c133e8d..d69a613 100644 (file)
 &sdmmc {
        clock-frequency = <150000000>;
        clock-freq-min-max = <200000 150000000>;
-       supports-sd;
        bus-width = <4>;
        cap-mmc-highspeed;
        cap-sd-highspeed;
        bus-width = <8>;
        mmc-hs400-1_8v;
        mmc-hs400-enhanced-strobe;
-       supports-emmc;
        non-removable;
        keep-power-in-suspend;
        status = "okay";
index 4944d78..e87a044 100644 (file)
        sd-uhs-sdr104;
        vqmmc-supply = <&vcc1v8_s3>;
        vmmc-supply = <&vccio_sd>;
+       #address-cells = <1>;
+       #size-cells = <0>;
        status = "okay";
 
        brcmf: wifi@1 {
+               reg = <1>;
                compatible = "brcm,bcm4329-fmac";
                interrupt-parent = <&gpio0>;
                interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
index 2a12798..e0d7561 100644 (file)
        };
 };
 
-&gpu_thermal {
-       trips {
-               gpu_warm: gpu_warm {
-                       temperature = <55000>;
-                       hysteresis = <2000>;
-                       type = "active";
-               };
-
-               gpu_hot: gpu_hot {
-                       temperature = <65000>;
-                       hysteresis = <2000>;
-                       type = "active";
-               };
-       };
-       cooling-maps {
-               map1 {
-                       trip = <&gpu_warm>;
-                       cooling-device = <&fan THERMAL_NO_LIMIT 1>;
-               };
-
-               map2 {
-                       trip = <&gpu_hot>;
-                       cooling-device = <&fan 2 THERMAL_NO_LIMIT>;
-               };
-       };
+&pcie0 {
+       num-lanes = <4>;
+       vpcie3v3-supply = <&vcc3v3_sys>;
 };
 
 &pinctrl {
index b788ae4..c88018a 100644 (file)
@@ -48,7 +48,7 @@
        };
 
        /* switched by pmic_sleep */
-       vcc1v8_s3: vcca1v8_s3: vcc1v8-s3 {
+       vcc1v8_s3: vcc1v8-s3 {
                compatible = "regulator-fixed";
                regulator-always-on;
                regulator-boot-on;
                vin-supply = <&vcc3v3_sys>;
        };
 
+       /*
+        * Really, this is supplied by vcc_1v8, and vcc1v8_s3 only
+        * drives the enable pin, but we can't quite model that.
+        */
+       vcca0v9_s3: vcca0v9-s3 {
+               compatible = "regulator-fixed";
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+               regulator-name = "vcca0v9_s3";
+               vin-supply = <&vcc1v8_s3>;
+       };
+
+       /* As above, actually supplied by vcc3v3_sys */
+       vcca1v8_s3: vcca1v8-s3 {
+               compatible = "regulator-fixed";
+               regulator-min-microvolt = <1800000>;
+               regulator-max-microvolt = <1800000>;
+               regulator-name = "vcca1v8_s3";
+               vin-supply = <&vcc1v8_s3>;
+       };
+
        vbus_typec: vbus-typec {
                compatible = "regulator-fixed";
                regulator-min-microvolt = <5000000>;
 &pcie0 {
        ep-gpios = <&gpio2 RK_PA4 GPIO_ACTIVE_HIGH>;
        max-link-speed = <2>;
-       num-lanes = <4>;
+       num-lanes = <2>;
+       vpcie0v9-supply = <&vcca0v9_s3>;
+       vpcie1v8-supply = <&vcca1v8_s3>;
        status = "okay";
 };
 
index 0541dfc..9c659f3 100644 (file)
        pinctrl-names = "default";
        pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
        sd-uhs-sdr104;
+       #address-cells = <1>;
+       #size-cells = <0>;
        status = "okay";
 
        brcmf: wifi@1 {
+               reg = <1>;
                compatible = "brcm,bcm4329-fmac";
                interrupt-parent = <&gpio0>;
                interrupts = <RK_PA3 GPIO_ACTIVE_HIGH>;
index d6b3042..2acb3d5 100644 (file)
@@ -32,8 +32,6 @@
                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>;
@@ -50,6 +48,8 @@
        pinctrl-names = "default";
        pinctrl-0 = <&pcie_perst>;
        vpcie3v3-supply = <&vcc3v3_pcie>;
+       vpcie1v8-supply = <&vcc1v8_pmu>;
+       vpcie0v9-supply = <&vcca_0v9>;
        status = "okay";
 };
 
                };
        };
 };
+
+&sdio0 {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       cap-sdio-irq;
+       keep-power-in-suspend;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+       sd-uhs-sdr104;
+       vmmc-supply = <&vcc3v3_ngff>;
+       vqmmc-supply = <&vcc_1v8>;
+       status = "okay";
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+       status = "okay";
+};
index 7e07dae..9f225e9 100644 (file)
                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";
                vin-supply = <&vcc_1v8>;
        };
 
+       vcc3v0_sd: vcc3v0-sd {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio4 RK_PD6 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc3v0_sd_en>;
+               regulator-name = "vcc3v0_sd";
+               regulator-boot-on;
+               regulator-min-microvolt = <3000000>;
+               regulator-max-microvolt = <3000000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
        vcc3v3_sys: vcc3v3-sys {
                compatible = "regulator-fixed";
                regulator-name = "vcc3v3_sys";
                vin-supply = <&dc_12v>;
        };
 
+       vcca_0v9: vcca-0v9 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcca_0v9";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
        /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
        vcc5v0_host: vcc5v0-host-regulator {
                compatible = "regulator-fixed";
                pinctrl-names = "default";
                pinctrl-0 = <&vcc5v0_host_en &hub_rst>;
                regulator-name = "vcc5v0_host";
-               regulator-always-on;
                vin-supply = <&vcc_sys>;
        };
 
                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>;
                regulator-name = "vdd_log";
                regulator-always-on;
                regulator-boot-on;
-               regulator-min-microvolt = <800000>;
+               regulator-min-microvolt = <450000>;
                regulator-max-microvolt = <1400000>;
-               vin-supply = <&vcc3v3_sys>;
+               pwm-supply = <&vcc3v3_sys>;
        };
 };
 
        status = "okay";
 };
 
+&gpu {
+       mali-supply = <&vdd_gpu>;
+       status = "okay";
+};
+
 &hdmi {
        ddc-i2c-bus = <&i2c3>;
        pinctrl-names = "default";
        status = "okay";
 };
 
+&hdmi_sound {
+       status = "okay";
+};
+
 &i2c0 {
        clock-frequency = <400000>;
        i2c-scl-rising-time-ns = <168>;
 
                        vcc_sdio: LDO_REG4 {
                                regulator-name = "vcc_sdio";
-                               regulator-always-on;
                                regulator-boot-on;
                                regulator-min-microvolt = <1800000>;
                                regulator-max-microvolt = <3000000>;
                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 {
                vbus-supply = <&vcc_vbus_typec0>;
                status = "okay";
        };
+
+       mp8859: regulator@66 {
+               compatible = "mps,mp8859";
+               reg = <0x66>;
+               dc_12v: mp8859_dcdc {
+                       regulator-name = "dc_12v";
+                       regulator-min-microvolt = <12000000>;
+                       regulator-max-microvolt = <12000000>;
+                       regulator-always-on;
+                       regulator-boot-on;
+                       vin-supply = <&vcc_vbus_typec0>;
+
+                       regulator-state-mem {
+                               regulator-on-in-suspend;
+                               regulator-suspend-microvolt = <12000000>;
+                       };
+               };
+       };
 };
 
 &i2s0 {
 
        lcd-panel {
                lcd_panel_reset: lcd-panel-reset {
-                       rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
+                       rockchip,pins = <4 RK_PD5 RK_FUNC_GPIO &pcfg_pull_up>;
                };
        };
 
                };
        };
 
+       sdmmc {
+               vcc3v0_sd_en: vcc3v0-sd-en {
+                       rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
        pmic {
                pmic_int_l: pmic-int-l {
                        rockchip,pins = <1 RK_PC5 RK_FUNC_GPIO &pcfg_pull_up>;
 
 &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>;
+       sd-uhs-sdr104;
+       vmmc-supply = <&vcc3v0_sd>;
+       vqmmc-supply = <&vcc_sdio>;
        status = "okay";
 };
 
 &sdhci {
        bus-width = <8>;
-       mmc-hs400-1_8v;
-       mmc-hs400-enhanced-strobe;
        non-removable;
        status = "okay";
 };
 
+&spi1 {
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <10000000>;
+       };
+};
+
 &tcphy0 {
        status = "okay";
 };
index 188d9df..3923ec0 100644 (file)
                vin-supply = <&vcc12v_dcin>;
        };
 
+       vcc_0v9: vcc-0v9 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_0v9";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
+
        vcc3v3_pcie: vcc3v3-pcie-regulator {
                compatible = "regulator-fixed";
                enable-active-high;
        pmu1830-supply = <&vcc_3v0>;
 };
 
+&pcie_phy {
+       status = "okay";
+};
+
+&pcie0 {
+       ep-gpios = <&gpio4 RK_PD3 GPIO_ACTIVE_HIGH>;
+       max-link-speed = <2>;
+       num-lanes = <4>;
+       pinctrl-0 = <&pcie_clkreqnb_cpm>;
+       pinctrl-names = "default";
+       vpcie0v9-supply = <&vcc_0v9>;
+       vpcie1v8-supply = <&vcc_1v8>;
+       vpcie3v3-supply = <&vcc3v3_pcie>;
+       status = "okay";
+};
+
 &pinctrl {
        bt {
                bt_enable_h: bt-enable-h {
index c7d48d4..b69f0f2 100644 (file)
                regulator-always-on;
                vin-supply = <&vcc5v0_sys>;
        };
+
+       vcc_0v9: vcc-0v9 {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc_0v9";
+               regulator-always-on;
+               regulator-min-microvolt = <900000>;
+               regulator-max-microvolt = <900000>;
+               vin-supply = <&vcc3v3_sys>;
+       };
 };
 
 &cpu_l0 {
        num-lanes = <4>;
        pinctrl-names = "default";
        pinctrl-0 = <&pcie_clkreqn_cpm>;
+       vpcie0v9-supply = <&vcc_0v9>;
+       vpcie1v8-supply = <&vcca_1v8>;
        vpcie3v3-supply = <&vcc3v3_pcie>;
        status = "okay";
 };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts
new file mode 100644 (file)
index 0000000..304e3c5
--- /dev/null
@@ -0,0 +1,30 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2018 Akash Gajjar <Akash_Gajjar@mentor.com>
+ * Copyright (c) 2019 Katsuhiro Suzuki <katsuhiro@katsuster.net>
+ */
+
+/dts-v1/;
+#include "rk3399-rockpro64.dtsi"
+
+/ {
+       model = "Pine64 RockPro64 v2.0";
+       compatible = "pine64,rockpro64-v2.0", "pine64,rockpro64", "rockchip,rk3399";
+};
+
+&i2c1 {
+       es8316: codec@10 {
+               compatible = "everest,es8316";
+               reg = <0x10>;
+               clocks = <&cru SCLK_I2S_8CH_OUT>;
+               clock-names = "mclk";
+               #sound-dai-cells = <0>;
+
+               port {
+                       es8316_p0_0: endpoint {
+                               remote-endpoint = <&i2s1_p0_0>;
+                       };
+               };
+       };
+};
index 7f4b2eb..4b42717 100644 (file)
 /*
  * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
  * Copyright (c) 2018 Akash Gajjar <Akash_Gajjar@mentor.com>
+ * Copyright (c) 2019 Katsuhiro Suzuki <katsuhiro@katsuster.net>
  */
 
 /dts-v1/;
-#include <dt-bindings/input/linux-event-codes.h>
-#include <dt-bindings/pwm/pwm.h>
-#include "rk3399.dtsi"
-#include "rk3399-opp.dtsi"
+#include "rk3399-rockpro64.dtsi"
 
 / {
-       model = "Pine64 RockPro64";
-       compatible = "pine64,rockpro64", "rockchip,rk3399";
-
-       chosen {
-               stdout-path = "serial2:1500000n8";
-       };
-
-       clkin_gmac: external-gmac-clock {
-               compatible = "fixed-clock";
-               clock-frequency = <125000000>;
-               clock-output-names = "clkin_gmac";
-               #clock-cells = <0>;
-       };
-
-       gpio-keys {
-               compatible = "gpio-keys";
-               autorepeat;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pwrbtn>;
-
-               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>;
-
-               work-led {
-                       label = "work";
-                       default-state = "on";
-                       gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>;
-               };
-
-               diy-led {
-                       label = "diy";
-                       default-state = "off";
-                       gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
-               };
-       };
-
-       fan: pwm-fan {
-               compatible = "pwm-fan";
-               #cooling-cells = <2>;
-               fan-supply = <&vcc12v_dcin>;
-               pwms = <&pwm1 0 50000 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>;
-       };
-
-       sound {
-               compatible = "audio-graph-card";
-               label = "rockchip,rk3399";
-               dais = <&i2s1_p0>;
-       };
-
-       vcc12v_dcin: vcc12v-dcin {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc12v_dcin";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <12000000>;
-               regulator-max-microvolt = <12000000>;
-       };
-
-       /* 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_pcie: vcc3v3-pcie-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&pcie_pwr_en>;
-               regulator-name = "vcc3v3_pcie";
-               regulator-always-on;
-               regulator-boot-on;
-               vin-supply = <&vcc12v_dcin>;
-       };
-
-       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 = <&vcc5v0_sys>;
-       };
-
-       /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
-       vcc5v0_host: vcc5v0-host-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&vcc5v0_host_en>;
-               regulator-name = "vcc5v0_host";
-               regulator-always-on;
-               vin-supply = <&vcc5v0_usb>;
-       };
-
-       vcc5v0_typec: vcc5v0-typec-regulator {
-               compatible = "regulator-fixed";
-               enable-active-high;
-               gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&vcc5v0_typec_en>;
-               regulator-name = "vcc5v0_typec";
-               regulator-always-on;
-               vin-supply = <&vcc5v0_usb>;
-       };
-
-       vcc5v0_sys: vcc5v0-sys {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc5v0_sys";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               vin-supply = <&vcc12v_dcin>;
-       };
-
-       vcc5v0_usb: vcc5v0-usb {
-               compatible = "regulator-fixed";
-               regulator-name = "vcc5v0_usb";
-               regulator-always-on;
-               regulator-boot-on;
-               regulator-min-microvolt = <5000000>;
-               regulator-max-microvolt = <5000000>;
-               vin-supply = <&vcc12v_dcin>;
-       };
-
-       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 = <1700000>;
-               vin-supply = <&vcc5v0_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";
-};
-
-&hdmi_sound {
-       status = "okay";
-};
-
-&gpu {
-       mali-supply = <&vdd_gpu>;
-       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 = <&gpio3>;
-               interrupts = <10 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 = <&vcc5v0_sys>;
-               vcc2-supply = <&vcc5v0_sys>;
-               vcc3-supply = <&vcc5v0_sys>;
-               vcc4-supply = <&vcc5v0_sys>;
-               vcc6-supply = <&vcc5v0_sys>;
-               vcc7-supply = <&vcc5v0_sys>;
-               vcc8-supply = <&vcc3v3_sys>;
-               vcc9-supply = <&vcc5v0_sys>;
-               vcc10-supply = <&vcc5v0_sys>;
-               vcc11-supply = <&vcc5v0_sys>;
-               vcc12-supply = <&vcc3v3_sys>;
-               vddio-supply = <&vcca_1v8>;
-
-               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>;
-                               };
-                       };
-
-                       vcc1v8_dvp: LDO_REG1 {
-                               regulator-name = "vcc1v8_dvp";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <1800000>;
-                               regulator-max-microvolt = <1800000>;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vcc3v0_touch: LDO_REG2 {
-                               regulator-name = "vcc3v0_touch";
-                               regulator-always-on;
-                               regulator-boot-on;
-                               regulator-min-microvolt = <3000000>;
-                               regulator-max-microvolt = <3000000>;
-                               regulator-state-mem {
-                                       regulator-off-in-suspend;
-                               };
-                       };
-
-                       vcca_1v8: LDO_REG3 {
-                               regulator-name = "vcca_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>;
-                               };
-                       };
-
-                       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>;
-                               };
-                       };
-
-                       vcca1v8_codec: LDO_REG7 {
-                               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;
-                               };
-                       };
-
-                       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 = <&vcc5v0_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 = <&vcc5v0_sys>;
-
-               regulator-state-mem {
-                       regulator-off-in-suspend;
-               };
-       };
+       model = "Pine64 RockPro64 v2.1";
+       compatible = "pine64,rockpro64-v2.1", "pine64,rockpro64", "rockchip,rk3399";
 };
 
 &i2c1 {
-       i2c-scl-rising-time-ns = <300>;
-       i2c-scl-falling-time-ns = <15>;
-       status = "okay";
-
        es8316: codec@11 {
                compatible = "everest,es8316";
                reg = <0x11>;
                };
        };
 };
-
-&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";
-
-       fusb0: typec-portc@22 {
-               compatible = "fcs,fusb302";
-               reg = <0x22>;
-               interrupt-parent = <&gpio1>;
-               interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
-               pinctrl-names = "default";
-               pinctrl-0 = <&fusb0_int>;
-               vbus-supply = <&vcc5v0_typec>;
-               status = "okay";
-       };
-};
-
-&i2s0 {
-       rockchip,playback-channels = <8>;
-       rockchip,capture-channels = <8>;
-       status = "okay";
-};
-
-&i2s1 {
-       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 {
-       status = "okay";
-};
-
-&io_domains {
-       status = "okay";
-
-       bt656-supply = <&vcc1v8_dvp>;
-       audio-supply = <&vcc_3v0>;
-       sdmmc-supply = <&vcc_sdio>;
-       gpio1830-supply = <&vcc_3v0>;
-};
-
-&pcie0 {
-       ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
-       num-lanes = <4>;
-       pinctrl-names = "default";
-       pinctrl-0 = <&pcie_perst>;
-       vpcie12v-supply = <&vcc12v_dcin>;
-       vpcie3v3-supply = <&vcc3v3_pcie>;
-       status = "okay";
-};
-
-&pcie_phy {
-       status = "okay";
-};
-
-&pmu_io_domains {
-       pmu1830-supply = <&vcc_3v0>;
-       status = "okay";
-};
-
-&pinctrl {
-       buttons {
-               pwrbtn: pwrbtn {
-                       rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-       };
-
-       fusb302x {
-               fusb0_int: fusb0-int {
-                       rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-       };
-
-       leds {
-               work_led_gpio: work_led-gpio {
-                       rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
-               diy_led_gpio: diy_led-gpio {
-                       rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
-       pcie {
-               pcie_perst: pcie-perst {
-                       rockchip,pins = <2 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-
-               pcie_pwr_en: pcie-pwr-en {
-                       rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-
-       pmic {
-               pmic_int_l: pmic-int-l {
-                       rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-
-               vsel1_gpio: vsel1-gpio {
-                       rockchip,pins = <1 RK_PC1 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>;
-               };
-       };
-
-       usb-typec {
-               vcc5v0_typec_en: vcc5v0_typec_en {
-                       rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
-               };
-       };
-
-       usb2 {
-               vcc5v0_host_en: vcc5v0-host-en {
-                       rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
-               };
-       };
-};
-
-&pwm0 {
-       status = "okay";
-};
-
-&pwm1 {
-       status = "okay";
-};
-
-&pwm2 {
-       status = "okay";
-};
-
-&saradc {
-       vref-supply = <&vcca1v8_s3>;
-       status = "okay";
-};
-
-&sdmmc {
-       bus-width = <4>;
-       cap-sd-highspeed;
-       cd-gpios = <&gpio0 7 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-hs200-1_8v;
-       non-removable;
-       status = "okay";
-};
-
-&spi1 {
-       status = "okay";
-
-       flash@0 {
-               compatible = "jedec,spi-nor";
-               reg = <0>;
-               spi-max-frequency = <10000000>;
-       };
-};
-
-&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 {
-               status = "okay";
-       };
-
-       u2phy0_host: host-port {
-               phy-supply = <&vcc5v0_host>;
-               status = "okay";
-       };
-};
-
-&u2phy1 {
-       status = "okay";
-
-       u2phy1_otg: otg-port {
-               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";
-       dr_mode = "otg";
-};
-
-&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-rockpro64.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dtsi
new file mode 100644 (file)
index 0000000..9bca258
--- /dev/null
@@ -0,0 +1,797 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2017 Fuzhou Rockchip Electronics Co., Ltd.
+ * Copyright (c) 2018 Akash Gajjar <Akash_Gajjar@mentor.com>
+ */
+
+#include <dt-bindings/input/linux-event-codes.h>
+#include <dt-bindings/pwm/pwm.h>
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+
+/ {
+       chosen {
+               stdout-path = "serial2:1500000n8";
+       };
+
+       clkin_gmac: external-gmac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "clkin_gmac";
+               #clock-cells = <0>;
+       };
+
+       gpio-keys {
+               compatible = "gpio-keys";
+               autorepeat;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pwrbtn>;
+
+               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>;
+
+               work-led {
+                       label = "work";
+                       default-state = "on";
+                       gpios = <&gpio0 RK_PB3 GPIO_ACTIVE_HIGH>;
+               };
+
+               diy-led {
+                       label = "diy";
+                       default-state = "off";
+                       gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_HIGH>;
+               };
+       };
+
+       fan: pwm-fan {
+               compatible = "pwm-fan";
+               #cooling-cells = <2>;
+               fan-supply = <&vcc12v_dcin>;
+               pwms = <&pwm1 0 50000 0>;
+       };
+
+       sdio_pwrseq: sdio-pwrseq {
+               compatible = "mmc-pwrseq-simple";
+               clocks = <&rk808 1>;
+               clock-names = "ext_clock";
+               pinctrl-names = "default";
+               pinctrl-0 = <&wifi_enable_h>;
+               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";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+       };
+
+       /* 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_pcie: vcc3v3-pcie-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PD0 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pcie_pwr_en>;
+               regulator-name = "vcc3v3_pcie";
+               regulator-always-on;
+               regulator-boot-on;
+               vin-supply = <&vcc12v_dcin>;
+       };
+
+       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 = <&vcc5v0_sys>;
+       };
+
+       /* Actually 3 regulators (host0, 1, 2) controlled by the same gpio */
+       vcc5v0_host: vcc5v0-host-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio4 RK_PD2 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_host_en>;
+               regulator-name = "vcc5v0_host";
+               regulator-always-on;
+               vin-supply = <&vcc5v0_usb>;
+       };
+
+       vcc5v0_typec: vcc5v0-typec-regulator {
+               compatible = "regulator-fixed";
+               enable-active-high;
+               gpio = <&gpio1 RK_PA3 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&vcc5v0_typec_en>;
+               regulator-name = "vcc5v0_typec";
+               regulator-always-on;
+               vin-supply = <&vcc5v0_usb>;
+       };
+
+       vcc5v0_sys: vcc5v0-sys {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc12v_dcin>;
+       };
+
+       vcc5v0_usb: vcc5v0-usb {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_usb";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc12v_dcin>;
+       };
+
+       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 = <1700000>;
+               vin-supply = <&vcc5v0_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";
+};
+
+&hdmi_sound {
+       status = "okay";
+};
+
+&gpu {
+       mali-supply = <&vdd_gpu>;
+       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 = <&gpio3>;
+               interrupts = <10 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 = <&vcc5v0_sys>;
+               vcc2-supply = <&vcc5v0_sys>;
+               vcc3-supply = <&vcc5v0_sys>;
+               vcc4-supply = <&vcc5v0_sys>;
+               vcc6-supply = <&vcc5v0_sys>;
+               vcc7-supply = <&vcc5v0_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc5v0_sys>;
+               vcc10-supply = <&vcc5v0_sys>;
+               vcc11-supply = <&vcc5v0_sys>;
+               vcc12-supply = <&vcc3v3_sys>;
+               vddio-supply = <&vcca_1v8>;
+
+               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>;
+                               };
+                       };
+
+                       vcc1v8_dvp: LDO_REG1 {
+                               regulator-name = "vcc1v8_dvp";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <1800000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc3v0_touch: LDO_REG2 {
+                               regulator-name = "vcc3v0_touch";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcca_1v8: LDO_REG3 {
+                               regulator-name = "vcca_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>;
+                               };
+                       };
+
+                       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>;
+                               };
+                       };
+
+                       vcca1v8_codec: LDO_REG7 {
+                               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;
+                               };
+                       };
+
+                       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 = <&vcc5v0_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 = <&vcc5v0_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";
+
+       fusb0: typec-portc@22 {
+               compatible = "fcs,fusb302";
+               reg = <0x22>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <RK_PA2 IRQ_TYPE_LEVEL_LOW>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&fusb0_int>;
+               vbus-supply = <&vcc5v0_typec>;
+               status = "okay";
+       };
+};
+
+&i2s0 {
+       rockchip,playback-channels = <8>;
+       rockchip,capture-channels = <8>;
+       status = "okay";
+};
+
+&i2s1 {
+       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 {
+       status = "okay";
+};
+
+&io_domains {
+       status = "okay";
+
+       bt656-supply = <&vcc1v8_dvp>;
+       audio-supply = <&vcc_3v0>;
+       sdmmc-supply = <&vcc_sdio>;
+       gpio1830-supply = <&vcc_3v0>;
+};
+
+&pcie0 {
+       ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>;
+       num-lanes = <4>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pcie_perst>;
+       vpcie12v-supply = <&vcc12v_dcin>;
+       vpcie3v3-supply = <&vcc3v3_pcie>;
+       status = "okay";
+};
+
+&pcie_phy {
+       status = "okay";
+};
+
+&pmu_io_domains {
+       pmu1830-supply = <&vcc_3v0>;
+       status = "okay";
+};
+
+&pinctrl {
+       bt {
+               bt_enable_h: bt-enable-h {
+                       rockchip,pins = <0 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               bt_host_wake_l: bt-host-wake-l {
+                       rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_down>;
+               };
+
+               bt_wake_l: bt-wake-l {
+                       rockchip,pins = <2 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       buttons {
+               pwrbtn: pwrbtn {
+                       rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       fusb302x {
+               fusb0_int: fusb0-int {
+                       rockchip,pins = <1 RK_PA2 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       leds {
+               work_led_gpio: work_led-gpio {
+                       rockchip,pins = <0 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               diy_led_gpio: diy_led-gpio {
+                       rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pcie {
+               pcie_perst: pcie-perst {
+                       rockchip,pins = <2 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+
+               pcie_pwr_en: pcie-pwr-en {
+                       rockchip,pins = <1 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins = <3 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+
+               vsel1_gpio: vsel1-gpio {
+                       rockchip,pins = <1 RK_PC1 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>;
+               };
+       };
+
+       usb-typec {
+               vcc5v0_typec_en: vcc5v0_typec_en {
+                       rockchip,pins = <1 RK_PA3 RK_FUNC_GPIO &pcfg_pull_up>;
+               };
+       };
+
+       usb2 {
+               vcc5v0_host_en: vcc5v0-host-en {
+                       rockchip,pins = <4 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
+               };
+       };
+};
+
+&pwm0 {
+       status = "okay";
+};
+
+&pwm1 {
+       status = "okay";
+};
+
+&pwm2 {
+       status = "okay";
+};
+
+&saradc {
+       vref-supply = <&vcca1v8_s3>;
+       status = "okay";
+};
+
+&sdio0 {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       cap-sdio-irq;
+       disable-wp;
+       keep-power-in-suspend;
+       mmc-pwrseq = <&sdio_pwrseq>;
+       non-removable;
+       pinctrl-names = "default";
+       pinctrl-0 = <&sdio0_bus4 &sdio0_cmd &sdio0_clk>;
+       sd-uhs-sdr104;
+       status = "okay";
+};
+
+&sdmmc {
+       bus-width = <4>;
+       cap-sd-highspeed;
+       cd-gpios = <&gpio0 7 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-hs200-1_8v;
+       non-removable;
+       status = "okay";
+};
+
+&spi1 {
+       status = "okay";
+
+       flash@0 {
+               compatible = "jedec,spi-nor";
+               reg = <0>;
+               spi-max-frequency = <10000000>;
+       };
+};
+
+&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 {
+               status = "okay";
+       };
+
+       u2phy0_host: host-port {
+               phy-supply = <&vcc5v0_host>;
+               status = "okay";
+       };
+};
+
+&u2phy1 {
+       status = "okay";
+
+       u2phy1_otg: otg-port {
+               status = "okay";
+       };
+
+       u2phy1_host: host-port {
+               phy-supply = <&vcc5v0_host>;
+               status = "okay";
+       };
+};
+
+&uart0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&uart0_xfer &uart0_cts &uart0_rts>;
+       status = "okay";
+
+       bluetooth {
+               compatible = "brcm,bcm43438-bt";
+               clocks = <&rk808 1>;
+               clock-names = "lpo";
+               device-wakeup-gpios = <&gpio2 RK_PD3 GPIO_ACTIVE_HIGH>;
+               host-wakeup-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_HIGH>;
+               shutdown-gpios = <&gpio0 RK_PB1 GPIO_ACTIVE_HIGH>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&bt_host_wake_l &bt_wake_l &bt_enable_h>;
+               vbat-supply = <&vcc3v3_sys>;
+               vddio-supply = <&vcc_1v8>;
+       };
+};
+
+&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";
+       dr_mode = "otg";
+};
+
+&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 808ea77..b4d8f60 100644 (file)
@@ -84,7 +84,7 @@
        };
 
        edp_panel: edp-panel {
-               compatible ="lg,lp079qx1-sp0v", "simple-panel";
+               compatible ="lg,lp079qx1-sp0v";
                backlight = <&backlight>;
                enable-gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>;
                pinctrl-names = "default";
index e62ea0e..33cc21f 100644 (file)
                status = "disabled";
        };
 
-       sdio0: dwmmc@fe310000 {
+       sdio0: mmc@fe310000 {
                compatible = "rockchip,rk3399-dw-mshc",
                             "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xfe310000 0x0 0x4000>;
                status = "disabled";
        };
 
-       sdmmc: dwmmc@fe320000 {
+       sdmmc: mmc@fe320000 {
                compatible = "rockchip,rk3399-dw-mshc",
                             "rockchip,rk3288-dw-mshc";
                reg = <0x0 0xfe320000 0x0 0x4000>;
                                        type = "critical";
                                };
                        };
+
+                       cooling-maps {
+                               map0 {
+                                       trip = <&gpu_alert0>;
+                                       cooling-device =
+                                               <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
+                               };
+                       };
                };
        };
 
                             <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH 0>;
                interrupt-names = "gpu", "job", "mmu";
                clocks = <&cru ACLK_GPU>;
+               #cooling-cells = <2>;
                power-domains = <&power RK3399_PD_GPU>;
                status = "disabled";
        };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-rock-pi-n10.dts b/arch/arm64/boot/dts/rockchip/rk3399pro-rock-pi-n10.dts
new file mode 100644 (file)
index 0000000..b42f941
--- /dev/null
@@ -0,0 +1,17 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2019 Radxa Limited
+ * Copyright (c) 2019 Amarula Solutions(India)
+ */
+
+/dts-v1/;
+#include "rk3399.dtsi"
+#include "rk3399-opp.dtsi"
+#include "rk3399pro-vmarc-som.dtsi"
+#include <arm/rockchip-radxa-dalang-carrier.dtsi>
+
+/ {
+       model = "Radxa ROCK Pi N10";
+       compatible = "radxa,rockpi-n10", "rockchip,rk3399pro";
+};
diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
new file mode 100644 (file)
index 0000000..0a51633
--- /dev/null
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+/*
+ * Copyright (c) 2019 Fuzhou Rockchip Electronics Co., Ltd
+ * Copyright (c) 2019 Vamrs Limited
+ * Copyright (c) 2019 Amarula Solutions(India)
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/pinctrl/rockchip.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/ {
+       compatible = "vamrs,rk3399pro-vmarc-som", "rockchip,rk3399pro";
+
+       clkin_gmac: external-gmac-clock {
+               compatible = "fixed-clock";
+               clock-frequency = <125000000>;
+               clock-output-names = "clkin_gmac";
+               #clock-cells = <0>;
+       };
+
+       vcc12v_dcin: vcc12v-dcin-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc12v_dcin";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <12000000>;
+               regulator-max-microvolt = <12000000>;
+       };
+
+       vcc5v0_sys: vcc5v0-sys-regulator {
+               compatible = "regulator-fixed";
+               regulator-name = "vcc5v0_sys";
+               regulator-always-on;
+               regulator-boot-on;
+               regulator-min-microvolt = <5000000>;
+               regulator-max-microvolt = <5000000>;
+               vin-supply = <&vcc12v_dcin>;
+       };
+};
+
+&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>;
+};
+
+&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>;
+};
+
+&i2c0 {
+       clock-frequency = <400000>;
+       i2c-scl-rising-time-ns = <180>;
+       i2c-scl-falling-time-ns = <30>;
+       status = "okay";
+
+       rk809: pmic@20 {
+               compatible = "rockchip,rk809";
+               reg = <0x20>;
+               interrupt-parent = <&gpio1>;
+               interrupts = <RK_PC2 IRQ_TYPE_LEVEL_LOW>;
+               #clock-cells = <1>;
+               clock-output-names = "rk808-clkout1", "rk808-clkout2";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pmic_int_l>;
+               rockchip,system-power-controller;
+               wakeup-source;
+
+               vcc1-supply = <&vcc5v0_sys>;
+               vcc2-supply = <&vcc5v0_sys>;
+               vcc3-supply = <&vcc5v0_sys>;
+               vcc4-supply = <&vcc5v0_sys>;
+               vcc5-supply = <&vcc_buck5>;
+               vcc6-supply = <&vcc_buck5>;
+               vcc7-supply = <&vcc5v0_sys>;
+               vcc8-supply = <&vcc3v3_sys>;
+               vcc9-supply = <&vcc5v0_sys>;
+
+               regulators {
+                       vdd_log: DCDC_REG1 {
+                               regulator-name = "vdd_log";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <750000>;
+                               regulator-max-microvolt = <1350000>;
+                               regulator-initial-mode = <0x2>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                                       regulator-suspend-microvolt = <900000>;
+                               };
+                       };
+
+                       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-initial-mode = <0x2>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_ddr: DCDC_REG3 {
+                               regulator-name = "vcc_ddr";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-initial-mode = <0x2>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                               };
+                       };
+
+                       vcc3v3_sys: DCDC_REG4 {
+                               regulator-name = "vcc3v3_sys";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-initial-mode = <0x2>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <3300000>;
+                               };
+                       };
+
+                       vcc_buck5: DCDC_REG5 {
+                               regulator-name = "vcc_buck5";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <2200000>;
+                               regulator-max-microvolt = <2200000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <2200000>;
+                               };
+                       };
+
+                       vcca_0v9: LDO_REG1 {
+                               regulator-name = "vcca_0v9";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc_1v8: LDO_REG2 {
+                               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>;
+                               };
+                       };
+
+                       vcc_0v9: LDO_REG3 {
+                               regulator-name = "vcc_0v9";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <900000>;
+                               regulator-max-microvolt = <900000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <900000>;
+                               };
+                       };
+
+                       vcca_1v8: LDO_REG4 {
+                               regulator-name = "vcca_1v8";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1850000>;
+                               regulator-max-microvolt = <1850000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       /*
+                        * As per BSP, but schematic not showing any regulator
+                        * pin for LD05.
+                        */
+                       vdd1v5_dvp: LDO_REG5 {
+                               regulator-name = "vdd1v5_dvp";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1500000>;
+                               regulator-max-microvolt = <1500000>;
+                               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-off-in-suspend;
+                               };
+                       };
+
+                       vccio_3v0: LDO_REG7 {
+                               regulator-name = "vccio_3v0";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3000000>;
+                               regulator-max-microvolt = <3000000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vccio_sd: LDO_REG8 {
+                               regulator-name = "vccio_sd";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <1800000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       /*
+                        * As per BSP, but schematic not showing any regulator
+                        * pin for LD09.
+                        */
+                       vcc_sd: LDO_REG9 {
+                               regulator-name = "vcc_sd";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+
+                       vcc5v0_usb2: SWITCH_REG1 {
+                               regulator-name = "vcc5v0_usb2";
+                               regulator-min-microvolt = <5000000>;
+                               regulator-max-microvolt = <5000000>;
+                               regulator-state-mem {
+                                       regulator-on-in-suspend;
+                                       regulator-suspend-microvolt = <5000000>;
+                               };
+                       };
+
+                       vccio_3v3: vcc_lan: SWITCH_REG2 {
+                               regulator-name = "vccio_3v3";
+                               regulator-always-on;
+                               regulator-boot-on;
+                               regulator-min-microvolt = <3300000>;
+                               regulator-max-microvolt = <3300000>;
+                               regulator-state-mem {
+                                       regulator-off-in-suspend;
+                               };
+                       };
+               };
+       };
+};
+
+&io_domains {
+       status = "okay";
+       bt656-supply = <&vcca_1v8>;
+       sdmmc-supply = <&vccio_sd>;
+       gpio1830-supply = <&vccio_3v0>;
+};
+
+&pmu_io_domains {
+       status = "okay";
+       pmu1830-supply = <&vcc_1v8>;
+};
+
+&sdhci {
+       bus-width = <8>;
+       mmc-hs400-1_8v;
+       mmc-hs400-enhanced-strobe;
+       non-removable;
+       status = "okay";
+};
+
+&tsadc {
+       status = "okay";
+       rockchip,hw-tshut-mode = <1>;
+       rockchip,hw-tshut-polarity = <1>;
+};
+
+&pinctrl {
+       pmic {
+               pmic_int_l: pmic-int-l {
+                       rockchip,pins =
+                               <1 RK_PC2 0 &pcfg_pull_up>;
+               };
+       };
+};
index 8ec40a0..5b18bda 100644 (file)
                        pinctrl-0 = <&pinctrl_nand>;
                        clock-names = "nand", "nand_x", "ecc";
                        clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
-                       resets = <&sys_rst 2>;
+                       reset-names = "nand", "reg";
+                       resets = <&sys_rst 2>, <&sys_rst 2>;
                };
        };
 };
index b658f2b..f2dc5f6 100644 (file)
                        pinctrl-0 = <&pinctrl_nand>;
                        clock-names = "nand", "nand_x", "ecc";
                        clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
-                       resets = <&sys_rst 2>;
+                       reset-names = "nand", "reg";
+                       resets = <&sys_rst 2>, <&sys_rst 2>;
                };
        };
 };
index d6f6cee..73e7e12 100644 (file)
                        pinctrl-0 = <&pinctrl_nand>;
                        clock-names = "nand", "nand_x", "ecc";
                        clocks = <&sys_clk 2>, <&sys_clk 3>, <&sys_clk 3>;
-                       resets = <&sys_rst 2>;
+                       reset-names = "nand", "reg";
+                       resets = <&sys_rst 2>, <&sys_rst 2>;
                };
        };
 };
index 2bdc238..f4f1f51 100644 (file)
@@ -1,3 +1,4 @@
 # SPDX-License-Identifier: GPL-2.0
 dtb-$(CONFIG_ARCH_SPRD) += sc9836-openphone.dtb \
-                       sp9860g-1h10.dtb
+                       sp9860g-1h10.dtb        \
+                       sp9863a-1h10.dtb
diff --git a/arch/arm64/boot/dts/sprd/sc9863a.dtsi b/arch/arm64/boot/dts/sprd/sc9863a.dtsi
new file mode 100644 (file)
index 0000000..cd80756
--- /dev/null
@@ -0,0 +1,523 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Unisoc SC9863A SoC DTS file
+ *
+ * Copyright (C) 2019, Unisoc Inc.
+ */
+
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+#include "sharkl3.dtsi"
+
+/ {
+       cpus {
+               #address-cells = <2>;
+               #size-cells = <0>;
+
+               cpu-map {
+                       cluster0 {
+                               core0 {
+                                       cpu = <&CPU0>;
+                               };
+                               core1 {
+                                       cpu = <&CPU1>;
+                               };
+                               core2 {
+                                       cpu = <&CPU2>;
+                               };
+                               core3 {
+                                       cpu = <&CPU3>;
+                               };
+                               core4 {
+                                       cpu = <&CPU4>;
+                               };
+                               core5 {
+                                       cpu = <&CPU5>;
+                               };
+                               core6 {
+                                       cpu = <&CPU6>;
+                               };
+                               core7 {
+                                       cpu = <&CPU7>;
+                               };
+                       };
+               };
+
+               CPU0: cpu@0 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x0>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CORE_PD>;
+               };
+
+               CPU1: cpu@100 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x100>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CORE_PD>;
+               };
+
+               CPU2: cpu@200 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x200>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CORE_PD>;
+               };
+
+               CPU3: cpu@300 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x300>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CORE_PD>;
+               };
+
+               CPU4: cpu@400 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x400>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CORE_PD>;
+               };
+
+               CPU5: cpu@500 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x500>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CORE_PD>;
+               };
+
+               CPU6: cpu@600 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x600>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CORE_PD>;
+               };
+
+               CPU7: cpu@700 {
+                       device_type = "cpu";
+                       compatible = "arm,cortex-a55";
+                       reg = <0x0 0x700>;
+                       enable-method = "psci";
+                       cpu-idle-states = <&CORE_PD>;
+               };
+       };
+
+       idle-states {
+               entry-method = "arm,psci";
+               CORE_PD: core-pd {
+                       compatible = "arm,idle-state";
+                       entry-latency-us = <4000>;
+                       exit-latency-us = <4000>;
+                       min-residency-us = <10000>;
+                       local-timer-stop;
+                       arm,psci-suspend-param = <0x00010000>;
+               };
+       };
+
+       psci {
+               compatible = "arm,psci-0.2";
+               method = "smc";
+       };
+
+       timer {
+               compatible = "arm,armv8-timer";
+               interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_HIGH>, /* Physical Secure PPI */
+                            <GIC_PPI 14 IRQ_TYPE_LEVEL_HIGH>, /* Physical Non-Secure PPI */
+                            <GIC_PPI 11 IRQ_TYPE_LEVEL_HIGH>, /* Virtual PPI */
+                            <GIC_PPI 10 IRQ_TYPE_LEVEL_HIGH>; /* Hipervisor PPI */
+       };
+
+       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>,
+                            <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>,
+                            <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>;
+       };
+
+       soc {
+               gic: interrupt-controller@14000000 {
+                       compatible = "arm,gic-v3";
+                       #interrupt-cells = <3>;
+                       #address-cells = <2>;
+                       #size-cells = <2>;
+                       ranges;
+                       redistributor-stride = <0x0 0x20000>;   /* 128KB stride */
+                       #redistributor-regions = <1>;
+                       interrupt-controller;
+                       reg = <0x0 0x14000000 0 0x20000>,       /* GICD */
+                             <0x0 0x14040000 0 0x100000>;      /* GICR */
+                       interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               funnel@10001000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x10001000 0 0x1000>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       funnel_soc_out_port: endpoint {
+                                               remote-endpoint = <&etb_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               port {
+                                       funnel_soc_in_port: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_ca55_out_port>;
+                                       };
+                               };
+                       };
+               };
+
+               etb@10003000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0 0x10003000 0 0x1000>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       in-ports {
+                               port {
+                                       etb_in: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_soc_out_port>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@12001000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x12001000 0 0x1000>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       funnel_little_out_port: endpoint {
+                                               remote-endpoint =
+                                               <&etf_little_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       funnel_little_in_port0: endpoint {
+                                               remote-endpoint = <&etm0_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       funnel_little_in_port1: endpoint {
+                                               remote-endpoint = <&etm1_out>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       funnel_little_in_port2: endpoint {
+                                               remote-endpoint = <&etm2_out>;
+                                       };
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       funnel_little_in_port3: endpoint {
+                                               remote-endpoint = <&etm3_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etf@12002000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0 0x12002000 0 0x1000>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etf_little_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_ca55_in_port0>;
+                                       };
+                               };
+                       };
+
+                       in-port {
+                               port {
+                                       etf_little_in: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_little_out_port>;
+                                       };
+                               };
+                       };
+               };
+
+               etf@12003000 {
+                       compatible = "arm,coresight-tmc", "arm,primecell";
+                       reg = <0 0x12003000 0 0x1000>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etf_big_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_ca55_in_port1>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               port {
+                                       etf_big_in: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_big_out_port>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@12004000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x12004000 0 0x1000>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       funnel_ca55_out_port: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_soc_in_port>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       funnel_ca55_in_port0: endpoint {
+                                               remote-endpoint =
+                                               <&etf_little_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       funnel_ca55_in_port1: endpoint {
+                                               remote-endpoint =
+                                               <&etf_big_out>;
+                                       };
+                               };
+                       };
+               };
+
+               funnel@12005000 {
+                       compatible = "arm,coresight-dynamic-funnel", "arm,primecell";
+                       reg = <0 0x12005000 0 0x1000>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       funnel_big_out_port: endpoint {
+                                               remote-endpoint =
+                                               <&etf_big_in>;
+                                       };
+                               };
+                       };
+
+                       in-ports {
+                               #address-cells = <1>;
+                               #size-cells = <0>;
+
+                               port@0 {
+                                       reg = <0>;
+                                       funnel_big_in_port0: endpoint {
+                                               remote-endpoint = <&etm4_out>;
+                                       };
+                               };
+
+                               port@1 {
+                                       reg = <1>;
+                                       funnel_big_in_port1: endpoint {
+                                               remote-endpoint = <&etm5_out>;
+                                       };
+                               };
+
+                               port@2 {
+                                       reg = <2>;
+                                       funnel_big_in_port2: endpoint {
+                                               remote-endpoint = <&etm6_out>;
+                                       };
+                               };
+
+                               port@3 {
+                                       reg = <3>;
+                                       funnel_big_in_port3: endpoint {
+                                               remote-endpoint = <&etm7_out>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@13040000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x13040000 0 0x1000>;
+                       cpu = <&CPU0>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm0_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_little_in_port0>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@13140000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x13140000 0 0x1000>;
+                       cpu = <&CPU1>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm1_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_little_in_port1>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@13240000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x13240000 0 0x1000>;
+                       cpu = <&CPU2>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm2_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_little_in_port2>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@13340000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x13340000 0 0x1000>;
+                       cpu = <&CPU3>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm3_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_little_in_port3>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@13440000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x13440000 0 0x1000>;
+                       cpu = <&CPU4>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm4_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_big_in_port0>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@13540000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x13540000 0 0x1000>;
+                       cpu = <&CPU5>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm5_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_big_in_port1>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@13640000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x13640000 0 0x1000>;
+                       cpu = <&CPU6>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm6_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_big_in_port2>;
+                                       };
+                               };
+                       };
+               };
+
+               etm@13740000 {
+                       compatible = "arm,coresight-etm4x", "arm,primecell";
+                       reg = <0 0x13740000 0 0x1000>;
+                       cpu = <&CPU7>;
+                       clocks = <&ext_26m>;
+                       clock-names = "apb_pclk";
+
+                       out-ports {
+                               port {
+                                       etm7_out: endpoint {
+                                               remote-endpoint =
+                                               <&funnel_big_in_port3>;
+                                       };
+                               };
+                       };
+               };
+       };
+};
diff --git a/arch/arm64/boot/dts/sprd/sharkl3.dtsi b/arch/arm64/boot/dts/sprd/sharkl3.dtsi
new file mode 100644 (file)
index 0000000..0222128
--- /dev/null
@@ -0,0 +1,78 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Unisoc Sharkl3 platform DTS file
+ *
+ * Copyright (C) 2019, Unisoc Inc.
+ */
+
+/ {
+       interrupt-parent = <&gic>;
+       #address-cells = <2>;
+       #size-cells = <2>;
+
+       soc: soc {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               apb@70000000 {
+                       compatible = "simple-bus";
+                       #address-cells = <1>;
+                       #size-cells = <1>;
+                       ranges = <0 0x0 0x70000000 0x10000000>;
+
+                       uart0: serial@0 {
+                               compatible = "sprd,sc9863a-uart",
+                                            "sprd,sc9836-uart";
+                               reg = <0x0 0x100>;
+                               interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&ext_26m>;
+                               status = "disabled";
+                       };
+
+                       uart1: serial@100000 {
+                               compatible = "sprd,sc9863a-uart",
+                                            "sprd,sc9836-uart";
+                               reg = <0x100000 0x100>;
+                               interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&ext_26m>;
+                               status = "disabled";
+                       };
+
+                       uart2: serial@200000 {
+                               compatible = "sprd,sc9863a-uart",
+                                            "sprd,sc9836-uart";
+                               reg = <0x200000 0x100>;
+                               interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&ext_26m>;
+                               status = "disabled";
+                       };
+
+                       uart3: serial@300000 {
+                               compatible = "sprd,sc9863a-uart",
+                                            "sprd,sc9836-uart";
+                               reg = <0x300000 0x100>;
+                               interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&ext_26m>;
+                               status = "disabled";
+                       };
+
+                       uart4: serial@400000 {
+                               compatible = "sprd,sc9863a-uart",
+                                            "sprd,sc9836-uart";
+                               reg = <0x400000 0x100>;
+                               interrupts = <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>;
+                               clocks = <&ext_26m>;
+                               status = "disabled";
+                       };
+               };
+       };
+
+       ext_26m: ext-26m {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <26000000>;
+               clock-output-names = "ext-26m";
+       };
+};
diff --git a/arch/arm64/boot/dts/sprd/sp9863a-1h10.dts b/arch/arm64/boot/dts/sprd/sp9863a-1h10.dts
new file mode 100644 (file)
index 0000000..5c32c15
--- /dev/null
@@ -0,0 +1,39 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Unisoc SP9863A-1h10 boards DTS file
+ *
+ * Copyright (C) 2019, Unisoc Inc.
+ */
+
+/dts-v1/;
+
+#include "sc9863a.dtsi"
+
+/ {
+       model = "Spreadtrum SP9863A-1H10 Board";
+
+       compatible = "sprd,sp9863a-1h10", "sprd,sc9863a";
+
+       aliases {
+               serial0 = &uart0;
+               serial1 = &uart1;
+       };
+
+       memory@80000000 {
+               device_type = "memory";
+               reg = <0x0 0x80000000 0x0 0x80000000>;
+       };
+
+       chosen {
+               stdout-path = "serial1:115200n8";
+               bootargs = "earlycon";
+       };
+};
+
+&uart0 {
+       status = "okay";
+};
+
+&uart1 {
+       status = "okay";
+};
index efb2457..e5df20a 100644 (file)
                };
        };
 
-       secure_proxy_main: mailbox@32c00000 {
-               compatible = "ti,am654-secure-proxy";
-               #mbox-cells = <1>;
-               reg-names = "target_data", "rt", "scfg";
-               reg = <0x00 0x32c00000 0x00 0x100000>,
-                     <0x00 0x32400000 0x00 0x100000>,
-                     <0x00 0x32800000 0x00 0x100000>;
-               interrupt-names = "rx_011";
-               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
-       };
-
        serdes0: serdes@900000 {
                compatible = "ti,phy-am654-serdes";
                reg = <0x0 0x900000 0x0 0x2000>;
                ti,sci-rm-range-girq = <0x1>;
        };
 
-       cbass_main_navss: interconnect0 {
-               compatible = "simple-bus";
+       main_navss {
+               compatible = "simple-mfd";
                #address-cells = <2>;
                #size-cells = <2>;
                ranges;
+               dma-coherent;
+               dma-ranges;
+
+               ti,sci-dev-id = <118>;
 
                intr_main_navss: interrupt-controller1 {
                        compatible = "ti,sci-intr";
                        ti,sci-rm-range-global-event = <0x1>;
                };
 
+               secure_proxy_main: mailbox@32c00000 {
+                       compatible = "ti,am654-secure-proxy";
+                       #mbox-cells = <1>;
+                       reg-names = "target_data", "rt", "scfg";
+                       reg = <0x00 0x32c00000 0x00 0x100000>,
+                             <0x00 0x32400000 0x00 0x100000>,
+                             <0x00 0x32800000 0x00 0x100000>;
+                       interrupt-names = "rx_011";
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
                hwspinlock: spinlock@30e00000 {
                        compatible = "ti,am654-hwspinlock";
                        reg = <0x00 0x30e00000 0x00 0x1000>;
                        ti,mbox-num-fifos = <16>;
                        interrupt-parent = <&intr_main_navss>;
                };
+
+               ringacc: ringacc@3c000000 {
+                       compatible = "ti,am654-navss-ringacc";
+                       reg =   <0x0 0x3c000000 0x0 0x400000>,
+                               <0x0 0x38000000 0x0 0x400000>,
+                               <0x0 0x31120000 0x0 0x100>,
+                               <0x0 0x33000000 0x0 0x40000>;
+                       reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target";
+                       ti,num-rings = <818>;
+                       ti,sci-rm-range-gp-rings = <0x2>; /* GP ring range */
+                       ti,dma-ring-reset-quirk;
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <187>;
+                       msi-parent = <&inta_main_udmass>;
+               };
+
+               main_udmap: dma-controller@31150000 {
+                       compatible = "ti,am654-navss-main-udmap";
+                       reg =   <0x0 0x31150000 0x0 0x100>,
+                               <0x0 0x34000000 0x0 0x100000>,
+                               <0x0 0x35000000 0x0 0x100000>;
+                       reg-names = "gcfg", "rchanrt", "tchanrt";
+                       msi-parent = <&inta_main_udmass>;
+                       #dma-cells = <1>;
+
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <188>;
+                       ti,ringacc = <&ringacc>;
+
+                       ti,sci-rm-range-tchan = <0x1>, /* TX_HCHAN */
+                                               <0x2>; /* TX_CHAN */
+                       ti,sci-rm-range-rchan = <0x4>, /* RX_HCHAN */
+                                               <0x5>; /* RX_CHAN */
+                       ti,sci-rm-range-rflow = <0x6>; /* GP RFLOW */
+               };
        };
 
        main_gpio0:  main_gpio0@600000 {
                dma-coherent;
                interrupts = <GIC_SPI 355 IRQ_TYPE_EDGE_RISING>;
        };
+
+       mcasp0: mcasp@2b00000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b00000 0x0 0x2000>,
+                       <0x0 0x02b08000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 209 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc400>, <&main_udmap 0x4400>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 104 0>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp1: mcasp@2b10000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b10000 0x0 0x2000>,
+                       <0x0 0x02b18000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc401>, <&main_udmap 0x4401>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 105 0>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 105 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp2: mcasp@2b20000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b20000 0x0 0x2000>,
+                       <0x0 0x02b28000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 213 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc402>, <&main_udmap 0x4402>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 106 0>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 106 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       cal: cal@6f03000 {
+               compatible = "ti,am654-cal";
+               reg = <0x0 0x06f03000 0x0 0x400>,
+                     <0x0 0x06f03800 0x0 0x40>;
+               reg-names = "cal_top",
+                           "cal_rx_core0";
+               interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>;
+               ti,camerrx-control = <&scm_conf 0x40c0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 2 0>;
+               power-domains = <&k3_pds 2 TI_SCI_PD_EXCLUSIVE>;
+
+               ports {
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+
+                       csi2_0: port@0 {
+                               reg = <0>;
+                       };
+               };
+       };
 };
index 7bdf534..92629cb 100644 (file)
@@ -6,6 +6,14 @@
  */
 
 &cbass_mcu {
+       mcu_conf: scm_conf@40f00000 {
+               compatible = "syscon", "simple-mfd";
+               reg = <0x0 0x40f00000 0x0 0x20000>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+               ranges = <0x0 0x0 0x40f00000 0x20000>;
+       };
+
        mcu_uart0: serial@40a00000 {
                compatible = "ti,am654-uart";
                        reg = <0x00 0x40a00000 0x00 0x100>;
                        compatible = "ti,am654-adc", "ti,am3359-adc";
                };
        };
+
+       mcu_navss {
+               compatible = "simple-mfd";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+               dma-coherent;
+               dma-ranges;
+
+               ti,sci-dev-id = <119>;
+
+               mcu_ringacc: ringacc@2b800000 {
+                       compatible = "ti,am654-navss-ringacc";
+                       reg =   <0x0 0x2b800000 0x0 0x400000>,
+                               <0x0 0x2b000000 0x0 0x400000>,
+                               <0x0 0x28590000 0x0 0x100>,
+                               <0x0 0x2a500000 0x0 0x40000>;
+                       reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target";
+                       ti,num-rings = <286>;
+                       ti,sci-rm-range-gp-rings = <0x2>; /* GP ring range */
+                       ti,dma-ring-reset-quirk;
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <195>;
+                       msi-parent = <&inta_main_udmass>;
+               };
+
+               mcu_udmap: dma-controller@285c0000 {
+                       compatible = "ti,am654-navss-mcu-udmap";
+                       reg =   <0x0 0x285c0000 0x0 0x100>,
+                               <0x0 0x2a800000 0x0 0x40000>,
+                               <0x0 0x2aa00000 0x0 0x40000>;
+                       reg-names = "gcfg", "rchanrt", "tchanrt";
+                       msi-parent = <&inta_main_udmass>;
+                       #dma-cells = <1>;
+
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <194>;
+                       ti,ringacc = <&mcu_ringacc>;
+
+                       ti,sci-rm-range-tchan = <0x1>, /* TX_HCHAN */
+                                               <0x2>; /* TX_CHAN */
+                       ti,sci-rm-range-rchan = <0x3>, /* RX_HCHAN */
+                                               <0x4>; /* RX_CHAN */
+                       ti,sci-rm-range-rflow = <0x5>; /* GP RFLOW */
+               };
+       };
+
+       fss: fss@47000000 {
+               compatible = "simple-bus";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               ospi0: spi@47040000 {
+                       compatible = "ti,am654-ospi", "cdns,qspi-nor";
+                       reg = <0x0 0x47040000 0x0 0x100>,
+                               <0x5 0x00000000 0x1 0x0000000>;
+                       interrupts = <GIC_SPI 552 IRQ_TYPE_LEVEL_HIGH>;
+                       cdns,fifo-depth = <256>;
+                       cdns,fifo-width = <4>;
+                       cdns,trigger-address = <0x0>;
+                       clocks = <&k3_clks 248 0>;
+                       assigned-clocks = <&k3_clks 248 0>;
+                       assigned-clock-parents = <&k3_clks 248 2>;
+                       assigned-clock-rates = <166666666>;
+                       power-domains = <&k3_pds 248 TI_SCI_PD_EXCLUSIVE>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               ospi1: spi@47050000 {
+                       compatible = "ti,am654-ospi", "cdns,qspi-nor";
+                       reg = <0x0 0x47050000 0x0 0x100>,
+                               <0x7 0x00000000 0x1 0x00000000>;
+                       interrupts = <GIC_SPI 553 IRQ_TYPE_LEVEL_HIGH>;
+                       cdns,fifo-depth = <256>;
+                       cdns,fifo-width = <4>;
+                       cdns,trigger-address = <0x0>;
+                       clocks = <&k3_clks 249 6>;
+                       power-domains = <&k3_pds 249 TI_SCI_PD_EXCLUSIVE>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
 };
index 6dfccd5..aea36e2 100644 (file)
                         /* MCUSS Range */
                         <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>,
                         <0x00 0x40200000 0x00 0x40200000 0x00 0x00900100>,
+                        <0x00 0x40f00000 0x00 0x40f00000 0x00 0x00020000>, /* CTRL_MMR0 */
                         <0x00 0x41000000 0x00 0x41000000 0x00 0x00020000>,
                         <0x00 0x41400000 0x00 0x41400000 0x00 0x00020000>,
                         <0x00 0x41c00000 0x00 0x41c00000 0x00 0x00080000>,
                         <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>,
                         <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>,
                         <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>,
-                        <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>;
+                        <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>,
+                        <0x00 0x50000000 0x00 0x50000000 0x00 0x8000000>,
+                        <0x00 0x70000000 0x00 0x70000000 0x00 0x200000>,
+                        <0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>,
+                        <0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>;
 
                cbass_mcu: interconnect@28380000 {
                        compatible = "simple-bus";
                        #size-cells = <2>;
                        ranges = <0x00 0x28380000 0x00 0x28380000 0x00 0x03880000>, /* MCU NAVSS*/
                                 <0x00 0x40200000 0x00 0x40200000 0x00 0x00900100>, /* First peripheral window */
+                                <0x00 0x40f00000 0x00 0x40f00000 0x00 0x00020000>, /* CTRL_MMR0 */
                                 <0x00 0x41000000 0x00 0x41000000 0x00 0x00020000>, /* MCU R5F Core0 */
                                 <0x00 0x41400000 0x00 0x41400000 0x00 0x00020000>, /* MCU R5F Core1 */
                                 <0x00 0x41c00000 0x00 0x41c00000 0x00 0x00080000>, /* MCU SRAM */
                                 <0x00 0x42040000 0x00 0x42040000 0x00 0x03ac2400>, /* WKUP */
                                 <0x00 0x45100000 0x00 0x45100000 0x00 0x00c24000>, /* MMRs, remaining NAVSS */
                                 <0x00 0x46000000 0x00 0x46000000 0x00 0x00200000>, /* CPSW */
-                                <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>; /* OSPI space 1 */
+                                <0x00 0x47000000 0x00 0x47000000 0x00 0x00068400>, /* OSPI space 1 */
+                                <0x00 0x50000000 0x00 0x50000000 0x00 0x8000000>, /*  FSS OSPI0 data region 1 */
+                                <0x05 0x00000000 0x05 0x00000000 0x01 0x0000000>, /* FSS OSPI0 data region 3*/
+                                <0x07 0x00000000 0x07 0x00000000 0x01 0x0000000>; /* FSS OSPI1 data region 3*/
 
                        cbass_wakeup: interconnect@42040000 {
                                compatible = "simple-bus";
index 8a85b48..1700996 100644 (file)
                        gpios = <&wkup_gpio0 27 GPIO_ACTIVE_LOW>;
                };
        };
+
+       clk_ov5640_fixed: clock {
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <24000000>;
+       };
 };
 
 &wkup_pmx0 {
                        AM65X_WKUP_IOPAD(0x003c, PIN_INPUT, 7) /* (P2) WKUP_GPIO0_27 */
                >;
        };
+
+       mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins_default {
+               pinctrl-single,pins = <
+                       AM65X_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* (V1) MCU_OSPI0_CLK */
+                       AM65X_WKUP_IOPAD(0x0008, PIN_INPUT, 0)   /* (U2) MCU_OSPI0_DQS */
+                       AM65X_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* (U4) MCU_OSPI0_D0 */
+                       AM65X_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* (U5) MCU_OSPI0_D1 */
+                       AM65X_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* (T2) MCU_OSPI0_D2 */
+                       AM65X_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* (T3) MCU_OSPI0_D3 */
+                       AM65X_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* (T4) MCU_OSPI0_D4 */
+                       AM65X_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* (T5) MCU_OSPI0_D5 */
+                       AM65X_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* (R2) MCU_OSPI0_D6 */
+                       AM65X_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* (R3) MCU_OSPI0_D7 */
+                       AM65X_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* (R4) MCU_OSPI0_CSn0 */
+               >;
+       };
+
+       wkup_pca554_default: wkup_pca554_default {
+               pinctrl-single,pins = <
+                       AM65X_WKUP_IOPAD(0x0034, PIN_INPUT, 7) /* (T1) MCU_OSPI1_CLK.WKUP_GPIO0_25 */
+
+               >;
+       };
 };
 
 &main_pmx0 {
                reg = <0x39>;
                gpio-controller;
                #gpio-cells = <2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&wkup_pca554_default>;
+               interrupt-parent = <&wkup_gpio0>;
+               interrupts = <25 IRQ_TYPE_EDGE_FALLING>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
        };
 };
 
        pinctrl-names = "default";
        pinctrl-0 = <&main_i2c1_pins_default>;
        clock-frequency = <400000>;
+
+       ov5640@3c {
+               compatible = "ovti,ov5640";
+               reg = <0x3c>;
+
+               clocks = <&clk_ov5640_fixed>;
+               clock-names = "xclk";
+
+               port {
+                       csi2_cam0: endpoint {
+                               remote-endpoint = <&csi2_phy0>;
+                               clock-lanes = <0>;
+                               data-lanes = <1 2>;
+                       };
+               };
+       };
+
 };
 
 &main_i2c2 {
 &mailbox0_cluster11 {
        status = "disabled";
 };
+
+&ospi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+       flash@0{
+               compatible = "jedec,spi-nor";
+               reg = <0x0>;
+               spi-tx-bus-width = <1>;
+               spi-rx-bus-width = <8>;
+               spi-max-frequency = <40000000>;
+               cdns,tshsl-ns = <60>;
+               cdns,tsd2d-ns = <60>;
+               cdns,tchsh-ns = <60>;
+               cdns,tslch-ns = <60>;
+               cdns,read-delay = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
+
+&csi2_0 {
+       csi2_phy0: endpoint {
+               remote-endpoint = <&csi2_cam0>;
+               clock-lanes = <0>;
+               data-lanes = <1 2>;
+       };
+};
index 2a3cd61..7a5c3d4 100644 (file)
                        J721E_IOPAD(0x214, PIN_OUTPUT, 4) /* (V4) MCAN1_TX.USB1_DRVVBUS */
                >;
        };
+
+       main_i2c1_exp4_pins_default: main-i2c1-exp4-pins-default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x230, PIN_INPUT, 7) /* (U2) ECAP0_IN_APWM_OUT.GPIO1_11 */
+               >;
+       };
+
+       main_i2c0_pins_default: main-i2c0-pins-default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x220, PIN_INPUT_PULLUP, 0) /* (AC5) I2C0_SCL */
+                       J721E_IOPAD(0x224, PIN_INPUT_PULLUP, 0) /* (AA5) I2C0_SDA */
+               >;
+       };
+
+       main_i2c1_pins_default: main-i2c1-pins-default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x228, PIN_INPUT_PULLUP, 0) /* (Y6) I2C1_SCL */
+                       J721E_IOPAD(0x22c, PIN_INPUT_PULLUP, 0) /* (AA6) I2C1_SDA */
+               >;
+       };
+
+       main_i2c3_pins_default: main-i2c3-pins-default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x270, PIN_INPUT_PULLUP, 4) /* (T26) MMC2_CLK.I2C3_SCL */
+                       J721E_IOPAD(0x274, PIN_INPUT_PULLUP, 4) /* (T25) MMC2_CMD.I2C3_SDA */
+               >;
+       };
+
+       main_i2c6_pins_default: main-i2c6-pins-default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x1d0, PIN_INPUT_PULLUP, 2) /* (AA3) SPI0_D1.I2C6_SCL */
+                       J721E_IOPAD(0x1e4, PIN_INPUT_PULLUP, 2) /* (Y2) SPI1_D1.I2C6_SDA */
+               >;
+       };
+
+       main_i2c1_exp4_pins_default: main-i2c1-exp4-pins-default {
+               pinctrl-single,pins = <
+                       J721E_IOPAD(0x230, PIN_INPUT, 7) /* (U2) ECAP0_IN_APWM_OUT.GPIO1_11 */
+                >;
+       };
 };
 
 &wkup_pmx0 {
                        J721E_WKUP_IOPAD(0xcc, PIN_INPUT, 7) /* (G28) WKUP_GPIO0_7 */
                >;
        };
+
+       mcu_fss0_ospi1_pins_default: mcu-fss0-ospi1-pins-default {
+               pinctrl-single,pins = <
+                       J721E_WKUP_IOPAD(0x34, PIN_OUTPUT, 0) /* (F22) MCU_OSPI1_CLK */
+                       J721E_WKUP_IOPAD(0x50, PIN_OUTPUT, 0) /* (C22) MCU_OSPI1_CSn0 */
+                       J721E_WKUP_IOPAD(0x40, PIN_INPUT, 0) /* (D22) MCU_OSPI1_D0 */
+                       J721E_WKUP_IOPAD(0x44, PIN_INPUT, 0) /* (G22) MCU_OSPI1_D1 */
+                       J721E_WKUP_IOPAD(0x48, PIN_INPUT, 0) /* (D23) MCU_OSPI1_D2 */
+                       J721E_WKUP_IOPAD(0x4c, PIN_INPUT, 0) /* (C23) MCU_OSPI1_D3 */
+                       J721E_WKUP_IOPAD(0x3c, PIN_INPUT, 0) /* (B23) MCU_OSPI1_DQS */
+                       J721E_WKUP_IOPAD(0x38, PIN_INPUT, 0) /* (A23) MCU_OSPI1_LBCLKO */
+               >;
+       };
 };
 
 &wkup_uart0 {
        dr_mode = "host";
        maximum-speed = "high-speed";
 };
+
+&ospi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcu_fss0_ospi1_pins_default>;
+
+       flash@0{
+               compatible = "jedec,spi-nor";
+               reg = <0x0>;
+               spi-tx-bus-width = <1>;
+               spi-rx-bus-width = <4>;
+               spi-max-frequency = <40000000>;
+               cdns,tshsl-ns = <60>;
+               cdns,tsd2d-ns = <60>;
+               cdns,tchsh-ns = <60>;
+               cdns,tslch-ns = <60>;
+               cdns,read-delay = <2>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
+
+&tscadc0 {
+       adc {
+               ti,adc-channels = <0 1 2 3 4 5 6 7>;
+       };
+};
+
+&tscadc1 {
+       adc {
+               ti,adc-channels = <0 1 2 3 4 5 6 7>;
+       };
+};
+
+&main_i2c0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_i2c0_pins_default>;
+       clock-frequency = <400000>;
+
+       exp1: gpio@20 {
+               compatible = "ti,tca6416";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+
+       exp2: gpio@22 {
+               compatible = "ti,tca6424";
+               reg = <0x22>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
+&main_i2c1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_i2c1_pins_default>;
+       clock-frequency = <400000>;
+
+       exp4: gpio@20 {
+               compatible = "ti,tca6408";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&main_i2c1_exp4_pins_default>;
+               interrupt-parent = <&main_gpio1>;
+               interrupts = <11 IRQ_TYPE_EDGE_FALLING>;
+               interrupt-controller;
+               #interrupt-cells = <2>;
+       };
+};
+
+&main_i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_i2c3_pins_default>;
+       clock-frequency = <400000>;
+
+       exp3: gpio@20 {
+               compatible = "ti,tca6408";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
+
+&main_i2c6 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&main_i2c6_pins_default>;
+       clock-frequency = <400000>;
+
+       exp5: gpio@20 {
+               compatible = "ti,tca6408";
+               reg = <0x20>;
+               gpio-controller;
+               #gpio-cells = <2>;
+       };
+};
index 1e4c2b7..0b9d14b 100644 (file)
                };
        };
 
-       smmu0: smmu@36600000 {
-               compatible = "arm,smmu-v3";
-               reg = <0x0 0x36600000 0x0 0x100000>;
-               interrupt-parent = <&gic500>;
-               interrupts = <GIC_SPI 772 IRQ_TYPE_EDGE_RISING>,
-                            <GIC_SPI 768 IRQ_TYPE_EDGE_RISING>;
-               interrupt-names = "eventq", "gerror";
-               #iommu-cells = <1>;
-       };
-
        main_gpio_intr: interrupt-controller0 {
                compatible = "ti,sci-intr";
                ti,intr-trigger-type = <1>;
                ti,sci-rm-range-girq = <0x1>;
        };
 
-       cbass_main_navss: interconnect0 {
-               compatible = "simple-bus";
+       main_navss {
+               compatible = "simple-mfd";
                #address-cells = <2>;
                #size-cells = <2>;
                ranges;
+               dma-coherent;
+               dma-ranges;
+
+               ti,sci-dev-id = <199>;
 
                main_navss_intr: interrupt-controller1 {
                        compatible = "ti,sci-intr";
                        ti,sci-rm-range-global-event = <0xd>;
                };
 
+               secure_proxy_main: mailbox@32c00000 {
+                       compatible = "ti,am654-secure-proxy";
+                       #mbox-cells = <1>;
+                       reg-names = "target_data", "rt", "scfg";
+                       reg = <0x00 0x32c00000 0x00 0x100000>,
+                             <0x00 0x32400000 0x00 0x100000>,
+                             <0x00 0x32800000 0x00 0x100000>;
+                       interrupt-names = "rx_011";
+                       interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               };
+
+               smmu0: smmu@36600000 {
+                       compatible = "arm,smmu-v3";
+                       reg = <0x0 0x36600000 0x0 0x100000>;
+                       interrupt-parent = <&gic500>;
+                       interrupts = <GIC_SPI 772 IRQ_TYPE_EDGE_RISING>,
+                                    <GIC_SPI 768 IRQ_TYPE_EDGE_RISING>;
+                       interrupt-names = "eventq", "gerror";
+                       #iommu-cells = <1>;
+               };
+
                hwspinlock: spinlock@30e00000 {
                        compatible = "ti,am654-hwspinlock";
                        reg = <0x00 0x30e00000 0x00 0x1000>;
                        ti,mbox-num-fifos = <16>;
                        interrupt-parent = <&main_navss_intr>;
                };
-       };
 
-       secure_proxy_main: mailbox@32c00000 {
-               compatible = "ti,am654-secure-proxy";
-               #mbox-cells = <1>;
-               reg-names = "target_data", "rt", "scfg";
-               reg = <0x00 0x32c00000 0x00 0x100000>,
-                     <0x00 0x32400000 0x00 0x100000>,
-                     <0x00 0x32800000 0x00 0x100000>;
-               interrupt-names = "rx_011";
-               interrupts = <GIC_SPI 37 IRQ_TYPE_LEVEL_HIGH>;
+               main_ringacc: ringacc@3c000000 {
+                       compatible = "ti,am654-navss-ringacc";
+                       reg =   <0x0 0x3c000000 0x0 0x400000>,
+                               <0x0 0x38000000 0x0 0x400000>,
+                               <0x0 0x31120000 0x0 0x100>,
+                               <0x0 0x33000000 0x0 0x40000>;
+                       reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target";
+                       ti,num-rings = <1024>;
+                       ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <211>;
+                       msi-parent = <&main_udmass_inta>;
+               };
+
+               main_udmap: dma-controller@31150000 {
+                       compatible = "ti,j721e-navss-main-udmap";
+                       reg =   <0x0 0x31150000 0x0 0x100>,
+                               <0x0 0x34000000 0x0 0x100000>,
+                               <0x0 0x35000000 0x0 0x100000>;
+                       reg-names = "gcfg", "rchanrt", "tchanrt";
+                       msi-parent = <&main_udmass_inta>;
+                       #dma-cells = <1>;
+
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <212>;
+                       ti,ringacc = <&main_ringacc>;
+
+                       ti,sci-rm-range-tchan = <0x0d>, /* TX_CHAN */
+                                               <0x0f>, /* TX_HCHAN */
+                                               <0x10>; /* TX_UHCHAN */
+                       ti,sci-rm-range-rchan = <0x0a>, /* RX_CHAN */
+                                               <0x0b>, /* RX_HCHAN */
+                                               <0x0c>; /* RX_UHCHAN */
+                       ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */
+               };
        };
 
        main_pmx0: pinmux@11c000 {
                        dr_mode = "otg";
                };
        };
+
+       main_i2c0: i2c@2000000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2000000 0x0 0x100>;
+               interrupts = <GIC_SPI 200 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 187 0>;
+               power-domains = <&k3_pds 187 TI_SCI_PD_SHARED>;
+       };
+
+       main_i2c1: i2c@2010000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2010000 0x0 0x100>;
+               interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 188 0>;
+               power-domains = <&k3_pds 188 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c2: i2c@2020000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2020000 0x0 0x100>;
+               interrupts = <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 189 0>;
+               power-domains = <&k3_pds 189 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c3: i2c@2030000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2030000 0x0 0x100>;
+               interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 190 0>;
+               power-domains = <&k3_pds 190 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c4: i2c@2040000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2040000 0x0 0x100>;
+               interrupts = <GIC_SPI 204 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 191 0>;
+               power-domains = <&k3_pds 191 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c5: i2c@2050000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2050000 0x0 0x100>;
+               interrupts = <GIC_SPI 205 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 192 0>;
+               power-domains = <&k3_pds 192 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       main_i2c6: i2c@2060000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x2060000 0x0 0x100>;
+               interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 193 0>;
+               power-domains = <&k3_pds 193 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       ufs_wrapper: ufs-wrapper@4e80000 {
+               compatible = "ti,j721e-ufs";
+               reg = <0x0 0x4e80000 0x0 0x100>;
+               power-domains = <&k3_pds 277 TI_SCI_PD_EXCLUSIVE>;
+               clocks = <&k3_clks 277 1>;
+               assigned-clocks = <&k3_clks 277 1>;
+               assigned-clock-parents = <&k3_clks 277 4>;
+               ranges;
+               #address-cells = <2>;
+               #size-cells = <2>;
+
+               ufs@4e84000 {
+                       compatible = "cdns,ufshc-m31-16nm", "jedec,ufs-2.0";
+                       reg = <0x0 0x4e84000 0x0 0x10000>;
+                       interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>;
+                       freq-table-hz = <250000000 250000000>, <19200000 19200000>, <19200000 19200000>;
+                       clocks = <&k3_clks 277 0>, <&k3_clks 277 1>, <&k3_clks 277 1>;
+                       clock-names = "core_clk", "phy_clk", "ref_clk";
+                       dma-coherent;
+               };
+       };
+
+       mcasp0: mcasp@2b00000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b00000 0x0 0x2000>,
+                       <0x0 0x02b08000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 544 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 545 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc400>, <&main_udmap 0x4400>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 174 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 174 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp1: mcasp@2b10000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b10000 0x0 0x2000>,
+                       <0x0 0x02b18000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 546 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 547 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc401>, <&main_udmap 0x4401>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 175 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 175 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp2: mcasp@2b20000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b20000 0x0 0x2000>,
+                       <0x0 0x02b28000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 548 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 549 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc402>, <&main_udmap 0x4402>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 176 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 176 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp3: mcasp@2b30000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b30000 0x0 0x2000>,
+                       <0x0 0x02b38000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 550 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 551 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc500>, <&main_udmap 0x4500>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 177 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 177 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp4: mcasp@2b40000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b40000 0x0 0x2000>,
+                       <0x0 0x02b48000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 552 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 553 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc501>, <&main_udmap 0x4501>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 178 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 178 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp5: mcasp@2b50000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b50000 0x0 0x2000>,
+                       <0x0 0x02b58000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 554 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 555 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc502>, <&main_udmap 0x4502>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 179 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp6: mcasp@2b60000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b60000 0x0 0x2000>,
+                       <0x0 0x02b68000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 556 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 557 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc503>, <&main_udmap 0x4503>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 180 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 180 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp7: mcasp@2b70000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b70000 0x0 0x2000>,
+                       <0x0 0x02b78000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 558 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 559 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc504>, <&main_udmap 0x4504>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 181 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 181 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp8: mcasp@2b80000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b80000 0x0 0x2000>,
+                       <0x0 0x02b88000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 560 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 561 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc505>, <&main_udmap 0x4505>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 182 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 182 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp9: mcasp@2b90000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02b90000 0x0 0x2000>,
+                       <0x0 0x02b98000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 562 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 563 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc506>, <&main_udmap 0x4506>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 183 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 183 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp10: mcasp@2ba0000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02ba0000 0x0 0x2000>,
+                       <0x0 0x02ba8000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 564 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 565 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc507>, <&main_udmap 0x4507>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 184 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 184 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
+
+       mcasp11: mcasp@2bb0000 {
+               compatible = "ti,am33xx-mcasp-audio";
+               reg = <0x0 0x02bb0000 0x0 0x2000>,
+                       <0x0 0x02bb8000 0x0 0x1000>;
+               reg-names = "mpu","dat";
+               interrupts = <GIC_SPI 566 IRQ_TYPE_LEVEL_HIGH>,
+                               <GIC_SPI 567 IRQ_TYPE_LEVEL_HIGH>;
+               interrupt-names = "tx", "rx";
+
+               dmas = <&main_udmap 0xc508>, <&main_udmap 0x4508>;
+               dma-names = "tx", "rx";
+
+               clocks = <&k3_clks 185 1>;
+               clock-names = "fck";
+               power-domains = <&k3_pds 185 TI_SCI_PD_EXCLUSIVE>;
+
+               status = "disabled";
+       };
 };
index 555dc7b..16c874b 100644 (file)
                clocks = <&k3_clks 114 0>;
                clock-names = "gpio";
        };
+
+       mcu_i2c0: i2c@40b00000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x40b00000 0x0 0x100>;
+               interrupts = <GIC_SPI 852 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 194 0>;
+               power-domains = <&k3_pds 194 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       mcu_i2c1: i2c@40b10000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x40b10000 0x0 0x100>;
+               interrupts = <GIC_SPI 853 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 195 0>;
+               power-domains = <&k3_pds 195 TI_SCI_PD_EXCLUSIVE>;
+       };
+
+       wkup_i2c0: i2c@42120000 {
+               compatible = "ti,j721e-i2c", "ti,omap4-i2c";
+               reg = <0x0 0x42120000 0x0 0x100>;
+               interrupts = <GIC_SPI 896 IRQ_TYPE_LEVEL_HIGH>;
+               #address-cells = <1>;
+               #size-cells = <0>;
+               clock-names = "fck";
+               clocks = <&k3_clks 197 0>;
+               power-domains = <&k3_pds 197 TI_SCI_PD_SHARED>;
+       };
+
+       fss: fss@47000000 {
+               compatible = "simple-bus";
+               reg = <0x0 0x47000000 0x0 0x100>;
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+
+               ospi0: spi@47040000 {
+                       compatible = "ti,am654-ospi";
+                       reg = <0x0 0x47040000 0x0 0x100>,
+                               <0x5 0x00000000 0x1 0x0000000>;
+                       interrupts = <GIC_SPI 840 IRQ_TYPE_LEVEL_HIGH>;
+                       cdns,fifo-depth = <256>;
+                       cdns,fifo-width = <4>;
+                       cdns,trigger-address = <0x0>;
+                       clocks = <&k3_clks 103 0>;
+                       assigned-clocks = <&k3_clks 103 0>;
+                       assigned-clock-parents = <&k3_clks 103 2>;
+                       assigned-clock-rates = <166666666>;
+                       power-domains = <&k3_pds 103 TI_SCI_PD_EXCLUSIVE>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+
+               ospi1: spi@47050000 {
+                       compatible = "ti,am654-ospi";
+                       reg = <0x0 0x47050000 0x0 0x100>,
+                               <0x7 0x00000000 0x1 0x00000000>;
+                       interrupts = <GIC_SPI 841 IRQ_TYPE_LEVEL_HIGH>;
+                       cdns,fifo-depth = <256>;
+                       cdns,fifo-width = <4>;
+                       cdns,trigger-address = <0x0>;
+                       clocks = <&k3_clks 104 0>;
+                       power-domains = <&k3_pds 104 TI_SCI_PD_EXCLUSIVE>;
+                       #address-cells = <1>;
+                       #size-cells = <0>;
+               };
+       };
+
+       tscadc0: tscadc@40200000 {
+               compatible = "ti,am3359-tscadc";
+               reg = <0x0 0x40200000 0x0 0x1000>;
+               interrupts = <GIC_SPI 860 IRQ_TYPE_LEVEL_HIGH>;
+               power-domains = <&k3_pds 0 TI_SCI_PD_EXCLUSIVE>;
+               clocks = <&k3_clks 0 1>;
+               assigned-clocks = <&k3_clks 0 3>;
+               assigned-clock-rates = <60000000>;
+               clock-names = "adc_tsc_fck";
+
+               adc {
+                       #io-channel-cells = <1>;
+                       compatible = "ti,am3359-adc";
+               };
+       };
+
+       tscadc1: tscadc@40210000 {
+               compatible = "ti,am3359-tscadc";
+               reg = <0x0 0x40210000 0x0 0x1000>;
+               interrupts = <GIC_SPI 861 IRQ_TYPE_LEVEL_HIGH>;
+               power-domains = <&k3_pds 1 TI_SCI_PD_EXCLUSIVE>;
+               clocks = <&k3_clks 1 1>;
+               assigned-clocks = <&k3_clks 1 3>;
+               assigned-clock-rates = <60000000>;
+               clock-names = "adc_tsc_fck";
+
+               adc {
+                       #io-channel-cells = <1>;
+                       compatible = "ti,am3359-adc";
+               };
+       };
+
+       mcu_navss {
+               compatible = "simple-mfd";
+               #address-cells = <2>;
+               #size-cells = <2>;
+               ranges;
+               dma-coherent;
+               dma-ranges;
+
+               ti,sci-dev-id = <232>;
+
+               mcu_ringacc: ringacc@2b800000 {
+                       compatible = "ti,am654-navss-ringacc";
+                       reg =   <0x0 0x2b800000 0x0 0x400000>,
+                               <0x0 0x2b000000 0x0 0x400000>,
+                               <0x0 0x28590000 0x0 0x100>,
+                               <0x0 0x2a500000 0x0 0x40000>;
+                       reg-names = "rt", "fifos", "proxy_gcfg", "proxy_target";
+                       ti,num-rings = <286>;
+                       ti,sci-rm-range-gp-rings = <0x1>; /* GP ring range */
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <235>;
+                       msi-parent = <&main_udmass_inta>;
+               };
+
+               mcu_udmap: dma-controller@285c0000 {
+                       compatible = "ti,j721e-navss-mcu-udmap";
+                       reg =   <0x0 0x285c0000 0x0 0x100>,
+                               <0x0 0x2a800000 0x0 0x40000>,
+                               <0x0 0x2aa00000 0x0 0x40000>;
+                       reg-names = "gcfg", "rchanrt", "tchanrt";
+                       msi-parent = <&main_udmass_inta>;
+                       #dma-cells = <1>;
+
+                       ti,sci = <&dmsc>;
+                       ti,sci-dev-id = <236>;
+                       ti,ringacc = <&mcu_ringacc>;
+
+                       ti,sci-rm-range-tchan = <0x0d>, /* TX_CHAN */
+                                               <0x0f>; /* TX_HCHAN */
+                       ti,sci-rm-range-rchan = <0x0a>, /* RX_CHAN */
+                                               <0x0b>; /* RX_HCHAN */
+                       ti,sci-rm-range-rflow = <0x00>; /* GP RFLOW */
+               };
+       };
 };
index 1884fc7..7680109 100644 (file)
                };
        };
 };
+
+&wkup_pmx0 {
+       wkup_i2c0_pins_default: wkup_i2c0_pins_default {
+               pinctrl-single,pins = <
+                       J721E_WKUP_IOPAD(0xf8, PIN_INPUT_PULLUP, 0) /* (J25) WKUP_I2C0_SCL */
+                       J721E_WKUP_IOPAD(0xfc, PIN_INPUT_PULLUP, 0) /* (H24) WKUP_I2C0_SDA */
+               >;
+       };
+
+       mcu_fss0_ospi0_pins_default: mcu-fss0-ospi0-pins-default {
+               pinctrl-single,pins = <
+                       J721E_WKUP_IOPAD(0x0000, PIN_OUTPUT, 0) /* MCU_OSPI0_CLK */
+                       J721E_WKUP_IOPAD(0x0008, PIN_INPUT, 0)  /* MCU_OSPI0_DQS */
+                       J721E_WKUP_IOPAD(0x000c, PIN_INPUT, 0)  /* MCU_OSPI0_D0 */
+                       J721E_WKUP_IOPAD(0x0010, PIN_INPUT, 0)  /* MCU_OSPI0_D1 */
+                       J721E_WKUP_IOPAD(0x0014, PIN_INPUT, 0)  /* MCU_OSPI0_D2 */
+                       J721E_WKUP_IOPAD(0x0018, PIN_INPUT, 0)  /* MCU_OSPI0_D3 */
+                       J721E_WKUP_IOPAD(0x001c, PIN_INPUT, 0)  /* MCU_OSPI0_D4 */
+                       J721E_WKUP_IOPAD(0x0020, PIN_INPUT, 0)  /* MCU_OSPI0_D5 */
+                       J721E_WKUP_IOPAD(0x0024, PIN_INPUT, 0)  /* MCU_OSPI0_D6 */
+                       J721E_WKUP_IOPAD(0x0028, PIN_INPUT, 0)  /* MCU_OSPI0_D7 */
+                       J721E_WKUP_IOPAD(0x002c, PIN_OUTPUT, 0) /* MCU_OSPI0_CSn0 */
+               >;
+       };
+};
+
+&ospi0 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&mcu_fss0_ospi0_pins_default>;
+
+       flash@0{
+               compatible = "jedec,spi-nor";
+               reg = <0x0>;
+               spi-tx-bus-width = <1>;
+               spi-rx-bus-width = <8>;
+               spi-max-frequency = <40000000>;
+               cdns,tshsl-ns = <60>;
+               cdns,tsd2d-ns = <60>;
+               cdns,tchsh-ns = <60>;
+               cdns,tslch-ns = <60>;
+               cdns,read-delay = <0>;
+               #address-cells = <1>;
+               #size-cells = <1>;
+       };
+};
index ee5470e..027bd1f 100644 (file)
                         <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 0x30000000 0x00 0x30000000 0x00 0x0c400000>, /* MAIN NAVSS */
                         <0x00 0x0d000000 0x00 0x0d000000 0x00 0x01000000>, /* PCIe Core*/
                         <0x00 0x10000000 0x00 0x10000000 0x00 0x10000000>, /* PCIe DAT */
                         <0x00 0x64800000 0x00 0x64800000 0x00 0x00800000>, /* C71 */
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk-ccf.dtsi
new file mode 100644 (file)
index 0000000..9868ca1
--- /dev/null
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Clock specification for Xilinx ZynqMP
+ *
+ * (C) Copyright 2017 - 2019, Xilinx, Inc.
+ *
+ * Michal Simek <michal.simek@xilinx.com>
+ */
+
+#include <dt-bindings/clock/xlnx-zynqmp-clk.h>
+/ {
+       pss_ref_clk: pss_ref_clk {
+               u-boot,dm-pre-reloc;
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <33333333>;
+       };
+
+       video_clk: video_clk {
+               u-boot,dm-pre-reloc;
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <27000000>;
+       };
+
+       pss_alt_ref_clk: pss_alt_ref_clk {
+               u-boot,dm-pre-reloc;
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <0>;
+       };
+
+       gt_crx_ref_clk: gt_crx_ref_clk {
+               u-boot,dm-pre-reloc;
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <108000000>;
+       };
+
+       aux_ref_clk: aux_ref_clk {
+               u-boot,dm-pre-reloc;
+               compatible = "fixed-clock";
+               #clock-cells = <0>;
+               clock-frequency = <27000000>;
+       };
+};
+
+&can0 {
+       clocks = <&zynqmp_clk CAN0_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&can1 {
+       clocks = <&zynqmp_clk CAN1_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&cpu0 {
+       clocks = <&zynqmp_clk ACPU>;
+};
+
+&fpd_dma_chan1 {
+       clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&fpd_dma_chan2 {
+       clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&fpd_dma_chan3 {
+       clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&fpd_dma_chan4 {
+       clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&fpd_dma_chan5 {
+       clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&fpd_dma_chan6 {
+       clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&fpd_dma_chan7 {
+       clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&fpd_dma_chan8 {
+       clocks = <&zynqmp_clk GDMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&lpd_dma_chan1 {
+       clocks = <&zynqmp_clk ADMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&lpd_dma_chan2 {
+       clocks = <&zynqmp_clk ADMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&lpd_dma_chan3 {
+       clocks = <&zynqmp_clk ADMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&lpd_dma_chan4 {
+       clocks = <&zynqmp_clk ADMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&lpd_dma_chan5 {
+       clocks = <&zynqmp_clk ADMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&lpd_dma_chan6 {
+       clocks = <&zynqmp_clk ADMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&lpd_dma_chan7 {
+       clocks = <&zynqmp_clk ADMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&lpd_dma_chan8 {
+       clocks = <&zynqmp_clk ADMA_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&gem0 {
+       clocks = <&zynqmp_clk LPD_LSBUS>, <&zynqmp_clk GEM0_REF>,
+                <&zynqmp_clk GEM0_TX>, <&zynqmp_clk GEM0_RX>,
+                <&zynqmp_clk GEM_TSU>;
+       clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+};
+
+&gem1 {
+       clocks = <&zynqmp_clk LPD_LSBUS>, <&zynqmp_clk GEM1_REF>,
+                <&zynqmp_clk GEM1_TX>, <&zynqmp_clk GEM1_RX>,
+                <&zynqmp_clk GEM_TSU>;
+       clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+};
+
+&gem2 {
+       clocks = <&zynqmp_clk LPD_LSBUS>, <&zynqmp_clk GEM2_REF>,
+                <&zynqmp_clk GEM2_TX>, <&zynqmp_clk GEM2_RX>,
+                <&zynqmp_clk GEM_TSU>;
+       clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+};
+
+&gem3 {
+       clocks = <&zynqmp_clk LPD_LSBUS>, <&zynqmp_clk GEM3_REF>,
+                <&zynqmp_clk GEM3_TX>, <&zynqmp_clk GEM3_RX>,
+                <&zynqmp_clk GEM_TSU>;
+       clock-names = "pclk", "hclk", "tx_clk", "rx_clk", "tsu_clk";
+};
+
+&gpio {
+       clocks = <&zynqmp_clk LPD_LSBUS>;
+};
+
+&i2c0 {
+       clocks = <&zynqmp_clk I2C0_REF>;
+};
+
+&i2c1 {
+       clocks = <&zynqmp_clk I2C1_REF>;
+};
+
+&pcie {
+       clocks = <&zynqmp_clk PCIE_REF>;
+};
+
+&sata {
+       clocks = <&zynqmp_clk SATA_REF>;
+};
+
+&sdhci0 {
+       clocks = <&zynqmp_clk SDIO0_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&sdhci1 {
+       clocks = <&zynqmp_clk SDIO1_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&spi0 {
+       clocks = <&zynqmp_clk SPI0_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&spi1 {
+       clocks = <&zynqmp_clk SPI1_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&ttc0 {
+       clocks = <&zynqmp_clk LPD_LSBUS>;
+};
+
+&ttc1 {
+       clocks = <&zynqmp_clk LPD_LSBUS>;
+};
+
+&ttc2 {
+       clocks = <&zynqmp_clk LPD_LSBUS>;
+};
+
+&ttc3 {
+       clocks = <&zynqmp_clk LPD_LSBUS>;
+};
+
+&uart0 {
+       clocks = <&zynqmp_clk UART0_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&uart1 {
+       clocks = <&zynqmp_clk UART1_REF>, <&zynqmp_clk LPD_LSBUS>;
+};
+
+&usb0 {
+       clocks = <&zynqmp_clk USB0_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
+};
+
+&usb1 {
+       clocks = <&zynqmp_clk USB1_BUS_REF>, <&zynqmp_clk USB3_DUAL_REF>;
+};
+
+&watchdog0 {
+       clocks = <&zynqmp_clk WDT>;
+};
diff --git a/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi b/arch/arm64/boot/dts/xilinx/zynqmp-clk.dtsi
deleted file mode 100644 (file)
index 306ad21..0000000
+++ /dev/null
@@ -1,213 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0+
-/*
- * Clock specification for Xilinx ZynqMP
- *
- * (C) Copyright 2015 - 2018, Xilinx, Inc.
- *
- * Michal Simek <michal.simek@xilinx.com>
- */
-
-/ {
-       clk100: clk100 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <100000000>;
-       };
-
-       clk125: clk125 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <125000000>;
-       };
-
-       clk200: clk200 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <200000000>;
-       };
-
-       clk250: clk250 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <250000000>;
-       };
-
-       clk300: clk300 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <300000000>;
-       };
-
-       clk600: clk600 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <600000000>;
-       };
-
-       dp_aclk: clock0 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <100000000>;
-               clock-accuracy = <100>;
-       };
-
-       dp_aud_clk: clock1 {
-               compatible = "fixed-clock";
-               #clock-cells = <0>;
-               clock-frequency = <24576000>;
-               clock-accuracy = <100>;
-       };
-
-       dpdma_clk: dpdma-clk {
-               compatible = "fixed-clock";
-               #clock-cells = <0x0>;
-               clock-frequency = <533000000>;
-       };
-
-       drm_clock: drm-clock {
-               compatible = "fixed-clock";
-               #clock-cells = <0x0>;
-               clock-frequency = <262750000>;
-               clock-accuracy = <0x64>;
-       };
-};
-
-&can0 {
-       clocks = <&clk100 &clk100>;
-};
-
-&can1 {
-       clocks = <&clk100 &clk100>;
-};
-
-&fpd_dma_chan1 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan2 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan3 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan4 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan5 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan6 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan7 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&fpd_dma_chan8 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&lpd_dma_chan1 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&lpd_dma_chan2 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&lpd_dma_chan3 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&lpd_dma_chan4 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&lpd_dma_chan5 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&lpd_dma_chan6 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&lpd_dma_chan7 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&lpd_dma_chan8 {
-       clocks = <&clk600>, <&clk100>;
-};
-
-&gem0 {
-       clocks = <&clk125>, <&clk125>, <&clk125>;
-};
-
-&gem1 {
-       clocks = <&clk125>, <&clk125>, <&clk125>;
-};
-
-&gem2 {
-       clocks = <&clk125>, <&clk125>, <&clk125>;
-};
-
-&gem3 {
-       clocks = <&clk125>, <&clk125>, <&clk125>;
-};
-
-&gpio {
-       clocks = <&clk100>;
-};
-
-&i2c0 {
-       clocks = <&clk100>;
-};
-
-&i2c1 {
-       clocks = <&clk100>;
-};
-
-&sata {
-       clocks = <&clk250>;
-};
-
-&sdhci0 {
-       clocks = <&clk200 &clk200>;
-};
-
-&sdhci1 {
-       clocks = <&clk200 &clk200>;
-};
-
-&spi0 {
-       clocks = <&clk200 &clk200>;
-};
-
-&spi1 {
-       clocks = <&clk200 &clk200>;
-};
-
-&uart0 {
-       clocks = <&clk100 &clk100>;
-};
-
-&uart1 {
-       clocks = <&clk100 &clk100>;
-};
-
-&usb0 {
-       clocks = <&clk250>, <&clk250>;
-};
-
-&usb1 {
-       clocks = <&clk250>, <&clk250>;
-};
-
-&watchdog0 {
-       clocks = <&clk250>;
-};
index 0f7b4cf..2e05fa4 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZC1232
  *
- * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ * (C) Copyright 2017 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 
 / {
        model = "ZynqMP ZC1232 RevA";
index 9092828..3d0aaa0 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZC1254
  *
- * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ * (C) Copyright 2015 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  * Siva Durga Prasad Paladugu <sivadur@xilinx.com>
@@ -11,7 +11,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 
 / {
        model = "ZynqMP ZC1254 RevA";
index 4f404c5..66a9048 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZC1275
  *
- * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ * (C) Copyright 2017 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  * Siva Durga Prasad Paladugu <sivadur@xilinx.com>
@@ -11,7 +11,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 
 / {
        model = "ZynqMP ZC1275 RevA";
index 9a3e39d..69f6e46 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP zc1751-xm015-dc1
  *
- * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ * (C) Copyright 2015 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
@@ -73,7 +73,7 @@
        status = "okay";
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       phy0: phy@0 {
+       phy0: ethernet-phy@0 {
                reg = <0>;
        };
 };
 /* ULPI SMSC USB3320 */
 &usb0 {
        status = "okay";
+       dr_mode = "host";
 };
index 2421ec7..4a86efa 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP zc1751-xm016-dc2
  *
- * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ * (C) Copyright 2015 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
@@ -84,7 +84,7 @@
        status = "okay";
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       phy0: phy@5 {
+       phy0: ethernet-phy@5 {
                reg = <5>;
                ti,rx-internal-delay = <0x8>;
                ti,tx-internal-delay = <0xa>;
        status = "okay";
        num-cs = <1>;
 
-       spi0_flash0: flash0@0 {
+       spi0_flash0: flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "sst,sst25wf080", "jedec,spi-nor";
        status = "okay";
        num-cs = <1>;
 
-       spi1_flash0: flash0@0 {
+       spi1_flash0: flash@0 {
                #address-cells = <1>;
                #size-cells = <1>;
                compatible = "atmel,at45db041e", "atmel,at45", "atmel,dataflash";
 /* ULPI SMSC USB3320 */
 &usb1 {
        status = "okay";
+       dr_mode = "host";
 };
 
 &uart0 {
index 7a49dee..4ea6ef5 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP zc1751-xm017-dc3
  *
- * (C) Copyright 2016 - 2018, Xilinx, Inc.
+ * (C) Copyright 2016 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 
 / {
        model = "ZynqMP zc1751-xm017-dc3 RevA";
@@ -73,7 +73,7 @@
        status = "okay";
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       phy0: phy@0 { /* VSC8211 */
+       phy0: ethernet-phy@0 { /* VSC8211 */
                reg = <0>;
        };
 };
index 54c7b4f..2366cd9 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP zc1751-xm018-dc4
  *
- * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ * (C) Copyright 2015 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 
 / {
        model = "ZynqMP zc1751-xm018-dc4";
index b8b5ff1..41934e3 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP zc1751-xm019-dc5
  *
- * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ * (C) Copyright 2015 - 2019, Xilinx, Inc.
  *
  * Siva Durga Prasad <siva.durga.paladugu@xilinx.com>
  * Michal Simek <michal.simek@xilinx.com>
@@ -11,7 +11,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
@@ -74,7 +74,7 @@
        status = "okay";
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       phy0: phy@0 {
+       phy0: ethernet-phy@0 {
                reg = <0>;
        };
 };
index e5699d0..d60110a 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZCU100 revC
  *
- * (C) Copyright 2016 - 2018, Xilinx, Inc.
+ * (C) Copyright 2016 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  * Nathalie Chan King Choy
@@ -11,7 +11,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/interrupt-controller/irq.h>
 #include <dt-bindings/gpio/gpio.h>
                reset-gpios = <&gpio 7 GPIO_ACTIVE_LOW>; /* WIFI_EN */
                post-power-on-delay-ms = <10>;
        };
+
+       ina226 {
+               compatible = "iio-hwmon";
+               io-channels = <&u35 0>, <&u35 1>, <&u35 2>, <&u35 3>;
+       };
 };
 
 &dcc {
                        #size-cells = <0>;
                        reg = <5>;
                        /* PS_PMBUS */
-                       ina226@40 { /* u35 */
+                       u35: ina226@40 { /* u35 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
                                reg = <0x40>;
                                shunt-resistor = <10000>;
                                /* MIO31 is alert which should be routed to PMUFW */
 &sdhci0 {
        status = "okay";
        no-1-8-v;
-       broken-cd; /* CD has to be enabled by default */
        disable-wp;
 };
 
 &spi0 { /* Low Speed connector */
        status = "okay";
        label = "LS-SPI0";
+       num-cs = <1>;
 };
 
 &spi1 { /* High Speed connector */
        status = "okay";
        label = "HS-SPI1";
+       num-cs = <1>;
 };
 
 &uart0 {
 /* ULPI SMSC USB3320 */
 &usb0 {
        status = "okay";
+       dr_mode = "peripheral";
 };
 
 /* ULPI SMSC USB3320 */
 &usb1 {
        status = "okay";
+       dr_mode = "host";
 };
 
 &watchdog0 {
index 2a3b665..4f80172 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZCU102 RevA
  *
- * (C) Copyright 2015 - 2018, Xilinx, Inc.
+ * (C) Copyright 2015 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
 
                        linux,default-trigger = "heartbeat";
                };
        };
+
+       ina226-u76 {
+               compatible = "iio-hwmon";
+               io-channels = <&u76 0>, <&u76 1>, <&u76 2>, <&u76 3>;
+       };
+       ina226-u77 {
+               compatible = "iio-hwmon";
+               io-channels = <&u77 0>, <&u77 1>, <&u77 2>, <&u77 3>;
+       };
+       ina226-u78 {
+               compatible = "iio-hwmon";
+               io-channels = <&u78 0>, <&u78 1>, <&u78 2>, <&u78 3>;
+       };
+       ina226-u87 {
+               compatible = "iio-hwmon";
+               io-channels = <&u87 0>, <&u87 1>, <&u87 2>, <&u87 3>;
+       };
+       ina226-u85 {
+               compatible = "iio-hwmon";
+               io-channels = <&u85 0>, <&u85 1>, <&u85 2>, <&u85 3>;
+       };
+       ina226-u86 {
+               compatible = "iio-hwmon";
+               io-channels = <&u86 0>, <&u86 1>, <&u86 2>, <&u86 3>;
+       };
+       ina226-u93 {
+               compatible = "iio-hwmon";
+               io-channels = <&u93 0>, <&u93 1>, <&u93 2>, <&u93 3>;
+       };
+       ina226-u88 {
+               compatible = "iio-hwmon";
+               io-channels = <&u88 0>, <&u88 1>, <&u88 2>, <&u88 3>;
+       };
+       ina226-u15 {
+               compatible = "iio-hwmon";
+               io-channels = <&u15 0>, <&u15 1>, <&u15 2>, <&u15 3>;
+       };
+       ina226-u92 {
+               compatible = "iio-hwmon";
+               io-channels = <&u92 0>, <&u92 1>, <&u92 2>, <&u92 3>;
+       };
+       ina226-u79 {
+               compatible = "iio-hwmon";
+               io-channels = <&u79 0>, <&u79 1>, <&u79 2>, <&u79 3>;
+       };
+       ina226-u81 {
+               compatible = "iio-hwmon";
+               io-channels = <&u81 0>, <&u81 1>, <&u81 2>, <&u81 3>;
+       };
+       ina226-u80 {
+               compatible = "iio-hwmon";
+               io-channels = <&u80 0>, <&u80 1>, <&u80 2>, <&u80 3>;
+       };
+       ina226-u84 {
+               compatible = "iio-hwmon";
+               io-channels = <&u84 0>, <&u84 1>, <&u84 2>, <&u84 3>;
+       };
+       ina226-u16 {
+               compatible = "iio-hwmon";
+               io-channels = <&u16 0>, <&u16 1>, <&u16 2>, <&u16 3>;
+       };
+       ina226-u65 {
+               compatible = "iio-hwmon";
+               io-channels = <&u65 0>, <&u65 1>, <&u65 2>, <&u65 3>;
+       };
+       ina226-u74 {
+               compatible = "iio-hwmon";
+               io-channels = <&u74 0>, <&u74 1>, <&u74 2>, <&u74 3>;
+       };
+       ina226-u75 {
+               compatible = "iio-hwmon";
+               io-channels = <&u75 0>, <&u75 1>, <&u75 2>, <&u75 3>;
+       };
 };
 
 &can1 {
        status = "okay";
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       phy0: phy@21 {
+       phy0: ethernet-phy@21 {
                reg = <21>;
                ti,rx-internal-delay = <0x8>;
                ti,tx-internal-delay = <0xa>;
        tca6416_u97: gpio@20 {
                compatible = "ti,tca6416";
                reg = <0x20>;
-               gpio-controller;
+               gpio-controller; /* IRQ not connected */
                #gpio-cells = <2>;
-               /*
-                * IRQ not connected
-                * Lines:
-                * 0 - PS_GTR_LAN_SEL0
-                * 1 - PS_GTR_LAN_SEL1
-                * 2 - PS_GTR_LAN_SEL2
-                * 3 - PS_GTR_LAN_SEL3
-                * 4 - PCI_CLK_DIR_SEL
-                * 5 - IIC_MUX_RESET_B
-                * 6 - GEM3_EXP_RESET_B
-                * 7, 10 - 17 - not connected
-                */
-
+               gpio-line-names = "PS_GTR_LAN_SEL0", "PS_GTR_LAN_SEL1", "PS_GTR_LAN_SEL2", "PS_GTR_LAN_SEL3",
+                               "PCI_CLK_DIR_SEL", "IIC_MUX_RESET_B", "GEM3_EXP_RESET_B",
+                               "", "", "", "", "", "", "", "", "";
                gtr-sel0 {
                        gpio-hog;
                        gpios = <0 0>;
        tca6416_u61: gpio@21 {
                compatible = "ti,tca6416";
                reg = <0x21>;
-               gpio-controller;
+               gpio-controller; /* IRQ not connected */
                #gpio-cells = <2>;
-               /*
-                * IRQ not connected
-                * Lines:
-                * 0 - VCCPSPLL_EN
-                * 1 - MGTRAVCC_EN
-                * 2 - MGTRAVTT_EN
-                * 3 - VCCPSDDRPLL_EN
-                * 4 - MIO26_PMU_INPUT_LS
-                * 5 - PL_PMBUS_ALERT
-                * 6 - PS_PMBUS_ALERT
-                * 7 - MAXIM_PMBUS_ALERT
-                * 10 - PL_DDR4_VTERM_EN
-                * 11 - PL_DDR4_VPP_2V5_EN
-                * 12 - PS_DIMM_VDDQ_TO_PSVCCO_ON
-                * 13 - PS_DIMM_SUSPEND_EN
-                * 14 - PS_DDR4_VTERM_EN
-                * 15 - PS_DDR4_VPP_2V5_EN
-                * 16 - 17 - not connected
-                */
+               gpio-line-names = "VCCPSPLL_EN", "MGTRAVCC_EN", "MGTRAVTT_EN", "VCCPSDDRPLL_EN", "MIO26_PMU_INPUT_LS",
+                               "PL_PMBUS_ALERT", "PS_PMBUS_ALERT", "MAXIM_PMBUS_ALERT", "PL_DDR4_VTERM_EN",
+                               "PL_DDR4_VPP_2V5_EN", "PS_DIMM_VDDQ_TO_PSVCCO_ON", "PS_DIMM_SUSPEND_EN",
+                               "PS_DDR4_VTERM_EN", "PS_DDR4_VPP_2V5_EN", "", "";
        };
 
        i2c-mux@75 { /* u60 */
                        #size-cells = <0>;
                        reg = <0>;
                        /* PS_PMBUS */
-                       ina226@40 { /* u76 */
+                       u76: ina226@40 { /* u76 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u76";
                                reg = <0x40>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@41 { /* u77 */
+                       u77: ina226@41 { /* u77 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u77";
                                reg = <0x41>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@42 { /* u78 */
+                       u78: ina226@42 { /* u78 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u78";
                                reg = <0x42>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@43 { /* u87 */
+                       u87: ina226@43 { /* u87 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u87";
                                reg = <0x43>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@44 { /* u85 */
+                       u85: ina226@44 { /* u85 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u85";
                                reg = <0x44>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@45 { /* u86 */
+                       u86: ina226@45 { /* u86 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u86";
                                reg = <0x45>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@46 { /* u93 */
+                       u93: ina226@46 { /* u93 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u93";
                                reg = <0x46>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@47 { /* u88 */
+                       u88: ina226@47 { /* u88 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u88";
                                reg = <0x47>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4a { /* u15 */
+                       u15: ina226@4a { /* u15 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u15";
                                reg = <0x4a>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4b { /* u92 */
+                       u92: ina226@4b { /* u92 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u92";
                                reg = <0x4b>;
                                shunt-resistor = <5000>;
                        };
                        #size-cells = <0>;
                        reg = <1>;
                        /* PL_PMBUS */
-                       ina226@40 { /* u79 */
+                       u79: ina226@40 { /* u79 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u79";
                                reg = <0x40>;
                                shunt-resistor = <2000>;
                        };
-                       ina226@41 { /* u81 */
+                       u81: ina226@41 { /* u81 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u81";
                                reg = <0x41>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@42 { /* u80 */
+                       u80: ina226@42 { /* u80 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u80";
                                reg = <0x42>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@43 { /* u84 */
+                       u84: ina226@43 { /* u84 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u84";
                                reg = <0x43>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@44 { /* u16 */
+                       u16: ina226@44 { /* u16 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u16";
                                reg = <0x44>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@45 { /* u65 */
+                       u65: ina226@45 { /* u65 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u65";
                                reg = <0x45>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@46 { /* u74 */
+                       u74: ina226@46 { /* u74 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u74";
                                reg = <0x46>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@47 { /* u75 */
+                       u75: ina226@47 { /* u75 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u75";
                                reg = <0x47>;
                                shunt-resistor = <5000>;
                        };
                                temperature-stability = <50>;
                                factory-fout = <300000000>;
                                clock-frequency = <300000000>;
+                               clock-output-names = "si570_user";
                        };
                };
                i2c@3 {
                                temperature-stability = <50>; /* copy from zc702 */
                                factory-fout = <156250000>;
                                clock-frequency = <148500000>;
+                               clock-output-names = "si570_mgt";
                        };
                };
                i2c@4 {
 /* ULPI SMSC USB3320 */
 &usb0 {
        status = "okay";
+       dr_mode = "host";
 };
 
 &watchdog0 {
index 1780ed2..d9ad8a4 100644 (file)
@@ -16,7 +16,7 @@
 
 &gem3 {
        phy-handle = <&phyc>;
-       phyc: phy@c {
+       phyc: ethernet-phy@c {
                reg = <0xc>;
                ti,rx-internal-delay = <0x8>;
                ti,tx-internal-delay = <0xa>;
@@ -24,7 +24,7 @@
                ti,dp83867-rxctrl-strap-quirk;
        };
        /* Cleanup from RevA */
-       /delete-node/ phy@21;
+       /delete-node/ ethernet-phy@21;
 };
 
 /* Fix collision with u61 */
index 8f45614..7a4614e 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZCU104
  *
- * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ * (C) Copyright 2017 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 #include <dt-bindings/gpio/gpio.h>
 
 / {
@@ -50,7 +50,7 @@
        status = "okay";
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       phy0: phy@c {
+       phy0: ethernet-phy@c {
                reg = <0xc>;
                ti,rx-internal-delay = <0x8>;
                ti,tx-internal-delay = <0xa>;
                        #address-cells = <1>;
                        #size-cells = <0>;
                        reg = <4>;
-                       tca6416_u97: gpio@21 {
+                       tca6416_u97: gpio@20 {
                                compatible = "ti,tca6416";
-                               reg = <0x21>;
+                               reg = <0x20>;
                                gpio-controller;
                                #gpio-cells = <2>;
                                /*
 /* ULPI SMSC USB3320 */
 &usb0 {
        status = "okay";
+       dr_mode = "host";
 };
 
 &watchdog0 {
index 93ce7eb..6e9efe2 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZCU106
  *
- * (C) Copyright 2016, Xilinx, Inc.
+ * (C) Copyright 2016 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
 
                        linux,default-trigger = "heartbeat";
                };
        };
+
+       ina226-u76 {
+               compatible = "iio-hwmon";
+               io-channels = <&u76 0>, <&u76 1>, <&u76 2>, <&u76 3>;
+       };
+       ina226-u77 {
+               compatible = "iio-hwmon";
+               io-channels = <&u77 0>, <&u77 1>, <&u77 2>, <&u77 3>;
+       };
+       ina226-u78 {
+               compatible = "iio-hwmon";
+               io-channels = <&u78 0>, <&u78 1>, <&u78 2>, <&u78 3>;
+       };
+       ina226-u87 {
+               compatible = "iio-hwmon";
+               io-channels = <&u87 0>, <&u87 1>, <&u87 2>, <&u87 3>;
+       };
+       ina226-u85 {
+               compatible = "iio-hwmon";
+               io-channels = <&u85 0>, <&u85 1>, <&u85 2>, <&u85 3>;
+       };
+       ina226-u86 {
+               compatible = "iio-hwmon";
+               io-channels = <&u86 0>, <&u86 1>, <&u86 2>, <&u86 3>;
+       };
+       ina226-u93 {
+               compatible = "iio-hwmon";
+               io-channels = <&u93 0>, <&u93 1>, <&u93 2>, <&u93 3>;
+       };
+       ina226-u88 {
+               compatible = "iio-hwmon";
+               io-channels = <&u88 0>, <&u88 1>, <&u88 2>, <&u88 3>;
+       };
+       ina226-u15 {
+               compatible = "iio-hwmon";
+               io-channels = <&u15 0>, <&u15 1>, <&u15 2>, <&u15 3>;
+       };
+       ina226-u92 {
+               compatible = "iio-hwmon";
+               io-channels = <&u92 0>, <&u92 1>, <&u92 2>, <&u92 3>;
+       };
+       ina226-u79 {
+               compatible = "iio-hwmon";
+               io-channels = <&u79 0>, <&u79 1>, <&u79 2>, <&u79 3>;
+       };
+       ina226-u81 {
+               compatible = "iio-hwmon";
+               io-channels = <&u81 0>, <&u81 1>, <&u81 2>, <&u81 3>;
+       };
+       ina226-u80 {
+               compatible = "iio-hwmon";
+               io-channels = <&u80 0>, <&u80 1>, <&u80 2>, <&u80 3>;
+       };
+       ina226-u84 {
+               compatible = "iio-hwmon";
+               io-channels = <&u84 0>, <&u84 1>, <&u84 2>, <&u84 3>;
+       };
+       ina226-u16 {
+               compatible = "iio-hwmon";
+               io-channels = <&u16 0>, <&u16 1>, <&u16 2>, <&u16 3>;
+       };
+       ina226-u65 {
+               compatible = "iio-hwmon";
+               io-channels = <&u65 0>, <&u65 1>, <&u65 2>, <&u65 3>;
+       };
+       ina226-u74 {
+               compatible = "iio-hwmon";
+               io-channels = <&u74 0>, <&u74 1>, <&u74 2>, <&u74 3>;
+       };
+       ina226-u75 {
+               compatible = "iio-hwmon";
+               io-channels = <&u75 0>, <&u75 1>, <&u75 2>, <&u75 3>;
+       };
 };
 
 &can1 {
        status = "okay";
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       phy0: phy@c {
+       phy0: ethernet-phy@c {
                reg = <0xc>;
                ti,rx-internal-delay = <0x8>;
                ti,tx-internal-delay = <0xa>;
                        #size-cells = <0>;
                        reg = <0>;
                        /* PS_PMBUS */
-                       ina226@40 { /* u76 */
+                       u76: ina226@40 { /* u76 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u76";
                                reg = <0x40>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@41 { /* u77 */
+                       u77: ina226@41 { /* u77 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u77";
                                reg = <0x41>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@42 { /* u78 */
+                       u78: ina226@42 { /* u78 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u78";
                                reg = <0x42>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@43 { /* u87 */
+                       u87: ina226@43 { /* u87 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u87";
                                reg = <0x43>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@44 { /* u85 */
+                       u85: ina226@44 { /* u85 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u85";
                                reg = <0x44>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@45 { /* u86 */
+                       u86: ina226@45 { /* u86 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u86";
                                reg = <0x45>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@46 { /* u93 */
+                       u93: ina226@46 { /* u93 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u93";
                                reg = <0x46>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@47 { /* u88 */
+                       u88: ina226@47 { /* u88 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u88";
                                reg = <0x47>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4a { /* u15 */
+                       u15: ina226@4a { /* u15 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u15";
                                reg = <0x4a>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4b { /* u92 */
+                       u92: ina226@4b { /* u92 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u92";
                                reg = <0x4b>;
                                shunt-resistor = <5000>;
                        };
                        #size-cells = <0>;
                        reg = <1>;
                        /* PL_PMBUS */
-                       ina226@40 { /* u79 */
+                       u79: ina226@40 { /* u79 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u79";
                                reg = <0x40>;
                                shunt-resistor = <2000>;
                        };
-                       ina226@41 { /* u81 */
+                       u81: ina226@41 { /* u81 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u81";
                                reg = <0x41>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@42 { /* u80 */
+                       u80: ina226@42 { /* u80 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u80";
                                reg = <0x42>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@43 { /* u84 */
+                       u84: ina226@43 { /* u84 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u84";
                                reg = <0x43>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@44 { /* u16 */
+                       u16: ina226@44 { /* u16 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u16";
                                reg = <0x44>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@45 { /* u65 */
+                       u65: ina226@45 { /* u65 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u65";
                                reg = <0x45>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@46 { /* u74 */
+                       u74: ina226@46 { /* u74 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u74";
                                reg = <0x46>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@47 { /* u75 */
+                       u75: ina226@47 { /* u75 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u75";
                                reg = <0x47>;
                                shunt-resistor = <5000>;
                        };
                                temperature-stability = <50>;
                                factory-fout = <300000000>;
                                clock-frequency = <300000000>;
+                               clock-output-names = "si570_user";
                        };
                };
                i2c@3 {
                                temperature-stability = <50>; /* copy from zc702 */
                                factory-fout = <156250000>;
                                clock-frequency = <148500000>;
+                               clock-output-names = "si570_mgt";
                        };
                };
                i2c@4 {
 /* ULPI SMSC USB3320 */
 &usb0 {
        status = "okay";
+       dr_mode = "host";
 };
 
 &watchdog0 {
index 8bb0001..2e92634 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP ZCU111
  *
- * (C) Copyright 2017 - 2018, Xilinx, Inc.
+ * (C) Copyright 2017 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  */
@@ -10,7 +10,7 @@
 /dts-v1/;
 
 #include "zynqmp.dtsi"
-#include "zynqmp-clk.dtsi"
+#include "zynqmp-clk-ccf.dtsi"
 #include <dt-bindings/input/input.h>
 #include <dt-bindings/gpio/gpio.h>
 
                        linux,default-trigger = "heartbeat";
                };
        };
+
+       ina226-u67 {
+               compatible = "iio-hwmon";
+               io-channels = <&u67 0>, <&u67 1>, <&u67 2>, <&u67 3>;
+       };
+       ina226-u59 {
+               compatible = "iio-hwmon";
+               io-channels = <&u59 0>, <&u59 1>, <&u59 2>, <&u59 3>;
+       };
+       ina226-u61 {
+               compatible = "iio-hwmon";
+               io-channels = <&u61 0>, <&u61 1>, <&u61 2>, <&u61 3>;
+       };
+       ina226-u60 {
+               compatible = "iio-hwmon";
+               io-channels = <&u60 0>, <&u60 1>, <&u60 2>, <&u60 3>;
+       };
+       ina226-u64 {
+               compatible = "iio-hwmon";
+               io-channels = <&u64 0>, <&u64 1>, <&u64 2>, <&u64 3>;
+       };
+       ina226-u69 {
+               compatible = "iio-hwmon";
+               io-channels = <&u69 0>, <&u69 1>, <&u69 2>, <&u69 3>;
+       };
+       ina226-u66 {
+               compatible = "iio-hwmon";
+               io-channels = <&u66 0>, <&u66 1>, <&u66 2>, <&u66 3>;
+       };
+       ina226-u65 {
+               compatible = "iio-hwmon";
+               io-channels = <&u65 0>, <&u65 1>, <&u65 2>, <&u65 3>;
+       };
+       ina226-u63 {
+               compatible = "iio-hwmon";
+               io-channels = <&u63 0>, <&u63 1>, <&u63 2>, <&u63 3>;
+       };
+       ina226-u3 {
+               compatible = "iio-hwmon";
+               io-channels = <&u3 0>, <&u3 1>, <&u3 2>, <&u3 3>;
+       };
+       ina226-u71 {
+               compatible = "iio-hwmon";
+               io-channels = <&u71 0>, <&u71 1>, <&u71 2>, <&u71 3>;
+       };
+       ina226-u77 {
+               compatible = "iio-hwmon";
+               io-channels = <&u77 0>, <&u77 1>, <&u77 2>, <&u77 3>;
+       };
+       ina226-u73 {
+               compatible = "iio-hwmon";
+               io-channels = <&u73 0>, <&u73 1>, <&u73 2>, <&u73 3>;
+       };
+       ina226-u79 {
+               compatible = "iio-hwmon";
+               io-channels = <&u79 0>, <&u79 1>, <&u79 2>, <&u79 3>;
+       };
 };
 
 &dcc {
        status = "okay";
        phy-handle = <&phy0>;
        phy-mode = "rgmii-id";
-       phy0: phy@c {
+       phy0: ethernet-phy@c {
                reg = <0xc>;
                ti,rx-internal-delay = <0x8>;
                ti,tx-internal-delay = <0xa>;
                        reg = <0>;
                        /* PS_PMBUS */
                        /* PMBUS_ALERT done via pca9544 */
-                       ina226@40 { /* u67 */
+                       u67: ina226@40 { /* u67 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u67";
                                reg = <0x40>;
                                shunt-resistor = <2000>;
                        };
-                       ina226@41 { /* u59 */
+                       u59: ina226@41 { /* u59 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u59";
                                reg = <0x41>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@42 { /* u61 */
+                       u61: ina226@42 { /* u61 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u61";
                                reg = <0x42>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@43 { /* u60 */
+                       u60: ina226@43 { /* u60 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u60";
                                reg = <0x43>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@45 { /* u64 */
+                       u64: ina226@45 { /* u64 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u64";
                                reg = <0x45>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@46 { /* u69 */
+                       u69: ina226@46 { /* u69 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u69";
                                reg = <0x46>;
                                shunt-resistor = <2000>;
                        };
-                       ina226@47 { /* u66 */
+                       u66: ina226@47 { /* u66 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u66";
                                reg = <0x47>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@48 { /* u65 */
+                       u65: ina226@48 { /* u65 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u65";
                                reg = <0x48>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@49 { /* u63 */
+                       u63: ina226@49 { /* u63 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u63";
                                reg = <0x49>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4a { /* u3 */
+                       u3: ina226@4a { /* u3 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u3";
                                reg = <0x4a>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4b { /* u71 */
+                       u71: ina226@4b { /* u71 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u71";
                                reg = <0x4b>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4c { /* u77 */
+                       u77: ina226@4c { /* u77 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u77";
                                reg = <0x4c>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4d { /* u73 */
+                       u73: ina226@4d { /* u73 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u73";
                                reg = <0x4d>;
                                shunt-resistor = <5000>;
                        };
-                       ina226@4e { /* u79 */
+                       u79: ina226@4e { /* u79 */
                                compatible = "ti,ina226";
+                               #io-channel-cells = <1>;
+                               label = "ina226-u79";
                                reg = <0x4e>;
                                shunt-resistor = <5000>;
                        };
                                temperature-stability = <50>;
                                factory-fout = <300000000>;
                                clock-frequency = <300000000>;
+                               clock-output-names = "si570_user";
                        };
                };
                i2c@3 {
                                reg = <0x5d>;
                                temperature-stability = <50>;
                                factory-fout = <156250000>;
-                               clock-frequency = <148500000>;
+                               clock-frequency = <156250000>;
+                               clock-output-names = "si570_mgt";
                        };
                };
                i2c@4 {
 /* ULPI SMSC USB3320 */
 &usb0 {
        status = "okay";
+       dr_mode = "host";
 };
index 3c731e7..26d926e 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * dts file for Xilinx ZynqMP
  *
- * (C) Copyright 2014 - 2015, Xilinx, Inc.
+ * (C) Copyright 2014 - 2019, Xilinx, Inc.
  *
  * Michal Simek <michal.simek@xilinx.com>
  *
@@ -12,6 +12,8 @@
  * the License, or (at your option) any later version.
  */
 
+#include <dt-bindings/power/xlnx-zynqmp-power.h>
+
 / {
        compatible = "xlnx,zynqmp";
        #address-cells = <2>;
        firmware {
                zynqmp_firmware: zynqmp-firmware {
                        compatible = "xlnx,zynqmp-firmware";
+                       #power-domain-cells = <1>;
                        method = "smc";
 
+                       zynqmp_power: zynqmp-power {
+                               compatible = "xlnx,zynqmp-power";
+                               interrupt-parent = <&gic>;
+                               interrupts = <0 35 4>;
+                       };
+
+                       zynqmp_clk: clock-controller {
+                               u-boot,dm-pre-reloc;
+                               #clock-cells = <1>;
+                               compatible = "xlnx,zynqmp-clk";
+                               clocks = <&pss_ref_clk>,
+                                        <&video_clk>,
+                                        <&pss_alt_ref_clk>,
+                                        <&aux_ref_clk>,
+                                        <&gt_crx_ref_clk>;
+                               clock-names = "pss_ref_clk",
+                                             "video_clk",
+                                             "pss_alt_ref_clk",
+                                             "aux_ref_clk",
+                                             "gt_crx_ref_clk";
+                       };
+
                        nvmem_firmware {
                                compatible = "xlnx,zynqmp-nvmem-fw";
                                #address-cells = <1>;
                        interrupt-parent = <&gic>;
                        tx-fifo-depth = <0x40>;
                        rx-fifo-depth = <0x40>;
+                       power-domains = <&zynqmp_firmware PD_CAN_0>;
                };
 
                can1: can@ff070000 {
                        interrupt-parent = <&gic>;
                        tx-fifo-depth = <0x40>;
                        rx-fifo-depth = <0x40>;
+                       power-domains = <&zynqmp_firmware PD_CAN_1>;
                };
 
                cci: cci@fd6e0000 {
                        interrupts = <0 124 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <128>;
+                       power-domains = <&zynqmp_firmware PD_GDMA>;
                };
 
                fpd_dma_chan2: dma@fd510000 {
                        interrupts = <0 125 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <128>;
+                       power-domains = <&zynqmp_firmware PD_GDMA>;
                };
 
                fpd_dma_chan3: dma@fd520000 {
                        interrupts = <0 126 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <128>;
+                       power-domains = <&zynqmp_firmware PD_GDMA>;
                };
 
                fpd_dma_chan4: dma@fd530000 {
                        interrupts = <0 127 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <128>;
+                       power-domains = <&zynqmp_firmware PD_GDMA>;
                };
 
                fpd_dma_chan5: dma@fd540000 {
                        interrupts = <0 128 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <128>;
+                       power-domains = <&zynqmp_firmware PD_GDMA>;
                };
 
                fpd_dma_chan6: dma@fd550000 {
                        interrupts = <0 129 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <128>;
+                       power-domains = <&zynqmp_firmware PD_GDMA>;
                };
 
                fpd_dma_chan7: dma@fd560000 {
                        interrupts = <0 130 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <128>;
+                       power-domains = <&zynqmp_firmware PD_GDMA>;
                };
 
                fpd_dma_chan8: dma@fd570000 {
                        interrupts = <0 131 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <128>;
+                       power-domains = <&zynqmp_firmware PD_GDMA>;
                };
 
                /* LPDDMA default allows only secured access. inorder to enable
                        interrupts = <0 77 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <64>;
+                       power-domains = <&zynqmp_firmware PD_ADMA>;
                };
 
                lpd_dma_chan2: dma@ffa90000 {
                        interrupts = <0 78 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <64>;
+                       power-domains = <&zynqmp_firmware PD_ADMA>;
                };
 
                lpd_dma_chan3: dma@ffaa0000 {
                        interrupts = <0 79 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <64>;
+                       power-domains = <&zynqmp_firmware PD_ADMA>;
                };
 
                lpd_dma_chan4: dma@ffab0000 {
                        interrupts = <0 80 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <64>;
+                       power-domains = <&zynqmp_firmware PD_ADMA>;
                };
 
                lpd_dma_chan5: dma@ffac0000 {
                        interrupts = <0 81 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <64>;
+                       power-domains = <&zynqmp_firmware PD_ADMA>;
                };
 
                lpd_dma_chan6: dma@ffad0000 {
                        interrupts = <0 82 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <64>;
+                       power-domains = <&zynqmp_firmware PD_ADMA>;
                };
 
                lpd_dma_chan7: dma@ffae0000 {
                        interrupts = <0 83 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <64>;
+                       power-domains = <&zynqmp_firmware PD_ADMA>;
                };
 
                lpd_dma_chan8: dma@ffaf0000 {
                        interrupts = <0 84 4>;
                        clock-names = "clk_main", "clk_apb";
                        xlnx,bus-width = <64>;
+                       power-domains = <&zynqmp_firmware PD_ADMA>;
                };
 
                mc: memory-controller@fd070000 {
                        clock-names = "pclk", "hclk", "tx_clk";
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       power-domains = <&zynqmp_firmware PD_ETH_0>;
                };
 
                gem1: ethernet@ff0c0000 {
                        clock-names = "pclk", "hclk", "tx_clk";
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       power-domains = <&zynqmp_firmware PD_ETH_1>;
                };
 
                gem2: ethernet@ff0d0000 {
                        clock-names = "pclk", "hclk", "tx_clk";
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       power-domains = <&zynqmp_firmware PD_ETH_2>;
                };
 
                gem3: ethernet@ff0e0000 {
                        clock-names = "pclk", "hclk", "tx_clk";
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       power-domains = <&zynqmp_firmware PD_ETH_3>;
                };
 
                gpio: gpio@ff0a0000 {
                        interrupt-controller;
                        #interrupt-cells = <2>;
                        reg = <0x0 0xff0a0000 0x0 0x1000>;
+                       power-domains = <&zynqmp_firmware PD_GPIO>;
                };
 
                i2c0: i2c@ff020000 {
                        reg = <0x0 0xff020000 0x0 0x1000>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       power-domains = <&zynqmp_firmware PD_I2C_0>;
                };
 
                i2c1: i2c@ff030000 {
                        reg = <0x0 0xff030000 0x0 0x1000>;
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       power-domains = <&zynqmp_firmware PD_I2C_1>;
                };
 
                pcie: pcie@fd0e0000 {
                                        <0x0 0x0 0x0 0x2 &pcie_intc 0x2>,
                                        <0x0 0x0 0x0 0x3 &pcie_intc 0x3>,
                                        <0x0 0x0 0x0 0x4 &pcie_intc 0x4>;
+                       power-domains = <&zynqmp_firmware PD_PCIE>;
                        pcie_intc: legacy-interrupt-controller {
                                interrupt-controller;
                                #address-cells = <0>;
                        reg = <0x0 0xfd0c0000 0x0 0x2000>;
                        interrupt-parent = <&gic>;
                        interrupts = <0 133 4>;
+                       power-domains = <&zynqmp_firmware PD_SATA>;
                };
 
                sdhci0: mmc@ff160000 {
-                       compatible = "arasan,sdhci-8.9a";
+                       compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
                        status = "disabled";
                        interrupt-parent = <&gic>;
                        interrupts = <0 48 4>;
                        reg = <0x0 0xff160000 0x0 0x1000>;
                        clock-names = "clk_xin", "clk_ahb";
+                       #clock-cells = <1>;
+                       clock-output-names = "clk_out_sd0", "clk_in_sd0";
+                       power-domains = <&zynqmp_firmware PD_SD_0>;
                };
 
                sdhci1: mmc@ff170000 {
-                       compatible = "arasan,sdhci-8.9a";
+                       compatible = "xlnx,zynqmp-8.9a", "arasan,sdhci-8.9a";
                        status = "disabled";
                        interrupt-parent = <&gic>;
                        interrupts = <0 49 4>;
                        reg = <0x0 0xff170000 0x0 0x1000>;
                        clock-names = "clk_xin", "clk_ahb";
+                       #clock-cells = <1>;
+                       clock-output-names = "clk_out_sd1", "clk_in_sd1";
+                       power-domains = <&zynqmp_firmware PD_SD_1>;
                };
 
                smmu: smmu@fd800000 {
                        clock-names = "ref_clk", "pclk";
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       power-domains = <&zynqmp_firmware PD_SPI_0>;
                };
 
                spi1: spi@ff050000 {
                        clock-names = "ref_clk", "pclk";
                        #address-cells = <1>;
                        #size-cells = <0>;
+                       power-domains = <&zynqmp_firmware PD_SPI_1>;
                };
 
                ttc0: timer@ff110000 {
                        interrupts = <0 36 4>, <0 37 4>, <0 38 4>;
                        reg = <0x0 0xff110000 0x0 0x1000>;
                        timer-width = <32>;
+                       power-domains = <&zynqmp_firmware PD_TTC_0>;
                };
 
                ttc1: timer@ff120000 {
                        interrupts = <0 39 4>, <0 40 4>, <0 41 4>;
                        reg = <0x0 0xff120000 0x0 0x1000>;
                        timer-width = <32>;
+                       power-domains = <&zynqmp_firmware PD_TTC_1>;
                };
 
                ttc2: timer@ff130000 {
                        interrupts = <0 42 4>, <0 43 4>, <0 44 4>;
                        reg = <0x0 0xff130000 0x0 0x1000>;
                        timer-width = <32>;
+                       power-domains = <&zynqmp_firmware PD_TTC_2>;
                };
 
                ttc3: timer@ff140000 {
                        interrupts = <0 45 4>, <0 46 4>, <0 47 4>;
                        reg = <0x0 0xff140000 0x0 0x1000>;
                        timer-width = <32>;
+                       power-domains = <&zynqmp_firmware PD_TTC_3>;
                };
 
                uart0: serial@ff000000 {
                        interrupts = <0 21 4>;
                        reg = <0x0 0xff000000 0x0 0x1000>;
                        clock-names = "uart_clk", "pclk";
+                       power-domains = <&zynqmp_firmware PD_UART_0>;
                };
 
                uart1: serial@ff010000 {
                        interrupts = <0 22 4>;
                        reg = <0x0 0xff010000 0x0 0x1000>;
                        clock-names = "uart_clk", "pclk";
+                       power-domains = <&zynqmp_firmware PD_UART_1>;
                };
 
                usb0: usb@fe200000 {
                        interrupts = <0 65 4>;
                        reg = <0x0 0xfe200000 0x0 0x40000>;
                        clock-names = "clk_xin", "clk_ahb";
+                       power-domains = <&zynqmp_firmware PD_USB_0>;
                };
 
                usb1: usb@fe300000 {
                        interrupts = <0 70 4>;
                        reg = <0x0 0xfe300000 0x0 0x40000>;
                        clock-names = "clk_xin", "clk_ahb";
+                       power-domains = <&zynqmp_firmware PD_USB_1>;
                };
 
                watchdog0: watchdog@fd4d0000 {
index b2f6673..0f21288 100644 (file)
@@ -86,6 +86,8 @@ CONFIG_ACPI_CPPC_CPUFREQ=m
 CONFIG_ARM_ARMADA_37XX_CPUFREQ=y
 CONFIG_ARM_SCPI_CPUFREQ=y
 CONFIG_ARM_IMX_CPUFREQ_DT=m
+CONFIG_ARM_QCOM_CPUFREQ_NVMEM=y
+CONFIG_ARM_QCOM_CPUFREQ_HW=y
 CONFIG_ARM_RASPBERRYPI_CPUFREQ=m
 CONFIG_ARM_TEGRA186_CPUFREQ=y
 CONFIG_ARM_SCPI_PROTOCOL=y
@@ -169,6 +171,7 @@ CONFIG_BT_HCIBTUSB=m
 CONFIG_BT_HCIUART=m
 CONFIG_BT_HCIUART_LL=y
 CONFIG_BT_HCIUART_BCM=y
+CONFIG_BT_HCIUART_QCA=y
 CONFIG_CFG80211=m
 CONFIG_MAC80211=m
 CONFIG_MAC80211_LEDS=y
@@ -190,6 +193,7 @@ CONFIG_PCIE_ALTERA_MSI=y
 CONFIG_PCI_HOST_THUNDER_PEM=y
 CONFIG_PCI_HOST_THUNDER_ECAM=y
 CONFIG_PCIE_ROCKCHIP_HOST=m
+CONFIG_PCIE_BRCMSTB=m
 CONFIG_PCI_LAYERSCAPE=y
 CONFIG_PCI_HISI=y
 CONFIG_PCIE_QCOM=y
@@ -252,6 +256,7 @@ CONFIG_VIRTIO_NET=y
 CONFIG_AMD_XGBE=y
 CONFIG_NET_XGENE=y
 CONFIG_ATL1C=m
+CONFIG_BCMGENET=m
 CONFIG_BNX2X=m
 CONFIG_MACB=y
 CONFIG_THUNDER_NIC_PF=y
@@ -299,6 +304,7 @@ CONFIG_USB_NET_PLUSB=m
 CONFIG_USB_NET_MCS7830=m
 CONFIG_ATH10K=m
 CONFIG_ATH10K_PCI=m
+CONFIG_ATH10K_SNOC=m
 CONFIG_BRCMFMAC=m
 CONFIG_MWIFIEX=m
 CONFIG_MWIFIEX_PCIE=m
@@ -350,6 +356,7 @@ CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
 CONFIG_SERIAL_FSL_LINFLEXUART=y
 CONFIG_SERIAL_FSL_LINFLEXUART_CONSOLE=y
 CONFIG_SERIAL_MVEBU_UART=y
+CONFIG_SERIAL_OWL=y
 CONFIG_SERIAL_DEV_BUS=y
 CONFIG_VIRTIO_CONSOLE=y
 CONFIG_IPMI_HANDLER=m
@@ -367,6 +374,7 @@ CONFIG_I2C_IMX=y
 CONFIG_I2C_IMX_LPI2C=y
 CONFIG_I2C_MESON=y
 CONFIG_I2C_MV64XXX=y
+CONFIG_I2C_OWL=y
 CONFIG_I2C_PXA=y
 CONFIG_I2C_QCOM_GENI=m
 CONFIG_I2C_QUP=y
@@ -387,13 +395,18 @@ CONFIG_SPI_MESON_SPIFC=m
 CONFIG_SPI_ORION=y
 CONFIG_SPI_PL022=y
 CONFIG_SPI_ROCKCHIP=y
+CONFIG_SPI_QCOM_QSPI=m
 CONFIG_SPI_QUP=y
+CONFIG_SPI_QCOM_GENI=m
 CONFIG_SPI_S3C64XX=y
 CONFIG_SPI_SUN6I=y
 CONFIG_SPI_SPIDEV=m
 CONFIG_SPMI=y
 CONFIG_PINCTRL_SINGLE=y
 CONFIG_PINCTRL_MAX77620=y
+CONFIG_PINCTRL_OWL=y
+CONFIG_PINCTRL_S700=y
+CONFIG_PINCTRL_S900=y
 CONFIG_PINCTRL_IMX8MM=y
 CONFIG_PINCTRL_IMX8MN=y
 CONFIG_PINCTRL_IMX8MQ=y
@@ -421,6 +434,7 @@ CONFIG_GPIO_PCA953X=y
 CONFIG_GPIO_PCA953X_IRQ=y
 CONFIG_GPIO_MAX77620=y
 CONFIG_POWER_AVS=y
+CONFIG_QCOM_CPR=y
 CONFIG_ROCKCHIP_IODOMAIN=y
 CONFIG_POWER_RESET_MSM=y
 CONFIG_POWER_RESET_XGENE=y
@@ -448,6 +462,7 @@ CONFIG_BRCMSTB_THERMAL=m
 CONFIG_EXYNOS_THERMAL=y
 CONFIG_TEGRA_BPMP_THERMAL=m
 CONFIG_QCOM_TSENS=y
+CONFIG_QCOM_SPMI_TEMP_ALARM=m
 CONFIG_UNIPHIER_THERMAL=y
 CONFIG_WATCHDOG=y
 CONFIG_ARM_SP805_WATCHDOG=y
@@ -458,6 +473,7 @@ CONFIG_IMX2_WDT=y
 CONFIG_IMX_SC_WDT=m
 CONFIG_MESON_GXBB_WATCHDOG=m
 CONFIG_MESON_WATCHDOG=m
+CONFIG_QCOM_WDT=m
 CONFIG_RENESAS_WDT=y
 CONFIG_UNIPHIER_WATCHDOG=y
 CONFIG_BCM2835_WDT=y
@@ -537,6 +553,7 @@ CONFIG_DRM_MSM=m
 CONFIG_DRM_TEGRA=m
 CONFIG_DRM_PANEL_SIMPLE=m
 CONFIG_DRM_SII902X=m
+CONFIG_DRM_TI_SN65DSI86=m
 CONFIG_DRM_I2C_ADV7511=m
 CONFIG_DRM_VC4=m
 CONFIG_DRM_ETNAVIV=m
@@ -578,6 +595,7 @@ CONFIG_SND_SIMPLE_CARD=m
 CONFIG_SND_AUDIO_GRAPH_CARD=m
 CONFIG_I2C_HID=m
 CONFIG_USB=y
+CONFIG_USB_CONN_GPIO=m
 CONFIG_USB_OTG=y
 CONFIG_USB_XHCI_HCD=y
 CONFIG_USB_XHCI_TEGRA=y
@@ -603,7 +621,10 @@ CONFIG_USB_ULPI=y
 CONFIG_USB_GADGET=y
 CONFIG_USB_RENESAS_USBHS_UDC=m
 CONFIG_USB_RENESAS_USB3=m
+CONFIG_USB_TEGRA_XUDC=m
 CONFIG_TYPEC=m
+CONFIG_TYPEC_TCPM=m
+CONFIG_TYPEC_FUSB302=m
 CONFIG_TYPEC_HD3SS3220=m
 CONFIG_MMC=y
 CONFIG_MMC_BLOCK_MINORS=32
@@ -630,6 +651,7 @@ CONFIG_MMC_DW_ROCKCHIP=y
 CONFIG_MMC_SUNXI=y
 CONFIG_MMC_BCM2835=y
 CONFIG_MMC_SDHCI_XENON=y
+CONFIG_MMC_OWL=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 CONFIG_LEDS_GPIO=y
@@ -666,6 +688,7 @@ CONFIG_IMX_SDMA=y
 CONFIG_K3_DMA=y
 CONFIG_MV_XOR=y
 CONFIG_MV_XOR_V2=y
+CONFIG_OWL_DMA=y
 CONFIG_PL330_DMA=y
 CONFIG_TEGRA20_APB_DMA=y
 CONFIG_QCOM_BAM_DMA=y
@@ -692,6 +715,7 @@ CONFIG_COMMON_CLK_PWM=y
 CONFIG_CLK_RASPBERRYPI=m
 CONFIG_CLK_IMX8MM=y
 CONFIG_CLK_IMX8MN=y
+CONFIG_CLK_IMX8MP=y
 CONFIG_CLK_IMX8MQ=y
 CONFIG_CLK_IMX8QXP=y
 CONFIG_TI_SCI_CLK=y
@@ -708,6 +732,7 @@ CONFIG_MSM_GCC_8998=y
 CONFIG_QCS_GCC_404=y
 CONFIG_SDM_GCC_845=y
 CONFIG_SM_GCC_8150=y
+CONFIG_QCOM_HFPLL=y
 CONFIG_HWSPINLOCK=y
 CONFIG_HWSPINLOCK_QCOM=y
 CONFIG_ARM_MHU=y
@@ -727,15 +752,21 @@ CONFIG_QCOM_SYSMON=m
 CONFIG_RPMSG_QCOM_GLINK_RPM=y
 CONFIG_RPMSG_QCOM_GLINK_SMEM=m
 CONFIG_RPMSG_QCOM_SMD=y
+CONFIG_OWL_PM_DOMAINS=y
 CONFIG_RASPBERRYPI_POWER=y
 CONFIG_IMX_SCU_SOC=y
+CONFIG_QCOM_AOSS_QMP=y
+CONFIG_QCOM_COMMAND_DB=y
 CONFIG_QCOM_GENI_SE=y
 CONFIG_QCOM_GLINK_SSR=m
+CONFIG_QCOM_RMTFS_MEM=m
 CONFIG_QCOM_RPMH=y
+CONFIG_QCOM_RPMHPD=y
 CONFIG_QCOM_SMEM=y
 CONFIG_QCOM_SMD_RPM=y
 CONFIG_QCOM_SMP2P=y
 CONFIG_QCOM_SMSM=y
+CONFIG_QCOM_SOCINFO=m
 CONFIG_ARCH_R8A774A1=y
 CONFIG_ARCH_R8A774B1=y
 CONFIG_ARCH_R8A774C0=y
@@ -747,6 +778,7 @@ CONFIG_ARCH_R8A77970=y
 CONFIG_ARCH_R8A77980=y
 CONFIG_ARCH_R8A77990=y
 CONFIG_ARCH_R8A77995=y
+CONFIG_QCOM_PDC=y
 CONFIG_ROCKCHIP_PM_DOMAINS=y
 CONFIG_ARCH_TEGRA_132_SOC=y
 CONFIG_ARCH_TEGRA_210_SOC=y
@@ -760,6 +792,7 @@ CONFIG_EXTCON_USBC_CROS_EC=y
 CONFIG_MEMORY=y
 CONFIG_IIO=y
 CONFIG_EXYNOS_ADC=y
+CONFIG_QCOM_SPMI_ADC5=m
 CONFIG_ROCKCHIP_SARADC=m
 CONFIG_IIO_CROS_EC_SENSORS_CORE=m
 CONFIG_IIO_CROS_EC_SENSORS=m
@@ -776,6 +809,8 @@ CONFIG_PWM_ROCKCHIP=y
 CONFIG_PWM_SAMSUNG=y
 CONFIG_PWM_SUN4I=m
 CONFIG_PWM_TEGRA=m
+CONFIG_RESET_QCOM_AOSS=y
+CONFIG_RESET_QCOM_PDC=m
 CONFIG_RESET_TI_SCI=y
 CONFIG_PHY_XGENE=y
 CONFIG_PHY_SUN4I_USB=y
@@ -846,7 +881,10 @@ CONFIG_SECURITY=y
 CONFIG_CRYPTO_ECHAINIV=y
 CONFIG_CRYPTO_ANSI_CPRNG=y
 CONFIG_CRYPTO_DEV_SUN8I_CE=m
+CONFIG_CRYPTO_DEV_FSL_CAAM=m
 CONFIG_CRYPTO_DEV_HISI_ZIP=m
+CONFIG_CRYPTO_USER_API_RNG=m
+CONFIG_CRYPTO_DEV_QCOM_RNG=m
 CONFIG_CMA_SIZE_MBYTES=32
 CONFIG_PRINTK_TIME=y
 CONFIG_DEBUG_INFO=y
index bd23f87..d3077c9 100644 (file)
@@ -3,7 +3,6 @@ generic-y += bugs.h
 generic-y += delay.h
 generic-y += div64.h
 generic-y += dma.h
-generic-y += dma-contiguous.h
 generic-y += dma-mapping.h
 generic-y += early_ioremap.h
 generic-y += emergency-restart.h
index 4750fc8..25fec4b 100644 (file)
@@ -140,11 +140,11 @@ static inline u32 gic_read_rpr(void)
 #define gicr_write_pendbaser(v, c)     writeq_relaxed(v, c)
 #define gicr_read_pendbaser(c)         readq_relaxed(c)
 
-#define gits_write_vpropbaser(v, c)    writeq_relaxed(v, c)
-#define gits_read_vpropbaser(c)                readq_relaxed(c)
+#define gicr_write_vpropbaser(v, c)    writeq_relaxed(v, c)
+#define gicr_read_vpropbaser(c)                readq_relaxed(c)
 
-#define gits_write_vpendbaser(v, c)    writeq_relaxed(v, c)
-#define gits_read_vpendbaser(c)                readq_relaxed(c)
+#define gicr_write_vpendbaser(v, c)    writeq_relaxed(v, c)
+#define gicr_read_vpendbaser(c)                readq_relaxed(c)
 
 static inline bool gic_prio_masking_enabled(void)
 {
index cd5de0e..538c85e 100644 (file)
@@ -441,6 +441,7 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
                                 PMD_TYPE_TABLE)
 #define pmd_sect(pmd)          ((pmd_val(pmd) & PMD_TYPE_MASK) == \
                                 PMD_TYPE_SECT)
+#define pmd_leaf(pmd)          pmd_sect(pmd)
 
 #if defined(CONFIG_ARM64_64K_PAGES) || CONFIG_PGTABLE_LEVELS < 3
 static inline bool pud_sect(pud_t pud) { return false; }
@@ -525,6 +526,7 @@ static inline void pte_unmap(pte_t *pte) { }
 #define pud_none(pud)          (!pud_val(pud))
 #define pud_bad(pud)           (!(pud_val(pud) & PUD_TABLE_BIT))
 #define pud_present(pud)       pte_present(pud_pte(pud))
+#define pud_leaf(pud)          pud_sect(pud)
 #define pud_valid(pud)         pte_valid(pud_pte(pud))
 
 static inline void set_pud(pud_t *pudp, pud_t pud)
index 0b8e726..38187f7 100644 (file)
@@ -5,7 +5,7 @@
 #ifndef __ASM_PTDUMP_H
 #define __ASM_PTDUMP_H
 
-#ifdef CONFIG_ARM64_PTDUMP_CORE
+#ifdef CONFIG_PTDUMP_CORE
 
 #include <linux/mm_types.h>
 #include <linux/seq_file.h>
@@ -21,15 +21,15 @@ struct ptdump_info {
        unsigned long                   base_addr;
 };
 
-void ptdump_walk_pgd(struct seq_file *s, struct ptdump_info *info);
-#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS
+void ptdump_walk(struct seq_file *s, struct ptdump_info *info);
+#ifdef CONFIG_PTDUMP_DEBUGFS
 void ptdump_debugfs_register(struct ptdump_info *info, const char *name);
 #else
 static inline void ptdump_debugfs_register(struct ptdump_info *info,
                                           const char *name) { }
 #endif
 void ptdump_check_wx(void);
-#endif /* CONFIG_ARM64_PTDUMP_CORE */
+#endif /* CONFIG_PTDUMP_CORE */
 
 #ifdef CONFIG_DEBUG_WX
 #define debug_checkwx()        ptdump_check_wx()
index 849c1df..d91030f 100644 (file)
@@ -4,8 +4,8 @@ obj-y                           := dma-mapping.o extable.o fault.o init.o \
                                   ioremap.o mmap.o pgd.o mmu.o \
                                   context.o proc.o pageattr.o
 obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
-obj-$(CONFIG_ARM64_PTDUMP_CORE)        += dump.o
-obj-$(CONFIG_ARM64_PTDUMP_DEBUGFS)     += ptdump_debugfs.o
+obj-$(CONFIG_PTDUMP_CORE)      += dump.o
+obj-$(CONFIG_PTDUMP_DEBUGFS)   += ptdump_debugfs.o
 obj-$(CONFIG_NUMA)             += numa.o
 obj-$(CONFIG_DEBUG_VIRTUAL)    += physaddr.o
 KASAN_SANITIZE_physaddr.o      += n
index 0a920b5..860c00e 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/io.h>
 #include <linux/init.h>
 #include <linux/mm.h>
+#include <linux/ptdump.h>
 #include <linux/sched.h>
 #include <linux/seq_file.h>
 
@@ -75,10 +76,11 @@ static struct addr_marker address_markers[] = {
  * dumps out a description of the range.
  */
 struct pg_state {
+       struct ptdump_state ptdump;
        struct seq_file *seq;
        const struct addr_marker *marker;
        unsigned long start_address;
-       unsigned level;
+       int level;
        u64 current_prot;
        bool check_wx;
        unsigned long wx_pages;
@@ -174,11 +176,14 @@ struct pg_level {
 };
 
 static struct pg_level pg_level[] = {
-       {
-       }, { /* pgd */
+       { /* pgd */
                .name   = "PGD",
                .bits   = pte_bits,
                .num    = ARRAY_SIZE(pte_bits),
+       }, { /* p4d */
+               .name   = "P4D",
+               .bits   = pte_bits,
+               .num    = ARRAY_SIZE(pte_bits),
        }, { /* pud */
                .name   = (CONFIG_PGTABLE_LEVELS > 3) ? "PUD" : "PGD",
                .bits   = pte_bits,
@@ -241,13 +246,17 @@ static void note_prot_wx(struct pg_state *st, unsigned long addr)
        st->wx_pages += (addr - st->start_address) / PAGE_SIZE;
 }
 
-static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
-                               u64 val)
+static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+                     unsigned long val)
 {
+       struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
        static const char units[] = "KMGTPE";
-       u64 prot = val & pg_level[level].mask;
+       u64 prot = 0;
+
+       if (level >= 0)
+               prot = val & pg_level[level].mask;
 
-       if (!st->level) {
+       if (st->level == -1) {
                st->level = level;
                st->current_prot = prot;
                st->start_address = addr;
@@ -260,21 +269,22 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
                if (st->current_prot) {
                        note_prot_uxn(st, addr);
                        note_prot_wx(st, addr);
-                       pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx   ",
+               }
+
+               pt_dump_seq_printf(st->seq, "0x%016lx-0x%016lx   ",
                                   st->start_address, addr);
 
-                       delta = (addr - st->start_address) >> 10;
-                       while (!(delta & 1023) && unit[1]) {
-                               delta >>= 10;
-                               unit++;
-                       }
-                       pt_dump_seq_printf(st->seq, "%9lu%c %s", delta, *unit,
-                                  pg_level[st->level].name);
-                       if (pg_level[st->level].bits)
-                               dump_prot(st, pg_level[st->level].bits,
-                                         pg_level[st->level].num);
-                       pt_dump_seq_puts(st->seq, "\n");
+               delta = (addr - st->start_address) >> 10;
+               while (!(delta & 1023) && unit[1]) {
+                       delta >>= 10;
+                       unit++;
                }
+               pt_dump_seq_printf(st->seq, "%9lu%c %s", delta, *unit,
+                                  pg_level[st->level].name);
+               if (st->current_prot && pg_level[st->level].bits)
+                       dump_prot(st, pg_level[st->level].bits,
+                                 pg_level[st->level].num);
+               pt_dump_seq_puts(st->seq, "\n");
 
                if (addr >= st->marker[1].start_address) {
                        st->marker++;
@@ -293,85 +303,27 @@ static void note_page(struct pg_state *st, unsigned long addr, unsigned level,
 
 }
 
-static void walk_pte(struct pg_state *st, pmd_t *pmdp, unsigned long start,
-                    unsigned long end)
-{
-       unsigned long addr = start;
-       pte_t *ptep = pte_offset_kernel(pmdp, start);
-
-       do {
-               note_page(st, addr, 4, READ_ONCE(pte_val(*ptep)));
-       } while (ptep++, addr += PAGE_SIZE, addr != end);
-}
-
-static void walk_pmd(struct pg_state *st, pud_t *pudp, unsigned long start,
-                    unsigned long end)
-{
-       unsigned long next, addr = start;
-       pmd_t *pmdp = pmd_offset(pudp, start);
-
-       do {
-               pmd_t pmd = READ_ONCE(*pmdp);
-               next = pmd_addr_end(addr, end);
-
-               if (pmd_none(pmd) || pmd_sect(pmd)) {
-                       note_page(st, addr, 3, pmd_val(pmd));
-               } else {
-                       BUG_ON(pmd_bad(pmd));
-                       walk_pte(st, pmdp, addr, next);
-               }
-       } while (pmdp++, addr = next, addr != end);
-}
-
-static void walk_pud(struct pg_state *st, pgd_t *pgdp, unsigned long start,
-                    unsigned long end)
+void ptdump_walk(struct seq_file *s, struct ptdump_info *info)
 {
-       unsigned long next, addr = start;
-       pud_t *pudp = pud_offset(pgdp, start);
-
-       do {
-               pud_t pud = READ_ONCE(*pudp);
-               next = pud_addr_end(addr, end);
-
-               if (pud_none(pud) || pud_sect(pud)) {
-                       note_page(st, addr, 2, pud_val(pud));
-               } else {
-                       BUG_ON(pud_bad(pud));
-                       walk_pmd(st, pudp, addr, next);
-               }
-       } while (pudp++, addr = next, addr != end);
-}
+       unsigned long end = ~0UL;
+       struct pg_state st;
 
-static void walk_pgd(struct pg_state *st, struct mm_struct *mm,
-                    unsigned long start)
-{
-       unsigned long end = (start < TASK_SIZE_64) ? TASK_SIZE_64 : 0;
-       unsigned long next, addr = start;
-       pgd_t *pgdp = pgd_offset(mm, start);
-
-       do {
-               pgd_t pgd = READ_ONCE(*pgdp);
-               next = pgd_addr_end(addr, end);
-
-               if (pgd_none(pgd)) {
-                       note_page(st, addr, 1, pgd_val(pgd));
-               } else {
-                       BUG_ON(pgd_bad(pgd));
-                       walk_pud(st, pgdp, addr, next);
-               }
-       } while (pgdp++, addr = next, addr != end);
-}
+       if (info->base_addr < TASK_SIZE_64)
+               end = TASK_SIZE_64;
 
-void ptdump_walk_pgd(struct seq_file *m, struct ptdump_info *info)
-{
-       struct pg_state st = {
-               .seq = m,
+       st = (struct pg_state){
+               .seq = s,
                .marker = info->markers,
+               .ptdump = {
+                       .note_page = note_page,
+                       .range = (struct ptdump_range[]){
+                               {info->base_addr, end},
+                               {0, 0}
+                       }
+               }
        };
 
-       walk_pgd(&st, info->mm, info->base_addr);
-
-       note_page(&st, 0, 0, 0);
+       ptdump_walk_pgd(&st.ptdump, info->mm, NULL);
 }
 
 static void ptdump_initialize(void)
@@ -398,11 +350,19 @@ void ptdump_check_wx(void)
                        { 0, NULL},
                        { -1, NULL},
                },
+               .level = -1,
                .check_wx = true,
+               .ptdump = {
+                       .note_page = note_page,
+                       .range = (struct ptdump_range[]) {
+                               {PAGE_OFFSET, ~0UL},
+                               {0, 0}
+                       }
+               }
        };
 
-       walk_pgd(&st, &init_mm, PAGE_OFFSET);
-       note_page(&st, 0, 0, 0);
+       ptdump_walk_pgd(&st.ptdump, &init_mm, NULL);
+
        if (st.wx_pages || st.uxn_pages)
                pr_warn("Checked W+X mappings: FAILED, %lu W+X pages found, %lu non-UXN pages found\n",
                        st.wx_pages, st.uxn_pages);
index 40797cb..128f708 100644 (file)
@@ -943,13 +943,13 @@ int __init arch_ioremap_pud_supported(void)
         * SW table walks can't handle removal of intermediate entries.
         */
        return IS_ENABLED(CONFIG_ARM64_4K_PAGES) &&
-              !IS_ENABLED(CONFIG_ARM64_PTDUMP_DEBUGFS);
+              !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS);
 }
 
 int __init arch_ioremap_pmd_supported(void)
 {
        /* See arch_ioremap_pud_supported() */
-       return !IS_ENABLED(CONFIG_ARM64_PTDUMP_DEBUGFS);
+       return !IS_ENABLED(CONFIG_PTDUMP_DEBUGFS);
 }
 
 int pud_set_huge(pud_t *pudp, phys_addr_t phys, pgprot_t prot)
index 064163f..1f2eae3 100644 (file)
@@ -7,7 +7,7 @@
 static int ptdump_show(struct seq_file *m, void *v)
 {
        struct ptdump_info *info = m->private;
-       ptdump_walk_pgd(m, info);
+       ptdump_walk(m, info);
        return 0;
 }
 DEFINE_SHOW_ATTRIBUTE(ptdump);
index 4d4754e..bc15a26 100644 (file)
@@ -7,7 +7,6 @@ generic-y += delay.h
 generic-y += device.h
 generic-y += div64.h
 generic-y += dma.h
-generic-y += dma-contiguous.h
 generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
index b392c0a..a25ab9b 100644 (file)
@@ -331,10 +331,10 @@ retry:
        return size;
 }
 
-static const struct file_operations salinfo_event_fops = {
-       .open  = salinfo_event_open,
-       .read  = salinfo_event_read,
-       .llseek = noop_llseek,
+static const struct proc_ops salinfo_event_proc_ops = {
+       .proc_open      = salinfo_event_open,
+       .proc_read      = salinfo_event_read,
+       .proc_lseek     = noop_llseek,
 };
 
 static int
@@ -534,12 +534,12 @@ salinfo_log_write(struct file *file, const char __user *buffer, size_t count, lo
        return count;
 }
 
-static const struct file_operations salinfo_data_fops = {
-       .open    = salinfo_log_open,
-       .release = salinfo_log_release,
-       .read    = salinfo_log_read,
-       .write   = salinfo_log_write,
-       .llseek  = default_llseek,
+static const struct proc_ops salinfo_data_proc_ops = {
+       .proc_open      = salinfo_log_open,
+       .proc_release   = salinfo_log_release,
+       .proc_read      = salinfo_log_read,
+       .proc_write     = salinfo_log_write,
+       .proc_lseek     = default_llseek,
 };
 
 static int salinfo_cpu_online(unsigned int cpu)
@@ -617,13 +617,13 @@ salinfo_init(void)
                        continue;
 
                entry = proc_create_data("event", S_IRUSR, dir,
-                                        &salinfo_event_fops, data);
+                                        &salinfo_event_proc_ops, data);
                if (!entry)
                        continue;
                *sdir++ = entry;
 
                entry = proc_create_data("data", S_IRUSR | S_IWUSR, dir,
-                                        &salinfo_data_fops, data);
+                                        &salinfo_data_proc_ops, data);
                if (!entry)
                        continue;
                *sdir++ = entry;
index d5e683d..3a84f24 100644 (file)
@@ -13,7 +13,6 @@ CONFIG_EMBEDDED=y
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_COMPAT_BRK is not set
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_MMU is not set
 CONFIG_M5307=y
 CONFIG_AMCORE=y
index a3102ff..0ee3079 100644 (file)
@@ -10,8 +10,6 @@ CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_COMPAT_BRK is not set
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_MMU is not set
 # CONFIG_4KSTACKS is not set
 CONFIG_RAMBASE=0x40000000
index f7bb9ed..f84f68c 100644 (file)
@@ -10,8 +10,6 @@ CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_MMU is not set
 CONFIG_M5249=y
 CONFIG_M5249C3=y
index 1e679f6..eca6502 100644 (file)
@@ -10,8 +10,6 @@ CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_MMU is not set
 CONFIG_M5272=y
 CONFIG_M5272C3=y
index d2987b4..9402c7a 100644 (file)
@@ -10,8 +10,6 @@ CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_MMU is not set
 CONFIG_M5275=y
 # CONFIG_4KSTACKS is not set
index 97a78c9..bb8b0eb 100644 (file)
@@ -10,8 +10,6 @@ CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_SLUB_DEBUG is not set
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_MMU is not set
 CONFIG_M5307=y
 CONFIG_M5307C3=y
index 766a97f..ce9ccf1 100644 (file)
@@ -11,8 +11,6 @@ CONFIG_EXPERT=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_MMU is not set
 CONFIG_M5407=y
 CONFIG_M5407C3=y
index 579fd98..93f7c7a 100644 (file)
@@ -11,8 +11,6 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_EMBEDDED=y
 CONFIG_MODULES=y
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_COLDFIRE=y
 # CONFIG_4KSTACKS is not set
 CONFIG_RAMBASE=0x0
index 0134008..6bc80c3 100644 (file)
@@ -71,26 +71,29 @@ extern int __put_user_bad(void);
 #define get_user(x, ptr)                                       \
 ({                                                             \
     int __gu_err = 0;                                          \
-    typeof(x) __gu_val = 0;                                    \
     switch (sizeof(*(ptr))) {                                  \
     case 1:                                                    \
-       __get_user_asm(__gu_err, __gu_val, ptr, b, "=d");       \
+       __get_user_asm(__gu_err, x, ptr, b, "=d");              \
        break;                                                  \
     case 2:                                                    \
-       __get_user_asm(__gu_err, __gu_val, ptr, w, "=r");       \
+       __get_user_asm(__gu_err, x, ptr, w, "=r");              \
        break;                                                  \
     case 4:                                                    \
-       __get_user_asm(__gu_err, __gu_val, ptr, l, "=r");       \
+       __get_user_asm(__gu_err, x, ptr, l, "=r");              \
        break;                                                  \
-    case 8:                                                    \
-       memcpy((void *) &__gu_val, ptr, sizeof (*(ptr)));       \
+    case 8: {                                                  \
+       union {                                                 \
+           u64 l;                                              \
+           __typeof__(*(ptr)) t;                               \
+       } __gu_val;                                             \
+       memcpy(&__gu_val.l, ptr, sizeof(__gu_val.l));           \
+       (x) = __gu_val.t;                                       \
        break;                                                  \
+    }                                                          \
     default:                                                   \
-       __gu_val = 0;                                           \
        __gu_err = __get_user_bad();                            \
        break;                                                  \
     }                                                          \
-    (x) = (typeof(*(ptr))) __gu_val;                           \
     __gu_err;                                                  \
 })
 #define __get_user(x, ptr) get_user(x, ptr)
index 3b9cab8..857fa2a 100644 (file)
@@ -26,9 +26,9 @@ static ssize_t bootinfo_read(struct file *file, char __user *buf,
                                       bootinfo_size);
 }
 
-static const struct file_operations bootinfo_fops = {
-       .read = bootinfo_read,
-       .llseek = default_llseek,
+static const struct proc_ops bootinfo_proc_ops = {
+       .proc_read      = bootinfo_read,
+       .proc_lseek     = default_llseek,
 };
 
 void __init save_bootinfo(const struct bi_record *bi)
@@ -67,7 +67,7 @@ static int __init init_bootinfo_procfs(void)
        if (!bootinfo_copy)
                return -ENOMEM;
 
-       pde = proc_create_data("bootinfo", 0400, NULL, &bootinfo_fops, NULL);
+       pde = proc_create_data("bootinfo", 0400, NULL, &bootinfo_proc_ops, NULL);
        if (!pde) {
                kfree(bootinfo_copy);
                return -ENOMEM;
index a105f11..6a331bd 100644 (file)
@@ -27,6 +27,7 @@ config MICROBLAZE
        select HAVE_ARCH_HASH
        select HAVE_ARCH_KGDB
        select HAVE_DEBUG_KMEMLEAK
+       select HAVE_DMA_CONTIGUOUS
        select HAVE_DYNAMIC_FTRACE
        select HAVE_FTRACE_MCOUNT_RECORD
        select HAVE_FUNCTION_GRAPH_TRACER
index b3b433d..9b8a50f 100644 (file)
@@ -26,6 +26,7 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_EFI_PARTITION is not set
+CONFIG_CMA=y
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -73,7 +74,7 @@ CONFIG_FB_XILINX=y
 CONFIG_UIO=y
 CONFIG_UIO_PDRV_GENIRQ=y
 CONFIG_UIO_DMEM_GENIRQ=y
-CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
 # CONFIG_DNOTIFY is not set
 CONFIG_TMPFS=y
 CONFIG_CRAMFS=y
@@ -82,10 +83,11 @@ CONFIG_NFS_FS=y
 CONFIG_CIFS=y
 CONFIG_CIFS_STATS2=y
 CONFIG_ENCRYPTED_KEYS=y
+CONFIG_DMA_CMA=y
 CONFIG_DEBUG_INFO=y
-CONFIG_DEBUG_SLAB=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_DEBUG_SPINLOCK=y
 CONFIG_KGDB=y
 CONFIG_KGDB_TESTS=y
 CONFIG_KGDB_KDB=y
+CONFIG_DEBUG_SLAB=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEBUG_SPINLOCK=y
index 377de39..8c42078 100644 (file)
@@ -70,7 +70,7 @@ CONFIG_XILINX_WATCHDOG=y
 CONFIG_FB=y
 CONFIG_FB_XILINX=y
 # CONFIG_USB_SUPPORT is not set
-CONFIG_EXT2_FS=y
+CONFIG_EXT3_FS=y
 # CONFIG_DNOTIFY is not set
 CONFIG_CRAMFS=y
 CONFIG_ROMFS_FS=y
index 0bde47e..dcba538 100644 (file)
@@ -92,7 +92,8 @@ static inline void __disable_dcache_nomsr(void)
 #define CACHE_LOOP_LIMITS(start, end, cache_line_length, cache_size)   \
 do {                                                                   \
        int align = ~(cache_line_length - 1);                           \
-       end = min(start + cache_size, end);                             \
+       if (start <  UINT_MAX - cache_size)                             \
+               end = min(start + cache_size, end);                     \
        start &= align;                                                 \
 } while (0)
 
index ef2f494..cd9b445 100644 (file)
@@ -51,6 +51,7 @@ const struct cpu_ver_key cpu_ver_lookup[] = {
        {"9.5", 0x22},
        {"9.6", 0x23},
        {"10.0", 0x24},
+       {"11.0", 0x25},
        {NULL, 0},
 };
 
index 7d28944..14b2764 100644 (file)
@@ -121,10 +121,10 @@ no_fdt_arg:
        tophys(r4,r4)                   /* convert to phys address */
        ori     r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */
 _copy_command_line:
-       /* r2=r5+r6 - r5 contain pointer to command line */
+       /* r2=r5+r11 - r5 contain pointer to command line */
        lbu     r2, r5, r11
        beqid   r2, skip                /* Skip if no data */
-       sb      r2, r4, r11             /* addr[r4+r6]= r2 */
+       sb      r2, r4, r11             /* addr[r4+r11]= r2 */
        addik   r11, r11, 1             /* increment counting */
        bgtid   r3, _copy_command_line  /* loop for all entries       */
        addik   r3, r3, -1              /* decrement loop */
@@ -139,8 +139,8 @@ skip:
        ori     r4, r0, TOPHYS(_bram_load_start)        /* save bram context */
        ori     r3, r0, (LMB_SIZE - 4)
 _copy_bram:
-       lw      r7, r0, r11             /* r7 = r0 + r6 */
-       sw      r7, r4, r11             /* addr[r4 + r6] = r7 */
+       lw      r7, r0, r11             /* r7 = r0 + r11 */
+       sw      r7, r4, r11             /* addr[r4 + r11] = r7 */
        addik   r11, r11, 4             /* increment counting */
        bgtid   r3, _copy_bram          /* loop for all entries */
        addik   r3, r3, -4              /* descrement loop */
index 050fc62..1056f16 100644 (file)
@@ -7,6 +7,7 @@
  * for more details.
  */
 
+#include <linux/dma-contiguous.h>
 #include <linux/memblock.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -345,6 +346,9 @@ asmlinkage void __init mmu_init(void)
        /* This will also cause that unflatten device tree will be allocated
         * inside 768MB limit */
        memblock_set_current_limit(memory_start + lowmem_size - 1);
+
+       /* CMA initialization */
+       dma_contiguous_reserve(memory_start + lowmem_size - 1);
 }
 
 /* This is only called until mem_init is done. */
index 16d1eb4..4ebd8ce 100644 (file)
@@ -6,7 +6,6 @@ generated-y += syscall_table_64_n64.h
 generated-y += syscall_table_64_o32.h
 generic-y += current.h
 generic-y += device.h
-generic-y += dma-contiguous.h
 generic-y += emergency-restart.h
 generic-y += export.h
 generic-y += irq_work.h
index 91b89aa..aef5378 100644 (file)
@@ -639,6 +639,11 @@ static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
 
 #endif /* CONFIG_TRANSPARENT_HUGEPAGE */
 
+#ifdef _PAGE_HUGE
+#define pmd_leaf(pmd)  ((pmd_val(pmd) & _PAGE_HUGE) != 0)
+#define pud_leaf(pud)  ((pud_val(pud) & _PAGE_HUGE) != 0)
+#endif
+
 #define gup_fast_permitted(start, end) (!cpu_has_dc_aliases)
 
 #include <asm-generic/pgtable.h>
index 83f2a43..31968cb 100644 (file)
@@ -210,11 +210,6 @@ void show_stack(struct task_struct *task, unsigned long *sp)
                        regs.regs[29] = task->thread.reg29;
                        regs.regs[31] = 0;
                        regs.cp0_epc = task->thread.reg31;
-#ifdef CONFIG_KGDB_KDB
-               } else if (atomic_read(&kgdb_active) != -1 &&
-                          kdb_current_regs) {
-                       memcpy(&regs, kdb_current_regs, sizeof(regs));
-#endif /* CONFIG_KGDB_KDB */
                } else {
                        prepare_frametrace(&regs);
                }
index 2606f3f..71244bf 100644 (file)
@@ -280,6 +280,22 @@ static inline void dump_handler(const char *symbol, void *start, void *end)
        pr_debug("\tEND(%s)\n", symbol);
 }
 
+/* low level hrtimer wake routine */
+static enum hrtimer_restart kvm_mips_comparecount_wakeup(struct hrtimer *timer)
+{
+       struct kvm_vcpu *vcpu;
+
+       vcpu = container_of(timer, struct kvm_vcpu, arch.comparecount_timer);
+
+       kvm_mips_callbacks->queue_timer_int(vcpu);
+
+       vcpu->arch.wait = 0;
+       if (swq_has_sleeper(&vcpu->wq))
+               swake_up_one(&vcpu->wq);
+
+       return kvm_mips_count_timeout(vcpu);
+}
+
 int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
 {
        return 0;
@@ -1209,27 +1225,6 @@ int kvm_arch_vcpu_ioctl_get_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
        return 0;
 }
 
-static void kvm_mips_comparecount_func(unsigned long data)
-{
-       struct kvm_vcpu *vcpu = (struct kvm_vcpu *)data;
-
-       kvm_mips_callbacks->queue_timer_int(vcpu);
-
-       vcpu->arch.wait = 0;
-       if (swq_has_sleeper(&vcpu->wq))
-               swake_up_one(&vcpu->wq);
-}
-
-/* low level hrtimer wake routine */
-static enum hrtimer_restart kvm_mips_comparecount_wakeup(struct hrtimer *timer)
-{
-       struct kvm_vcpu *vcpu;
-
-       vcpu = container_of(timer, struct kvm_vcpu, arch.comparecount_timer);
-       kvm_mips_comparecount_func((unsigned long) vcpu);
-       return kvm_mips_count_timeout(vcpu);
-}
-
 int kvm_arch_vcpu_ioctl_translate(struct kvm_vcpu *vcpu,
                                  struct kvm_translation *tr)
 {
index 8126f15..61c0334 100644 (file)
@@ -89,13 +89,12 @@ static ssize_t pvc_line_proc_write(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct file_operations pvc_line_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = pvc_line_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = pvc_line_proc_write,
+static const struct proc_ops pvc_line_proc_ops = {
+       .proc_open      = pvc_line_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = pvc_line_proc_write,
 };
 
 static ssize_t pvc_scroll_proc_write(struct file *file, const char __user *buf,
@@ -148,13 +147,12 @@ static int pvc_scroll_proc_open(struct inode *inode, struct file *file)
        return single_open(file, pvc_scroll_proc_show, NULL);
 }
 
-static const struct file_operations pvc_scroll_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = pvc_scroll_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = pvc_scroll_proc_write,
+static const struct proc_ops pvc_scroll_proc_ops = {
+       .proc_open      = pvc_scroll_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = pvc_scroll_proc_write,
 };
 
 void pvc_proc_timerfunc(struct timer_list *unused)
@@ -189,12 +187,11 @@ static int __init pvc_proc_init(void)
        }
        for (i = 0; i < PVC_NLINES; i++) {
                proc_entry = proc_create_data(pvc_linename[i], 0644, dir,
-                                       &pvc_line_proc_fops, &pvc_linedata[i]);
+                                       &pvc_line_proc_ops, &pvc_linedata[i]);
                if (proc_entry == NULL)
                        goto error;
        }
-       proc_entry = proc_create("scroll", 0644, dir,
-                                &pvc_scroll_proc_fops);
+       proc_entry = proc_create("scroll", 0644, dir, &pvc_scroll_proc_ops);
        if (proc_entry == NULL)
                goto error;
 
diff --git a/arch/parisc/configs/712_defconfig b/arch/parisc/configs/712_defconfig
deleted file mode 100644 (file)
index d3e3d94..0000000
+++ /dev/null
@@ -1,181 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_PA7100LC=y
-CONFIG_PREEMPT_VOLUNTARY=y
-CONFIG_GSC_LASI=y
-# CONFIG_PDC_CHASSIS is not set
-CONFIG_BINFMT_MISC=m
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_DIAG=m
-# CONFIG_IPV6 is not set
-CONFIG_NETFILTER=y
-CONFIG_LLC2=m
-CONFIG_NET_PKTGEN=m
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=m
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_ATA_OVER_ETH=m
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_SCSI_LASI700=y
-CONFIG_SCSI_DEBUG=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=m
-CONFIG_MD_LINEAR=m
-CONFIG_MD_RAID0=m
-CONFIG_MD_RAID1=m
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_TUN=m
-CONFIG_LASI_82596=y
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_KEYBOARD_HIL_OLD is not set
-CONFIG_MOUSE_SERIAL=m
-CONFIG_LEGACY_PTY_COUNT=64
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=17
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_SERIAL_MUX is not set
-CONFIG_PDC_CONSOLE=y
-CONFIG_PRINTER=m
-CONFIG_PPDEV=m
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-CONFIG_DUMMY_CONSOLE_COLUMNS=128
-CONFIG_DUMMY_CONSOLE_ROWS=48
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_HARMONY=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_JFS_FS=m
-CONFIG_XFS_FS=m
-CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_UFS_FS=m
-CONFIG_NFS_FS=y
-CONFIG_NFS_V4=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_CIFS=m
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-CONFIG_CRYPTO_DEFLATE=m
-# CONFIG_CRYPTO_HW is not set
-CONFIG_FONTS=y
-CONFIG_FONT_8x8=y
-CONFIG_FONT_8x16=y
diff --git a/arch/parisc/configs/a500_defconfig b/arch/parisc/configs/a500_defconfig
deleted file mode 100644 (file)
index 3335734..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_PA8X00=y
-CONFIG_64BIT=y
-CONFIG_SMP=y
-CONFIG_NR_CPUS=8
-# CONFIG_GSC is not set
-CONFIG_PCI=y
-CONFIG_PCI_LBA=y
-CONFIG_PCCARD=m
-# CONFIG_PCMCIA_LOAD_CIS is not set
-CONFIG_YENTA=m
-CONFIG_PD6729=m
-CONFIG_I82092=m
-# CONFIG_SUPERIO is not set
-# CONFIG_CHASSIS_LCD_LED is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET6_AH=m
-CONFIG_INET6_ESP=m
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETFILTER=y
-# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
-CONFIG_IP_NF_IPTABLES=m
-CONFIG_IP_NF_MATCH_ECN=m
-CONFIG_IP_NF_MATCH_TTL=m
-CONFIG_IP_NF_FILTER=m
-CONFIG_IP_NF_TARGET_REJECT=m
-CONFIG_IP_NF_MANGLE=m
-CONFIG_IP_NF_TARGET_ECN=m
-CONFIG_IP_NF_RAW=m
-CONFIG_IP_NF_ARPTABLES=m
-CONFIG_IP_NF_ARPFILTER=m
-CONFIG_IP_NF_ARP_MANGLE=m
-CONFIG_IP6_NF_IPTABLES=m
-CONFIG_IP6_NF_MATCH_FRAG=m
-CONFIG_IP6_NF_MATCH_OPTS=m
-CONFIG_IP6_NF_MATCH_HL=m
-CONFIG_IP6_NF_MATCH_IPV6HEADER=m
-CONFIG_IP6_NF_MATCH_RT=m
-CONFIG_IP6_NF_FILTER=m
-CONFIG_IP6_NF_TARGET_REJECT=m
-CONFIG_IP6_NF_MANGLE=m
-CONFIG_IP6_NF_RAW=m
-CONFIG_IP_DCCP=m
-# CONFIG_IP_DCCP_CCID3 is not set
-CONFIG_LLC2=m
-CONFIG_NET_PKTGEN=m
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_BLK_DEV_UMEM=m
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_RAID_ATTRS=m
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_QLOGIC_1280=m
-CONFIG_SCSI_DEBUG=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=m
-CONFIG_FUSION_CTL=m
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_TUN=m
-CONFIG_PCMCIA_3C574=m
-CONFIG_PCMCIA_3C589=m
-CONFIG_VORTEX=m
-CONFIG_TYPHOON=m
-CONFIG_ACENIC=m
-CONFIG_ACENIC_OMIT_TIGON_I=y
-CONFIG_PCNET32=m
-CONFIG_TIGON3=m
-CONFIG_NET_TULIP=y
-CONFIG_DE2104X=m
-CONFIG_TULIP=y
-CONFIG_TULIP_MMIO=y
-CONFIG_PCMCIA_XIRCOM=m
-CONFIG_HP100=m
-CONFIG_E100=m
-CONFIG_E1000=m
-CONFIG_PCMCIA_SMC91C92=m
-CONFIG_PCMCIA_XIRC2PS=m
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_INPUT_KEYBOARD is not set
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_CS=m
-CONFIG_SERIAL_8250_NR_UARTS=17
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_PDC_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-# CONFIG_HWMON is not set
-CONFIG_AGP=y
-CONFIG_AGP_PARISC=y
-# CONFIG_STI_CONSOLE is not set
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_JFS_FS=m
-CONFIG_XFS_FS=m
-CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_UDF_FS=m
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_UFS_FS=m
-CONFIG_NFS_FS=m
-CONFIG_NFS_V4=m
-CONFIG_NFSD=m
-CONFIG_NFSD_V4=y
-CONFIG_CIFS=m
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_FS=y
-CONFIG_HEADERS_INSTALL=y
-CONFIG_HEADERS_CHECK=y
-CONFIG_MAGIC_SYSRQ=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_HMAC=y
-CONFIG_CRYPTO_MD5=y
-CONFIG_CRYPTO_BLOWFISH=m
-# CONFIG_CRYPTO_HW is not set
diff --git a/arch/parisc/configs/b180_defconfig b/arch/parisc/configs/b180_defconfig
deleted file mode 100644 (file)
index 07fde5b..0000000
+++ /dev/null
@@ -1,97 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
-CONFIG_PA7100LC=y
-CONFIG_HPPB=y
-CONFIG_IOMMU_CCIO=y
-CONFIG_GSC_LASI=y
-CONFIG_GSC_WAX=y
-CONFIG_EISA=y
-CONFIG_ISA=y
-CONFIG_PCI=y
-CONFIG_GSC_DINO=y
-# CONFIG_PDC_CHASSIS is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=y
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_ATA_OVER_ETH=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_LASI700=y
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
-CONFIG_SCSI_ZALON=y
-CONFIG_SCSI_NCR53C8XX_SYNC=40
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_NETDEVICES=y
-CONFIG_NET_TULIP=y
-CONFIG_TULIP=y
-CONFIG_LASI_82596=y
-CONFIG_PPP=y
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_HIL_OLD is not set
-CONFIG_INPUT_MISC=y
-# CONFIG_SERIO_SERPORT is not set
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=13
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_PRINTER=y
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_HARMONY=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_HEADERS_INSTALL=y
-CONFIG_HEADERS_CHECK=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_SECURITY=y
diff --git a/arch/parisc/configs/c3000_defconfig b/arch/parisc/configs/c3000_defconfig
deleted file mode 100644 (file)
index 64d45a8..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_PA8X00=y
-CONFIG_PREEMPT_VOLUNTARY=y
-# CONFIG_GSC is not set
-CONFIG_PCI=y
-CONFIG_PCI_LBA=y
-# CONFIG_PDC_CHASSIS is not set
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
-# CONFIG_INET_DIAG is not set
-CONFIG_INET6_IPCOMP=m
-CONFIG_IPV6_TUNNEL=m
-CONFIG_NETFILTER=y
-CONFIG_NET_PKTGEN=m
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_BLK_DEV_UMEM=m
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_NS87415=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_ISCSI_ATTRS=m
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0
-CONFIG_SCSI_DEBUG=m
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_BLK_DEV_DM=m
-CONFIG_DM_CRYPT=m
-CONFIG_DM_SNAPSHOT=m
-CONFIG_DM_MIRROR=m
-CONFIG_DM_ZERO=m
-CONFIG_DM_MULTIPATH=m
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=m
-CONFIG_FUSION_CTL=m
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_TUN=m
-CONFIG_ACENIC=m
-CONFIG_TIGON3=m
-CONFIG_NET_TULIP=y
-CONFIG_DE2104X=m
-CONFIG_TULIP=y
-CONFIG_TULIP_MMIO=y
-CONFIG_E100=m
-CONFIG_E1000=m
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_MOUSE_PS2 is not set
-CONFIG_SERIO=m
-CONFIG_SERIO_LIBPS2=m
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=13
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_RAW_DRIVER=y
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_AD1889=y
-CONFIG_USB_HIDDEV=y
-CONFIG_USB=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_PRINTER=m
-CONFIG_USB_STORAGE=m
-CONFIG_USB_STORAGE_USBAT=m
-CONFIG_USB_STORAGE_SDDR09=m
-CONFIG_USB_STORAGE_SDDR55=m
-CONFIG_USB_STORAGE_JUMPSHOT=m
-CONFIG_USB_MDC800=m
-CONFIG_USB_MICROTEK=m
-CONFIG_USB_LEGOTOWER=m
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_XFS_FS=m
-CONFIG_AUTOFS4_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V3=y
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_UTF8=m
-CONFIG_DEBUG_FS=y
-CONFIG_HEADERS_INSTALL=y
-CONFIG_HEADERS_CHECK=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_MUTEXES=y
-# CONFIG_DEBUG_BUGVERBOSE is not set
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_MD5=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_DES=m
-# CONFIG_CRYPTO_HW is not set
diff --git a/arch/parisc/configs/c8000_defconfig b/arch/parisc/configs/c8000_defconfig
deleted file mode 100644 (file)
index db864b1..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-# CONFIG_CROSS_MEMORY_ATTACH is not set
-CONFIG_BSD_PROCESS_ACCT=y
-CONFIG_BSD_PROCESS_ACCT_V3=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_RELAY=y
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_EXPERT=y
-CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_BLK_DEV_INTEGRITY=y
-CONFIG_PA8X00=y
-CONFIG_64BIT=y
-CONFIG_SMP=y
-CONFIG_PREEMPT=y
-CONFIG_IOMMU_CCIO=y
-CONFIG_PCI=y
-CONFIG_PCI_LBA=y
-# CONFIG_SUPERIO is not set
-# CONFIG_CHASSIS_LCD_LED is not set
-# CONFIG_PDC_CHASSIS is not set
-# CONFIG_PDC_CHASSIS_WARN is not set
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_BINFMT_MISC=m
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_XFRM_SUB_POLICY=y
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_IP_PNP_RARP=y
-CONFIG_NET_IPIP=m
-CONFIG_IP_MROUTE=y
-CONFIG_IP_PIMSM_V1=y
-CONFIG_IP_PIMSM_V2=y
-CONFIG_SYN_COOKIES=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_IPCOMP=m
-CONFIG_INET_XFRM_MODE_BEET=m
-CONFIG_INET_DIAG=m
-# CONFIG_IPV6 is not set
-CONFIG_IP_DCCP=m
-# CONFIG_IP_DCCP_CCID3 is not set
-CONFIG_TIPC=m
-CONFIG_LLC2=m
-CONFIG_DNS_RESOLVER=y
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_STANDALONE is not set
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=y
-CONFIG_PARPORT_PC_FIFO=y
-CONFIG_BLK_DEV_UMEM=m
-CONFIG_BLK_DEV_LOOP=m
-CONFIG_BLK_DEV_CRYPTOLOOP=m
-CONFIG_BLK_DEV_SX8=m
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_CDROM_PKTCDVD=m
-CONFIG_CDROM_PKTCDVD_WCACHE=y
-CONFIG_ATA_OVER_ETH=m
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_PLATFORM=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=m
-CONFIG_BLK_DEV_SR=m
-CONFIG_CHR_DEV_SG=y
-CONFIG_CHR_DEV_SCH=m
-CONFIG_SCSI_CONSTANTS=y
-CONFIG_SCSI_LOGGING=y
-CONFIG_SCSI_FC_ATTRS=y
-CONFIG_SCSI_SAS_LIBSAS=m
-CONFIG_ISCSI_TCP=m
-CONFIG_ISCSI_BOOT_SYSFS=m
-CONFIG_ATA=y
-CONFIG_PATA_SIL680=y
-CONFIG_FUSION=y
-CONFIG_FUSION_SPI=y
-CONFIG_FUSION_SAS=y
-CONFIG_NETDEVICES=y
-CONFIG_DUMMY=m
-CONFIG_NETCONSOLE=m
-CONFIG_TUN=y
-CONFIG_E1000=y
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPP_MPPE=m
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_WLAN is not set
-CONFIG_INPUT_FF_MEMLESS=m
-# CONFIG_KEYBOARD_ATKBD is not set
-# CONFIG_KEYBOARD_HIL_OLD is not set
-# CONFIG_KEYBOARD_HIL is not set
-# CONFIG_MOUSE_PS2 is not set
-CONFIG_INPUT_MISC=y
-CONFIG_SERIO_SERPORT=m
-CONFIG_SERIO_PARKBD=m
-CONFIG_SERIO_GSCPS2=m
-# CONFIG_HP_SDC is not set
-CONFIG_SERIO_PCIPS2=m
-CONFIG_SERIO_LIBPS2=y
-CONFIG_SERIO_RAW=m
-CONFIG_SERIAL_8250=y
-# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_NR_UARTS=8
-CONFIG_SERIAL_8250_RUNTIME_UARTS=8
-CONFIG_SERIAL_8250_EXTENDED=y
-# CONFIG_SERIAL_MUX is not set
-CONFIG_SERIAL_JSM=m
-CONFIG_PRINTER=y
-CONFIG_HW_RANDOM=y
-CONFIG_RAW_DRIVER=m
-CONFIG_PTP_1588_CLOCK=y
-CONFIG_SSB=m
-CONFIG_SSB_DRIVER_PCICORE=y
-CONFIG_AGP=y
-CONFIG_AGP_PARISC=y
-CONFIG_DRM=y
-CONFIG_DRM_RADEON=y
-CONFIG_FIRMWARE_EDID=y
-CONFIG_FB_FOREIGN_ENDIAN=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-# CONFIG_FB_STI is not set
-# CONFIG_LCD_CLASS_DEVICE is not set
-# CONFIG_BACKLIGHT_GENERIC is not set
-CONFIG_FRAMEBUFFER_CONSOLE=y
-# CONFIG_STI_CONSOLE is not set
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-CONFIG_SOUND=m
-CONFIG_SND=m
-CONFIG_SND_VERBOSE_PRINTK=y
-CONFIG_SND_SEQUENCER=m
-CONFIG_SND_SEQ_DUMMY=m
-CONFIG_SND_AD1889=m
-# CONFIG_SND_USB is not set
-# CONFIG_SND_GSC is not set
-CONFIG_USB=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_STORAGE=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT2_FS_XATTR=y
-CONFIG_EXT2_FS_POSIX_ACL=y
-CONFIG_EXT2_FS_SECURITY=y
-CONFIG_EXT3_FS=y
-CONFIG_REISERFS_FS=m
-CONFIG_REISERFS_PROC_INFO=y
-CONFIG_XFS_FS=m
-CONFIG_XFS_POSIX_ACL=y
-CONFIG_QUOTA=y
-CONFIG_QFMT_V1=m
-CONFIG_QFMT_V2=m
-CONFIG_AUTOFS4_FS=m
-CONFIG_FUSE_FS=m
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_MSDOS_FS=m
-CONFIG_VFAT_FS=m
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_TMPFS_XATTR=y
-CONFIG_NFS_FS=m
-CONFIG_NLS_CODEPAGE_437=m
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=m
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=m
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=m
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_SLAB=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_PANIC_ON_OOPS=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_BLOCK_EXT_DEVT=y
-CONFIG_LATENCYTOP=y
-CONFIG_KEYS=y
-# CONFIG_CRYPTO_HW is not set
-CONFIG_FONTS=y
diff --git a/arch/parisc/configs/defconfig b/arch/parisc/configs/defconfig
deleted file mode 100644 (file)
index 5b877ca..0000000
+++ /dev/null
@@ -1,206 +0,0 @@
-# CONFIG_LOCALVERSION_AUTO is not set
-CONFIG_SYSVIPC=y
-CONFIG_POSIX_MQUEUE=y
-CONFIG_IKCONFIG=y
-CONFIG_IKCONFIG_PROC=y
-CONFIG_LOG_BUF_SHIFT=16
-CONFIG_BLK_DEV_INITRD=y
-CONFIG_KALLSYMS_ALL=y
-CONFIG_SLAB=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
-CONFIG_PA7100LC=y
-CONFIG_PREEMPT_VOLUNTARY=y
-CONFIG_IOMMU_CCIO=y
-CONFIG_GSC_LASI=y
-CONFIG_GSC_WAX=y
-CONFIG_EISA=y
-CONFIG_PCI=y
-CONFIG_GSC_DINO=y
-CONFIG_PCI_LBA=y
-CONFIG_PCCARD=y
-CONFIG_YENTA=y
-CONFIG_PD6729=y
-CONFIG_I82092=y
-CONFIG_BINFMT_MISC=m
-CONFIG_NET=y
-CONFIG_PACKET=y
-CONFIG_UNIX=y
-CONFIG_XFRM_USER=m
-CONFIG_NET_KEY=m
-CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_DHCP=y
-CONFIG_IP_PNP_BOOTP=y
-CONFIG_INET_AH=m
-CONFIG_INET_ESP=m
-CONFIG_INET_DIAG=m
-CONFIG_INET6_AH=y
-CONFIG_INET6_ESP=y
-CONFIG_INET6_IPCOMP=y
-CONFIG_LLC2=m
-CONFIG_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-# CONFIG_STANDALONE is not set
-# CONFIG_PREVENT_FIRMWARE_BUILD is not set
-CONFIG_PARPORT=y
-CONFIG_PARPORT_PC=m
-CONFIG_PARPORT_PC_PCMCIA=m
-CONFIG_PARPORT_1284=y
-CONFIG_BLK_DEV_LOOP=y
-CONFIG_BLK_DEV_CRYPTOLOOP=y
-CONFIG_BLK_DEV_RAM=y
-CONFIG_BLK_DEV_RAM_SIZE=6144
-CONFIG_IDE=y
-CONFIG_BLK_DEV_IDECS=y
-CONFIG_BLK_DEV_IDECD=y
-CONFIG_BLK_DEV_GENERIC=y
-CONFIG_BLK_DEV_NS87415=y
-CONFIG_SCSI=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_CHR_DEV_ST=y
-CONFIG_BLK_DEV_SR=y
-CONFIG_CHR_DEV_SG=y
-CONFIG_SCSI_LASI700=y
-CONFIG_SCSI_SYM53C8XX_2=y
-CONFIG_SCSI_ZALON=y
-CONFIG_MD=y
-CONFIG_BLK_DEV_MD=y
-CONFIG_MD_LINEAR=y
-CONFIG_MD_RAID0=y
-CONFIG_MD_RAID1=y
-CONFIG_MD_RAID10=y
-CONFIG_BLK_DEV_DM=y
-CONFIG_NETDEVICES=y
-CONFIG_BONDING=m
-CONFIG_DUMMY=m
-CONFIG_TUN=m
-CONFIG_ACENIC=y
-CONFIG_TIGON3=y
-CONFIG_NET_TULIP=y
-CONFIG_TULIP=y
-CONFIG_LASI_82596=y
-CONFIG_PPP=m
-CONFIG_PPP_BSDCOMP=m
-CONFIG_PPP_DEFLATE=m
-CONFIG_PPPOE=m
-CONFIG_PPP_ASYNC=m
-CONFIG_PPP_SYNC_TTY=m
-# CONFIG_KEYBOARD_HIL_OLD is not set
-CONFIG_MOUSE_SERIAL=y
-CONFIG_LEGACY_PTY_COUNT=64
-CONFIG_SERIAL_8250=y
-CONFIG_SERIAL_8250_CONSOLE=y
-CONFIG_SERIAL_8250_CS=y
-CONFIG_SERIAL_8250_NR_UARTS=17
-CONFIG_SERIAL_8250_EXTENDED=y
-CONFIG_SERIAL_8250_MANY_PORTS=y
-CONFIG_SERIAL_8250_SHARE_IRQ=y
-CONFIG_PRINTER=m
-CONFIG_PPDEV=m
-# CONFIG_HW_RANDOM is not set
-# CONFIG_HWMON is not set
-CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
-CONFIG_FB_TILEBLITTING=y
-CONFIG_DUMMY_CONSOLE_COLUMNS=128
-CONFIG_DUMMY_CONSOLE_ROWS=48
-CONFIG_FRAMEBUFFER_CONSOLE=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
-# CONFIG_LOGO_LINUX_VGA16 is not set
-# CONFIG_LOGO_LINUX_CLUT224 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_DYNAMIC_MINORS=y
-CONFIG_SND_SEQUENCER=y
-CONFIG_SND_AD1889=y
-CONFIG_SND_HARMONY=y
-CONFIG_HID_GYRATION=y
-CONFIG_HID_NTRIG=y
-CONFIG_HID_PANTHERLORD=y
-CONFIG_HID_PETALYNX=y
-CONFIG_HID_SAMSUNG=y
-CONFIG_HID_SUNPLUS=y
-CONFIG_HID_TOPSEED=y
-CONFIG_USB=y
-CONFIG_USB_MON=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_UHCI_HCD=y
-CONFIG_EXT2_FS=y
-CONFIG_EXT3_FS=y
-CONFIG_ISO9660_FS=y
-CONFIG_JOLIET=y
-CONFIG_VFAT_FS=y
-CONFIG_PROC_KCORE=y
-CONFIG_TMPFS=y
-CONFIG_NFS_FS=y
-CONFIG_ROOT_NFS=y
-CONFIG_NFSD=y
-CONFIG_NFSD_V4=y
-CONFIG_CIFS=m
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=y
-CONFIG_DEBUG_FS=y
-CONFIG_HEADERS_INSTALL=y
-CONFIG_HEADERS_CHECK=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_KEYS=y
-CONFIG_CRYPTO_TEST=m
-CONFIG_CRYPTO_MICHAEL_MIC=m
-CONFIG_CRYPTO_SHA512=m
-CONFIG_CRYPTO_TGR192=m
-CONFIG_CRYPTO_WP512=m
-CONFIG_CRYPTO_ANUBIS=m
-CONFIG_CRYPTO_BLOWFISH=m
-CONFIG_CRYPTO_CAST6=m
-CONFIG_CRYPTO_KHAZAD=m
-CONFIG_CRYPTO_SERPENT=m
-CONFIG_CRYPTO_TEA=m
-CONFIG_CRYPTO_TWOFISH=m
-# CONFIG_CRYPTO_HW is not set
-CONFIG_LIBCRC32C=m
-CONFIG_FONTS=y
index c7a5726..61bac8f 100644 (file)
@@ -10,23 +10,20 @@ CONFIG_BLK_DEV_INITRD=y
 CONFIG_EXPERT=y
 CONFIG_PERF_EVENTS=y
 CONFIG_SLAB=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_BLK_DEV_BSG is not set
 CONFIG_PA7100LC=y
 CONFIG_SMP=y
 CONFIG_HZ_100=y
 CONFIG_IOMMU_CCIO=y
 CONFIG_GSC_LASI=y
 CONFIG_GSC_WAX=y
-CONFIG_EISA=y
-CONFIG_PCI=y
 CONFIG_GSC_DINO=y
 CONFIG_PCI_LBA=y
-CONFIG_PCCARD=m
-CONFIG_YENTA=m
 # CONFIG_PDC_CHASSIS is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_UNUSED_SYMBOLS=y
+# CONFIG_BLK_DEV_BSG is not set
 # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
 CONFIG_BINFMT_MISC=m
 CONFIG_NET=y
@@ -35,17 +32,15 @@ CONFIG_UNIX=y
 CONFIG_XFRM_USER=m
 CONFIG_NET_KEY=m
 CONFIG_INET=y
-CONFIG_IP_MULTICAST=y
-CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
 CONFIG_INET_DIAG=m
 CONFIG_LLC2=m
 # CONFIG_WIRELESS is not set
+CONFIG_EISA=y
+CONFIG_PCI=y
+CONFIG_PCCARD=m
+CONFIG_YENTA=m
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 # CONFIG_STANDALONE is not set
@@ -88,7 +83,6 @@ CONFIG_TUN=m
 # CONFIG_NET_VENDOR_ALTEON is not set
 # CONFIG_NET_VENDOR_AMD is not set
 # CONFIG_NET_VENDOR_ATHEROS is not set
-# CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_BROCADE is not set
 # CONFIG_NET_VENDOR_CHELSIO is not set
@@ -97,8 +91,6 @@ CONFIG_NET_TULIP=y
 CONFIG_TULIP=y
 # CONFIG_NET_VENDOR_DLINK is not set
 # CONFIG_NET_VENDOR_EMULEX is not set
-# CONFIG_NET_VENDOR_EXAR is not set
-# CONFIG_NET_VENDOR_HP is not set
 CONFIG_LASI_82596=y
 # CONFIG_NET_VENDOR_MELLANOX is not set
 # CONFIG_NET_VENDOR_MICREL is not set
@@ -106,10 +98,9 @@ CONFIG_LASI_82596=y
 # CONFIG_NET_VENDOR_NATSEMI is not set
 # CONFIG_NET_VENDOR_NVIDIA is not set
 # CONFIG_NET_VENDOR_OKI is not set
-# CONFIG_NET_PACKET_ENGINE is not set
 # CONFIG_NET_VENDOR_QLOGIC is not set
-# CONFIG_NET_VENDOR_REALTEK is not set
 # CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SILAN is not set
 # CONFIG_NET_VENDOR_SIS is not set
@@ -142,7 +133,6 @@ CONFIG_PPDEV=m
 # CONFIG_HW_RANDOM is not set
 CONFIG_I2C=y
 # CONFIG_HWMON is not set
-CONFIG_AGP=y
 CONFIG_FB=y
 CONFIG_FB_FOREIGN_ENDIAN=y
 CONFIG_FB_MODE_HELPERS=y
@@ -230,63 +220,11 @@ CONFIG_CIFS_WEAK_PW_HASH=y
 CONFIG_CIFS_XATTR=y
 CONFIG_CIFS_POSIX=y
 # CONFIG_CIFS_DEBUG is not set
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_CODEPAGE_737=m
-CONFIG_NLS_CODEPAGE_775=m
-CONFIG_NLS_CODEPAGE_850=m
-CONFIG_NLS_CODEPAGE_852=m
-CONFIG_NLS_CODEPAGE_855=m
-CONFIG_NLS_CODEPAGE_857=m
-CONFIG_NLS_CODEPAGE_860=m
-CONFIG_NLS_CODEPAGE_861=m
-CONFIG_NLS_CODEPAGE_862=m
-CONFIG_NLS_CODEPAGE_863=m
-CONFIG_NLS_CODEPAGE_864=m
-CONFIG_NLS_CODEPAGE_865=m
-CONFIG_NLS_CODEPAGE_866=m
-CONFIG_NLS_CODEPAGE_869=m
-CONFIG_NLS_CODEPAGE_936=m
-CONFIG_NLS_CODEPAGE_950=m
-CONFIG_NLS_CODEPAGE_932=m
-CONFIG_NLS_CODEPAGE_949=m
-CONFIG_NLS_CODEPAGE_874=m
-CONFIG_NLS_ISO8859_8=m
-CONFIG_NLS_CODEPAGE_1250=y
-CONFIG_NLS_CODEPAGE_1251=m
-CONFIG_NLS_ASCII=m
-CONFIG_NLS_ISO8859_1=y
-CONFIG_NLS_ISO8859_2=m
-CONFIG_NLS_ISO8859_3=m
-CONFIG_NLS_ISO8859_4=m
-CONFIG_NLS_ISO8859_5=m
-CONFIG_NLS_ISO8859_6=m
-CONFIG_NLS_ISO8859_7=m
-CONFIG_NLS_ISO8859_9=m
-CONFIG_NLS_ISO8859_13=m
-CONFIG_NLS_ISO8859_14=m
-CONFIG_NLS_ISO8859_15=m
-CONFIG_NLS_KOI8_R=m
-CONFIG_NLS_KOI8_U=m
-CONFIG_NLS_UTF8=y
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_MEMORY_INIT=y
-CONFIG_DEBUG_STACKOVERFLOW=y
-CONFIG_DEBUG_SHIRQ=y
-CONFIG_DETECT_HUNG_TASK=y
-CONFIG_DEBUG_RT_MUTEXES=y
-CONFIG_DEBUG_SPINLOCK=y
-CONFIG_DEBUG_MUTEXES=y
-CONFIG_LATENCYTOP=y
-CONFIG_LKDTM=m
-CONFIG_KEYS=y
 CONFIG_CRYPTO_TEST=m
 CONFIG_CRYPTO_HMAC=y
 CONFIG_CRYPTO_MD5=y
 CONFIG_CRYPTO_MICHAEL_MIC=m
 CONFIG_CRYPTO_SHA1=y
-CONFIG_CRYPTO_SHA512=m
 CONFIG_CRYPTO_TGR192=m
 CONFIG_CRYPTO_WP512=m
 CONFIG_CRYPTO_ANUBIS=m
@@ -302,3 +240,14 @@ CONFIG_CRYPTO_DEFLATE=y
 CONFIG_CRC_CCITT=m
 CONFIG_CRC_T10DIF=y
 CONFIG_FONTS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_DEBUG_SHIRQ=y
+CONFIG_DETECT_HUNG_TASK=y
+CONFIG_DEBUG_RT_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_LATENCYTOP=y
+CONFIG_LKDTM=m
index d39e7f8..59561e0 100644 (file)
@@ -17,27 +17,24 @@ CONFIG_RELAY=y
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_COMPAT_BRK is not set
-CONFIG_MODULES=y
-CONFIG_MODULE_FORCE_LOAD=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_MODVERSIONS=y
-CONFIG_BLK_DEV_INTEGRITY=y
-# CONFIG_IOSCHED_DEADLINE is not set
 CONFIG_PA8X00=y
 CONFIG_64BIT=y
 CONFIG_SMP=y
-# CONFIG_COMPACTION is not set
 CONFIG_HPPB=y
 CONFIG_IOMMU_CCIO=y
 CONFIG_GSC_LASI=y
 CONFIG_GSC_WAX=y
-CONFIG_PCI=y
-CONFIG_PCI_STUB=m
-CONFIG_PCI_IOV=y
 CONFIG_GSC_DINO=y
 CONFIG_PCI_LBA=y
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_UNUSED_SYMBOLS=y
+CONFIG_BLK_DEV_INTEGRITY=y
 CONFIG_BINFMT_MISC=m
+# CONFIG_COMPACTION is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -47,18 +44,17 @@ CONFIG_XFRM_MIGRATE=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 CONFIG_IP_PNP=y
-CONFIG_IP_PNP_BOOTP=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
-CONFIG_INET_XFRM_MODE_TRANSPORT=m
-CONFIG_INET_XFRM_MODE_TUNNEL=m
-CONFIG_INET_XFRM_MODE_BEET=m
 CONFIG_INET_DIAG=m
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_ADVANCED is not set
 CONFIG_NETFILTER_NETLINK_LOG=y
 CONFIG_DCB=y
 # CONFIG_WIRELESS is not set
+CONFIG_PCI=y
+CONFIG_PCI_STUB=m
+CONFIG_PCI_IOV=y
 CONFIG_DEVTMPFS=y
 CONFIG_DEVTMPFS_MOUNT=y
 CONFIG_BLK_DEV_LOOP=y
@@ -102,7 +98,6 @@ CONFIG_TUN=y
 # CONFIG_NET_VENDOR_ALTEON is not set
 # CONFIG_NET_VENDOR_AMD is not set
 # CONFIG_NET_VENDOR_ATHEROS is not set
-# CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_BROADCOM is not set
 # CONFIG_NET_VENDOR_BROCADE is not set
 # CONFIG_NET_VENDOR_CHELSIO is not set
@@ -111,10 +106,8 @@ CONFIG_NET_TULIP=y
 CONFIG_TULIP=y
 # CONFIG_NET_VENDOR_DLINK is not set
 # CONFIG_NET_VENDOR_EMULEX is not set
-# CONFIG_NET_VENDOR_EXAR is not set
-CONFIG_HP100=m
-CONFIG_E1000=y
 CONFIG_LASI_82596=y
+CONFIG_E1000=y
 # CONFIG_NET_VENDOR_MARVELL is not set
 # CONFIG_NET_VENDOR_MELLANOX is not set
 # CONFIG_NET_VENDOR_MICREL is not set
@@ -124,9 +117,8 @@ CONFIG_LASI_82596=y
 # CONFIG_NET_VENDOR_OKI is not set
 CONFIG_QLA3XXX=m
 CONFIG_QLCNIC=m
-CONFIG_QLGE=m
-# CONFIG_NET_VENDOR_REALTEK is not set
 # CONFIG_NET_VENDOR_RDC is not set
+# CONFIG_NET_VENDOR_REALTEK is not set
 # CONFIG_NET_VENDOR_SEEQ is not set
 # CONFIG_NET_VENDOR_SILAN is not set
 # CONFIG_NET_VENDOR_SIS is not set
@@ -153,9 +145,6 @@ CONFIG_SMSC_PHY=m
 CONFIG_STE10XP=m
 CONFIG_VITESSE_PHY=m
 CONFIG_SLIP=m
-CONFIG_SLIP_COMPRESSED=y
-CONFIG_SLIP_SMART=y
-CONFIG_SLIP_MODE_SLIP6=y
 # CONFIG_WLAN is not set
 CONFIG_INPUT_EVDEV=y
 # CONFIG_KEYBOARD_HIL_OLD is not set
@@ -208,34 +197,18 @@ CONFIG_FIRMWARE_EDID=y
 CONFIG_FB_MODE_HELPERS=y
 # CONFIG_BACKLIGHT_GENERIC is not set
 CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
-CONFIG_LOGO=y
-# CONFIG_LOGO_LINUX_MONO is not set
 CONFIG_HIDRAW=y
 CONFIG_HID_PID=y
 CONFIG_USB_HIDDEV=y
 CONFIG_USB=y
-CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
-CONFIG_USB_DYNAMIC_MINORS=y
-CONFIG_USB_MON=m
-CONFIG_USB_WUSB_CBAF=m
-CONFIG_USB_XHCI_HCD=m
-CONFIG_USB_EHCI_HCD=y
-CONFIG_USB_OHCI_HCD=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_TRIGGERS=y
-CONFIG_LEDS_TRIGGER_TIMER=y
-CONFIG_LEDS_TRIGGER_ONESHOT=y
-CONFIG_LEDS_TRIGGER_DISK=y
-CONFIG_LEDS_TRIGGER_HEARTBEAT=m
-CONFIG_LEDS_TRIGGER_BACKLIGHT=m
-CONFIG_LEDS_TRIGGER_DEFAULT_ON=m
 CONFIG_UIO=y
 CONFIG_UIO_PDRV_GENIRQ=m
 CONFIG_UIO_AEC=m
 CONFIG_UIO_SERCOS3=m
 CONFIG_UIO_PCI_GENERIC=m
 CONFIG_STAGING=y
+CONFIG_QLGE=m
+CONFIG_HP100=m
 CONFIG_EXT2_FS=y
 CONFIG_EXT2_FS_XATTR=y
 CONFIG_EXT2_FS_SECURITY=y
@@ -272,14 +245,6 @@ CONFIG_NLS_ASCII=m
 CONFIG_NLS_ISO8859_1=m
 CONFIG_NLS_ISO8859_2=m
 CONFIG_NLS_UTF8=m
-CONFIG_PRINTK_TIME=y
-CONFIG_STRIP_ASM_SYMS=y
-CONFIG_UNUSED_SYMBOLS=y
-CONFIG_DEBUG_FS=y
-CONFIG_MAGIC_SYSRQ=y
-CONFIG_DEBUG_KERNEL=y
-CONFIG_DEBUG_STACKOVERFLOW=y
-# CONFIG_SCHED_DEBUG is not set
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_ECB=m
 CONFIG_CRYPTO_PCBC=m
@@ -292,3 +257,10 @@ CONFIG_CRYPTO_DEFLATE=m
 # CONFIG_CRYPTO_HW is not set
 CONFIG_CRC_CCITT=m
 CONFIG_LIBCRC32C=y
+CONFIG_PRINTK_TIME=y
+CONFIG_STRIP_ASM_SYMS=y
+CONFIG_MAGIC_SYSRQ=y
+CONFIG_DEBUG_FS=y
+CONFIG_DEBUG_KERNEL=y
+CONFIG_DEBUG_STACKOVERFLOW=y
+# CONFIG_SCHED_DEBUG is not set
index 354cf06..5224fb3 100644 (file)
@@ -351,7 +351,6 @@ static void __init map_pages(unsigned long start_vaddr,
                             unsigned long start_paddr, unsigned long size,
                             pgprot_t pgprot, int force)
 {
-       pgd_t *pg_dir;
        pmd_t *pmd;
        pte_t *pg_table;
        unsigned long end_paddr;
@@ -372,62 +371,37 @@ static void __init map_pages(unsigned long start_vaddr,
 
        end_paddr = start_paddr + size;
 
-       pg_dir = pgd_offset_k(start_vaddr);
-
-#if PTRS_PER_PMD == 1
-       start_pmd = 0;
-#else
+       /* for 2-level configuration PTRS_PER_PMD is 0 so start_pmd will be 0 */
        start_pmd = ((start_vaddr >> PMD_SHIFT) & (PTRS_PER_PMD - 1));
-#endif
        start_pte = ((start_vaddr >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
 
        address = start_paddr;
        vaddr = start_vaddr;
        while (address < end_paddr) {
-#if PTRS_PER_PMD == 1
-               pmd = (pmd_t *)__pa(pg_dir);
-#else
-               pmd = (pmd_t *)pgd_address(*pg_dir);
-
-               /*
-                * pmd is physical at this point
-                */
+               pgd_t *pgd = pgd_offset_k(vaddr);
+               p4d_t *p4d = p4d_offset(pgd, vaddr);
+               pud_t *pud = pud_offset(p4d, vaddr);
 
-               if (!pmd) {
+#if CONFIG_PGTABLE_LEVELS == 3
+               if (pud_none(*pud)) {
                        pmd = memblock_alloc(PAGE_SIZE << PMD_ORDER,
                                             PAGE_SIZE << PMD_ORDER);
                        if (!pmd)
                                panic("pmd allocation failed.\n");
-                       pmd = (pmd_t *) __pa(pmd);
+                       pud_populate(NULL, pud, pmd);
                }
-
-               pud_populate(NULL, (pud_t *)pg_dir, __va(pmd));
 #endif
-               pg_dir++;
-
-               /* now change pmd to kernel virtual addresses */
 
-               pmd = (pmd_t *)__va(pmd) + start_pmd;
+               pmd = pmd_offset(pud, vaddr);
                for (tmp1 = start_pmd; tmp1 < PTRS_PER_PMD; tmp1++, pmd++) {
-
-                       /*
-                        * pg_table is physical at this point
-                        */
-
-                       pg_table = (pte_t *)pmd_address(*pmd);
-                       if (!pg_table) {
-                               pg_table = memblock_alloc(PAGE_SIZE,
-                                                         PAGE_SIZE);
+                       if (pmd_none(*pmd)) {
+                               pg_table = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
                                if (!pg_table)
                                        panic("page table allocation failed\n");
-                               pg_table = (pte_t *) __pa(pg_table);
+                               pmd_populate_kernel(NULL, pmd, pg_table);
                        }
 
-                       pmd_populate_kernel(NULL, pmd, __va(pg_table));
-
-                       /* now change pg_table to kernel virtual addresses */
-
-                       pg_table = (pte_t *) __va(pg_table) + start_pte;
+                       pg_table = pte_offset_kernel(pmd, vaddr);
                        for (tmp2 = start_pte; tmp2 < PTRS_PER_PTE; tmp2++, pg_table++) {
                                pte_t pte;
                                pgprot_t prot;
index c150a9d..497b7d0 100644 (file)
@@ -1,10 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 source "arch/powerpc/platforms/Kconfig.cputype"
 
-config PPC32
-       bool
-       default y if !PPC64
-
 config 32BIT
        bool
        default y if PPC32
@@ -133,7 +129,7 @@ config PPC
        select ARCH_HAS_PTE_SPECIAL
        select ARCH_HAS_MEMBARRIER_CALLBACKS
        select ARCH_HAS_SCALED_CPUTIME          if VIRT_CPU_ACCOUNTING_NATIVE && PPC_BOOK3S_64
-       select ARCH_HAS_STRICT_KERNEL_RWX       if ((PPC_BOOK3S_64 || PPC32) && !RELOCATABLE && !HIBERNATION)
+       select ARCH_HAS_STRICT_KERNEL_RWX       if ((PPC_BOOK3S_64 || PPC32) && !HIBERNATION)
        select ARCH_HAS_TICK_BROADCAST          if GENERIC_CLOCKEVENTS_BROADCAST
        select ARCH_HAS_UACCESS_FLUSHCACHE
        select ARCH_HAS_UACCESS_MCSAFE          if PPC64
@@ -173,6 +169,7 @@ config PPC
        select HAVE_ARCH_HUGE_VMAP              if PPC_BOOK3S_64 && PPC_RADIX_MMU
        select HAVE_ARCH_JUMP_LABEL
        select HAVE_ARCH_KASAN                  if PPC32
+       select HAVE_ARCH_KASAN_VMALLOC          if PPC32
        select HAVE_ARCH_KGDB
        select HAVE_ARCH_MMAP_RND_BITS
        select HAVE_ARCH_MMAP_RND_COMPAT_BITS   if COMPAT
@@ -222,9 +219,8 @@ config PPC
        select HAVE_HARDLOCKUP_DETECTOR_PERF    if PERF_EVENTS && HAVE_PERF_EVENTS_NMI && !HAVE_HARDLOCKUP_DETECTOR_ARCH
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
-       select HAVE_RCU_TABLE_FREE              if SMP
-       select HAVE_RCU_TABLE_NO_INVALIDATE     if HAVE_RCU_TABLE_FREE
-       select HAVE_MMU_GATHER_PAGE_SIZE
+       select MMU_GATHER_RCU_TABLE_FREE
+       select MMU_GATHER_PAGE_SIZE
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RELIABLE_STACKTRACE         if PPC_BOOK3S_64 && CPU_LITTLE_ENDIAN
        select HAVE_SYSCALL_TRACEPOINTS
@@ -483,7 +479,7 @@ config MPROFILE_KERNEL
 config HOTPLUG_CPU
        bool "Support for enabling/disabling CPUs"
        depends on SMP && (PPC_PSERIES || \
-       PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE)
+               PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE)
        help
          Say Y here to be able to disable and re-enable individual
          CPUs at runtime on SMP machines.
index 4e1d398..0b06383 100644 (file)
@@ -371,7 +371,7 @@ config PPC_PTDUMP
 
 config PPC_DEBUG_WX
        bool "Warn on W+X mappings at boot"
-       depends on PPC_PTDUMP
+       depends on PPC_PTDUMP && STRICT_KERNEL_RWX
        help
          Generate a warning if any W+X mappings are found at boot.
 
index 134f12f..2268396 100644 (file)
@@ -17,11 +17,11 @@ quiet_cmd_head_check = CHKHEAD $@
 quiet_cmd_relocs_check = CHKREL  $@
 ifdef CONFIG_PPC_BOOK3S_64
       cmd_relocs_check =                                               \
-       $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" ; \
+       $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" ; \
        $(BASH) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@"
 else
       cmd_relocs_check =                                               \
-       $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@"
+       $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@"
 endif
 
 # `@true` prevents complaint when there is nothing to be done
index 1699e95..00c4d84 100644 (file)
@@ -228,7 +228,7 @@ void ibm4xx_denali_fixup_memsize(void)
                dpath = 8; /* 64 bits */
 
        /* get address pins (rows) */
-       val = SDRAM0_READ(DDR0_42);
+       val = SDRAM0_READ(DDR0_42);
 
        row = DDR_GET_VAL(val, DDR_APIN, DDR_APIN_SHIFT);
        if (row > max_row)
index a2dd5f1..7de0689 100644 (file)
                                reg = <0x11a80 0x40 0x89fc 0x2>;
                                interrupts = <2 8>;
                                interrupt-parent = <&PIC>;
-                               gpios = < &cpm2_pio_d 19 0>;
+                               cs-gpios = < &cpm2_pio_d 19 0>;
                                #address-cells = <1>;
                                #size-cells = <0>;
                                ds3106@1 {
index b625718..ecebc27 100644 (file)
                        reg = <0x4c0 0x40>;
                        interrupts = <2>;
                        interrupt-parent = <&qeic>;
-                       gpios = <&qe_pio_d 13 0>;
+                       cs-gpios = <&qe_pio_d 13 0>;
                        mode = "cpu-qe";
 
                        mmc-slot@0 {
index 1a8321a..33bbe58 100644 (file)
                        interrupts = <59 2>;
                        interrupt-parent = <&mpic>;
                        mode = "cpu";
-                       gpios = <&sdcsr_pio 7 0>;
+                       cs-gpios = <&sdcsr_pio 7 0>;
                        sleep = <&pmc 0x00000800 0>;
 
                        mmc-slot@0 {
index f0c8a07..7705a5c 100644 (file)
@@ -59,7 +59,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_NET_VENDOR_DLINK is not set
 # CONFIG_NET_VENDOR_EMULEX is not set
 # CONFIG_NET_VENDOR_EXAR is not set
-# CONFIG_NET_VENDOR_HP is not set
 CONFIG_IBM_EMAC=y
 # CONFIG_NET_VENDOR_MARVELL is not set
 # CONFIG_NET_VENDOR_MELLANOX is not set
index ed02f12..22dc0da 100644 (file)
@@ -10,8 +10,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 CONFIG_AMIGA_PARTITION=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_EBONY is not set
 CONFIG_SAM440EP=y
 CONFIG_CMDLINE_BOOL=y
index fdb11da..789622f 100644 (file)
@@ -14,8 +14,6 @@ CONFIG_SLAB=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PPC_CHRP is not set
 CONFIG_PPC_MPC52xx=y
 CONFIG_PPC_MPC5200_SIMPLE=y
index 648c6b3..24bf1bd 100644 (file)
@@ -11,8 +11,6 @@ CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
 # CONFIG_MSDOS_PARTITION is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_83xx=y
index 510f7fd..f55e23c 100644 (file)
@@ -9,7 +9,6 @@ CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_PPC_ADDER875=y
 CONFIG_8xx_COPYBACK=y
 CONFIG_GEN_RTC=y
index 6e08d95..00d6996 100644 (file)
@@ -6,7 +6,6 @@ CONFIG_EXPERT=y
 CONFIG_KALLSYMS_ALL=y
 CONFIG_SLAB=y
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PPC_CHRP is not set
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_82xx=y
index 9c1bf60..0e2e5e8 100644 (file)
@@ -11,7 +11,6 @@ CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_PPC_EP88XC=y
 CONFIG_8xx_COPYBACK=y
 CONFIG_GEN_RTC=y
index 8b8cd18..209f585 100644 (file)
@@ -1,5 +1,4 @@
 CONFIG_VIRTIO_BLK=y
-CONFIG_VIRTIO_BLK_SCSI=y
 CONFIG_SCSI_VIRTIO=y
 CONFIG_VIRTIO_NET=y
 CONFIG_NET_FAILOVER=y
index 6ce4f20..dcc8dcc 100644 (file)
@@ -12,7 +12,6 @@ CONFIG_KALLSYMS_ALL=y
 CONFIG_EMBEDDED=y
 CONFIG_SLAB=y
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PPC_PMAC is not set
 CONFIG_PPC_82xx=y
 CONFIG_MGCOGE=y
index 1f3a045..e39346b 100644 (file)
@@ -9,7 +9,6 @@ CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PPC_CHRP is not set
 CONFIG_PPC_MPC512x=y
 CONFIG_MPC512x_LPBFIFO=y
index 0327a32..82a008c 100644 (file)
@@ -11,7 +11,6 @@ CONFIG_EXPERT=y
 # CONFIG_VM_EVENT_COUNTERS is not set
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_8xx_COPYBACK=y
 CONFIG_GEN_RTC=y
 CONFIG_HZ_100=y
index 3284145..7174937 100644 (file)
@@ -181,7 +181,6 @@ CONFIG_MLX5_FPGA=y
 CONFIG_MLX5_CORE_EN=y
 CONFIG_MLX5_CORE_IPOIB=y
 CONFIG_MYRI10GE=m
-CONFIG_QLGE=m
 CONFIG_NETXEN_NIC=m
 CONFIG_USB_NET_DRIVERS=m
 # CONFIG_WLAN is not set
index b250e6f..7e68cb2 100644 (file)
@@ -189,7 +189,6 @@ CONFIG_MLX4_EN=m
 CONFIG_MYRI10GE=m
 CONFIG_S2IO=m
 CONFIG_PASEMI_MAC=y
-CONFIG_QLGE=m
 CONFIG_NETXEN_NIC=m
 CONFIG_SUNGEM=y
 CONFIG_GELIC_NET=m
index 7e28919..3e2f44f 100644 (file)
@@ -507,7 +507,6 @@ CONFIG_FORCEDETH=m
 CONFIG_HAMACHI=m
 CONFIG_YELLOWFIN=m
 CONFIG_QLA3XXX=m
-CONFIG_QLGE=m
 CONFIG_NETXEN_NIC=m
 CONFIG_8139CP=m
 CONFIG_8139TOO=m
index 26126b4..6b68109 100644 (file)
@@ -169,7 +169,6 @@ CONFIG_IXGBE=m
 CONFIG_I40E=m
 CONFIG_MLX4_EN=m
 CONFIG_MYRI10GE=m
-CONFIG_QLGE=m
 CONFIG_NETXEN_NIC=m
 CONFIG_PPP=m
 CONFIG_PPP_BSDCOMP=m
index 069f67f..1b6bdad 100644 (file)
@@ -1,8 +1,3 @@
-CONFIG_PPC64=y
-CONFIG_ALTIVEC=y
-CONFIG_VSX=y
-CONFIG_NR_CPUS=2048
-CONFIG_CPU_LITTLE_ENDIAN=y
 CONFIG_KERNEL_XZ=y
 # CONFIG_SWAP is not set
 CONFIG_SYSVIPC=y
@@ -28,17 +23,15 @@ CONFIG_EXPERT=y
 # CONFIG_AIO is not set
 CONFIG_PERF_EVENTS=y
 # CONFIG_COMPAT_BRK is not set
+# CONFIG_SLAB_MERGE_DEFAULT is not set
+CONFIG_SLAB_FREELIST_RANDOM=y
 CONFIG_SLAB_FREELIST_HARDENED=y
-CONFIG_JUMP_LABEL=y
-CONFIG_STRICT_KERNEL_RWX=y
-CONFIG_MODULES=y
-CONFIG_MODULE_UNLOAD=y
-CONFIG_MODULE_SIG=y
-CONFIG_MODULE_SIG_FORCE=y
-CONFIG_MODULE_SIG_SHA512=y
-CONFIG_PARTITION_ADVANCED=y
-# CONFIG_MQ_IOSCHED_DEADLINE is not set
-# CONFIG_MQ_IOSCHED_KYBER is not set
+CONFIG_PPC64=y
+CONFIG_ALTIVEC=y
+CONFIG_VSX=y
+CONFIG_NR_CPUS=2048
+CONFIG_CPU_LITTLE_ENDIAN=y
+CONFIG_PANIC_TIMEOUT=30
 # CONFIG_PPC_VAS is not set
 # CONFIG_PPC_PSERIES is not set
 # CONFIG_PPC_OF_BOOT_TRAMPOLINE is not set
@@ -46,17 +39,27 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
 CONFIG_CPU_IDLE=y
 CONFIG_HZ_100=y
 CONFIG_KEXEC=y
+CONFIG_KEXEC_FILE=y
 CONFIG_PRESERVE_FA_DUMP=y
 CONFIG_IRQ_ALL_CPUS=y
 CONFIG_NUMA=y
-# CONFIG_COMPACTION is not set
-# CONFIG_MIGRATION is not set
 CONFIG_PPC_64K_PAGES=y
 CONFIG_SCHED_SMT=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=tty0 console=hvc0 ipr.fast_reboot=1 quiet"
 # CONFIG_SECCOMP is not set
 # CONFIG_PPC_MEM_KEYS is not set
+CONFIG_JUMP_LABEL=y
+CONFIG_STRICT_KERNEL_RWX=y
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_SIG_FORCE=y
+CONFIG_MODULE_SIG_SHA512=y
+CONFIG_PARTITION_ADVANCED=y
+# CONFIG_MQ_IOSCHED_DEADLINE is not set
+# CONFIG_MQ_IOSCHED_KYBER is not set
+# CONFIG_COMPACTION is not set
+# CONFIG_MIGRATION is not set
 CONFIG_NET=y
 CONFIG_PACKET=y
 CONFIG_UNIX=y
@@ -138,7 +141,6 @@ CONFIG_TIGON3=m
 CONFIG_BNX2X=m
 # CONFIG_NET_VENDOR_BROCADE is not set
 # CONFIG_NET_VENDOR_CADENCE is not set
-# CONFIG_NET_CADENCE is not set
 # CONFIG_NET_VENDOR_CAVIUM is not set
 CONFIG_CHELSIO_T1=m
 # CONFIG_NET_VENDOR_CISCO is not set
@@ -147,7 +149,6 @@ CONFIG_CHELSIO_T1=m
 # CONFIG_NET_VENDOR_DLINK is not set
 CONFIG_BE2NET=m
 # CONFIG_NET_VENDOR_EZCHIP is not set
-# CONFIG_NET_VENDOR_HP is not set
 # CONFIG_NET_VENDOR_HUAWEI is not set
 CONFIG_E1000=m
 CONFIG_E1000E=m
@@ -155,7 +156,6 @@ CONFIG_IGB=m
 CONFIG_IXGB=m
 CONFIG_IXGBE=m
 CONFIG_I40E=m
-CONFIG_S2IO=m
 # CONFIG_NET_VENDOR_MARVELL is not set
 CONFIG_MLX4_EN=m
 # CONFIG_MLX4_CORE_GEN2 is not set
@@ -166,12 +166,12 @@ CONFIG_MLX5_CORE_EN=y
 # CONFIG_NET_VENDOR_MICROSEMI is not set
 CONFIG_MYRI10GE=m
 # CONFIG_NET_VENDOR_NATSEMI is not set
+CONFIG_S2IO=m
 # CONFIG_NET_VENDOR_NETRONOME is not set
 # CONFIG_NET_VENDOR_NI is not set
 # CONFIG_NET_VENDOR_NVIDIA is not set
 # CONFIG_NET_VENDOR_OKI is not set
 # CONFIG_NET_VENDOR_PACKET_ENGINES is not set
-CONFIG_QLGE=m
 CONFIG_NETXEN_NIC=m
 CONFIG_QED=m
 CONFIG_QEDE=m
@@ -238,7 +238,6 @@ CONFIG_HID_CYPRESS=y
 CONFIG_HID_EZKEY=y
 CONFIG_HID_ITE=y
 CONFIG_HID_KENSINGTON=y
-CONFIG_HID_LOGITECH=y
 CONFIG_HID_MICROSOFT=y
 CONFIG_HID_MONTEREY=y
 CONFIG_USB_HIDDEV=y
@@ -275,6 +274,18 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ASCII=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_UTF8=y
+CONFIG_ENCRYPTED_KEYS=y
+CONFIG_SECURITY=y
+CONFIG_HARDENED_USERCOPY=y
+# CONFIG_HARDENED_USERCOPY_FALLBACK is not set
+CONFIG_HARDENED_USERCOPY_PAGESPAN=y
+CONFIG_FORTIFY_SOURCE=y
+CONFIG_SECURITY_LOCKDOWN_LSM=y
+CONFIG_SECURITY_LOCKDOWN_LSM_EARLY=y
+CONFIG_LOCK_DOWN_KERNEL_FORCE_INTEGRITY=y
+# CONFIG_INTEGRITY is not set
+CONFIG_LSM="yama,loadpin,safesetid,integrity"
+# CONFIG_CRYPTO_HW is not set
 CONFIG_CRC16=y
 CONFIG_CRC_ITU_T=y
 CONFIG_LIBCRC32C=y
@@ -285,17 +296,20 @@ CONFIG_LIBCRC32C=y
 # CONFIG_XZ_DEC_SPARC is not set
 CONFIG_PRINTK_TIME=y
 CONFIG_MAGIC_SYSRQ=y
+CONFIG_SLUB_DEBUG_ON=y
+CONFIG_SCHED_STACK_END_CHECK=y
 CONFIG_DEBUG_STACKOVERFLOW=y
+CONFIG_PANIC_ON_OOPS=y
 CONFIG_SOFTLOCKUP_DETECTOR=y
 CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC=y
 CONFIG_HARDLOCKUP_DETECTOR=y
 CONFIG_BOOTPARAM_HARDLOCKUP_PANIC=y
 CONFIG_WQ_WATCHDOG=y
 # CONFIG_SCHED_DEBUG is not set
+CONFIG_DEBUG_SG=y
+CONFIG_DEBUG_NOTIFIERS=y
+CONFIG_BUG_ON_DATA_CORRUPTION=y
+CONFIG_DEBUG_CREDENTIALS=y
 # CONFIG_FTRACE is not set
-# CONFIG_RUNTIME_TESTING_MENU is not set
 CONFIG_XMON=y
-CONFIG_XMON_DEFAULT=y
-CONFIG_ENCRYPTED_KEYS=y
-# CONFIG_CRYPTO_ECHAINIV is not set
-# CONFIG_CRYPTO_HW is not set
+# CONFIG_RUNTIME_TESTING_MENU is not set
index 29b19ec..b964084 100644 (file)
@@ -77,5 +77,4 @@ CONFIG_NLS_CODEPAGE_437=y
 CONFIG_NLS_ISO8859_1=y
 CONFIG_NLS_UTF8=y
 CONFIG_CRC_T10DIF=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
 # CONFIG_ENABLE_MUST_CHECK is not set
index ffed2b4..eda8bfb 100644 (file)
@@ -14,7 +14,6 @@ CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 # CONFIG_BLK_DEV_BSG is not set
 CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_TQM8XX=y
 CONFIG_8xx_COPYBACK=y
 # CONFIG_8xx_CPU15 is not set
index f9dc597..3c0ba22 100644 (file)
@@ -102,41 +102,91 @@ static inline void kuap_update_sr(u32 sr, u32 addr, u32 end)
        isync();        /* Context sync required after mtsrin() */
 }
 
-static inline void allow_user_access(void __user *to, const void __user *from, u32 size)
+static __always_inline void allow_user_access(void __user *to, const void __user *from,
+                                             u32 size, unsigned long dir)
 {
        u32 addr, end;
 
-       if (__builtin_constant_p(to) && to == NULL)
+       BUILD_BUG_ON(!__builtin_constant_p(dir));
+       BUILD_BUG_ON(dir == KUAP_CURRENT);
+
+       if (!(dir & KUAP_WRITE))
                return;
 
        addr = (__force u32)to;
 
-       if (!addr || addr >= TASK_SIZE || !size)
+       if (unlikely(addr >= TASK_SIZE || !size))
                return;
 
        end = min(addr + size, TASK_SIZE);
+
        current->thread.kuap = (addr & 0xf0000000) | ((((end - 1) >> 28) + 1) & 0xf);
        kuap_update_sr(mfsrin(addr) & ~SR_KS, addr, end);       /* Clear Ks */
 }
 
-static inline void prevent_user_access(void __user *to, const void __user *from, u32 size)
+static __always_inline void prevent_user_access(void __user *to, const void __user *from,
+                                               u32 size, unsigned long dir)
 {
-       u32 addr = (__force u32)to;
-       u32 end = min(addr + size, TASK_SIZE);
+       u32 addr, end;
+
+       BUILD_BUG_ON(!__builtin_constant_p(dir));
+
+       if (dir == KUAP_CURRENT) {
+               u32 kuap = current->thread.kuap;
 
-       if (!addr || addr >= TASK_SIZE || !size)
+               if (unlikely(!kuap))
+                       return;
+
+               addr = kuap & 0xf0000000;
+               end = kuap << 28;
+       } else if (dir & KUAP_WRITE) {
+               addr = (__force u32)to;
+               end = min(addr + size, TASK_SIZE);
+
+               if (unlikely(addr >= TASK_SIZE || !size))
+                       return;
+       } else {
                return;
+       }
 
        current->thread.kuap = 0;
        kuap_update_sr(mfsrin(addr) | SR_KS, addr, end);        /* set Ks */
 }
 
-static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write)
+static inline unsigned long prevent_user_access_return(void)
+{
+       unsigned long flags = current->thread.kuap;
+       unsigned long addr = flags & 0xf0000000;
+       unsigned long end = flags << 28;
+       void __user *to = (__force void __user *)addr;
+
+       if (flags)
+               prevent_user_access(to, to, end - addr, KUAP_READ_WRITE);
+
+       return flags;
+}
+
+static inline void restore_user_access(unsigned long flags)
 {
+       unsigned long addr = flags & 0xf0000000;
+       unsigned long end = flags << 28;
+       void __user *to = (__force void __user *)addr;
+
+       if (flags)
+               allow_user_access(to, to, end - addr, KUAP_READ_WRITE);
+}
+
+static inline bool
+bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
+{
+       unsigned long begin = regs->kuap & 0xf0000000;
+       unsigned long end = regs->kuap << 28;
+
        if (!is_write)
                return false;
 
-       return WARN(!regs->kuap, "Bug: write fault blocked by segment registers !");
+       return WARN(address < begin || address >= end,
+                   "Bug: write fault blocked by segment registers !");
 }
 
 #endif /* CONFIG_PPC_KUAP */
index 9983177..dc5c039 100644 (file)
@@ -49,7 +49,6 @@ static inline void pgtable_free(void *table, unsigned index_size)
 
 #define get_hugepd_cache_index(x)  (x)
 
-#ifdef CONFIG_SMP
 static inline void pgtable_free_tlb(struct mmu_gather *tlb,
                                    void *table, int shift)
 {
@@ -66,13 +65,6 @@ static inline void __tlb_remove_table(void *_table)
 
        pgtable_free(table, shift);
 }
-#else
-static inline void pgtable_free_tlb(struct mmu_gather *tlb,
-                                   void *table, int shift)
-{
-       pgtable_free(table, shift);
-}
-#endif
 
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
                                  unsigned long address)
index 0796533..5b39c11 100644 (file)
@@ -193,7 +193,12 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
 #else
 #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
 #endif
+
+#ifdef CONFIG_KASAN_VMALLOC
+#define VMALLOC_END    _ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
+#else
 #define VMALLOC_END    ioremap_bot
+#endif
 
 #ifndef __ASSEMBLY__
 #include <linux/sched.h>
index f254de9..90dd3a3 100644 (file)
  * because that would require an expensive read/modify write of the AMR.
  */
 
+static inline unsigned long get_kuap(void)
+{
+       if (!early_mmu_has_feature(MMU_FTR_RADIX_KUAP))
+               return 0;
+
+       return mfspr(SPRN_AMR);
+}
+
 static inline void set_kuap(unsigned long value)
 {
        if (!early_mmu_has_feature(MMU_FTR_RADIX_KUAP))
@@ -77,25 +85,43 @@ static inline void set_kuap(unsigned long value)
        isync();
 }
 
-static inline void allow_user_access(void __user *to, const void __user *from,
-                                    unsigned long size)
+static __always_inline void allow_user_access(void __user *to, const void __user *from,
+                                             unsigned long size, unsigned long dir)
 {
        // This is written so we can resolve to a single case at build time
-       if (__builtin_constant_p(to) && to == NULL)
+       BUILD_BUG_ON(!__builtin_constant_p(dir));
+       if (dir == KUAP_READ)
                set_kuap(AMR_KUAP_BLOCK_WRITE);
-       else if (__builtin_constant_p(from) && from == NULL)
+       else if (dir == KUAP_WRITE)
                set_kuap(AMR_KUAP_BLOCK_READ);
-       else
+       else if (dir == KUAP_READ_WRITE)
                set_kuap(0);
+       else
+               BUILD_BUG();
 }
 
 static inline void prevent_user_access(void __user *to, const void __user *from,
-                                      unsigned long size)
+                                      unsigned long size, unsigned long dir)
+{
+       set_kuap(AMR_KUAP_BLOCKED);
+}
+
+static inline unsigned long prevent_user_access_return(void)
 {
+       unsigned long flags = get_kuap();
+
        set_kuap(AMR_KUAP_BLOCKED);
+
+       return flags;
+}
+
+static inline void restore_user_access(unsigned long flags)
+{
+       set_kuap(flags);
 }
 
-static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write)
+static inline bool
+bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
 {
        return WARN(mmu_has_feature(MMU_FTR_RADIX_KUAP) &&
                    (regs->kuap & (is_write ? AMR_KUAP_BLOCK_WRITE : AMR_KUAP_BLOCK_READ)),
index f6968c8..a41e91b 100644 (file)
@@ -19,9 +19,7 @@ extern struct vmemmap_backing *vmemmap_list;
 extern pmd_t *pmd_fragment_alloc(struct mm_struct *, unsigned long);
 extern void pmd_fragment_free(unsigned long *);
 extern void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift);
-#ifdef CONFIG_SMP
 extern void __tlb_remove_table(void *_table);
-#endif
 void pte_frag_destroy(void *pte_frag);
 
 static inline pgd_t *radix__pgd_alloc(struct mm_struct *mm)
index b01624e..201a69e 100644 (file)
@@ -1355,18 +1355,21 @@ static inline bool is_pte_rw_upgrade(unsigned long old_val, unsigned long new_va
  * Like pmd_huge() and pmd_large(), but works regardless of config options
  */
 #define pmd_is_leaf pmd_is_leaf
+#define pmd_leaf pmd_is_leaf
 static inline bool pmd_is_leaf(pmd_t pmd)
 {
        return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE));
 }
 
 #define pud_is_leaf pud_is_leaf
+#define pud_leaf pud_is_leaf
 static inline bool pud_is_leaf(pud_t pud)
 {
        return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE));
 }
 
 #define pgd_is_leaf pgd_is_leaf
+#define pgd_leaf pgd_is_leaf
 static inline bool pgd_is_leaf(pgd_t pgd)
 {
        return !!(pgd_raw(pgd) & cpu_to_be64(_PAGE_PTE));
index 4c24ea8..ce483b0 100644 (file)
@@ -1,171 +1 @@
-/* SPDX-License-Identifier: GPL-2.0 */
-#ifndef __CPM_H
-#define __CPM_H
-
-#include <linux/compiler.h>
-#include <linux/types.h>
-#include <linux/errno.h>
-#include <linux/of.h>
-#include <soc/fsl/qe/qe.h>
-
-/*
- * SPI Parameter RAM common to QE and CPM.
- */
-struct spi_pram {
-       __be16  rbase;  /* Rx Buffer descriptor base address */
-       __be16  tbase;  /* Tx Buffer descriptor base address */
-       u8      rfcr;   /* Rx function code */
-       u8      tfcr;   /* Tx function code */
-       __be16  mrblr;  /* Max receive buffer length */
-       __be32  rstate; /* Internal */
-       __be32  rdp;    /* Internal */
-       __be16  rbptr;  /* Internal */
-       __be16  rbc;    /* Internal */
-       __be32  rxtmp;  /* Internal */
-       __be32  tstate; /* Internal */
-       __be32  tdp;    /* Internal */
-       __be16  tbptr;  /* Internal */
-       __be16  tbc;    /* Internal */
-       __be32  txtmp;  /* Internal */
-       __be32  res;    /* Tx temp. */
-       __be16  rpbase; /* Relocation pointer (CPM1 only) */
-       __be16  res1;   /* Reserved */
-};
-
-/*
- * USB Controller pram common to QE and CPM.
- */
-struct usb_ctlr {
-       u8      usb_usmod;
-       u8      usb_usadr;
-       u8      usb_uscom;
-       u8      res1[1];
-       __be16  usb_usep[4];
-       u8      res2[4];
-       __be16  usb_usber;
-       u8      res3[2];
-       __be16  usb_usbmr;
-       u8      res4[1];
-       u8      usb_usbs;
-       /* Fields down below are QE-only */
-       __be16  usb_ussft;
-       u8      res5[2];
-       __be16  usb_usfrn;
-       u8      res6[0x22];
-} __attribute__ ((packed));
-
-/*
- * Function code bits, usually generic to devices.
- */
-#ifdef CONFIG_CPM1
-#define CPMFCR_GBL     ((u_char)0x00)  /* Flag doesn't exist in CPM1 */
-#define CPMFCR_TC2     ((u_char)0x00)  /* Flag doesn't exist in CPM1 */
-#define CPMFCR_DTB     ((u_char)0x00)  /* Flag doesn't exist in CPM1 */
-#define CPMFCR_BDB     ((u_char)0x00)  /* Flag doesn't exist in CPM1 */
-#else
-#define CPMFCR_GBL     ((u_char)0x20)  /* Set memory snooping */
-#define CPMFCR_TC2     ((u_char)0x04)  /* Transfer code 2 value */
-#define CPMFCR_DTB     ((u_char)0x02)  /* Use local bus for data when set */
-#define CPMFCR_BDB     ((u_char)0x01)  /* Use local bus for BD when set */
-#endif
-#define CPMFCR_EB      ((u_char)0x10)  /* Set big endian byte order */
-
-/* Opcodes common to CPM1 and CPM2
-*/
-#define CPM_CR_INIT_TRX                ((ushort)0x0000)
-#define CPM_CR_INIT_RX         ((ushort)0x0001)
-#define CPM_CR_INIT_TX         ((ushort)0x0002)
-#define CPM_CR_HUNT_MODE       ((ushort)0x0003)
-#define CPM_CR_STOP_TX         ((ushort)0x0004)
-#define CPM_CR_GRA_STOP_TX     ((ushort)0x0005)
-#define CPM_CR_RESTART_TX      ((ushort)0x0006)
-#define CPM_CR_CLOSE_RX_BD     ((ushort)0x0007)
-#define CPM_CR_SET_GADDR       ((ushort)0x0008)
-#define CPM_CR_SET_TIMER       ((ushort)0x0008)
-#define CPM_CR_STOP_IDMA       ((ushort)0x000b)
-
-/* Buffer descriptors used by many of the CPM protocols. */
-typedef struct cpm_buf_desc {
-       ushort  cbd_sc;         /* Status and Control */
-       ushort  cbd_datlen;     /* Data length in buffer */
-       uint    cbd_bufaddr;    /* Buffer address in host memory */
-} cbd_t;
-
-/* Buffer descriptor control/status used by serial
- */
-
-#define BD_SC_EMPTY    (0x8000)        /* Receive is empty */
-#define BD_SC_READY    (0x8000)        /* Transmit is ready */
-#define BD_SC_WRAP     (0x2000)        /* Last buffer descriptor */
-#define BD_SC_INTRPT   (0x1000)        /* Interrupt on change */
-#define BD_SC_LAST     (0x0800)        /* Last buffer in frame */
-#define BD_SC_TC       (0x0400)        /* Transmit CRC */
-#define BD_SC_CM       (0x0200)        /* Continuous mode */
-#define BD_SC_ID       (0x0100)        /* Rec'd too many idles */
-#define BD_SC_P                (0x0100)        /* xmt preamble */
-#define BD_SC_BR       (0x0020)        /* Break received */
-#define BD_SC_FR       (0x0010)        /* Framing error */
-#define BD_SC_PR       (0x0008)        /* Parity error */
-#define BD_SC_NAK      (0x0004)        /* NAK - did not respond */
-#define BD_SC_OV       (0x0002)        /* Overrun */
-#define BD_SC_UN       (0x0002)        /* Underrun */
-#define BD_SC_CD       (0x0001)        /* */
-#define BD_SC_CL       (0x0001)        /* Collision */
-
-/* Buffer descriptor control/status used by Ethernet receive.
- * Common to SCC and FCC.
- */
-#define BD_ENET_RX_EMPTY       (0x8000)
-#define BD_ENET_RX_WRAP                (0x2000)
-#define BD_ENET_RX_INTR                (0x1000)
-#define BD_ENET_RX_LAST                (0x0800)
-#define BD_ENET_RX_FIRST       (0x0400)
-#define BD_ENET_RX_MISS                (0x0100)
-#define BD_ENET_RX_BC          (0x0080)        /* FCC Only */
-#define BD_ENET_RX_MC          (0x0040)        /* FCC Only */
-#define BD_ENET_RX_LG          (0x0020)
-#define BD_ENET_RX_NO          (0x0010)
-#define BD_ENET_RX_SH          (0x0008)
-#define BD_ENET_RX_CR          (0x0004)
-#define BD_ENET_RX_OV          (0x0002)
-#define BD_ENET_RX_CL          (0x0001)
-#define BD_ENET_RX_STATS       (0x01ff)        /* All status bits */
-
-/* Buffer descriptor control/status used by Ethernet transmit.
- * Common to SCC and FCC.
- */
-#define BD_ENET_TX_READY       (0x8000)
-#define BD_ENET_TX_PAD         (0x4000)
-#define BD_ENET_TX_WRAP                (0x2000)
-#define BD_ENET_TX_INTR                (0x1000)
-#define BD_ENET_TX_LAST                (0x0800)
-#define BD_ENET_TX_TC          (0x0400)
-#define BD_ENET_TX_DEF         (0x0200)
-#define BD_ENET_TX_HB          (0x0100)
-#define BD_ENET_TX_LC          (0x0080)
-#define BD_ENET_TX_RL          (0x0040)
-#define BD_ENET_TX_RCMASK      (0x003c)
-#define BD_ENET_TX_UN          (0x0002)
-#define BD_ENET_TX_CSL         (0x0001)
-#define BD_ENET_TX_STATS       (0x03ff)        /* All status bits */
-
-/* Buffer descriptor control/status used by Transparent mode SCC.
- */
-#define BD_SCC_TX_LAST         (0x0800)
-
-/* Buffer descriptor control/status used by I2C.
- */
-#define BD_I2C_START           (0x0400)
-
-#ifdef CONFIG_CPM
-int cpm_command(u32 command, u8 opcode);
-#else
-static inline int cpm_command(u32 command, u8 opcode)
-{
-       return -ENOSYS;
-}
-#endif /* CONFIG_CPM */
-
-int cpm2_gpiochip_add32(struct device *dev);
-
-#endif
+#include <soc/fsl/cpm.h>
index cf00ff0..40a4d3c 100644 (file)
@@ -212,6 +212,7 @@ static inline void cpu_feature_keys_init(void) { }
 #define CPU_FTR_P9_TLBIE_STQ_BUG       LONG_ASM_CONST(0x0000400000000000)
 #define CPU_FTR_P9_TIDR                        LONG_ASM_CONST(0x0000800000000000)
 #define CPU_FTR_P9_TLBIE_ERAT_BUG      LONG_ASM_CONST(0x0001000000000000)
+#define CPU_FTR_P9_RADIX_PREFETCH_BUG  LONG_ASM_CONST(0x0002000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -459,8 +460,10 @@ static inline void cpu_feature_keys_init(void) { }
            CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_ARCH_207S | \
            CPU_FTR_TM_COMP | CPU_FTR_ARCH_300 | CPU_FTR_PKEY | \
            CPU_FTR_P9_TLBIE_STQ_BUG | CPU_FTR_P9_TLBIE_ERAT_BUG | CPU_FTR_P9_TIDR)
-#define CPU_FTRS_POWER9_DD2_0 CPU_FTRS_POWER9
-#define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1)
+#define CPU_FTRS_POWER9_DD2_0 (CPU_FTRS_POWER9 | CPU_FTR_P9_RADIX_PREFETCH_BUG)
+#define CPU_FTRS_POWER9_DD2_1 (CPU_FTRS_POWER9 | \
+                              CPU_FTR_P9_RADIX_PREFETCH_BUG | \
+                              CPU_FTR_POWER9_DD2_1)
 #define CPU_FTRS_POWER9_DD2_2 (CPU_FTRS_POWER9 | CPU_FTR_POWER9_DD2_1 | \
                               CPU_FTR_P9_TM_HV_ASSIST | \
                               CPU_FTR_P9_TM_XER_SO_BUG)
index b3e214a..ca33f4e 100644 (file)
@@ -33,7 +33,7 @@
 #define FW_FEATURE_LLAN                ASM_CONST(0x0000000000010000)
 #define FW_FEATURE_BULK_REMOVE ASM_CONST(0x0000000000020000)
 #define FW_FEATURE_XDABR       ASM_CONST(0x0000000000040000)
-#define FW_FEATURE_MULTITCE    ASM_CONST(0x0000000000080000)
+#define FW_FEATURE_PUT_TCE_IND ASM_CONST(0x0000000000080000)
 #define FW_FEATURE_SPLPAR      ASM_CONST(0x0000000000100000)
 #define FW_FEATURE_LPAR                ASM_CONST(0x0000000000400000)
 #define FW_FEATURE_PS3_LV1     ASM_CONST(0x0000000000800000)
@@ -51,6 +51,7 @@
 #define FW_FEATURE_BLOCK_REMOVE ASM_CONST(0x0000001000000000)
 #define FW_FEATURE_PAPR_SCM    ASM_CONST(0x0000002000000000)
 #define FW_FEATURE_ULTRAVISOR  ASM_CONST(0x0000004000000000)
+#define FW_FEATURE_STUFF_TCE   ASM_CONST(0x0000008000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -63,7 +64,8 @@ enum {
                FW_FEATURE_MIGRATE | FW_FEATURE_PERFMON | FW_FEATURE_CRQ |
                FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN |
                FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR |
-               FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
+               FW_FEATURE_PUT_TCE_IND | FW_FEATURE_STUFF_TCE |
+               FW_FEATURE_SPLPAR | FW_FEATURE_LPAR |
                FW_FEATURE_CMO | FW_FEATURE_VPHN | FW_FEATURE_XCMO |
                FW_FEATURE_SET_MODE | FW_FEATURE_BEST_ENERGY |
                FW_FEATURE_TYPE1_AFFINITY | FW_FEATURE_PRRN |
index eea28ca..bc7d9d0 100644 (file)
@@ -35,7 +35,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
 {
        int oldval = 0, ret;
 
-       allow_write_to_user(uaddr, sizeof(*uaddr));
+       allow_read_write_user(uaddr, uaddr, sizeof(*uaddr));
        pagefault_disable();
 
        switch (op) {
@@ -62,7 +62,7 @@ static inline int arch_futex_atomic_op_inuser(int op, int oparg, int *oval,
 
        *oval = oldval;
 
-       prevent_write_to_user(uaddr, sizeof(*uaddr));
+       prevent_read_write_user(uaddr, uaddr, sizeof(*uaddr));
        return ret;
 }
 
@@ -76,7 +76,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
        if (!access_ok(uaddr, sizeof(u32)))
                return -EFAULT;
 
-       allow_write_to_user(uaddr, sizeof(*uaddr));
+       allow_read_write_user(uaddr, uaddr, sizeof(*uaddr));
+
         __asm__ __volatile__ (
         PPC_ATOMIC_ENTRY_BARRIER
 "1:     lwarx   %1,0,%3         # futex_atomic_cmpxchg_inatomic\n\
@@ -97,7 +98,8 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
         : "cc", "memory");
 
        *uval = prev;
-       prevent_write_to_user(uaddr, sizeof(*uaddr));
+       prevent_read_write_user(uaddr, uaddr, sizeof(*uaddr));
+
         return ret;
 }
 
index 27ac6f5..f2f8d8a 100644 (file)
@@ -34,7 +34,11 @@ struct arch_hw_breakpoint {
 #define HW_BRK_TYPE_PRIV_ALL   (HW_BRK_TYPE_USER | HW_BRK_TYPE_KERNEL | \
                                 HW_BRK_TYPE_HYP)
 
+#ifdef CONFIG_PPC_8xx
+#define HW_BREAKPOINT_ALIGN 0x3
+#else
 #define HW_BREAKPOINT_ALIGN 0x7
+#endif
 
 #define DABR_MAX_LEN   8
 #define DAWR_MAX_LEN   512
index 296e51c..fbff9ff 100644 (file)
 void kasan_early_init(void);
 void kasan_mmu_init(void);
 void kasan_init(void);
+void kasan_late_init(void);
 #else
 static inline void kasan_init(void) { }
 static inline void kasan_mmu_init(void) { }
+static inline void kasan_late_init(void) { }
 #endif
 
 #endif /* __ASSEMBLY */
index 5b5e396..92bcd1a 100644 (file)
@@ -2,6 +2,16 @@
 #ifndef _ASM_POWERPC_KUP_H_
 #define _ASM_POWERPC_KUP_H_
 
+#define KUAP_READ      1
+#define KUAP_WRITE     2
+#define KUAP_READ_WRITE        (KUAP_READ | KUAP_WRITE)
+/*
+ * For prevent_user_access() only.
+ * Use the current saved situation instead of the to/from/size params.
+ * Used on book3s/32
+ */
+#define KUAP_CURRENT   4
+
 #ifdef CONFIG_PPC64
 #include <asm/book3s/64/kup-radix.h>
 #endif
@@ -42,32 +52,55 @@ void setup_kuap(bool disabled);
 #else
 static inline void setup_kuap(bool disabled) { }
 static inline void allow_user_access(void __user *to, const void __user *from,
-                                    unsigned long size) { }
+                                    unsigned long size, unsigned long dir) { }
 static inline void prevent_user_access(void __user *to, const void __user *from,
-                                      unsigned long size) { }
-static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write) { return false; }
+                                      unsigned long size, unsigned long dir) { }
+static inline unsigned long prevent_user_access_return(void) { return 0UL; }
+static inline void restore_user_access(unsigned long flags) { }
+static inline bool
+bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
+{
+       return false;
+}
 #endif /* CONFIG_PPC_KUAP */
 
 static inline void allow_read_from_user(const void __user *from, unsigned long size)
 {
-       allow_user_access(NULL, from, size);
+       allow_user_access(NULL, from, size, KUAP_READ);
 }
 
 static inline void allow_write_to_user(void __user *to, unsigned long size)
 {
-       allow_user_access(to, NULL, size);
+       allow_user_access(to, NULL, size, KUAP_WRITE);
+}
+
+static inline void allow_read_write_user(void __user *to, const void __user *from,
+                                        unsigned long size)
+{
+       allow_user_access(to, from, size, KUAP_READ_WRITE);
 }
 
 static inline void prevent_read_from_user(const void __user *from, unsigned long size)
 {
-       prevent_user_access(NULL, from, size);
+       prevent_user_access(NULL, from, size, KUAP_READ);
 }
 
 static inline void prevent_write_to_user(void __user *to, unsigned long size)
 {
-       prevent_user_access(to, NULL, size);
+       prevent_user_access(to, NULL, size, KUAP_WRITE);
+}
+
+static inline void prevent_read_write_user(void __user *to, const void __user *from,
+                                          unsigned long size)
+{
+       prevent_user_access(to, from, size, KUAP_READ_WRITE);
+}
+
+static inline void prevent_current_access_user(void)
+{
+       prevent_user_access(NULL, NULL, ~0UL, KUAP_CURRENT);
 }
 
 #endif /* !__ASSEMBLY__ */
 
-#endif /* _ASM_POWERPC_KUP_H_ */
+#endif /* _ASM_POWERPC_KUAP_H_ */
index 1006a42..85ed239 100644 (file)
 #include <asm/reg.h>
 
 static inline void allow_user_access(void __user *to, const void __user *from,
-                                    unsigned long size)
+                                    unsigned long size, unsigned long dir)
 {
        mtspr(SPRN_MD_AP, MD_APG_INIT);
 }
 
 static inline void prevent_user_access(void __user *to, const void __user *from,
-                                      unsigned long size)
+                                      unsigned long size, unsigned long dir)
 {
        mtspr(SPRN_MD_AP, MD_APG_KUAP);
 }
 
-static inline bool bad_kuap_fault(struct pt_regs *regs, bool is_write)
+static inline unsigned long prevent_user_access_return(void)
+{
+       unsigned long flags = mfspr(SPRN_MD_AP);
+
+       mtspr(SPRN_MD_AP, MD_APG_KUAP);
+
+       return flags;
+}
+
+static inline void restore_user_access(unsigned long flags)
+{
+       mtspr(SPRN_MD_AP, flags);
+}
+
+static inline bool
+bad_kuap_fault(struct pt_regs *regs, unsigned long address, bool is_write)
 {
        return WARN(!((regs->kuap ^ MD_APG_KUAP) & 0xf0000000),
                    "Bug: fault blocked by AP register !");
index 552b96e..60c4d82 100644 (file)
@@ -114,7 +114,12 @@ int map_kernel_page(unsigned long va, phys_addr_t pa, pgprot_t prot);
 #else
 #define VMALLOC_START ((((long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)))
 #endif
+
+#ifdef CONFIG_KASAN_VMALLOC
+#define VMALLOC_END    _ALIGN_DOWN(ioremap_bot, PAGE_SIZE << KASAN_SHADOW_SCALE_SHIFT)
+#else
 #define VMALLOC_END    ioremap_bot
+#endif
 
 /*
  * Bits in a linux-style PTE.  These match the bits in the
index 332b13b..29c4366 100644 (file)
@@ -46,7 +46,6 @@ static inline void pgtable_free(void *table, int shift)
 
 #define get_hugepd_cache_index(x)      (x)
 
-#ifdef CONFIG_SMP
 static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
 {
        unsigned long pgf = (unsigned long)table;
@@ -64,13 +63,6 @@ static inline void __tlb_remove_table(void *_table)
        pgtable_free(table, shift);
 }
 
-#else
-static inline void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int shift)
-{
-       pgtable_free(table, shift);
-}
-#endif
-
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
                                  unsigned long address)
 {
index 7f1fd41..8633208 100644 (file)
@@ -209,7 +209,7 @@ static inline bool pfn_valid(unsigned long pfn)
  */
 #if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
 #define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + VIRT_PHYS_OFFSET))
-#define __pa(x) ((unsigned long)(x) - VIRT_PHYS_OFFSET)
+#define __pa(x) ((phys_addr_t)(unsigned long)(x) - VIRT_PHYS_OFFSET)
 #else
 #ifdef CONFIG_PPC64
 /*
index ea6ec65..69f4cb3 100644 (file)
@@ -223,12 +223,15 @@ struct pci_dn {
 extern struct pci_dn *pci_get_pdn_by_devfn(struct pci_bus *bus,
                                           int devfn);
 extern struct pci_dn *pci_get_pdn(struct pci_dev *pdev);
-extern struct pci_dn *add_dev_pci_data(struct pci_dev *pdev);
-extern void remove_dev_pci_data(struct pci_dev *pdev);
 extern struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,
                                               struct device_node *dn);
 extern void pci_remove_device_node_info(struct device_node *dn);
 
+#ifdef CONFIG_PCI_IOV
+struct pci_dn *add_sriov_vf_pdns(struct pci_dev *pdev);
+void remove_sriov_vf_pdns(struct pci_dev *pdev);
+#endif
+
 static inline int pci_device_from_OF_node(struct device_node *np,
                                          u8 *bus, u8 *devfn)
 {
index 327567b..63ed7e3 100644 (file)
@@ -113,7 +113,6 @@ extern pgprot_t     pci_phys_mem_access_prot(struct file *file,
                                         pgprot_t prot);
 
 extern resource_size_t pcibios_io_space_offset(struct pci_controller *hose);
-extern void pcibios_setup_bus_devices(struct pci_bus *bus);
 extern void pcibios_setup_bus_self(struct pci_bus *bus);
 extern void pcibios_setup_phb_io_space(struct pci_controller *hose);
 extern void pcibios_scan_phb(struct pci_controller *hose);
index 0e4ec8c..8cc543e 100644 (file)
@@ -94,12 +94,6 @@ void mark_initmem_nx(void);
 static inline void mark_initmem_nx(void) { }
 #endif
 
-#ifdef CONFIG_PPC_DEBUG_WX
-void ptdump_check_wx(void);
-#else
-static inline void ptdump_check_wx(void) { }
-#endif
-
 /*
  * When used, PTE_FRAG_NR is defined in subarch pgtable.h
  * so we are sure it is included when arriving here.
index edcb1fc..d0ee0ed 100644 (file)
@@ -15,6 +15,7 @@
 #define PCI_SLOT_ID_PREFIX     (1UL << 63)
 #define PCI_SLOT_ID(phb_id, bdfn)      \
        (PCI_SLOT_ID_PREFIX | ((uint64_t)(bdfn) << 16) | (phb_id))
+#define PCI_PHB_SLOT_ID(phb_id)                (phb_id)
 
 extern int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id);
 extern int pnv_pci_get_device_tree(uint32_t phandle, void *buf, uint64_t len);
index a9993e7..8387698 100644 (file)
@@ -163,6 +163,12 @@ struct thread_struct {
 #if defined(CONFIG_PPC_BOOK3S_32) && defined(CONFIG_PPC_KUAP)
        unsigned long   kuap;           /* opened segments for user access */
 #endif
+#ifdef CONFIG_VMAP_STACK
+       unsigned long   srr0;
+       unsigned long   srr1;
+       unsigned long   dar;
+       unsigned long   dsisr;
+#endif
        /* Debug Registers */
        struct debug_reg debug;
        struct thread_fp_state  fp_state;
@@ -412,6 +418,9 @@ static inline unsigned long get_clean_sp(unsigned long sp, int is_32)
 extern unsigned long isa300_idle_stop_noloss(unsigned long psscr_val);
 extern unsigned long isa300_idle_stop_mayloss(unsigned long psscr_val);
 extern unsigned long isa206_idle_insn_mayloss(unsigned long type);
+#ifdef CONFIG_PPC_970_NAP
+extern void power4_idle_nap(void);
+#endif
 
 extern unsigned long cpuidle_disable;
 enum idle_boot_override {IDLE_NO_OVERRIDE = 0, IDLE_POWERSAVE_OFF};
index 07df35e..299ee7b 100644 (file)
 #define SPRN_CMPE      152
 #define SPRN_CMPF      153
 #define SPRN_LCTRL1    156
+#define   LCTRL1_CTE_GT                0xc0000000
+#define   LCTRL1_CTF_LT                0x14000000
+#define   LCTRL1_CRWE_RW       0x00000000
+#define   LCTRL1_CRWE_RO       0x00040000
+#define   LCTRL1_CRWE_WO       0x000c0000
+#define   LCTRL1_CRWF_RW       0x00000000
+#define   LCTRL1_CRWF_RO       0x00010000
+#define   LCTRL1_CRWF_WO       0x00030000
 #define SPRN_LCTRL2    157
+#define   LCTRL2_LW0EN         0x80000000
+#define   LCTRL2_LW0LA_E       0x00000000
+#define   LCTRL2_LW0LA_F       0x04000000
+#define   LCTRL2_LW0LA_EandF   0x08000000
+#define   LCTRL2_LW0LADC       0x02000000
+#define   LCTRL2_SLW0EN                0x00000002
 #ifdef CONFIG_PPC_8xx
 #define SPRN_ICTRL     158
 #endif
index 8e1d019..a227074 100644 (file)
 #define _ASM_POWERPC_THREAD_INFO_H
 
 #include <asm/asm-const.h>
+#include <asm/page.h>
 
 #ifdef __KERNEL__
 
+#if defined(CONFIG_VMAP_STACK) && CONFIG_THREAD_SHIFT < PAGE_SHIFT
+#define THREAD_SHIFT           PAGE_SHIFT
+#else
 #define THREAD_SHIFT           CONFIG_THREAD_SHIFT
+#endif
 
 #define THREAD_SIZE            (1 << THREAD_SHIFT)
 
+/*
+ * By aligning VMAP'd stacks to 2 * THREAD_SIZE, we can detect overflow by
+ * checking sp & (1 << THREAD_SHIFT), which we can do cheaply in the entry
+ * assembly.
+ */
+#ifdef CONFIG_VMAP_STACK
+#define THREAD_ALIGN_SHIFT     (THREAD_SHIFT + 1)
+#else
+#define THREAD_ALIGN_SHIFT     THREAD_SHIFT
+#endif
+
+#define THREAD_ALIGN           (1 << THREAD_ALIGN_SHIFT)
+
 #ifndef __ASSEMBLY__
 #include <linux/cache.h>
 #include <asm/processor.h>
index b2c0be9..7f3a8b9 100644 (file)
 
 #define tlb_flush tlb_flush
 extern void tlb_flush(struct mmu_gather *tlb);
+/*
+ * book3s:
+ * Hash does not use the linux page-tables, so we can avoid
+ * the TLB invalidate for page-table freeing, Radix otoh does use the
+ * page-tables and needs the TLBI.
+ *
+ * nohash:
+ * We still do TLB invalidate in the __pte_free_tlb routine before we
+ * add the page table pages to mmu gather table batch.
+ */
+#define tlb_needs_table_invalidate()   radix_enabled()
 
 /* Get the generic bits... */
 #include <asm-generic/tlb.h>
index c92fe7f..2f500de 100644 (file)
@@ -91,9 +91,14 @@ static inline int __access_ok(unsigned long addr, unsigned long size,
        __put_user_check((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
 
 #define __get_user(x, ptr) \
-       __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
+       __get_user_nocheck((x), (ptr), sizeof(*(ptr)), true)
 #define __put_user(x, ptr) \
-       __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
+       __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), true)
+
+#define __get_user_allowed(x, ptr) \
+       __get_user_nocheck((x), (ptr), sizeof(*(ptr)), false)
+#define __put_user_allowed(x, ptr) \
+       __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)), false)
 
 #define __get_user_inatomic(x, ptr) \
        __get_user_nosleep((x), (ptr), sizeof(*(ptr)))
@@ -138,10 +143,9 @@ extern long __put_user_bad(void);
                : "r" (x), "b" (addr), "i" (-EFAULT), "0" (err))
 #endif /* __powerpc64__ */
 
-#define __put_user_size(x, ptr, size, retval)                  \
+#define __put_user_size_allowed(x, ptr, size, retval)          \
 do {                                                           \
        retval = 0;                                             \
-       allow_write_to_user(ptr, size);                         \
        switch (size) {                                         \
          case 1: __put_user_asm(x, ptr, retval, "stb"); break; \
          case 2: __put_user_asm(x, ptr, retval, "sth"); break; \
@@ -149,17 +153,26 @@ do {                                                              \
          case 8: __put_user_asm2(x, ptr, retval); break;       \
          default: __put_user_bad();                            \
        }                                                       \
+} while (0)
+
+#define __put_user_size(x, ptr, size, retval)                  \
+do {                                                           \
+       allow_write_to_user(ptr, size);                         \
+       __put_user_size_allowed(x, ptr, size, retval);          \
        prevent_write_to_user(ptr, size);                       \
 } while (0)
 
-#define __put_user_nocheck(x, ptr, size)                       \
+#define __put_user_nocheck(x, ptr, size, do_allow)                     \
 ({                                                             \
        long __pu_err;                                          \
        __typeof__(*(ptr)) __user *__pu_addr = (ptr);           \
        if (!is_kernel_addr((unsigned long)__pu_addr))          \
                might_fault();                                  \
        __chk_user_ptr(ptr);                                    \
-       __put_user_size((x), __pu_addr, (size), __pu_err);      \
+       if (do_allow)                                                           \
+               __put_user_size((x), __pu_addr, (size), __pu_err);              \
+       else                                                                    \
+               __put_user_size_allowed((x), __pu_addr, (size), __pu_err);      \
        __pu_err;                                               \
 })
 
@@ -236,13 +249,12 @@ extern long __get_user_bad(void);
                : "b" (addr), "i" (-EFAULT), "0" (err))
 #endif /* __powerpc64__ */
 
-#define __get_user_size(x, ptr, size, retval)                  \
+#define __get_user_size_allowed(x, ptr, size, retval)          \
 do {                                                           \
        retval = 0;                                             \
        __chk_user_ptr(ptr);                                    \
        if (size > sizeof(x))                                   \
                (x) = __get_user_bad();                         \
-       allow_read_from_user(ptr, size);                        \
        switch (size) {                                         \
        case 1: __get_user_asm(x, ptr, retval, "lbz"); break;   \
        case 2: __get_user_asm(x, ptr, retval, "lhz"); break;   \
@@ -250,6 +262,12 @@ do {                                                               \
        case 8: __get_user_asm2(x, ptr, retval);  break;        \
        default: (x) = __get_user_bad();                        \
        }                                                       \
+} while (0)
+
+#define __get_user_size(x, ptr, size, retval)                  \
+do {                                                           \
+       allow_read_from_user(ptr, size);                        \
+       __get_user_size_allowed(x, ptr, size, retval);          \
        prevent_read_from_user(ptr, size);                      \
 } while (0)
 
@@ -260,7 +278,7 @@ do {                                                                \
 #define __long_type(x) \
        __typeof__(__builtin_choose_expr(sizeof(x) > sizeof(0UL), 0ULL, 0UL))
 
-#define __get_user_nocheck(x, ptr, size)                       \
+#define __get_user_nocheck(x, ptr, size, do_allow)                     \
 ({                                                             \
        long __gu_err;                                          \
        __long_type(*(ptr)) __gu_val;                           \
@@ -269,7 +287,10 @@ do {                                                               \
        if (!is_kernel_addr((unsigned long)__gu_addr))          \
                might_fault();                                  \
        barrier_nospec();                                       \
-       __get_user_size(__gu_val, __gu_addr, (size), __gu_err); \
+       if (do_allow)                                                           \
+               __get_user_size(__gu_val, __gu_addr, (size), __gu_err);         \
+       else                                                                    \
+               __get_user_size_allowed(__gu_val, __gu_addr, (size), __gu_err); \
        (x) = (__typeof__(*(ptr)))__gu_val;                     \
        __gu_err;                                               \
 })
@@ -313,9 +334,9 @@ raw_copy_in_user(void __user *to, const void __user *from, unsigned long n)
        unsigned long ret;
 
        barrier_nospec();
-       allow_user_access(to, from, n);
+       allow_read_write_user(to, from, n);
        ret = __copy_tofrom_user(to, from, n);
-       prevent_user_access(to, from, n);
+       prevent_read_write_user(to, from, n);
        return ret;
 }
 #endif /* __powerpc64__ */
@@ -356,33 +377,40 @@ static inline unsigned long raw_copy_from_user(void *to,
        return ret;
 }
 
-static inline unsigned long raw_copy_to_user(void __user *to,
-               const void *from, unsigned long n)
+static inline unsigned long
+raw_copy_to_user_allowed(void __user *to, const void *from, unsigned long n)
 {
-       unsigned long ret;
        if (__builtin_constant_p(n) && (n <= 8)) {
-               ret = 1;
+               unsigned long ret = 1;
 
                switch (n) {
                case 1:
-                       __put_user_size(*(u8 *)from, (u8 __user *)to, 1, ret);
+                       __put_user_size_allowed(*(u8 *)from, (u8 __user *)to, 1, ret);
                        break;
                case 2:
-                       __put_user_size(*(u16 *)from, (u16 __user *)to, 2, ret);
+                       __put_user_size_allowed(*(u16 *)from, (u16 __user *)to, 2, ret);
                        break;
                case 4:
-                       __put_user_size(*(u32 *)from, (u32 __user *)to, 4, ret);
+                       __put_user_size_allowed(*(u32 *)from, (u32 __user *)to, 4, ret);
                        break;
                case 8:
-                       __put_user_size(*(u64 *)from, (u64 __user *)to, 8, ret);
+                       __put_user_size_allowed(*(u64 *)from, (u64 __user *)to, 8, ret);
                        break;
                }
                if (ret == 0)
                        return 0;
        }
 
+       return __copy_tofrom_user(to, (__force const void __user *)from, n);
+}
+
+static inline unsigned long
+raw_copy_to_user(void __user *to, const void *from, unsigned long n)
+{
+       unsigned long ret;
+
        allow_write_to_user(to, n);
-       ret = __copy_tofrom_user(to, (__force const void __user *)from, n);
+       ret = raw_copy_to_user_allowed(to, from, n);
        prevent_write_to_user(to, n);
        return ret;
 }
@@ -428,4 +456,22 @@ extern long __copy_from_user_flushcache(void *dst, const void __user *src,
 extern void memcpy_page_flushcache(char *to, struct page *page, size_t offset,
                           size_t len);
 
+static __must_check inline bool user_access_begin(const void __user *ptr, size_t len)
+{
+       if (unlikely(!access_ok(ptr, len)))
+               return false;
+       allow_read_write_user((void __user *)ptr, ptr, len);
+       return true;
+}
+#define user_access_begin      user_access_begin
+#define user_access_end                prevent_current_access_user
+#define user_access_save       prevent_user_access_return
+#define user_access_restore    restore_user_access
+
+#define unsafe_op_wrap(op, err) do { if (unlikely(op)) goto err; } while (0)
+#define unsafe_get_user(x, p, e) unsafe_op_wrap(__get_user_allowed(x, p), e)
+#define unsafe_put_user(x, p, e) unsafe_op_wrap(__put_user_allowed(x, p), e)
+#define unsafe_copy_to_user(d, s, l, e) \
+       unsafe_op_wrap(raw_copy_to_user_allowed(d, s, l), e)
+
 #endif /* _ARCH_POWERPC_UACCESS_H */
index 40f13f3..b9ef6cf 100644 (file)
@@ -108,16 +108,22 @@ struct vdso_data {
        __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     */
-       __u32 dcache_log_block_size;    /* L1 d-cache log block size */
-       __u32 icache_log_block_size;    /* L1 i-cache log block size */
 };
 
 #endif /* CONFIG_PPC64 */
 
 extern struct vdso_data *vdso_data;
 
+#else /* __ASSEMBLY__ */
+
+.macro get_datapage ptr, tmp
+       bcl     20, 31, .+4
+       mflr    \ptr
+       addi    \ptr, \ptr, (__kernel_datapage_offset - (.-4))@l
+       lwz     \tmp, 0(\ptr)
+       add     \ptr, \tmp, \ptr
+.endm
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* __KERNEL__ */
index 24cdf97..93f982d 100644 (file)
@@ -87,56 +87,56 @@ extern bool __xive_enabled;
 
 static inline bool xive_enabled(void) { return __xive_enabled; }
 
-extern bool xive_spapr_init(void);
-extern bool xive_native_init(void);
-extern void xive_smp_probe(void);
-extern int  xive_smp_prepare_cpu(unsigned int cpu);
-extern void xive_smp_setup_cpu(void);
-extern void xive_smp_disable_cpu(void);
-extern void xive_teardown_cpu(void);
-extern void xive_shutdown(void);
-extern void xive_flush_interrupt(void);
+bool xive_spapr_init(void);
+bool xive_native_init(void);
+void xive_smp_probe(void);
+int  xive_smp_prepare_cpu(unsigned int cpu);
+void xive_smp_setup_cpu(void);
+void xive_smp_disable_cpu(void);
+void xive_teardown_cpu(void);
+void xive_shutdown(void);
+void xive_flush_interrupt(void);
 
 /* xmon hook */
-extern void xmon_xive_do_dump(int cpu);
-extern int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d);
+void xmon_xive_do_dump(int cpu);
+int xmon_xive_get_irq_config(u32 hw_irq, struct irq_data *d);
 
 /* APIs used by KVM */
-extern u32 xive_native_default_eq_shift(void);
-extern u32 xive_native_alloc_vp_block(u32 max_vcpus);
-extern void xive_native_free_vp_block(u32 vp_base);
-extern int xive_native_populate_irq_data(u32 hw_irq,
-                                        struct xive_irq_data *data);
-extern void xive_cleanup_irq_data(struct xive_irq_data *xd);
-extern u32 xive_native_alloc_irq(void);
-extern void xive_native_free_irq(u32 irq);
-extern int xive_native_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq);
-
-extern int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
-                                      __be32 *qpage, u32 order, bool can_escalate);
-extern void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
-
-extern void xive_native_sync_source(u32 hw_irq);
-extern void xive_native_sync_queue(u32 hw_irq);
-extern bool is_xive_irq(struct irq_chip *chip);
-extern int xive_native_enable_vp(u32 vp_id, bool single_escalation);
-extern int xive_native_disable_vp(u32 vp_id);
-extern int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id);
-extern bool xive_native_has_single_escalation(void);
-
-extern int xive_native_get_queue_info(u32 vp_id, uint32_t prio,
-                                     u64 *out_qpage,
-                                     u64 *out_qsize,
-                                     u64 *out_qeoi_page,
-                                     u32 *out_escalate_irq,
-                                     u64 *out_qflags);
-
-extern int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle,
-                                      u32 *qindex);
-extern int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle,
-                                      u32 qindex);
-extern int xive_native_get_vp_state(u32 vp_id, u64 *out_state);
-extern bool xive_native_has_queue_state_support(void);
+u32 xive_native_default_eq_shift(void);
+u32 xive_native_alloc_vp_block(u32 max_vcpus);
+void xive_native_free_vp_block(u32 vp_base);
+int xive_native_populate_irq_data(u32 hw_irq,
+                                 struct xive_irq_data *data);
+void xive_cleanup_irq_data(struct xive_irq_data *xd);
+u32 xive_native_alloc_irq(void);
+void xive_native_free_irq(u32 irq);
+int xive_native_configure_irq(u32 hw_irq, u32 target, u8 prio, u32 sw_irq);
+
+int xive_native_configure_queue(u32 vp_id, struct xive_q *q, u8 prio,
+                               __be32 *qpage, u32 order, bool can_escalate);
+void xive_native_disable_queue(u32 vp_id, struct xive_q *q, u8 prio);
+
+void xive_native_sync_source(u32 hw_irq);
+void xive_native_sync_queue(u32 hw_irq);
+bool is_xive_irq(struct irq_chip *chip);
+int xive_native_enable_vp(u32 vp_id, bool single_escalation);
+int xive_native_disable_vp(u32 vp_id);
+int xive_native_get_vp_info(u32 vp_id, u32 *out_cam_id, u32 *out_chip_id);
+bool xive_native_has_single_escalation(void);
+
+int xive_native_get_queue_info(u32 vp_id, uint32_t prio,
+                              u64 *out_qpage,
+                              u64 *out_qsize,
+                              u64 *out_qeoi_page,
+                              u32 *out_escalate_irq,
+                              u64 *out_qflags);
+
+int xive_native_get_queue_state(u32 vp_id, uint32_t prio, u32 *qtoggle,
+                               u32 *qindex);
+int xive_native_set_queue_state(u32 vp_id, uint32_t prio, u32 qtoggle,
+                               u32 qindex);
+int xive_native_get_vp_state(u32 vp_id, u64 *out_state);
+bool xive_native_has_queue_state_support(void);
 
 #else
 
index 157b014..78a1b22 100644 (file)
@@ -62,8 +62,7 @@ obj-$(CONFIG_PPC_BOOK3E_64)   += exceptions-64e.o idle_book3e.o
 obj-$(CONFIG_PPC_BARRIER_NOSPEC) += security.o
 obj-$(CONFIG_PPC64)            += vdso64/
 obj-$(CONFIG_ALTIVEC)          += vecemu.o
-obj-$(CONFIG_PPC_970_NAP)      += idle_power4.o
-obj-$(CONFIG_PPC_P7_NAP)       += idle_book3s.o
+obj-$(CONFIG_PPC_BOOK3S_IDLE)  += idle_book3s.o
 procfs-y                       := proc_powerpc.o
 obj-$(CONFIG_PROC_FS)          += $(procfs-y)
 rtaspci-$(CONFIG_PPC64)-$(CONFIG_PCI)  := rtas_pci.o
index 3d47aec..c25e562 100644 (file)
@@ -127,6 +127,12 @@ int main(void)
        OFFSET(KSP_VSID, thread_struct, ksp_vsid);
 #else /* CONFIG_PPC64 */
        OFFSET(PGDIR, thread_struct, pgdir);
+#ifdef CONFIG_VMAP_STACK
+       OFFSET(SRR0, thread_struct, srr0);
+       OFFSET(SRR1, thread_struct, srr1);
+       OFFSET(DAR, thread_struct, dar);
+       OFFSET(DSISR, thread_struct, dsisr);
+#endif
 #ifdef CONFIG_SPE
        OFFSET(THREAD_EVR0, thread_struct, evr[0]);
        OFFSET(THREAD_ACC, thread_struct, acc);
@@ -389,11 +395,11 @@ int main(void)
        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);
+#ifdef CONFIG_PPC64
        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);
        OFFSET(CFG_DCACHE_LOGBLOCKSZ, vdso_data, dcache_log_block_size);
-#ifdef CONFIG_PPC64
        OFFSET(CFG_SYSCALL_MAP64, vdso_data, syscall_map_64);
        OFFSET(TVAL64_TV_SEC, __kernel_old_timeval, tv_sec);
        OFFSET(TVAL64_TV_USEC, __kernel_old_timeval, tv_usec);
@@ -413,7 +419,10 @@ int main(void)
        DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
        DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
        DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
+       DEFINE(CLOCK_MAX, CLOCK_TAI);
        DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
+       DEFINE(EINVAL, EINVAL);
+       DEFINE(KTIME_LOW_RES, KTIME_LOW_RES);
 
 #ifdef CONFIG_BUG
        DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
index 180b3a5..182b404 100644 (file)
@@ -727,17 +727,20 @@ static __init void cpufeatures_cpu_quirks(void)
        /*
         * Not all quirks can be derived from the cpufeatures device tree.
         */
-       if ((version & 0xffffefff) == 0x004e0200)
-               ; /* DD2.0 has no feature flag */
-       else if ((version & 0xffffefff) == 0x004e0201)
+       if ((version & 0xffffefff) == 0x004e0200) {
+               /* DD2.0 has no feature flag */
+               cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
+       } else if ((version & 0xffffefff) == 0x004e0201) {
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
-       else if ((version & 0xffffefff) == 0x004e0202) {
+               cur_cpu_spec->cpu_features |= CPU_FTR_P9_RADIX_PREFETCH_BUG;
+       } else if ((version & 0xffffefff) == 0x004e0202) {
                cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_HV_ASSIST;
                cur_cpu_spec->cpu_features |= CPU_FTR_P9_TM_XER_SO_BUG;
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
-       } else if ((version & 0xffff0000) == 0x004e0000)
+       } else if ((version & 0xffff0000) == 0x004e0000) {
                /* DD2.1 and up have DD2_1 */
                cur_cpu_spec->cpu_features |= CPU_FTR_POWER9_DD2_1;
+       }
 
        if ((version & 0xffff0000) == 0x004e0000) {
                cur_cpu_spec->cpu_features &= ~(CPU_FTR_DAWR);
index bc8a551..17cb3e9 100644 (file)
@@ -503,7 +503,7 @@ int eeh_dev_check_failure(struct eeh_dev *edev)
        rc = 1;
        if (pe->state & EEH_PE_ISOLATED) {
                pe->check_count++;
-               if (pe->check_count % EEH_MAX_FAILS == 0) {
+               if (pe->check_count == EEH_MAX_FAILS) {
                        dn = pci_device_to_OF_node(dev);
                        if (dn)
                                location = of_get_property(dn, "ibm,loc-code",
@@ -1191,7 +1191,6 @@ void eeh_add_device_late(struct pci_dev *dev)
                eeh_rmv_from_parent_pe(edev);
                eeh_addr_cache_rmv_dev(edev->pdev);
                eeh_sysfs_remove_device(edev->pdev);
-               edev->mode &= ~EEH_DEV_SYSFS;
 
                /*
                 * We definitely should have the PCI device removed
@@ -1296,17 +1295,11 @@ void eeh_remove_device(struct pci_dev *dev)
        edev->pdev = NULL;
 
        /*
-        * The flag "in_error" is used to trace EEH devices for VFs
-        * in error state or not. It's set in eeh_report_error(). If
-        * it's not set, eeh_report_{reset,resume}() won't be called
-        * for the VF EEH device.
+        * eeh_sysfs_remove_device() uses pci_dev_to_eeh_dev() so we need to
+        * remove the sysfs files before clearing dev.archdata.edev
         */
-       edev->in_error = false;
-       dev->dev.archdata.edev = NULL;
-       if (!(edev->pe->state & EEH_PE_KEEP))
-               eeh_rmv_from_parent_pe(edev);
-       else
-               edev->mode |= EEH_DEV_DISCONNECTED;
+       if (edev->mode & EEH_DEV_SYSFS)
+               eeh_sysfs_remove_device(dev);
 
        /*
         * We're removing from the PCI subsystem, that means
@@ -1317,8 +1310,19 @@ void eeh_remove_device(struct pci_dev *dev)
        edev->mode |= EEH_DEV_NO_HANDLER;
 
        eeh_addr_cache_rmv_dev(dev);
-       eeh_sysfs_remove_device(dev);
-       edev->mode &= ~EEH_DEV_SYSFS;
+
+       /*
+        * The flag "in_error" is used to trace EEH devices for VFs
+        * in error state or not. It's set in eeh_report_error(). If
+        * it's not set, eeh_report_{reset,resume}() won't be called
+        * for the VF EEH device.
+        */
+       edev->in_error = false;
+       dev->dev.archdata.edev = NULL;
+       if (!(edev->pe->state & EEH_PE_KEEP))
+               eeh_rmv_from_parent_pe(edev);
+       else
+               edev->mode |= EEH_DEV_DISCONNECTED;
 }
 
 int eeh_unfreeze_pe(struct eeh_pe *pe)
index cf11277..6b50bf1 100644 (file)
@@ -159,18 +159,10 @@ eeh_addr_cache_insert(struct pci_dev *dev, resource_size_t alo,
 
 static void __eeh_addr_cache_insert_dev(struct pci_dev *dev)
 {
-       struct pci_dn *pdn;
        struct eeh_dev *edev;
        int i;
 
-       pdn = pci_get_pdn_by_devfn(dev->bus, dev->devfn);
-       if (!pdn) {
-               pr_warn("PCI: no pci dn found for dev=%s\n",
-                       pci_name(dev));
-               return;
-       }
-
-       edev = pdn_to_eeh_dev(pdn);
+       edev = pci_dev_to_eeh_dev(dev);
        if (!edev) {
                pr_warn("PCI: no EEH dev found for %s\n",
                        pci_name(dev));
index 3dd1a42..a1eaffe 100644 (file)
@@ -525,12 +525,6 @@ static void eeh_rmv_device(struct eeh_dev *edev, void *userdata)
 
                pci_iov_remove_virtfn(edev->physfn, pdn->vf_index);
                edev->pdev = NULL;
-
-               /*
-                * We have to set the VF PE number to invalid one, which is
-                * required to plug the VF successfully.
-                */
-               pdn->pe_number = IODA_INVALID_PE;
 #endif
                if (rmv_data)
                        list_add(&edev->rmv_entry, &rmv_data->removed_vf_list);
index ab44d96..4fb0f1e 100644 (file)
@@ -14,7 +14,7 @@
 /**
  * EEH_SHOW_ATTR -- Create sysfs entry for eeh statistic
  * @_name: name of file in sysfs directory
- * @_memb: name of member in struct pci_dn to access
+ * @_memb: name of member in struct eeh_dev to access
  * @_format: printf format for display
  *
  * All of the attributes look very similar, so just
@@ -75,7 +75,7 @@ static ssize_t eeh_pe_state_store(struct device *dev,
 
 static DEVICE_ATTR_RW(eeh_pe_state);
 
-#ifdef CONFIG_PCI_IOV
+#if defined(CONFIG_PCI_IOV) && defined(CONFIG_PPC_PSERIES)
 static ssize_t eeh_notify_resume_show(struct device *dev,
                                      struct device_attribute *attr, char *buf)
 {
@@ -86,7 +86,6 @@ static ssize_t eeh_notify_resume_show(struct device *dev,
        if (!edev || !edev->pe)
                return -ENODEV;
 
-       pdn = pci_get_pdn(pdev);
        return sprintf(buf, "%d\n", pdn->last_allow_rc);
 }
 
@@ -132,7 +131,7 @@ static void eeh_notify_resume_remove(struct pci_dev *pdev)
 #else
 static inline int eeh_notify_resume_add(struct pci_dev *pdev) { return 0; }
 static inline void eeh_notify_resume_remove(struct pci_dev *pdev) { }
-#endif /* CONFIG_PCI_IOV */
+#endif /* CONFIG_PCI_IOV && CONFIG PPC_PSERIES*/
 
 void eeh_sysfs_add_device(struct pci_dev *pdev)
 {
@@ -160,22 +159,23 @@ void eeh_sysfs_remove_device(struct pci_dev *pdev)
 {
        struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
 
+       if (!edev) {
+               WARN_ON(eeh_enabled());
+               return;
+       }
+
+       edev->mode &= ~EEH_DEV_SYSFS;
+
        /*
         * The parent directory might have been removed. We needn't
         * continue for that case.
         */
-       if (!pdev->dev.kobj.sd) {
-               if (edev)
-                       edev->mode &= ~EEH_DEV_SYSFS;
+       if (!pdev->dev.kobj.sd)
                return;
-       }
 
        device_remove_file(&pdev->dev, &dev_attr_eeh_mode);
        device_remove_file(&pdev->dev, &dev_attr_eeh_pe_config_addr);
        device_remove_file(&pdev->dev, &dev_attr_eeh_pe_state);
 
        eeh_notify_resume_remove(pdev);
-
-       if (edev)
-               edev->mode &= ~EEH_DEV_SYSFS;
 }
index e1a4c39..0713daa 100644 (file)
@@ -140,6 +140,7 @@ transfer_to_handler:
        stw     r12,_CTR(r11)
        stw     r2,_XER(r11)
        mfspr   r12,SPRN_SPRG_THREAD
+       tovirt_vmstack r12, r12
        beq     2f                      /* if from user, fix up THREAD.regs */
        addi    r2, r12, -THREAD
        addi    r11,r1,STACK_FRAME_OVERHEAD
@@ -179,11 +180,13 @@ transfer_to_handler:
 2:     /* if from kernel, check interrupted DOZE/NAP mode and
          * check for stack overflow
          */
-       kuap_save_and_lock r11, r12, r9, r2, r0
+       kuap_save_and_lock r11, r12, r9, r2, r6
        addi    r2, r12, -THREAD
+#ifndef CONFIG_VMAP_STACK
        lwz     r9,KSP_LIMIT(r12)
        cmplw   r1,r9                   /* if r1 <= ksp_limit */
        ble-    stack_ovf               /* then the kernel stack overflowed */
+#endif
 5:
 #if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_E500)
        lwz     r12,TI_LOCAL_FLAGS(r2)
@@ -195,7 +198,8 @@ transfer_to_handler:
 transfer_to_handler_cont:
 3:
        mflr    r9
-       tovirt(r2, r2)                  /* set r2 to current */
+       tovirt_novmstack r2, r2         /* set r2 to current */
+       tovirt_vmstack r9, r9
        lwz     r11,0(r9)               /* virtual address of handler */
        lwz     r9,4(r9)                /* where to go when done */
 #if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
@@ -210,7 +214,7 @@ transfer_to_handler_cont:
         * To speed up the syscall path where interrupts stay on, let's check
         * first if we are changing the MSR value at all.
         */
-       tophys(r12, r1)
+       tophys_novmstack r12, r1
        lwz     r12,_MSR(r12)
        andi.   r12,r12,MSR_EE
        bne     1f
@@ -284,9 +288,11 @@ reenable_mmu:
        rlwinm  r9,r9,0,~MSR_EE
        lwz     r12,_LINK(r11)          /* and return to address in LR */
        kuap_restore r11, r2, r3, r4, r5
+       lwz     r2, GPR2(r11)
        b       fast_exception_return
 #endif
 
+#ifndef CONFIG_VMAP_STACK
 /*
  * On kernel stack overflow, load up an initial stack pointer
  * and call StackOverflow(regs), which should not return.
@@ -312,6 +318,7 @@ stack_ovf:
        mtspr   SPRN_SRR1,r10
        SYNC
        RFI
+#endif
 
 #ifdef CONFIG_TRACE_IRQFLAGS
 trace_syscall_entry_irq_off:
@@ -397,7 +404,7 @@ ret_from_syscall:
        LOAD_REG_IMMEDIATE(r10,MSR_KERNEL)      /* doesn't include MSR_EE */
        /* Note: We don't bother telling lockdep about it */
        SYNC
-       MTMSRD(r10)
+       mtmsr   r10
        lwz     r9,TI_FLAGS(r2)
        li      r8,-MAX_ERRNO
        andi.   r0,r9,(_TIF_SYSCALL_DOTRACE|_TIF_SINGLESTEP|_TIF_USER_WORK_MASK|_TIF_PERSYSCALL_MASK)
@@ -554,7 +561,7 @@ syscall_exit_work:
         */
        ori     r10,r10,MSR_EE
        SYNC
-       MTMSRD(r10)
+       mtmsr   r10
 
        /* Save NVGPRS if they're not saved already */
        lwz     r4,_TRAP(r1)
@@ -621,7 +628,6 @@ ppc_swapcontext:
  */
        .globl  handle_page_fault
 handle_page_fault:
-       stw     r4,_DAR(r1)
        addi    r3,r1,STACK_FRAME_OVERHEAD
 #ifdef CONFIG_PPC_BOOK3S_32
        andis.  r0,r5,DSISR_DABRMATCH@h
@@ -697,7 +703,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPE)
        and.    r0,r0,r11       /* FP or altivec or SPE enabled? */
        beq+    1f
        andc    r11,r11,r0
-       MTMSRD(r11)
+       mtmsr   r11
        isync
 1:     stw     r11,_MSR(r1)
        mfcr    r10
@@ -831,7 +837,7 @@ ret_from_except:
        /* Note: We don't bother telling lockdep about it */
        LOAD_REG_IMMEDIATE(r10,MSR_KERNEL)
        SYNC                    /* Some chip revs have problems here... */
-       MTMSRD(r10)             /* disable interrupts */
+       mtmsr   r10             /* disable interrupts */
 
        lwz     r3,_MSR(r1)     /* Returning to user mode? */
        andi.   r0,r3,MSR_PR
@@ -998,7 +1004,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_NEED_PAIRED_STWCX)
         */
        LOAD_REG_IMMEDIATE(r10,MSR_KERNEL & ~MSR_RI)
        SYNC
-       MTMSRD(r10)             /* clear the RI bit */
+       mtmsr   r10             /* clear the RI bit */
        .globl exc_exit_restart
 exc_exit_restart:
        lwz     r12,_NIP(r1)
@@ -1234,7 +1240,7 @@ do_resched:                       /* r10 contains MSR_KERNEL here */
 #endif
        ori     r10,r10,MSR_EE
        SYNC
-       MTMSRD(r10)             /* hard-enable interrupts */
+       mtmsr   r10             /* hard-enable interrupts */
        bl      schedule
 recheck:
        /* Note: And we don't tell it we are disabling them again
@@ -1243,7 +1249,7 @@ recheck:
         */
        LOAD_REG_IMMEDIATE(r10,MSR_KERNEL)
        SYNC
-       MTMSRD(r10)             /* disable interrupts */
+       mtmsr   r10             /* disable interrupts */
        lwz     r9,TI_FLAGS(r2)
        andi.   r0,r9,_TIF_NEED_RESCHED
        bne-    do_resched
@@ -1252,7 +1258,7 @@ recheck:
 do_user_signal:                        /* r10 contains MSR_KERNEL here */
        ori     r10,r10,MSR_EE
        SYNC
-       MTMSRD(r10)             /* hard-enable interrupts */
+       mtmsr   r10             /* hard-enable interrupts */
        /* save r13-r31 in the exception frame, if not already done */
        lwz     r3,_TRAP(r1)
        andi.   r0,r3,1
@@ -1334,14 +1340,14 @@ _GLOBAL(enter_rtas)
        lis     r6,1f@ha        /* physical return address for rtas */
        addi    r6,r6,1f@l
        tophys(r6,r6)
-       tophys(r7,r1)
+       tophys_novmstack r7, r1
        lwz     r8,RTASENTRY(r4)
        lwz     r4,RTASBASE(r4)
        mfmsr   r9
        stw     r9,8(r1)
        LOAD_REG_IMMEDIATE(r0,MSR_KERNEL)
        SYNC                    /* disable interrupts so SRR0/1 */
-       MTMSRD(r0)              /* don't get trashed */
+       mtmsr   r0              /* don't get trashed */
        li      r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
        mtlr    r6
        stw     r7, THREAD + RTAS_SP(r2)
index a9a1d3c..6ba675b 100644 (file)
@@ -597,8 +597,7 @@ _GLOBAL(_switch)
        std     r0,16(r1)
        stdu    r1,-SWITCH_FRAME_SIZE(r1)
        /* r3-r13 are caller saved -- Cort */
-       SAVE_8GPRS(14, r1)
-       SAVE_10GPRS(22, r1)
+       SAVE_NVGPRS(r1)
        std     r0,_NIP(r1)     /* Return to switch caller */
        mfcr    r23
        std     r23,_CCR(r1)
@@ -722,8 +721,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
        mtcrf   0xFF,r6
 
        /* r3-r13 are destroyed -- Cort */
-       REST_8GPRS(14, r1)
-       REST_10GPRS(22, r1)
+       REST_NVGPRS(r1)
 
        /* convert old thread to its task_struct for return value */
        addi    r3,r3,-THREAD
@@ -1155,8 +1153,7 @@ _GLOBAL(enter_rtas)
         */
        SAVE_GPR(2, r1)                 /* Save the TOC */
        SAVE_GPR(13, r1)                /* Save paca */
-       SAVE_8GPRS(14, r1)              /* Save the non-volatiles */
-       SAVE_10GPRS(22, r1)             /* ditto */
+       SAVE_NVGPRS(r1)                 /* Save the non-volatiles */
 
        mfcr    r4
        std     r4,_CCR(r1)
@@ -1263,8 +1260,7 @@ rtas_restore_regs:
        /* relocation is on at this point */
        REST_GPR(2, r1)                 /* Restore the TOC */
        REST_GPR(13, r1)                /* Restore paca */
-       REST_8GPRS(14, r1)              /* Restore the non-volatiles */
-       REST_10GPRS(22, r1)             /* ditto */
+       REST_NVGPRS(r1)                 /* Restore the non-volatiles */
 
        GET_PACA(r13)
 
@@ -1298,8 +1294,7 @@ _GLOBAL(enter_prom)
         */
        SAVE_GPR(2, r1)
        SAVE_GPR(13, r1)
-       SAVE_8GPRS(14, r1)
-       SAVE_10GPRS(22, r1)
+       SAVE_NVGPRS(r1)
        mfcr    r10
        mfmsr   r11
        std     r10,_CCR(r1)
@@ -1343,8 +1338,7 @@ _GLOBAL(enter_prom)
        /* Restore other registers */
        REST_GPR(2, r1)
        REST_GPR(13, r1)
-       REST_8GPRS(14, r1)
-       REST_10GPRS(22, r1)
+       REST_NVGPRS(r1)
        ld      r4,_CCR(r1)
        mtcr    r4
 
index 46508b1..ffc15f4 100644 (file)
@@ -1408,22 +1408,9 @@ EXC_VIRT_NONE(0x4b00, 0x100)
  *
  * Call convention:
  *
- * syscall register convention is in Documentation/powerpc/syscall64-abi.rst
- *
- * For hypercalls, the register convention is as follows:
- * r0 volatile
- * r1-2 nonvolatile
- * r3 volatile parameter and return value for status
- * r4-r10 volatile input and output value
- * r11 volatile hypercall number and output value
- * r12 volatile input and output value
- * r13-r31 nonvolatile
- * LR nonvolatile
- * CTR volatile
- * XER volatile
- * CR0-1 CR5-7 volatile
- * CR2-4 nonvolatile
- * Other registers nonvolatile
+ * syscall and hypercalls register conventions are documented in
+ * Documentation/powerpc/syscall64-abi.rst and
+ * Documentation/powerpc/papr_hcalls.rst respectively.
  *
  * The intersection of volatile registers that don't contain possible
  * inputs is: cr0, xer, ctr. We may use these as scratch regs upon entry
@@ -2208,11 +2195,20 @@ __end_interrupts:
 DEFINE_FIXED_SYMBOL(__end_interrupts)
 
 #ifdef CONFIG_PPC_970_NAP
+       /*
+        * Called by exception entry code if _TLF_NAPPING was set, this clears
+        * the NAPPING flag, and redirects the exception exit to
+        * power4_fixup_nap_return.
+        */
+       .globl power4_fixup_nap
 EXC_COMMON_BEGIN(power4_fixup_nap)
        andc    r9,r9,r10
        std     r9,TI_LOCAL_FLAGS(r11)
-       ld      r10,_LINK(r1)           /* make idle task do the */
-       std     r10,_NIP(r1)            /* equivalent of a blr */
+       LOAD_REG_ADDR(r10, power4_idle_nap_return)
+       std     r10,_NIP(r1)
+       blr
+
+power4_idle_nap_return:
        blr
 #endif
 
index 0bb991d..3235a8d 100644 (file)
@@ -94,6 +94,9 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
        /* enable use of FP after return */
 #ifdef CONFIG_PPC32
        mfspr   r5,SPRN_SPRG_THREAD     /* current task's THREAD (phys) */
+#ifdef CONFIG_VMAP_STACK
+       tovirt(r5, r5)
+#endif
        lwz     r4,THREAD_FPEXC_MODE(r5)
        ori     r9,r9,MSR_FP            /* enable FP for current */
        or      r9,r9,r4
index 4a24f8f..0493fca 100644 (file)
@@ -272,16 +272,21 @@ __secondary_hold_acknowledge:
  */
        . = 0x200
        DO_KVM  0x200
-       mtspr   SPRN_SPRG_SCRATCH0,r10
-       mtspr   SPRN_SPRG_SCRATCH1,r11
-       mfcr    r10
+MachineCheck:
+       EXCEPTION_PROLOG_0
+#ifdef CONFIG_VMAP_STACK
+       li      r11, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */
+       mtmsr   r11
+       isync
+#endif
 #ifdef CONFIG_PPC_CHRP
        mfspr   r11, SPRN_SPRG_THREAD
+       tovirt_vmstack r11, r11
        lwz     r11, RTAS_SP(r11)
        cmpwi   cr1, r11, 0
        bne     cr1, 7f
 #endif /* CONFIG_PPC_CHRP */
-       EXCEPTION_PROLOG_1
+       EXCEPTION_PROLOG_1 for_rtas=1
 7:     EXCEPTION_PROLOG_2
        addi    r3,r1,STACK_FRAME_OVERHEAD
 #ifdef CONFIG_PPC_CHRP
@@ -296,24 +301,21 @@ __secondary_hold_acknowledge:
        . = 0x300
        DO_KVM  0x300
 DataAccess:
-       EXCEPTION_PROLOG
-       mfspr   r10,SPRN_DSISR
-       stw     r10,_DSISR(r11)
+       EXCEPTION_PROLOG handle_dar_dsisr=1
+       get_and_save_dar_dsisr_on_stack r4, r5, r11
+BEGIN_MMU_FTR_SECTION
 #ifdef CONFIG_PPC_KUAP
-       andis.  r0,r10,(DSISR_BAD_FAULT_32S | DSISR_DABRMATCH | DSISR_PROTFAULT)@h
+       andis.  r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH | DSISR_PROTFAULT)@h
 #else
-       andis.  r0,r10,(DSISR_BAD_FAULT_32S|DSISR_DABRMATCH)@h
+       andis.  r0, r5, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h
 #endif
-       bne     1f                      /* if not, try to put a PTE */
-       mfspr   r4,SPRN_DAR             /* into the hash table */
-       rlwinm  r3,r10,32-15,21,21      /* DSISR_STORE -> _PAGE_RW */
-BEGIN_MMU_FTR_SECTION
+       bne     handle_page_fault_tramp_2       /* if not, try to put a PTE */
+       rlwinm  r3, r5, 32 - 15, 21, 21         /* DSISR_STORE -> _PAGE_RW */
        bl      hash_page
-END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
-1:     lwz     r5,_DSISR(r11)          /* get DSISR value */
-       mfspr   r4,SPRN_DAR
-       EXC_XFER_LITE(0x300, handle_page_fault)
-
+       b       handle_page_fault_tramp_1
+FTR_SECTION_ELSE
+       b       handle_page_fault_tramp_2
+ALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE)
 
 /* Instruction access exception. */
        . = 0x400
@@ -329,6 +331,7 @@ BEGIN_MMU_FTR_SECTION
 END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
 1:     mr      r4,r12
        andis.  r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */
+       stw     r4, _DAR(r11)
        EXC_XFER_LITE(0x400, handle_page_fault)
 
 /* External interrupt */
@@ -338,11 +341,8 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
        . = 0x600
        DO_KVM  0x600
 Alignment:
-       EXCEPTION_PROLOG
-       mfspr   r4,SPRN_DAR
-       stw     r4,_DAR(r11)
-       mfspr   r5,SPRN_DSISR
-       stw     r5,_DSISR(r11)
+       EXCEPTION_PROLOG handle_dar_dsisr=1
+       save_dar_dsisr_on_stack r4, r5, r11
        addi    r3,r1,STACK_FRAME_OVERHEAD
        EXC_XFER_STD(0x600, alignment_exception)
 
@@ -645,6 +645,16 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
 
        . = 0x3000
 
+handle_page_fault_tramp_1:
+       lwz     r4, _DAR(r11)
+       lwz     r5, _DSISR(r11)
+       /* fall through */
+handle_page_fault_tramp_2:
+       EXC_XFER_LITE(0x300, handle_page_fault)
+
+stack_overflow:
+       vmap_stack_overflow_exception
+
 AltiVecUnavailable:
        EXCEPTION_PROLOG
 #ifdef CONFIG_ALTIVEC
@@ -917,6 +927,8 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE)
        ori     r4,r4,2f@l
        tophys(r4,r4)
        li      r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
+
+       .align  4
        mtspr   SPRN_SRR0,r4
        mtspr   SPRN_SRR1,r3
        SYNC
@@ -1058,6 +1070,8 @@ _ENTRY(update_bats)
        rlwinm  r0, r6, 0, ~MSR_RI
        rlwinm  r0, r0, 0, ~MSR_EE
        mtmsr   r0
+
+       .align  4
        mtspr   SPRN_SRR0, r4
        mtspr   SPRN_SRR1, r3
        SYNC
@@ -1097,6 +1111,8 @@ mmu_off:
        andi.   r0,r3,MSR_DR|MSR_IR             /* MMU enabled? */
        beqlr
        andc    r3,r3,r0
+
+       .align  4
        mtspr   SPRN_SRR0,r4
        mtspr   SPRN_SRR1,r3
        sync
index 8abc778..a6a5fbb 100644 (file)
  * We assume sprg3 has the physical address of the current
  * task's thread_struct.
  */
+.macro EXCEPTION_PROLOG handle_dar_dsisr=0
+       EXCEPTION_PROLOG_0      handle_dar_dsisr=\handle_dar_dsisr
+       EXCEPTION_PROLOG_1
+       EXCEPTION_PROLOG_2      handle_dar_dsisr=\handle_dar_dsisr
+.endm
 
-.macro EXCEPTION_PROLOG
+.macro EXCEPTION_PROLOG_0 handle_dar_dsisr=0
        mtspr   SPRN_SPRG_SCRATCH0,r10
        mtspr   SPRN_SPRG_SCRATCH1,r11
+#ifdef CONFIG_VMAP_STACK
+       mfspr   r10, SPRN_SPRG_THREAD
+       .if     \handle_dar_dsisr
+       mfspr   r11, SPRN_DAR
+       stw     r11, DAR(r10)
+       mfspr   r11, SPRN_DSISR
+       stw     r11, DSISR(r10)
+       .endif
+       mfspr   r11, SPRN_SRR0
+       stw     r11, SRR0(r10)
+#endif
+       mfspr   r11, SPRN_SRR1          /* check whether user or kernel */
+#ifdef CONFIG_VMAP_STACK
+       stw     r11, SRR1(r10)
+#endif
        mfcr    r10
-       EXCEPTION_PROLOG_1
-       EXCEPTION_PROLOG_2
+       andi.   r11, r11, MSR_PR
 .endm
 
-.macro EXCEPTION_PROLOG_1
-       mfspr   r11,SPRN_SRR1           /* check whether user or kernel */
-       andi.   r11,r11,MSR_PR
+.macro EXCEPTION_PROLOG_1 for_rtas=0
+#ifdef CONFIG_VMAP_STACK
+       .ifeq   \for_rtas
+       li      r11, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */
+       mtmsr   r11
+       isync
+       .endif
+       subi    r11, r1, INT_FRAME_SIZE         /* use r1 if kernel */
+#else
        tophys(r11,r1)                  /* use tophys(r1) if kernel */
+       subi    r11, r11, INT_FRAME_SIZE        /* alloc exc. frame */
+#endif
        beq     1f
        mfspr   r11,SPRN_SPRG_THREAD
+       tovirt_vmstack r11, r11
        lwz     r11,TASK_STACK-THREAD(r11)
-       addi    r11,r11,THREAD_SIZE
-       tophys(r11,r11)
-1:     subi    r11,r11,INT_FRAME_SIZE  /* alloc exc. frame */
+       addi    r11, r11, THREAD_SIZE - INT_FRAME_SIZE
+       tophys_novmstack r11, r11
+1:
+#ifdef CONFIG_VMAP_STACK
+       mtcrf   0x7f, r11
+       bt      32 - THREAD_ALIGN_SHIFT, stack_overflow
+#endif
 .endm
 
-.macro EXCEPTION_PROLOG_2
+.macro EXCEPTION_PROLOG_2 handle_dar_dsisr=0
        stw     r10,_CCR(r11)           /* save registers */
        stw     r12,GPR12(r11)
        stw     r9,GPR9(r11)
        stw     r12,GPR11(r11)
        mflr    r10
        stw     r10,_LINK(r11)
+#ifdef CONFIG_VMAP_STACK
+       mfspr   r12, SPRN_SPRG_THREAD
+       tovirt(r12, r12)
+       .if     \handle_dar_dsisr
+       lwz     r10, DAR(r12)
+       stw     r10, _DAR(r11)
+       lwz     r10, DSISR(r12)
+       stw     r10, _DSISR(r11)
+       .endif
+       lwz     r9, SRR1(r12)
+       lwz     r12, SRR0(r12)
+#else
        mfspr   r12,SPRN_SRR0
        mfspr   r9,SPRN_SRR1
+#endif
        stw     r1,GPR1(r11)
        stw     r1,0(r11)
-       tovirt(r1,r11)                  /* set new kernel sp */
+       tovirt_novmstack r1, r11        /* set new kernel sp */
 #ifdef CONFIG_40x
        rlwinm  r9,r9,0,14,12           /* clear MSR_WE (necessary?) */
 #else
+#ifdef CONFIG_VMAP_STACK
+       li      r10, MSR_KERNEL & ~MSR_IR /* can take exceptions */
+#else
        li      r10,MSR_KERNEL & ~(MSR_IR|MSR_DR) /* can take exceptions */
-       MTMSRD(r10)                     /* (except for mach check in rtas) */
+#endif
+       mtmsr   r10                     /* (except for mach check in rtas) */
 #endif
        stw     r0,GPR0(r11)
        lis     r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
 
 .macro SYSCALL_ENTRY trapno
        mfspr   r12,SPRN_SPRG_THREAD
+#ifdef CONFIG_VMAP_STACK
+       mfspr   r9, SPRN_SRR0
+       mfspr   r11, SPRN_SRR1
+       stw     r9, SRR0(r12)
+       stw     r11, SRR1(r12)
+#endif
        mfcr    r10
        lwz     r11,TASK_STACK-THREAD(r12)
-       mflr    r9
-       addi    r11,r11,THREAD_SIZE - INT_FRAME_SIZE
        rlwinm  r10,r10,0,4,2   /* Clear SO bit in CR */
-       tophys(r11,r11)
+       addi    r11, r11, THREAD_SIZE - INT_FRAME_SIZE
+#ifdef CONFIG_VMAP_STACK
+       li      r9, MSR_KERNEL & ~(MSR_IR | MSR_RI) /* can take DTLB miss */
+       mtmsr   r9
+       isync
+#endif
+       tovirt_vmstack r12, r12
+       tophys_novmstack r11, r11
+       mflr    r9
        stw     r10,_CCR(r11)           /* save registers */
+       stw     r9, _LINK(r11)
+#ifdef CONFIG_VMAP_STACK
+       lwz     r10, SRR0(r12)
+       lwz     r9, SRR1(r12)
+#else
        mfspr   r10,SPRN_SRR0
-       stw     r9,_LINK(r11)
        mfspr   r9,SPRN_SRR1
+#endif
        stw     r1,GPR1(r11)
        stw     r1,0(r11)
-       tovirt(r1,r11)                  /* set new kernel sp */
+       tovirt_novmstack r1, r11        /* set new kernel sp */
        stw     r10,_NIP(r11)
 #ifdef CONFIG_40x
        rlwinm  r9,r9,0,14,12           /* clear MSR_WE (necessary?) */
 #else
+#ifdef CONFIG_VMAP_STACK
+       LOAD_REG_IMMEDIATE(r10, MSR_KERNEL & ~MSR_IR) /* can take exceptions */
+#else
        LOAD_REG_IMMEDIATE(r10, MSR_KERNEL & ~(MSR_IR|MSR_DR)) /* can take exceptions */
-       MTMSRD(r10)                     /* (except for mach check in rtas) */
+#endif
+       mtmsr   r10                     /* (except for mach check in rtas) */
 #endif
        lis     r10,STACK_FRAME_REGS_MARKER@ha /* exception frame marker */
        stw     r2,GPR2(r11)
 #endif
 
 3:
-       tovirt(r2, r2)                  /* set r2 to current */
+       tovirt_novmstack r2, r2         /* set r2 to current */
        lis     r11, transfer_to_syscall@h
        ori     r11, r11, transfer_to_syscall@l
 #ifdef CONFIG_TRACE_IRQFLAGS
        RFI                             /* jump to handler, enable MMU */
 .endm
 
+.macro save_dar_dsisr_on_stack reg1, reg2, sp
+#ifndef CONFIG_VMAP_STACK
+       mfspr   \reg1, SPRN_DAR
+       mfspr   \reg2, SPRN_DSISR
+       stw     \reg1, _DAR(\sp)
+       stw     \reg2, _DSISR(\sp)
+#endif
+.endm
+
+.macro get_and_save_dar_dsisr_on_stack reg1, reg2, sp
+#ifdef CONFIG_VMAP_STACK
+       lwz     \reg1, _DAR(\sp)
+       lwz     \reg2, _DSISR(\sp)
+#else
+       save_dar_dsisr_on_stack \reg1, \reg2, \sp
+#endif
+.endm
+
+.macro tovirt_vmstack dst, src
+#ifdef CONFIG_VMAP_STACK
+       tovirt(\dst, \src)
+#else
+       .ifnc   \dst, \src
+       mr      \dst, \src
+       .endif
+#endif
+.endm
+
+.macro tovirt_novmstack dst, src
+#ifndef CONFIG_VMAP_STACK
+       tovirt(\dst, \src)
+#else
+       .ifnc   \dst, \src
+       mr      \dst, \src
+       .endif
+#endif
+.endm
+
+.macro tophys_novmstack dst, src
+#ifndef CONFIG_VMAP_STACK
+       tophys(\dst, \src)
+#else
+       .ifnc   \dst, \src
+       mr      \dst, \src
+       .endif
+#endif
+.endm
+
 /*
  * Note: code which follows this uses cr0.eq (set if from kernel),
  * r11, r12 (SRR0), and r9 (SRR1).
@@ -187,4 +305,28 @@ label:
        EXC_XFER_TEMPLATE(hdlr, n+1, MSR_KERNEL, transfer_to_handler, \
                          ret_from_except)
 
+.macro vmap_stack_overflow_exception
+#ifdef CONFIG_VMAP_STACK
+#ifdef CONFIG_SMP
+       mfspr   r11, SPRN_SPRG_THREAD
+       tovirt(r11, r11)
+       lwz     r11, TASK_CPU - THREAD(r11)
+       slwi    r11, r11, 3
+       addis   r11, r11, emergency_ctx@ha
+#else
+       lis     r11, emergency_ctx@ha
+#endif
+       lwz     r11, emergency_ctx@l(r11)
+       cmpwi   cr1, r11, 0
+       bne     cr1, 1f
+       lis     r11, init_thread_union@ha
+       addi    r11, r11, init_thread_union@l
+1:     addi    r11, r11, THREAD_SIZE - INT_FRAME_SIZE
+       EXCEPTION_PROLOG_2
+       SAVE_NVGPRS(r11)
+       addi    r3, r1, STACK_FRAME_OVERHEAD
+       EXC_XFER_STD(0, stack_overflow_exception)
+#endif
+.endm
+
 #endif /* __HEAD_32_H__ */
index 585ea19..9bb6639 100644 (file)
@@ -313,6 +313,7 @@ _ENTRY(saved_ksp_limit)
        START_EXCEPTION(0x0400, InstructionAccess)
        EXCEPTION_PROLOG
        mr      r4,r12                  /* Pass SRR0 as arg2 */
+       stw     r4, _DEAR(r11)
        li      r5,0                    /* Pass zero as arg3 */
        EXC_XFER_LITE(0x400, handle_page_fault)
 
@@ -676,6 +677,7 @@ DataAccess:
        mfspr   r5,SPRN_ESR             /* Grab the ESR, save it, pass arg3 */
        stw     r5,_ESR(r11)
        mfspr   r4,SPRN_DEAR            /* Grab the DEAR, save it, pass arg2 */
+       stw     r4, _DEAR(r11)
        EXC_XFER_LITE(0x300, handle_page_fault)
 
 /* Other PowerPC processors, namely those derived from the 6xx-series
index 19f583e..9922306 100644 (file)
@@ -127,56 +127,36 @@ instruction_counter:
 /* Machine check */
        . = 0x200
 MachineCheck:
-       EXCEPTION_PROLOG
-       mfspr r4,SPRN_DAR
-       stw r4,_DAR(r11)
-       li r5,RPN_PATTERN
-       mtspr SPRN_DAR,r5       /* Tag DAR, to be used in DTLB Error */
-       mfspr r5,SPRN_DSISR
-       stw r5,_DSISR(r11)
+       EXCEPTION_PROLOG handle_dar_dsisr=1
+       save_dar_dsisr_on_stack r4, r5, r11
+       li      r6, RPN_PATTERN
+       mtspr   SPRN_DAR, r6    /* Tag DAR, to be used in DTLB Error */
        addi r3,r1,STACK_FRAME_OVERHEAD
        EXC_XFER_STD(0x200, machine_check_exception)
 
-/* Data access exception.
- * This is "never generated" by the MPC8xx.
- */
-       . = 0x300
-DataAccess:
-
-/* Instruction access exception.
- * This is "never generated" by the MPC8xx.
- */
-       . = 0x400
-InstructionAccess:
-
 /* External interrupt */
        EXCEPTION(0x500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
 
 /* Alignment exception */
        . = 0x600
 Alignment:
-       EXCEPTION_PROLOG
-       mfspr   r4,SPRN_DAR
-       stw     r4,_DAR(r11)
-       li      r5,RPN_PATTERN
-       mtspr   SPRN_DAR,r5     /* Tag DAR, to be used in DTLB Error */
-       mfspr   r5,SPRN_DSISR
-       stw     r5,_DSISR(r11)
+       EXCEPTION_PROLOG handle_dar_dsisr=1
+       save_dar_dsisr_on_stack r4, r5, r11
+       li      r6, RPN_PATTERN
+       mtspr   SPRN_DAR, r6    /* Tag DAR, to be used in DTLB Error */
        addi    r3,r1,STACK_FRAME_OVERHEAD
-       EXC_XFER_STD(0x600, alignment_exception)
+       b       .Lalignment_exception_ool
 
 /* Program check exception */
        EXCEPTION(0x700, ProgramCheck, program_check_exception, EXC_XFER_STD)
 
-/* No FPU on MPC8xx.  This exception is not supposed to happen.
-*/
-       EXCEPTION(0x800, FPUnavailable, unknown_exception, EXC_XFER_STD)
-
 /* Decrementer */
        EXCEPTION(0x900, Decrementer, timer_interrupt, EXC_XFER_LITE)
 
-       EXCEPTION(0xa00, Trap_0a, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0xb00, Trap_0b, unknown_exception, EXC_XFER_STD)
+       /* With VMAP_STACK there's not enough room for this at 0x600 */
+       . = 0xa00
+.Lalignment_exception_ool:
+       EXC_XFER_STD(0x600, alignment_exception)
 
 /* System call */
        . = 0xc00
@@ -185,25 +165,12 @@ SystemCall:
 
 /* Single step - not used on 601 */
        EXCEPTION(0xd00, SingleStep, single_step_exception, EXC_XFER_STD)
-       EXCEPTION(0xe00, Trap_0e, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0xf00, Trap_0f, unknown_exception, EXC_XFER_STD)
 
 /* On the MPC8xx, this is a software emulation interrupt.  It occurs
  * for all unimplemented and illegal instructions.
  */
        EXCEPTION(0x1000, SoftEmu, program_check_exception, EXC_XFER_STD)
 
-/* Called from DataStoreTLBMiss when perf TLB misses events are activated */
-#ifdef CONFIG_PERF_EVENTS
-       patch_site      0f, patch__dtlbmiss_perf
-0:     lwz     r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0)
-       addi    r10, r10, 1
-       stw     r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0)
-       mfspr   r10, SPRN_SPRG_SCRATCH0
-       mfspr   r11, SPRN_SPRG_SCRATCH1
-       rfi
-#endif
-
        . = 0x1100
 /*
  * For the MPC8xx, this is a software tablewalk to load the instruction
@@ -343,8 +310,8 @@ ITLBMissLinear:
 
        . = 0x1200
 DataStoreTLBMiss:
-       mtspr   SPRN_SPRG_SCRATCH0, r10
-       mtspr   SPRN_SPRG_SCRATCH1, r11
+       mtspr   SPRN_DAR, r10
+       mtspr   SPRN_M_TW, r11
        mfcr    r11
 
        /* If we are faulting a kernel address, we have to use the
@@ -409,10 +376,10 @@ DataStoreTLBMiss:
        mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
 
        /* Restore registers */
-       mtspr   SPRN_DAR, r11   /* Tag DAR */
 
-0:     mfspr   r10, SPRN_SPRG_SCRATCH0
-       mfspr   r11, SPRN_SPRG_SCRATCH1
+0:     mfspr   r10, SPRN_DAR
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
+       mfspr   r11, SPRN_M_TW
        rfi
        patch_site      0b, patch__dtlbmiss_exit_1
 
@@ -428,10 +395,10 @@ DTLBMissIMMR:
        mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
 
        li      r11, RPN_PATTERN
-       mtspr   SPRN_DAR, r11   /* Tag DAR */
 
-0:     mfspr   r10, SPRN_SPRG_SCRATCH0
-       mfspr   r11, SPRN_SPRG_SCRATCH1
+0:     mfspr   r10, SPRN_DAR
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
+       mfspr   r11, SPRN_M_TW
        rfi
        patch_site      0b, patch__dtlbmiss_exit_2
 
@@ -465,10 +432,10 @@ DTLBMissLinear:
        mtspr   SPRN_MD_RPN, r10        /* Update TLB entry */
 
        li      r11, RPN_PATTERN
-       mtspr   SPRN_DAR, r11   /* Tag DAR */
 
-0:     mfspr   r10, SPRN_SPRG_SCRATCH0
-       mfspr   r11, SPRN_SPRG_SCRATCH1
+0:     mfspr   r10, SPRN_DAR
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
+       mfspr   r11, SPRN_M_TW
        rfi
        patch_site      0b, patch__dtlbmiss_exit_3
 
@@ -486,6 +453,7 @@ InstructionTLBError:
        tlbie   r4
        /* 0x400 is InstructionAccess exception, needed by bad_page_fault() */
 .Litlbie:
+       stw     r4, _DAR(r11)
        EXC_XFER_LITE(0x400, handle_page_fault)
 
 /* This is the data TLB error on the MPC8xx.  This could be due to
@@ -494,58 +462,69 @@ InstructionTLBError:
  */
        . = 0x1400
 DataTLBError:
-       mtspr   SPRN_SPRG_SCRATCH0, r10
-       mtspr   SPRN_SPRG_SCRATCH1, r11
-       mfcr    r10
-
+       EXCEPTION_PROLOG_0 handle_dar_dsisr=1
        mfspr   r11, SPRN_DAR
-       cmpwi   cr0, r11, RPN_PATTERN
-       beq-    FixupDAR        /* must be a buggy dcbX, icbi insn. */
+       cmpwi   cr1, r11, RPN_PATTERN
+       beq-    cr1, FixupDAR   /* must be a buggy dcbX, icbi insn. */
 DARFixed:/* Return from dcbx instruction bug workaround */
+#ifdef CONFIG_VMAP_STACK
+       li      r11, RPN_PATTERN
+       mtspr   SPRN_DAR, r11   /* Tag DAR, to be used in DTLB Error */
+#endif
        EXCEPTION_PROLOG_1
-       EXCEPTION_PROLOG_2
-       mfspr   r5,SPRN_DSISR
-       stw     r5,_DSISR(r11)
-       mfspr   r4,SPRN_DAR
+       EXCEPTION_PROLOG_2 handle_dar_dsisr=1
+       get_and_save_dar_dsisr_on_stack r4, r5, r11
        andis.  r10,r5,DSISR_NOHPTE@h
        beq+    .Ldtlbie
        tlbie   r4
 .Ldtlbie:
+#ifndef CONFIG_VMAP_STACK
        li      r10,RPN_PATTERN
        mtspr   SPRN_DAR,r10    /* Tag DAR, to be used in DTLB Error */
+#endif
        /* 0x300 is DataAccess exception, needed by bad_page_fault() */
        EXC_XFER_LITE(0x300, handle_page_fault)
 
-       EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1a00, Trap_1a, unknown_exception, EXC_XFER_STD)
-       EXCEPTION(0x1b00, Trap_1b, unknown_exception, EXC_XFER_STD)
+/* Called from DataStoreTLBMiss when perf TLB misses events are activated */
+#ifdef CONFIG_PERF_EVENTS
+       patch_site      0f, patch__dtlbmiss_perf
+0:     lwz     r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0)
+       addi    r10, r10, 1
+       stw     r10, (dtlb_miss_counter - PAGE_OFFSET)@l(0)
+       mfspr   r10, SPRN_DAR
+       mtspr   SPRN_DAR, r11   /* Tag DAR */
+       mfspr   r11, SPRN_M_TW
+       rfi
+#endif
+
+stack_overflow:
+       vmap_stack_overflow_exception
 
 /* On the MPC8xx, these next four traps are used for development
  * support of breakpoints and such.  Someday I will get around to
  * using them.
  */
-       . = 0x1c00
-DataBreakpoint:
-       mtspr   SPRN_SPRG_SCRATCH0, r10
-       mtspr   SPRN_SPRG_SCRATCH1, r11
-       mfcr    r10
-       mfspr   r11, SPRN_SRR0
-       cmplwi  cr0, r11, (.Ldtlbie - PAGE_OFFSET)@l
-       cmplwi  cr7, r11, (.Litlbie - PAGE_OFFSET)@l
-       beq-    cr0, 11f
-       beq-    cr7, 11f
+do_databreakpoint:
        EXCEPTION_PROLOG_1
-       EXCEPTION_PROLOG_2
+       EXCEPTION_PROLOG_2 handle_dar_dsisr=1
        addi    r3,r1,STACK_FRAME_OVERHEAD
        mfspr   r4,SPRN_BAR
        stw     r4,_DAR(r11)
+#ifdef CONFIG_VMAP_STACK
+       lwz     r5,_DSISR(r11)
+#else
        mfspr   r5,SPRN_DSISR
+#endif
        EXC_XFER_STD(0x1c00, do_break)
-11:
+
+       . = 0x1c00
+DataBreakpoint:
+       EXCEPTION_PROLOG_0 handle_dar_dsisr=1
+       mfspr   r11, SPRN_SRR0
+       cmplwi  cr1, r11, (.Ldtlbie - PAGE_OFFSET)@l
+       cmplwi  cr7, r11, (.Litlbie - PAGE_OFFSET)@l
+       cror    4*cr1+eq, 4*cr1+eq, 4*cr7+eq
+       bne     cr1, do_databreakpoint
        mtcr    r10
        mfspr   r10, SPRN_SPRG_SCRATCH0
        mfspr   r11, SPRN_SPRG_SCRATCH1
@@ -581,9 +560,9 @@ FixupDAR:/* Entry point for dcbx workaround. */
        mfspr   r10, SPRN_SRR0
        mtspr   SPRN_MD_EPN, r10
        rlwinm  r11, r10, 16, 0xfff8
-       cmpli   cr0, r11, PAGE_OFFSET@h
+       cmpli   cr1, r11, PAGE_OFFSET@h
        mfspr   r11, SPRN_M_TWB /* Get level 1 table */
-       blt+    3f
+       blt+    cr1, 3f
        rlwinm  r11, r10, 16, 0xfff8
 
 0:     cmpli   cr7, r11, (PAGE_OFFSET + 0x1800000)@h
@@ -598,7 +577,7 @@ FixupDAR:/* Entry point for dcbx workaround. */
 3:
        lwz     r11, (swapper_pg_dir-PAGE_OFFSET)@l(r11)        /* Get the level 1 entry */
        mtspr   SPRN_MD_TWC, r11
-       mtcr    r11
+       mtcrf   0x01, r11
        mfspr   r11, SPRN_MD_TWC
        lwz     r11, 0(r11)     /* Get the pte */
        bt      28,200f         /* bit 28 = Large page (8M) */
@@ -611,16 +590,16 @@ FixupDAR:/* Entry point for dcbx workaround. */
  * no need to include them here */
        xoris   r10, r11, 0x7c00        /* check if major OP code is 31 */
        rlwinm  r10, r10, 0, 21, 5
-       cmpwi   cr0, r10, 2028  /* Is dcbz? */
-       beq+    142f
-       cmpwi   cr0, r10, 940   /* Is dcbi? */
-       beq+    142f
-       cmpwi   cr0, r10, 108   /* Is dcbst? */
-       beq+    144f            /* Fix up store bit! */
-       cmpwi   cr0, r10, 172   /* Is dcbf? */
-       beq+    142f
-       cmpwi   cr0, r10, 1964  /* Is icbi? */
-       beq+    142f
+       cmpwi   cr1, r10, 2028  /* Is dcbz? */
+       beq+    cr1, 142f
+       cmpwi   cr1, r10, 940   /* Is dcbi? */
+       beq+    cr1, 142f
+       cmpwi   cr1, r10, 108   /* Is dcbst? */
+       beq+    cr1, 144f               /* Fix up store bit! */
+       cmpwi   cr1, r10, 172   /* Is dcbf? */
+       beq+    cr1, 142f
+       cmpwi   cr1, r10, 1964  /* Is icbi? */
+       beq+    cr1, 142f
 141:   mfspr   r10,SPRN_M_TW
        b       DARFixed        /* Nope, go back to normal TLB processing */
 
@@ -679,8 +658,9 @@ FixupDAR:/* Entry point for dcbx workaround. */
        add     r10, r10, r30   ;b      151f
        add     r10, r10, r31
 151:
-       rlwinm. r11,r11,19,24,28        /* offset into jump table for reg RA */
-       beq     152f                    /* if reg RA is zero, don't add it */
+       rlwinm  r11,r11,19,24,28        /* offset into jump table for reg RA */
+       cmpwi   cr1, r11, 0
+       beq     cr1, 152f               /* if reg RA is zero, don't add it */
        addi    r11, r11, 150b@l        /* add start of table */
        mtctr   r11                     /* load ctr with jump address */
        rlwinm  r11,r11,0,16,10         /* make sure we don't execute this more than once */
@@ -688,7 +668,14 @@ FixupDAR:/* Entry point for dcbx workaround. */
 152:
        mfdar   r11
        mtctr   r11                     /* restore ctr reg from DAR */
+#ifdef CONFIG_VMAP_STACK
+       mfspr   r11, SPRN_SPRG_THREAD
+       stw     r10, DAR(r11)
+       mfspr   r10, SPRN_DSISR
+       stw     r10, DSISR(r11)
+#else
        mtdar   r10                     /* save fault EA to DAR */
+#endif
        mfspr   r10,SPRN_M_TW
        b       DARFixed                /* Go back to normal TLB handling */
 
index 2ae635d..37fc84e 100644 (file)
@@ -467,6 +467,7 @@ label:
        mfspr   r5,SPRN_ESR;            /* Grab the ESR and save it */        \
        stw     r5,_ESR(r11);                                                 \
        mfspr   r4,SPRN_DEAR;           /* Grab the DEAR */                   \
+       stw     r4, _DEAR(r11);                                               \
        EXC_XFER_LITE(0x0300, handle_page_fault)
 
 #define INSTRUCTION_STORAGE_EXCEPTION                                        \
@@ -475,6 +476,7 @@ label:
        mfspr   r5,SPRN_ESR;            /* Grab the ESR and save it */        \
        stw     r5,_ESR(r11);                                                 \
        mr      r4,r12;                 /* Pass SRR0 as arg2 */               \
+       stw     r4, _DEAR(r11);                                               \
        li      r5,0;                   /* Pass zero as arg3 */               \
        EXC_XFER_LITE(0x0400, handle_page_fault)
 
index 6f7a3a7..840af00 100644 (file)
@@ -378,6 +378,7 @@ interrupt_base:
        mfspr   r4,SPRN_DEAR            /* Grab the DEAR, save it, pass arg2 */
        andis.  r10,r5,(ESR_ILK|ESR_DLK)@h
        bne     1f
+       stw     r4, _DEAR(r11)
        EXC_XFER_LITE(0x0300, handle_page_fault)
 1:
        addi    r3,r1,STACK_FRAME_OVERHEAD
index 58ce3d3..2462cd7 100644 (file)
@@ -160,6 +160,9 @@ static int hw_breakpoint_validate_len(struct arch_hw_breakpoint *hw)
                /* DAWR region can't cross 512 bytes boundary */
                if ((start_addr >> 9) != (end_addr >> 9))
                        return -EINVAL;
+       } else if (IS_ENABLED(CONFIG_PPC_8xx)) {
+               /* 8xx can setup a range without limitation */
+               max_len = U16_MAX;
        }
 
        if (hw_len > max_len)
@@ -328,13 +331,11 @@ int hw_breakpoint_handler(struct die_args *args)
        }
 
        info->type &= ~HW_BRK_TYPE_EXTRANEOUS_IRQ;
-       if (IS_ENABLED(CONFIG_PPC_8xx)) {
-               if (!dar_within_range(regs->dar, info))
-                       info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
-       } else {
-               if (!stepping_handler(regs, bp, info))
-                       goto out;
-       }
+       if (!dar_within_range(regs->dar, info))
+               info->type |= HW_BRK_TYPE_EXTRANEOUS_IRQ;
+
+       if (!IS_ENABLED(CONFIG_PPC_8xx) && !stepping_handler(regs, bp, info))
+               goto out;
 
        /*
         * As a policy, the callback is invoked in a 'trigger-after-execute'
index a36fd05..422e31d 100644 (file)
@@ -77,6 +77,31 @@ void arch_cpu_idle(void)
 
 int powersave_nap;
 
+#ifdef CONFIG_PPC_970_NAP
+void power4_idle(void)
+{
+       if (!cpu_has_feature(CPU_FTR_CAN_NAP))
+               return;
+
+       if (!powersave_nap)
+               return;
+
+       if (!prep_irq_for_idle())
+               return;
+
+       if (cpu_has_feature(CPU_FTR_ALTIVEC))
+               asm volatile("DSSALL ; sync" ::: "memory");
+
+       power4_idle_nap();
+
+       /*
+        * power4_idle_nap returns with interrupts enabled (soft and hard).
+        * to our caller with interrupts enabled (soft and hard). Our caller
+        * can cope with either interrupts disabled or enabled upon return.
+        */
+}
+#endif
+
 #ifdef CONFIG_SYSCTL
 /*
  * Register the sysctl to set/clear powersave_nap.
index d327519..22f249b 100644 (file)
@@ -15,7 +15,9 @@
 #include <asm/asm-offsets.h>
 #include <asm/ppc-opcode.h>
 #include <asm/cpuidle.h>
+#include <asm/thread_info.h> /* TLF_NAPPING */
 
+#ifdef CONFIG_PPC_P7_NAP
 /*
  * Desired PSSCR in r3
  *
@@ -181,4 +183,22 @@ _GLOBAL(isa206_idle_insn_mayloss)
        bne     2f
        IDLE_STATE_ENTER_SEQ_NORET(PPC_SLEEP)
 2:     IDLE_STATE_ENTER_SEQ_NORET(PPC_WINKLE)
+#endif
 
+#ifdef CONFIG_PPC_970_NAP
+_GLOBAL(power4_idle_nap)
+       LOAD_REG_IMMEDIATE(r7, MSR_KERNEL|MSR_EE|MSR_POW)
+       ld      r9,PACA_THREAD_INFO(r13)
+       ld      r8,TI_LOCAL_FLAGS(r9)
+       ori     r8,r8,_TLF_NAPPING
+       std     r8,TI_LOCAL_FLAGS(r9)
+       /*
+        * NAPPING bit is set, from this point onward power4_fixup_nap
+        * will cause exceptions to return to power4_idle_nap_return.
+        */
+1:     sync
+       isync
+       mtmsrd  r7
+       isync
+       b       1b
+#endif
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
deleted file mode 100644 (file)
index 33c6253..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- *  This file contains the power_save function for 970-family CPUs.
- */
-
-#include <linux/threads.h>
-#include <asm/processor.h>
-#include <asm/page.h>
-#include <asm/cputable.h>
-#include <asm/thread_info.h>
-#include <asm/ppc_asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/irqflags.h>
-#include <asm/hw_irq.h>
-#include <asm/feature-fixups.h>
-
-#undef DEBUG
-
-       .text
-
-_GLOBAL(power4_idle)
-BEGIN_FTR_SECTION
-       blr
-END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
-       /* Now check if user or arch enabled NAP mode */
-       LOAD_REG_ADDRBASE(r3,powersave_nap)
-       lwz     r4,ADDROFF(powersave_nap)(r3)
-       cmpwi   0,r4,0
-       beqlr
-
-       /* This sequence is similar to prep_irq_for_idle() */
-
-       /* Hard disable interrupts */
-       mfmsr   r7
-       rldicl  r0,r7,48,1
-       rotldi  r0,r0,16
-       mtmsrd  r0,1
-
-       /* Check if something happened while soft-disabled */
-       lbz     r0,PACAIRQHAPPENED(r13)
-       cmpwi   cr0,r0,0
-       bne-    2f
-
-       /*
-        * Soft-enable interrupts. This will make power4_fixup_nap return
-        * to our caller with interrupts enabled (soft and hard). The caller
-        * can cope with either interrupts disabled or enabled upon return.
-        */
-#ifdef CONFIG_TRACE_IRQFLAGS
-       /* Tell the tracer interrupts are on, because idle responds to them. */
-       mflr    r0
-       std     r0,16(r1)
-       stdu    r1,-128(r1)
-       bl      trace_hardirqs_on
-       addi    r1,r1,128
-       ld      r0,16(r1)
-       mtlr    r0
-       mfmsr   r7
-#endif /* CONFIG_TRACE_IRQFLAGS */
-
-       li      r0,IRQS_ENABLED
-       stb     r0,PACAIRQSOFTMASK(r13) /* we'll hard-enable shortly */
-BEGIN_FTR_SECTION
-       DSSALL
-       sync
-END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
-       ld      r9, PACA_THREAD_INFO(r13)
-       ld      r8,TI_LOCAL_FLAGS(r9)   /* set napping bit */
-       ori     r8,r8,_TLF_NAPPING      /* so when we take an exception */
-       std     r8,TI_LOCAL_FLAGS(r9)   /* it will return to our caller */
-       ori     r7,r7,MSR_EE
-       oris    r7,r7,MSR_POW@h
-1:     sync
-       isync
-       mtmsrd  r7
-       isync
-       b       1b
-
-2:     /* Return if an interrupt had happened while soft disabled */
-       /* Set the HARD_DIS flag because interrupts are now hard disabled */
-       ori     r0,r0,PACA_IRQ_HARD_DIS
-       stb     r0,PACAIRQHAPPENED(r13)
-       blr
index add6749..5c9b118 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/debugfs.h>
 #include <linux/of.h>
 #include <linux/of_irq.h>
+#include <linux/vmalloc.h>
 
 #include <linux/uaccess.h>
 #include <asm/io.h>
@@ -664,8 +665,29 @@ void do_IRQ(struct pt_regs *regs)
        set_irq_regs(old_regs);
 }
 
+static void *__init alloc_vm_stack(void)
+{
+       return __vmalloc_node_range(THREAD_SIZE, THREAD_ALIGN, VMALLOC_START,
+                                   VMALLOC_END, THREADINFO_GFP, PAGE_KERNEL,
+                                    0, NUMA_NO_NODE, (void*)_RET_IP_);
+}
+
+static void __init vmap_irqstack_init(void)
+{
+       int i;
+
+       for_each_possible_cpu(i) {
+               softirq_ctx[i] = alloc_vm_stack();
+               hardirq_ctx[i] = alloc_vm_stack();
+       }
+}
+
+
 void __init init_IRQ(void)
 {
+       if (IS_ENABLED(CONFIG_VMAP_STACK))
+               vmap_irqstack_init();
+
        if (ppc_md.init_IRQ)
                ppc_md.init_IRQ();
 }
index 1c448cf..c6c0341 100644 (file)
@@ -261,12 +261,6 @@ int pcibios_sriov_disable(struct pci_dev *pdev)
 
 #endif /* CONFIG_PCI_IOV */
 
-void pcibios_bus_add_device(struct pci_dev *pdev)
-{
-       if (ppc_md.pcibios_bus_add_device)
-               ppc_md.pcibios_bus_add_device(pdev);
-}
-
 static resource_size_t pcibios_io_size(const struct pci_controller *hose)
 {
 #ifdef CONFIG_PPC64
@@ -964,7 +958,7 @@ void pcibios_setup_bus_self(struct pci_bus *bus)
                phb->controller_ops.dma_bus_setup(bus);
 }
 
-static void pcibios_setup_device(struct pci_dev *dev)
+void pcibios_bus_add_device(struct pci_dev *dev)
 {
        struct pci_controller *phb;
        /* Fixup NUMA node as it may not be setup yet by the generic
@@ -985,17 +979,13 @@ static void pcibios_setup_device(struct pci_dev *dev)
        pci_read_irq_line(dev);
        if (ppc_md.pci_irq_fixup)
                ppc_md.pci_irq_fixup(dev);
+
+       if (ppc_md.pcibios_bus_add_device)
+               ppc_md.pcibios_bus_add_device(dev);
 }
 
 int pcibios_add_device(struct pci_dev *dev)
 {
-       /*
-        * We can only call pcibios_setup_device() after bus setup is complete,
-        * since some of the platform specific DMA setup code depends on it.
-        */
-       if (dev->bus->is_added)
-               pcibios_setup_device(dev);
-
 #ifdef CONFIG_PCI_IOV
        if (ppc_md.pcibios_fixup_sriov)
                ppc_md.pcibios_fixup_sriov(dev);
@@ -1004,24 +994,6 @@ int pcibios_add_device(struct pci_dev *dev)
        return 0;
 }
 
-void pcibios_setup_bus_devices(struct pci_bus *bus)
-{
-       struct pci_dev *dev;
-
-       pr_debug("PCI: Fixup bus devices %d (%s)\n",
-                bus->number, bus->self ? pci_name(bus->self) : "PHB");
-
-       list_for_each_entry(dev, &bus->devices, bus_list) {
-               /* Cardbus can call us to add new devices to a bus, so ignore
-                * those who are already fully discovered
-                */
-               if (pci_dev_is_added(dev))
-                       continue;
-
-               pcibios_setup_device(dev);
-       }
-}
-
 void pcibios_set_master(struct pci_dev *dev)
 {
        /* No special bus mastering setup handling */
@@ -1037,19 +1009,9 @@ void pcibios_fixup_bus(struct pci_bus *bus)
 
        /* Now fixup the bus bus */
        pcibios_setup_bus_self(bus);
-
-       /* Now fixup devices on that bus */
-       pcibios_setup_bus_devices(bus);
 }
 EXPORT_SYMBOL(pcibios_fixup_bus);
 
-void pci_fixup_cardbus(struct pci_bus *bus)
-{
-       /* Now fixup devices on that bus */
-       pcibios_setup_bus_devices(bus);
-}
-
-
 static int skip_isa_ioresource_align(struct pci_dev *dev)
 {
        if (pci_has_flag(PCI_CAN_SKIP_ISA_ALIGN) &&
index fc62c4b..d6a67f8 100644 (file)
@@ -134,7 +134,6 @@ void pci_hp_add_devices(struct pci_bus *bus)
                 */
                slotno = PCI_SLOT(PCI_DN(dn->child)->devfn);
                pci_scan_slot(bus, PCI_DEVFN(slotno, 0));
-               pcibios_setup_bus_devices(bus);
                max = bus->busn_res.start;
                /*
                 * Scan bridges that are already configured. We don't touch
index 9524009..4e654df 100644 (file)
@@ -125,7 +125,7 @@ struct pci_dn *pci_get_pdn(struct pci_dev *pdev)
 }
 
 #ifdef CONFIG_PCI_IOV
-static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
+static struct pci_dn *add_one_sriov_vf_pdn(struct pci_dn *parent,
                                           int vf_index,
                                           int busno, int devfn)
 {
@@ -151,17 +151,15 @@ static struct pci_dn *add_one_dev_pci_data(struct pci_dn *parent,
 
        return pdn;
 }
-#endif
 
-struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
+struct pci_dn *add_sriov_vf_pdns(struct pci_dev *pdev)
 {
-#ifdef CONFIG_PCI_IOV
        struct pci_dn *parent, *pdn;
        int i;
 
        /* Only support IOV for now */
-       if (!pdev->is_physfn)
-               return pci_get_pdn(pdev);
+       if (WARN_ON(!pdev->is_physfn))
+               return NULL;
 
        /* Check if VFs have been populated */
        pdn = pci_get_pdn(pdev);
@@ -176,7 +174,7 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
        for (i = 0; i < pci_sriov_get_totalvfs(pdev); i++) {
                struct eeh_dev *edev __maybe_unused;
 
-               pdn = add_one_dev_pci_data(parent, i,
+               pdn = add_one_sriov_vf_pdn(parent, i,
                                           pci_iov_virtfn_bus(pdev, i),
                                           pci_iov_virtfn_devfn(pdev, i));
                if (!pdn) {
@@ -192,31 +190,17 @@ struct pci_dn *add_dev_pci_data(struct pci_dev *pdev)
                edev->physfn = pdev;
 #endif /* CONFIG_EEH */
        }
-#endif /* CONFIG_PCI_IOV */
-
        return pci_get_pdn(pdev);
 }
 
-void remove_dev_pci_data(struct pci_dev *pdev)
+void remove_sriov_vf_pdns(struct pci_dev *pdev)
 {
-#ifdef CONFIG_PCI_IOV
        struct pci_dn *parent;
        struct pci_dn *pdn, *tmp;
        int i;
 
-       /*
-        * VF and VF PE are created/released dynamically, so we need to
-        * bind/unbind them.  Otherwise the VF and VF PE would be mismatched
-        * when re-enabling SR-IOV.
-        */
-       if (pdev->is_virtfn) {
-               pdn = pci_get_pdn(pdev);
-               pdn->pe_number = IODA_INVALID_PE;
-               return;
-       }
-
        /* Only support IOV PF for now */
-       if (!pdev->is_physfn)
+       if (WARN_ON(!pdev->is_physfn))
                return;
 
        /* Check if VFs have been populated */
@@ -244,9 +228,22 @@ void remove_dev_pci_data(struct pci_dev *pdev)
                                continue;
 
 #ifdef CONFIG_EEH
-                       /* Release EEH device for the VF */
+                       /*
+                        * Release EEH state for this VF. The PCI core
+                        * has already torn down the pci_dev for this VF, but
+                        * we're responsible to removing the eeh_dev since it
+                        * has the same lifetime as the pci_dn that spawned it.
+                        */
                        edev = pdn_to_eeh_dev(pdn);
                        if (edev) {
+                               /*
+                                * We allocate pci_dn's for the totalvfs count,
+                                * but only only the vfs that were activated
+                                * have a configured PE.
+                                */
+                               if (edev->pe)
+                                       eeh_rmv_from_parent_pe(edev);
+
                                pdn->edev = NULL;
                                kfree(edev);
                        }
@@ -258,8 +255,8 @@ void remove_dev_pci_data(struct pci_dev *pdev)
                        kfree(pdn);
                }
        }
-#endif /* CONFIG_PCI_IOV */
 }
+#endif /* CONFIG_PCI_IOV */
 
 struct pci_dn *pci_add_device_node_info(struct pci_controller *hose,
                                        struct device_node *dn)
index f91d7e9..c3024f1 100644 (file)
@@ -414,7 +414,6 @@ static void __of_scan_bus(struct device_node *node, struct pci_bus *bus,
         */
        if (!rescan_existing)
                pcibios_setup_bus_self(bus);
-       pcibios_setup_bus_devices(bus);
 
        /* Now scan child busses */
        for_each_pci_bridge(dev, bus)
index be3758d..8778174 100644 (file)
@@ -39,10 +39,10 @@ static int page_map_mmap( struct file *file, struct vm_area_struct *vma )
        return 0;
 }
 
-static const struct file_operations page_map_fops = {
-       .llseek = page_map_seek,
-       .read   = page_map_read,
-       .mmap   = page_map_mmap
+static const struct proc_ops page_map_proc_ops = {
+       .proc_lseek     = page_map_seek,
+       .proc_read      = page_map_read,
+       .proc_mmap      = page_map_mmap,
 };
 
 
@@ -51,7 +51,7 @@ static int __init proc_ppc64_init(void)
        struct proc_dir_entry *pde;
 
        pde = proc_create_data("powerpc/systemcfg", S_IFREG | 0444, NULL,
-                              &page_map_fops, vdso_data);
+                              &page_map_proc_ops, vdso_data);
        if (!pde)
                return 1;
        proc_set_size(pde, PAGE_SIZE);
index 4df94b6..fad50db 100644 (file)
@@ -740,28 +740,6 @@ static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
                mtspr(SPRN_DABRX, dabrx);
        return 0;
 }
-#elif defined(CONFIG_PPC_8xx)
-static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
-{
-       unsigned long addr = dabr & ~HW_BRK_TYPE_DABR;
-       unsigned long lctrl1 = 0x90000000; /* compare type: equal on E & F */
-       unsigned long lctrl2 = 0x8e000002; /* watchpoint 1 on cmp E | F */
-
-       if ((dabr & HW_BRK_TYPE_RDWR) == HW_BRK_TYPE_READ)
-               lctrl1 |= 0xa0000;
-       else if ((dabr & HW_BRK_TYPE_RDWR) == HW_BRK_TYPE_WRITE)
-               lctrl1 |= 0xf0000;
-       else if ((dabr & HW_BRK_TYPE_RDWR) == 0)
-               lctrl2 = 0;
-
-       mtspr(SPRN_LCTRL2, 0);
-       mtspr(SPRN_CMPE, addr);
-       mtspr(SPRN_CMPF, addr + 4);
-       mtspr(SPRN_LCTRL1, lctrl1);
-       mtspr(SPRN_LCTRL2, lctrl2);
-
-       return 0;
-}
 #else
 static inline int __set_dabr(unsigned long dabr, unsigned long dabrx)
 {
@@ -782,6 +760,39 @@ static inline int set_dabr(struct arch_hw_breakpoint *brk)
        return __set_dabr(dabr, dabrx);
 }
 
+static inline int set_breakpoint_8xx(struct arch_hw_breakpoint *brk)
+{
+       unsigned long lctrl1 = LCTRL1_CTE_GT | LCTRL1_CTF_LT | LCTRL1_CRWE_RW |
+                              LCTRL1_CRWF_RW;
+       unsigned long lctrl2 = LCTRL2_LW0EN | LCTRL2_LW0LADC | LCTRL2_SLW0EN;
+       unsigned long start_addr = brk->address & ~HW_BREAKPOINT_ALIGN;
+       unsigned long end_addr = (brk->address + brk->len - 1) | HW_BREAKPOINT_ALIGN;
+
+       if (start_addr == 0)
+               lctrl2 |= LCTRL2_LW0LA_F;
+       else if (end_addr == ~0U)
+               lctrl2 |= LCTRL2_LW0LA_E;
+       else
+               lctrl2 |= LCTRL2_LW0LA_EandF;
+
+       mtspr(SPRN_LCTRL2, 0);
+
+       if ((brk->type & HW_BRK_TYPE_RDWR) == 0)
+               return 0;
+
+       if ((brk->type & HW_BRK_TYPE_RDWR) == HW_BRK_TYPE_READ)
+               lctrl1 |= LCTRL1_CRWE_RO | LCTRL1_CRWF_RO;
+       if ((brk->type & HW_BRK_TYPE_RDWR) == HW_BRK_TYPE_WRITE)
+               lctrl1 |= LCTRL1_CRWE_WO | LCTRL1_CRWF_WO;
+
+       mtspr(SPRN_CMPE, start_addr - 1);
+       mtspr(SPRN_CMPF, end_addr + 1);
+       mtspr(SPRN_LCTRL1, lctrl1);
+       mtspr(SPRN_LCTRL2, lctrl2);
+
+       return 0;
+}
+
 void __set_breakpoint(struct arch_hw_breakpoint *brk)
 {
        memcpy(this_cpu_ptr(&current_brk), brk, sizeof(*brk));
@@ -789,6 +800,8 @@ void __set_breakpoint(struct arch_hw_breakpoint *brk)
        if (dawr_enabled())
                // Power8 or later
                set_dawr(brk);
+       else if (IS_ENABLED(CONFIG_PPC_8xx))
+               set_breakpoint_8xx(brk);
        else if (!cpu_has_feature(CPU_FTR_ARCH_207S))
                // Power7 or earlier
                set_dabr(brk);
@@ -1264,16 +1277,6 @@ void show_user_instructions(struct pt_regs *regs)
 
        pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int));
 
-       /*
-        * Make sure the NIP points at userspace, not kernel text/data or
-        * elsewhere.
-        */
-       if (!__access_ok(pc, NR_INSN_TO_PRINT * sizeof(int), USER_DS)) {
-               pr_info("%s[%d]: Bad NIP, not dumping instructions.\n",
-                       current->comm, current->pid);
-               return;
-       }
-
        seq_buf_init(&s, buf, sizeof(buf));
 
        while (n) {
@@ -1284,7 +1287,7 @@ void show_user_instructions(struct pt_regs *regs)
                for (i = 0; i < 8 && n; i++, n--, pc += sizeof(int)) {
                        int instr;
 
-                       if (probe_kernel_address((const void *)pc, instr)) {
+                       if (probe_user_read(&instr, (void __user *)pc, sizeof(instr))) {
                                seq_buf_printf(&s, "XXXXXXXX ");
                                continue;
                        }
index 487dcd8..2d33f34 100644 (file)
@@ -159,12 +159,12 @@ static int poweron_open(struct inode *inode, struct file *file)
        return single_open(file, ppc_rtas_poweron_show, NULL);
 }
 
-static const struct file_operations ppc_rtas_poweron_operations = {
-       .open           = poweron_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .write          = ppc_rtas_poweron_write,
-       .release        = single_release,
+static const struct proc_ops ppc_rtas_poweron_proc_ops = {
+       .proc_open      = poweron_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = ppc_rtas_poweron_write,
+       .proc_release   = single_release,
 };
 
 static int progress_open(struct inode *inode, struct file *file)
@@ -172,12 +172,12 @@ static int progress_open(struct inode *inode, struct file *file)
        return single_open(file, ppc_rtas_progress_show, NULL);
 }
 
-static const struct file_operations ppc_rtas_progress_operations = {
-       .open           = progress_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .write          = ppc_rtas_progress_write,
-       .release        = single_release,
+static const struct proc_ops ppc_rtas_progress_proc_ops = {
+       .proc_open      = progress_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = ppc_rtas_progress_write,
+       .proc_release   = single_release,
 };
 
 static int clock_open(struct inode *inode, struct file *file)
@@ -185,12 +185,12 @@ static int clock_open(struct inode *inode, struct file *file)
        return single_open(file, ppc_rtas_clock_show, NULL);
 }
 
-static const struct file_operations ppc_rtas_clock_operations = {
-       .open           = clock_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .write          = ppc_rtas_clock_write,
-       .release        = single_release,
+static const struct proc_ops ppc_rtas_clock_proc_ops = {
+       .proc_open      = clock_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = ppc_rtas_clock_write,
+       .proc_release   = single_release,
 };
 
 static int tone_freq_open(struct inode *inode, struct file *file)
@@ -198,12 +198,12 @@ static int tone_freq_open(struct inode *inode, struct file *file)
        return single_open(file, ppc_rtas_tone_freq_show, NULL);
 }
 
-static const struct file_operations ppc_rtas_tone_freq_operations = {
-       .open           = tone_freq_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .write          = ppc_rtas_tone_freq_write,
-       .release        = single_release,
+static const struct proc_ops ppc_rtas_tone_freq_proc_ops = {
+       .proc_open      = tone_freq_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = ppc_rtas_tone_freq_write,
+       .proc_release   = single_release,
 };
 
 static int tone_volume_open(struct inode *inode, struct file *file)
@@ -211,12 +211,12 @@ static int tone_volume_open(struct inode *inode, struct file *file)
        return single_open(file, ppc_rtas_tone_volume_show, NULL);
 }
 
-static const struct file_operations ppc_rtas_tone_volume_operations = {
-       .open           = tone_volume_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .write          = ppc_rtas_tone_volume_write,
-       .release        = single_release,
+static const struct proc_ops ppc_rtas_tone_volume_proc_ops = {
+       .proc_open      = tone_volume_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = ppc_rtas_tone_volume_write,
+       .proc_release   = single_release,
 };
 
 static int ppc_rtas_find_all_sensors(void);
@@ -238,17 +238,17 @@ static int __init proc_rtas_init(void)
                return -ENODEV;
 
        proc_create("powerpc/rtas/progress", 0644, NULL,
-                   &ppc_rtas_progress_operations);
+                   &ppc_rtas_progress_proc_ops);
        proc_create("powerpc/rtas/clock", 0644, NULL,
-                   &ppc_rtas_clock_operations);
+                   &ppc_rtas_clock_proc_ops);
        proc_create("powerpc/rtas/poweron", 0644, NULL,
-                   &ppc_rtas_poweron_operations);
+                   &ppc_rtas_poweron_proc_ops);
        proc_create_single("powerpc/rtas/sensors", 0444, NULL,
                        ppc_rtas_sensors_show);
        proc_create("powerpc/rtas/frequency", 0644, NULL,
-                   &ppc_rtas_tone_freq_operations);
+                   &ppc_rtas_tone_freq_proc_ops);
        proc_create("powerpc/rtas/volume", 0644, NULL,
-                   &ppc_rtas_tone_volume_operations);
+                   &ppc_rtas_tone_volume_proc_ops);
        proc_create_single("powerpc/rtas/rmo_buffer", 0400, NULL,
                        ppc_rtas_rmo_buf_show);
        return 0;
index 84f7947..a99179d 100644 (file)
@@ -655,7 +655,7 @@ struct rtas_flash_file {
        const char *filename;
        const char *rtas_call_name;
        int *status;
-       const struct file_operations fops;
+       const struct proc_ops ops;
 };
 
 static const struct rtas_flash_file rtas_flash_files[] = {
@@ -663,36 +663,36 @@ static const struct rtas_flash_file rtas_flash_files[] = {
                .filename       = "powerpc/rtas/" FIRMWARE_FLASH_NAME,
                .rtas_call_name = "ibm,update-flash-64-and-reboot",
                .status         = &rtas_update_flash_data.status,
-               .fops.read      = rtas_flash_read_msg,
-               .fops.write     = rtas_flash_write,
-               .fops.release   = rtas_flash_release,
-               .fops.llseek    = default_llseek,
+               .ops.proc_read  = rtas_flash_read_msg,
+               .ops.proc_write = rtas_flash_write,
+               .ops.proc_release = rtas_flash_release,
+               .ops.proc_lseek = default_llseek,
        },
        {
                .filename       = "powerpc/rtas/" FIRMWARE_UPDATE_NAME,
                .rtas_call_name = "ibm,update-flash-64-and-reboot",
                .status         = &rtas_update_flash_data.status,
-               .fops.read      = rtas_flash_read_num,
-               .fops.write     = rtas_flash_write,
-               .fops.release   = rtas_flash_release,
-               .fops.llseek    = default_llseek,
+               .ops.proc_read  = rtas_flash_read_num,
+               .ops.proc_write = rtas_flash_write,
+               .ops.proc_release = rtas_flash_release,
+               .ops.proc_lseek = default_llseek,
        },
        {
                .filename       = "powerpc/rtas/" VALIDATE_FLASH_NAME,
                .rtas_call_name = "ibm,validate-flash-image",
                .status         = &rtas_validate_flash_data.status,
-               .fops.read      = validate_flash_read,
-               .fops.write     = validate_flash_write,
-               .fops.release   = validate_flash_release,
-               .fops.llseek    = default_llseek,
+               .ops.proc_read  = validate_flash_read,
+               .ops.proc_write = validate_flash_write,
+               .ops.proc_release = validate_flash_release,
+               .ops.proc_lseek = default_llseek,
        },
        {
                .filename       = "powerpc/rtas/" MANAGE_FLASH_NAME,
                .rtas_call_name = "ibm,manage-flash-image",
                .status         = &rtas_manage_flash_data.status,
-               .fops.read      = manage_flash_read,
-               .fops.write     = manage_flash_write,
-               .fops.llseek    = default_llseek,
+               .ops.proc_read  = manage_flash_read,
+               .ops.proc_write = manage_flash_write,
+               .ops.proc_lseek = default_llseek,
        }
 };
 
@@ -723,7 +723,7 @@ static int __init rtas_flash_init(void)
                const struct rtas_flash_file *f = &rtas_flash_files[i];
                int token;
 
-               if (!proc_create(f->filename, 0600, NULL, &f->fops))
+               if (!proc_create(f->filename, 0600, NULL, &f->ops))
                        goto enomem;
 
                /*
index 8d02e04..89b798f 100644 (file)
@@ -385,12 +385,12 @@ static __poll_t rtas_log_poll(struct file *file, poll_table * wait)
        return 0;
 }
 
-static const struct file_operations proc_rtas_log_operations = {
-       .read =         rtas_log_read,
-       .poll =         rtas_log_poll,
-       .open =         rtas_log_open,
-       .release =      rtas_log_release,
-       .llseek =       noop_llseek,
+static const struct proc_ops rtas_log_proc_ops = {
+       .proc_read      = rtas_log_read,
+       .proc_poll      = rtas_log_poll,
+       .proc_open      = rtas_log_open,
+       .proc_release   = rtas_log_release,
+       .proc_lseek     = noop_llseek,
 };
 
 static int enable_surveillance(int timeout)
@@ -572,7 +572,7 @@ static int __init rtas_init(void)
                return -ENODEV;
 
        entry = proc_create("powerpc/rtas/error_log", 0400, NULL,
-                           &proc_rtas_log_operations);
+                           &rtas_log_proc_ops);
        if (!entry)
                printk(KERN_ERR "Failed to create error_log proc entry\n");
 
index c82577c..2dd0d9c 100644 (file)
@@ -35,7 +35,7 @@ void exc_lvl_early_init(void);
 static inline void exc_lvl_early_init(void) { };
 #endif
 
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC64) || defined(CONFIG_VMAP_STACK)
 void emergency_stack_init(void);
 #else
 static inline void emergency_stack_init(void) { };
index dcffe92..5b49b26 100644 (file)
@@ -140,7 +140,7 @@ arch_initcall(ppc_init);
 
 static void *__init alloc_stack(void)
 {
-       void *ptr = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+       void *ptr = memblock_alloc(THREAD_SIZE, THREAD_ALIGN);
 
        if (!ptr)
                panic("cannot allocate %d bytes for stack at %pS\n",
@@ -153,6 +153,9 @@ void __init irqstack_early_init(void)
 {
        unsigned int i;
 
+       if (IS_ENABLED(CONFIG_VMAP_STACK))
+               return;
+
        /* interrupt stacks must be in lowmem, we get that for free on ppc32
         * as the memblock is limited to lowmem by default */
        for_each_possible_cpu(i) {
@@ -161,6 +164,18 @@ void __init irqstack_early_init(void)
        }
 }
 
+#ifdef CONFIG_VMAP_STACK
+void *emergency_ctx[NR_CPUS] __ro_after_init;
+
+void __init emergency_stack_init(void)
+{
+       unsigned int i;
+
+       for_each_possible_cpu(i)
+               emergency_ctx[i] = alloc_stack();
+}
+#endif
+
 #if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
 void __init exc_lvl_early_init(void)
 {
index 6104917..e05e6dd 100644 (file)
@@ -633,7 +633,7 @@ static void *__init alloc_stack(unsigned long limit, int cpu)
 
        BUILD_BUG_ON(STACK_INT_FRAME_SIZE % 16);
 
-       ptr = memblock_alloc_try_nid(THREAD_SIZE, THREAD_SIZE,
+       ptr = memblock_alloc_try_nid(THREAD_SIZE, THREAD_ALIGN,
                                     MEMBLOCK_LOW_LIMIT, limit,
                                     early_cpu_to_node(cpu));
        if (!ptr)
index 014ff07..82a3438 100644 (file)
@@ -1637,6 +1637,15 @@ void StackOverflow(struct pt_regs *regs)
        panic("kernel stack overflow");
 }
 
+void stack_overflow_exception(struct pt_regs *regs)
+{
+       enum ctx_state prev_state = exception_enter();
+
+       die("Kernel stack overflow", regs, SIGSEGV);
+
+       exception_exit(prev_state);
+}
+
 void kernel_fp_unavailable_exception(struct pt_regs *regs)
 {
        enum ctx_state prev_state = exception_enter();
index eae9dda..b9a1084 100644 (file)
@@ -728,11 +728,6 @@ static int __init vdso_init(void)
         */
        vdso64_pages = (&vdso64_end - &vdso64_start) >> PAGE_SHIFT;
        DBG("vdso64_kbase: %p, 0x%x pages\n", vdso64_kbase, vdso64_pages);
-#else
-       vdso_data->dcache_block_size = L1_CACHE_BYTES;
-       vdso_data->dcache_log_block_size = L1_CACHE_SHIFT;
-       vdso_data->icache_block_size = L1_CACHE_BYTES;
-       vdso_data->icache_log_block_size = L1_CACHE_SHIFT;
 #endif /* CONFIG_PPC64 */
 
 
index 06f54d9..e147bbd 100644 (file)
@@ -2,9 +2,7 @@
 
 # List of files in the vdso, has to be asm only for now
 
-obj-vdso32-$(CONFIG_PPC64) = getcpu.o
-obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o \
-               $(obj-vdso32-y)
+obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o
 
 # Build rules
 
index 7f882e7..3440ddf 100644 (file)
@@ -8,7 +8,9 @@
 #include <asm/processor.h>
 #include <asm/ppc_asm.h>
 #include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
 #include <asm/asm-offsets.h>
+#include <asm/cache.h>
 
        .text
 
  */
 V_FUNCTION_BEGIN(__kernel_sync_dicache)
   .cfi_startproc
+#ifdef CONFIG_PPC64
        mflr    r12
   .cfi_register lr,r12
-       mr      r11,r3
-       bl      __get_datapage@local
+       get_datapage    r10, r0
        mtlr    r12
-       mr      r10,r3
+#endif
 
+#ifdef CONFIG_PPC64
        lwz     r7,CFG_DCACHE_BLOCKSZ(r10)
        addi    r5,r7,-1
-       andc    r6,r11,r5               /* round low to line bdy */
+#else
+       li      r5, L1_CACHE_BYTES - 1
+#endif
+       andc    r6,r3,r5                /* round low to line bdy */
        subf    r8,r6,r4                /* compute length */
        add     r8,r8,r5                /* ensure we get enough */
+#ifdef CONFIG_PPC64
        lwz     r9,CFG_DCACHE_LOGBLOCKSZ(r10)
        srw.    r8,r8,r9                /* compute line count */
+#else
+       srwi.   r8, r8, L1_CACHE_SHIFT
+       mr      r7, r6
+#endif
        crclr   cr0*4+so
        beqlr                           /* nothing to do? */
        mtctr   r8
 1:     dcbst   0,r6
+#ifdef CONFIG_PPC64
        add     r6,r6,r7
+#else
+       addi    r6, r6, L1_CACHE_BYTES
+#endif
        bdnz    1b
        sync
 
 /* Now invalidate the instruction cache */
 
+#ifdef CONFIG_PPC64
        lwz     r7,CFG_ICACHE_BLOCKSZ(r10)
        addi    r5,r7,-1
-       andc    r6,r11,r5               /* round low to line bdy */
+       andc    r6,r3,r5                /* round low to line bdy */
        subf    r8,r6,r4                /* compute length */
        add     r8,r8,r5
        lwz     r9,CFG_ICACHE_LOGBLOCKSZ(r10)
        srw.    r8,r8,r9                /* compute line count */
        crclr   cr0*4+so
        beqlr                           /* nothing to do? */
+#endif
        mtctr   r8
+#ifdef CONFIG_PPC64
 2:     icbi    0,r6
        add     r6,r6,r7
+#else
+2:     icbi    0, r7
+       addi    r7, r7, L1_CACHE_BYTES
+#endif
        bdnz    2b
        isync
        li      r3,0
index 6c7401b..217bb63 100644 (file)
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
 #include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
 
        .text
        .global __kernel_datapage_offset;
 __kernel_datapage_offset:
        .long   0
 
-V_FUNCTION_BEGIN(__get_datapage)
-  .cfi_startproc
-       /* We don't want that exposed or overridable as we want other objects
-        * to be able to bl directly to here
-        */
-       .protected __get_datapage
-       .hidden __get_datapage
-
-       mflr    r0
-  .cfi_register lr,r0
-
-       bcl     20,31,data_page_branch
-data_page_branch:
-       mflr    r3
-       mtlr    r0
-       addi    r3, r3, __kernel_datapage_offset-data_page_branch
-       lwz     r0,0(r3)
-  .cfi_restore lr
-       add     r3,r0,r3
-       blr
-  .cfi_endproc
-V_FUNCTION_END(__get_datapage)
-
 /*
  * void *__kernel_get_syscall_map(unsigned int *syscall_count) ;
  *
@@ -52,11 +30,10 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
   .cfi_startproc
        mflr    r12
   .cfi_register lr,r12
-       mr      r4,r3
-       bl      __get_datapage@local
+       mr.     r4,r3
+       get_datapage    r3, r0
        mtlr    r12
        addi    r3,r3,CFG_SYSCALL_MAP32
-       cmpli   cr0,r4,0
        beqlr
        li      r0,NR_syscalls
        stw     r0,0(r4)
@@ -75,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
   .cfi_startproc
        mflr    r12
   .cfi_register lr,r12
-       bl      __get_datapage@local
+       get_datapage    r3, r0
        lwz     r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
        lwz     r3,CFG_TB_TICKS_PER_SEC(r3)
        mtlr    r12
index 63e9145..ff5e214 100644 (file)
@@ -15,6 +15,7 @@
  * int __kernel_getcpu(unsigned *cpu, unsigned *node);
  *
  */
+#if defined(CONFIG_PPC64)
 V_FUNCTION_BEGIN(__kernel_getcpu)
   .cfi_startproc
        mfspr   r5,SPRN_SPRG_VDSO_READ
@@ -24,10 +25,26 @@ V_FUNCTION_BEGIN(__kernel_getcpu)
        rlwinm  r7,r5,16,31-15,31-0
        beq     cr0,1f
        stw     r6,0(r3)
-1:     beq     cr1,2f
-       stw     r7,0(r4)
-2:     crclr   cr0*4+so
+1:     crclr   cr0*4+so
        li      r3,0                    /* always success */
+       beqlr   cr1
+       stw     r7,0(r4)
+       blr
+  .cfi_endproc
+V_FUNCTION_END(__kernel_getcpu)
+#elif !defined(CONFIG_SMP)
+V_FUNCTION_BEGIN(__kernel_getcpu)
+  .cfi_startproc
+       cmpwi   cr0, r3, 0
+       cmpwi   cr1, r4, 0
+       li      r5, 0
+       beq     cr0, 1f
+       stw     r5, 0(r3)
+1:     li      r3, 0                   /* always success */
+       crclr   cr0*4+so
+       beqlr   cr1
+       stw     r5, 0(r4)
        blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_getcpu)
+#endif
index 3306672..a395156 100644 (file)
@@ -9,6 +9,7 @@
 #include <asm/processor.h>
 #include <asm/ppc_asm.h>
 #include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
 #include <asm/asm-offsets.h>
 #include <asm/unistd.h>
 
@@ -31,28 +32,26 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday)
        mflr    r12
   .cfi_register lr,r12
 
-       mr      r10,r3                  /* r10 saves tv */
+       mr.     r10,r3                  /* r10 saves tv */
        mr      r11,r4                  /* r11 saves tz */
-       bl      __get_datapage@local    /* get data page */
-       mr      r9, r3                  /* datapage ptr in r9 */
-       cmplwi  r10,0                   /* check if tv is NULL */
+       get_datapage    r9, r0
        beq     3f
-       lis     r7,1000000@ha           /* load up USEC_PER_SEC */
-       addi    r7,r7,1000000@l         /* so we get microseconds in r4 */
+       LOAD_REG_IMMEDIATE(r7, 1000000) /* load up USEC_PER_SEC */
        bl      __do_get_tspec@local    /* get sec/usec from tb & kernel */
        stw     r3,TVAL32_TV_SEC(r10)
        stw     r4,TVAL32_TV_USEC(r10)
 
 3:     cmplwi  r11,0                   /* check if tz is NULL */
-       beq     1f
+       mtlr    r12
+       crclr   cr0*4+so
+       li      r3,0
+       beqlr
+
        lwz     r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */
        lwz     r5,CFG_TZ_DSTTIME(r9)
        stw     r4,TZONE_TZ_MINWEST(r11)
        stw     r5,TZONE_TZ_DSTTIME(r11)
 
-1:     mtlr    r12
-       crclr   cr0*4+so
-       li      r3,0
        blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_gettimeofday)
@@ -69,17 +68,23 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        cmpli   cr0,r3,CLOCK_REALTIME
        cmpli   cr1,r3,CLOCK_MONOTONIC
        cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
-       bne     cr0,99f
+
+       cmpli   cr5,r3,CLOCK_REALTIME_COARSE
+       cmpli   cr6,r3,CLOCK_MONOTONIC_COARSE
+       cror    cr5*4+eq,cr5*4+eq,cr6*4+eq
+
+       cror    cr0*4+eq,cr0*4+eq,cr5*4+eq
+       bne     cr0, .Lgettime_fallback
 
        mflr    r12                     /* r12 saves lr */
   .cfi_register lr,r12
        mr      r11,r4                  /* r11 saves tp */
-       bl      __get_datapage@local    /* get data page */
-       mr      r9,r3                   /* datapage ptr in r9 */
-       lis     r7,NSEC_PER_SEC@h       /* want nanoseconds */
-       ori     r7,r7,NSEC_PER_SEC@l
-50:    bl      __do_get_tspec@local    /* get sec/nsec from tb & kernel */
-       bne     cr1,80f                 /* not monotonic -> all done */
+       get_datapage    r9, r0
+       LOAD_REG_IMMEDIATE(r7, NSEC_PER_SEC)    /* load up NSEC_PER_SEC */
+       beq     cr5, .Lcoarse_clocks
+.Lprecise_clocks:
+       bl      __do_get_tspec@local    /* get sec/nsec from tb & kernel */
+       bne     cr1, .Lfinish           /* not monotonic -> all done */
 
        /*
         * CLOCK_MONOTONIC
@@ -103,12 +108,53 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        add     r9,r9,r0
        lwz     r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
         cmpl    cr0,r8,r0              /* check if updated */
-       bne-    50b
+       bne-    .Lprecise_clocks
+       b       .Lfinish_monotonic
+
+       /*
+        * For coarse clocks we get data directly from the vdso data page, so
+        * we don't need to call __do_get_tspec, but we still need to do the
+        * counter trick.
+        */
+.Lcoarse_clocks:
+       lwz     r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
+       andi.   r0,r8,1                 /* pending update ? loop */
+       bne-    .Lcoarse_clocks
+       add     r9,r9,r0                /* r0 is already 0 */
+
+       /*
+        * CLOCK_REALTIME_COARSE, below values are needed for MONOTONIC_COARSE
+        * too
+        */
+       lwz     r3,STAMP_XTIME_SEC+LOPART(r9)
+       lwz     r4,STAMP_XTIME_NSEC+LOPART(r9)
+       bne     cr6,1f
+
+       /* CLOCK_MONOTONIC_COARSE */
+       lwz     r5,(WTOM_CLOCK_SEC+LOPART)(r9)
+       lwz     r6,WTOM_CLOCK_NSEC(r9)
+
+       /* check if counter has updated */
+       or      r0,r6,r5
+1:     or      r0,r0,r3
+       or      r0,r0,r4
+       xor     r0,r0,r0
+       add     r3,r3,r0
+       lwz     r0,CFG_TB_UPDATE_COUNT+LOPART(r9)
+       cmpl    cr0,r0,r8               /* check if updated */
+       bne-    .Lcoarse_clocks
+
+       /* Counter has not updated, so continue calculating proper values for
+        * sec and nsec if monotonic coarse, or just return with the proper
+        * values for realtime.
+        */
+       bne     cr6, .Lfinish
 
        /* Calculate and store result. Note that this mimics the C code,
         * which may cause funny results if nsec goes negative... is that
         * possible at all ?
         */
+.Lfinish_monotonic:
        add     r3,r3,r5
        add     r4,r4,r6
        cmpw    cr0,r4,r7
@@ -116,11 +162,12 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        blt     1f
        subf    r4,r7,r4
        addi    r3,r3,1
-1:     bge     cr1,80f
+1:     bge     cr1, .Lfinish
        addi    r3,r3,-1
        add     r4,r4,r7
 
-80:    stw     r3,TSPC32_TV_SEC(r11)
+.Lfinish:
+       stw     r3,TSPC32_TV_SEC(r11)
        stw     r4,TSPC32_TV_NSEC(r11)
 
        mtlr    r12
@@ -131,7 +178,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
        /*
         * syscall fallback
         */
-99:
+.Lgettime_fallback:
        li      r0,__NR_clock_gettime
   .cfi_restore lr
        sc
@@ -149,17 +196,20 @@ V_FUNCTION_END(__kernel_clock_gettime)
 V_FUNCTION_BEGIN(__kernel_clock_getres)
   .cfi_startproc
        /* Check for supported clock IDs */
-       cmpwi   cr0,r3,CLOCK_REALTIME
-       cmpwi   cr1,r3,CLOCK_MONOTONIC
-       cror    cr0*4+eq,cr0*4+eq,cr1*4+eq
-       bne     cr0,99f
+       cmplwi  cr0, r3, CLOCK_MAX
+       cmpwi   cr1, r3, CLOCK_REALTIME_COARSE
+       cmpwi   cr7, r3, CLOCK_MONOTONIC_COARSE
+       bgt     cr0, 99f
+       LOAD_REG_IMMEDIATE(r5, KTIME_LOW_RES)
+       beq     cr1, 1f
+       beq     cr7, 1f
 
        mflr    r12
   .cfi_register lr,r12
-       bl      __get_datapage@local    /* get data page */
+       get_datapage    r3, r0
        lwz     r5, CLOCK_HRTIMER_RES(r3)
        mtlr    r12
-       li      r3,0
+1:     li      r3,0
        cmpli   cr0,r4,0
        crclr   cr0*4+so
        beqlr
@@ -168,11 +218,11 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
        blr
 
        /*
-        * syscall fallback
+        * invalid clock
         */
 99:
-       li      r0,__NR_clock_getres
-       sc
+       li      r3, EINVAL
+       crset   so
        blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_clock_getres)
@@ -190,16 +240,15 @@ V_FUNCTION_BEGIN(__kernel_time)
   .cfi_register lr,r12
 
        mr      r11,r3                  /* r11 holds t */
-       bl      __get_datapage@local
-       mr      r9, r3                  /* datapage ptr in r9 */
+       get_datapage    r9, r0
 
        lwz     r3,STAMP_XTIME_SEC+LOPART(r9)
 
        cmplwi  r11,0                   /* check if t is NULL */
-       beq     2f
-       stw     r3,0(r11)               /* store result at *t */
-2:     mtlr    r12
+       mtlr    r12
        crclr   cr0*4+so
+       beqlr
+       stw     r3,0(r11)               /* store result at *t */
        blr
   .cfi_endproc
 V_FUNCTION_END(__kernel_time)
index 00c025b..5206c2e 100644 (file)
@@ -155,7 +155,7 @@ VERSION
                __kernel_sync_dicache_p5;
                __kernel_sigtramp32;
                __kernel_sigtramp_rt32;
-#ifdef CONFIG_PPC64
+#if defined(CONFIG_PPC64) || !defined(CONFIG_SMP)
                __kernel_getcpu;
 #endif
 
index 8eb867d..25c14a0 100644 (file)
@@ -67,6 +67,9 @@ _GLOBAL(load_up_altivec)
 #ifdef CONFIG_PPC32
        mfspr   r5,SPRN_SPRG_THREAD             /* current task's THREAD (phys) */
        oris    r9,r9,MSR_VEC@h
+#ifdef CONFIG_VMAP_STACK
+       tovirt(r5, r5)
+#endif
 #else
        ld      r4,PACACURRENT(r13)
        addi    r5,r4,THREAD            /* Get THREAD */
index 8834220..b4c89a1 100644 (file)
@@ -323,7 +323,7 @@ SECTIONS
 #endif
 
        /* The initial task and kernel stack */
-       INIT_TASK_DATA_SECTION(THREAD_SIZE)
+       INIT_TASK_DATA_SECTION(THREAD_ALIGN)
 
        .data..page_aligned : AT(ADDR(.data..page_aligned) - LOAD_OFFSET) {
                PAGE_ALIGNED_DATA(PAGE_SIZE)
index 744dba9..803940d 100644 (file)
@@ -63,12 +63,10 @@ unsigned long __kvmhv_copy_tofrom_guest_radix(int lpid, int pid,
        }
        isync();
 
-       pagefault_disable();
        if (is_load)
-               ret = raw_copy_from_user(to, from, n);
+               ret = probe_user_read(to, (const void __user *)from, n);
        else
-               ret = raw_copy_to_user(to, from, n);
-       pagefault_enable();
+               ret = probe_user_write((void __user *)to, from, n);
 
        /* switch the pid first to avoid running host with unallocated pid */
        if (quadrant == 1 && pid != old_pid)
index c6fbbd2..dbc2fec 100644 (file)
@@ -1801,6 +1801,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        tlbsync
        ptesync
 
+BEGIN_FTR_SECTION
        /* Radix: Handle the case where the guest used an illegal PID */
        LOAD_REG_ADDR(r4, mmu_base_pid)
        lwz     r3, VCPU_GUEST_PID(r9)
@@ -1830,6 +1831,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ARCH_300)
        addi    r7,r7,0x1000
        bdnz    1b
        ptesync
+END_FTR_SECTION_IFSET(CPU_FTR_P9_RADIX_PREFETCH_BUG)
 
 2:
 #endif /* CONFIG_PPC_RADIX_MMU */
index 66858b7..85215e7 100644 (file)
@@ -484,7 +484,7 @@ static void xive_finish_unmask(struct kvmppc_xive *xive,
        kvmppc_xive_select_irq(state, &hw_num, &xd);
 
        /*
-        * See command in xive_lock_and_mask() concerning masking
+        * See comment in xive_lock_and_mask() concerning masking
         * via firmware.
         */
        if (xd->flags & OPAL_XIVE_IRQ_MASK_VIA_FW) {
index 8bbbd97..c11b0a0 100644 (file)
 #include <asm/feature-fixups.h>
 #include <asm/code-patching-asm.h>
 
+#ifdef CONFIG_VMAP_STACK
+#define ADDR_OFFSET    0
+#else
+#define ADDR_OFFSET    PAGE_OFFSET
+#endif
+
 #ifdef CONFIG_SMP
        .section .bss
        .align  2
@@ -47,8 +53,8 @@ mmu_hash_lock:
        .text
 _GLOBAL(hash_page)
 #ifdef CONFIG_SMP
-       lis     r8, (mmu_hash_lock - PAGE_OFFSET)@h
-       ori     r8, r8, (mmu_hash_lock - PAGE_OFFSET)@l
+       lis     r8, (mmu_hash_lock - ADDR_OFFSET)@h
+       ori     r8, r8, (mmu_hash_lock - ADDR_OFFSET)@l
        lis     r0,0x0fff
        b       10f
 11:    lwz     r6,0(r8)
@@ -66,9 +72,12 @@ _GLOBAL(hash_page)
        cmplw   0,r4,r0
        ori     r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */
        mfspr   r5, SPRN_SPRG_PGDIR     /* phys page-table root */
+#ifdef CONFIG_VMAP_STACK
+       tovirt(r5, r5)
+#endif
        blt+    112f                    /* assume user more likely */
-       lis     r5, (swapper_pg_dir - PAGE_OFFSET)@ha   /* if kernel address, use */
-       addi    r5 ,r5 ,(swapper_pg_dir - PAGE_OFFSET)@l        /* kernel page table */
+       lis     r5, (swapper_pg_dir - ADDR_OFFSET)@ha   /* if kernel address, use */
+       addi    r5 ,r5 ,(swapper_pg_dir - ADDR_OFFSET)@l        /* kernel page table */
        rlwimi  r3,r9,32-12,29,29       /* MSR_PR -> _PAGE_USER */
 112:
 #ifndef CONFIG_PTE_64BIT
@@ -80,6 +89,9 @@ _GLOBAL(hash_page)
        lwzx    r8,r8,r5                /* Get L1 entry */
        rlwinm. r8,r8,0,0,20            /* extract pt base address */
 #endif
+#ifdef CONFIG_VMAP_STACK
+       tovirt(r8, r8)
+#endif
 #ifdef CONFIG_SMP
        beq-    hash_page_out           /* return if no mapping */
 #else
@@ -137,9 +149,9 @@ retry:
 
 #ifdef CONFIG_SMP
        eieio
-       lis     r8, (mmu_hash_lock - PAGE_OFFSET)@ha
+       lis     r8, (mmu_hash_lock - ADDR_OFFSET)@ha
        li      r0,0
-       stw     r0, (mmu_hash_lock - PAGE_OFFSET)@l(r8)
+       stw     r0, (mmu_hash_lock - ADDR_OFFSET)@l(r8)
 #endif
 
        /* Return from the exception */
@@ -152,9 +164,9 @@ retry:
 #ifdef CONFIG_SMP
 hash_page_out:
        eieio
-       lis     r8, (mmu_hash_lock - PAGE_OFFSET)@ha
+       lis     r8, (mmu_hash_lock - ADDR_OFFSET)@ha
        li      r0,0
-       stw     r0, (mmu_hash_lock - PAGE_OFFSET)@l(r8)
+       stw     r0, (mmu_hash_lock - ADDR_OFFSET)@l(r8)
        blr
 #endif /* CONFIG_SMP */
 
@@ -329,7 +341,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
        patch_site      1f, patch__hash_page_A1
        patch_site      2f, patch__hash_page_A2
        /* Get the address of the primary PTE group in the hash table (r3) */
-0:     lis     r0, (Hash_base - PAGE_OFFSET)@h /* base address of hash table */
+0:     lis     r0, (Hash_base - ADDR_OFFSET)@h /* base address of hash table */
 1:     rlwimi  r0,r3,LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT    /* VSID -> hash */
 2:     rlwinm  r3,r4,20+LG_PTEG_SIZE,HASH_LEFT,HASH_RIGHT /* PI -> hash */
        xor     r3,r3,r0                /* make primary hash */
@@ -343,10 +355,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
        beq+    10f                     /* no PTE: go look for an empty slot */
        tlbie   r4
 
-       lis     r4, (htab_hash_searches - PAGE_OFFSET)@ha
-       lwz     r6, (htab_hash_searches - PAGE_OFFSET)@l(r4)
+       lis     r4, (htab_hash_searches - ADDR_OFFSET)@ha
+       lwz     r6, (htab_hash_searches - ADDR_OFFSET)@l(r4)
        addi    r6,r6,1                 /* count how many searches we do */
-       stw     r6, (htab_hash_searches - PAGE_OFFSET)@l(r4)
+       stw     r6, (htab_hash_searches - ADDR_OFFSET)@l(r4)
 
        /* Search the primary PTEG for a PTE whose 1st (d)word matches r5 */
        mtctr   r0
@@ -378,10 +390,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
        beq+    found_empty
 
        /* update counter of times that the primary PTEG is full */
-       lis     r4, (primary_pteg_full - PAGE_OFFSET)@ha
-       lwz     r6, (primary_pteg_full - PAGE_OFFSET)@l(r4)
+       lis     r4, (primary_pteg_full - ADDR_OFFSET)@ha
+       lwz     r6, (primary_pteg_full - ADDR_OFFSET)@l(r4)
        addi    r6,r6,1
-       stw     r6, (primary_pteg_full - PAGE_OFFSET)@l(r4)
+       stw     r6, (primary_pteg_full - ADDR_OFFSET)@l(r4)
 
        patch_site      0f, patch__hash_page_C
        /* Search the secondary PTEG for an empty slot */
@@ -415,8 +427,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT)
         * lockup here but that shouldn't happen
         */
 
-1:     lis     r4, (next_slot - PAGE_OFFSET)@ha        /* get next evict slot */
-       lwz     r6, (next_slot - PAGE_OFFSET)@l(r4)
+1:     lis     r4, (next_slot - ADDR_OFFSET)@ha        /* get next evict slot */
+       lwz     r6, (next_slot - ADDR_OFFSET)@l(r4)
        addi    r6,r6,HPTE_SIZE                 /* search for candidate */
        andi.   r6,r6,7*HPTE_SIZE
        stw     r6,next_slot@l(r4)
index 69b2419..0a1c65a 100644 (file)
@@ -413,6 +413,7 @@ void __init MMU_init_hw(void)
 void __init MMU_init_hw_patch(void)
 {
        unsigned int hmask = Hash_mask >> (16 - LG_HPTEG_SIZE);
+       unsigned int hash;
 
        if (ppc_md.progress)
                ppc_md.progress("hash:patch", 0x345);
@@ -424,8 +425,12 @@ void __init MMU_init_hw_patch(void)
        /*
         * Patch up the instructions in hashtable.S:create_hpte
         */
-       modify_instruction_site(&patch__hash_page_A0, 0xffff,
-                               ((unsigned int)Hash - PAGE_OFFSET) >> 16);
+       if (IS_ENABLED(CONFIG_VMAP_STACK))
+               hash = (unsigned int)Hash;
+       else
+               hash = (unsigned int)Hash - PAGE_OFFSET;
+
+       modify_instruction_site(&patch__hash_page_A0, 0xffff, hash >> 16);
        modify_instruction_site(&patch__hash_page_A1, 0x7c0, hash_mb << 6);
        modify_instruction_site(&patch__hash_page_A2, 0x7c0, hash_mb2 << 6);
        modify_instruction_site(&patch__hash_page_B, 0xffff, hmask);
index b30435c..523d4d3 100644 (file)
@@ -652,6 +652,7 @@ static void init_hpte_page_sizes(void)
 
 static void __init htab_init_page_sizes(void)
 {
+       bool aligned = true;
        init_hpte_page_sizes();
 
        if (!debug_pagealloc_enabled()) {
@@ -659,7 +660,15 @@ static void __init htab_init_page_sizes(void)
                 * Pick a size for the linear mapping. Currently, we only
                 * support 16M, 1M and 4K which is the default
                 */
-               if (mmu_psize_defs[MMU_PAGE_16M].shift)
+               if (IS_ENABLED(STRICT_KERNEL_RWX) &&
+                   (unsigned long)_stext % 0x1000000) {
+                       if (mmu_psize_defs[MMU_PAGE_16M].shift)
+                               pr_warn("Kernel not 16M aligned, "
+                                       "disabling 16M linear map alignment");
+                       aligned = false;
+               }
+
+               if (mmu_psize_defs[MMU_PAGE_16M].shift && aligned)
                        mmu_linear_psize = MMU_PAGE_16M;
                else if (mmu_psize_defs[MMU_PAGE_1M].shift)
                        mmu_linear_psize = MMU_PAGE_1M;
index 75483b4..2bf7e1b 100644 (file)
@@ -378,7 +378,6 @@ static inline void pgtable_free(void *table, int index)
        }
 }
 
-#ifdef CONFIG_SMP
 void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int index)
 {
        unsigned long pgf = (unsigned long)table;
@@ -395,12 +394,6 @@ void __tlb_remove_table(void *_table)
 
        return pgtable_free(table, index);
 }
-#else
-void pgtable_free_tlb(struct mmu_gather *tlb, void *table, int index)
-{
-       return pgtable_free(table, index);
-}
-#endif
 
 #ifdef CONFIG_PROC_FS
 atomic_long_t direct_pages_count[MMU_PAGE_COUNT];
index 974109b..dd1bea4 100644 (file)
@@ -337,7 +337,11 @@ static void __init radix_init_pgtable(void)
        }
 
        /* Find out how many PID bits are supported */
-       if (cpu_has_feature(CPU_FTR_HVMODE)) {
+       if (!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG)) {
+               if (!mmu_pid_bits)
+                       mmu_pid_bits = 20;
+               mmu_base_pid = 1;
+       } else if (cpu_has_feature(CPU_FTR_HVMODE)) {
                if (!mmu_pid_bits)
                        mmu_pid_bits = 20;
 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
index a95175c..03f43c9 100644 (file)
@@ -1161,6 +1161,9 @@ extern void radix_kvm_prefetch_workaround(struct mm_struct *mm)
        if (unlikely(pid == MMU_NO_CONTEXT))
                return;
 
+       if (!cpu_has_feature(CPU_FTR_P9_RADIX_PREFETCH_BUG))
+               return;
+
        /*
         * If this context hasn't run on that CPU before and KVM is
         * around, there's a slim chance that the guest on another
index b5047f9..8db0507 100644 (file)
@@ -233,7 +233,7 @@ static bool bad_kernel_fault(struct pt_regs *regs, unsigned long error_code,
 
        // Read/write fault in a valid region (the exception table search passed
        // above), but blocked by KUAP is bad, it can never succeed.
-       if (bad_kuap_fault(regs, is_write))
+       if (bad_kuap_fault(regs, address, is_write))
                return true;
 
        // What's left? Kernel fault on user in well defined regions (extable
@@ -279,12 +279,8 @@ static bool bad_stack_expansion(struct pt_regs *regs, unsigned long address,
                if ((flags & FAULT_FLAG_WRITE) && (flags & FAULT_FLAG_USER) &&
                    access_ok(nip, sizeof(*nip))) {
                        unsigned int inst;
-                       int res;
 
-                       pagefault_disable();
-                       res = __get_user_inatomic(inst, nip);
-                       pagefault_enable();
-                       if (!res)
+                       if (!probe_user_read(&inst, nip, sizeof(inst)))
                                return !store_updates_sp(inst);
                        *must_retry = true;
                }
@@ -354,6 +350,9 @@ static void sanity_check_fault(bool is_write, bool is_user,
         * Userspace trying to access kernel address, we get PROTFAULT for that.
         */
        if (is_user && address >= TASK_SIZE) {
+               if ((long)address == -1)
+                       return;
+
                pr_crit_ratelimited("%s[%d]: User access of kernel address (%lx) - exploit attempt? (uid: %d)\n",
                                   current->comm, current->pid, address,
                                   from_kuid(&init_user_ns, current_uid()));
index 0e6ed44..16dd95b 100644 (file)
@@ -12,7 +12,7 @@
 #include <asm/code-patching.h>
 #include <mm/mmu_decl.h>
 
-static pgprot_t kasan_prot_ro(void)
+static pgprot_t __init kasan_prot_ro(void)
 {
        if (early_mmu_has_feature(MMU_FTR_HPTE_TABLE))
                return PAGE_READONLY;
@@ -20,7 +20,7 @@ static pgprot_t kasan_prot_ro(void)
        return PAGE_KERNEL_RO;
 }
 
-static void kasan_populate_pte(pte_t *ptep, pgprot_t prot)
+static void __init kasan_populate_pte(pte_t *ptep, pgprot_t prot)
 {
        unsigned long va = (unsigned long)kasan_early_shadow_page;
        phys_addr_t pa = __pa(kasan_early_shadow_page);
@@ -30,29 +30,25 @@ static void kasan_populate_pte(pte_t *ptep, pgprot_t prot)
                __set_pte_at(&init_mm, va, ptep, pfn_pte(PHYS_PFN(pa), prot), 0);
 }
 
-static int __ref kasan_init_shadow_page_tables(unsigned long k_start, unsigned long k_end)
+static int __init kasan_init_shadow_page_tables(unsigned long k_start, unsigned long k_end)
 {
        pmd_t *pmd;
        unsigned long k_cur, k_next;
-       pgprot_t prot = slab_is_available() ? kasan_prot_ro() : PAGE_KERNEL;
+       pte_t *new = NULL;
 
        pmd = pmd_offset(pud_offset(pgd_offset_k(k_start), k_start), k_start);
 
        for (k_cur = k_start; k_cur != k_end; k_cur = k_next, pmd++) {
-               pte_t *new;
-
                k_next = pgd_addr_end(k_cur, k_end);
                if ((void *)pmd_page_vaddr(*pmd) != kasan_early_shadow_pte)
                        continue;
 
-               if (slab_is_available())
-                       new = pte_alloc_one_kernel(&init_mm);
-               else
+               if (!new)
                        new = memblock_alloc(PTE_FRAG_SIZE, PTE_FRAG_SIZE);
 
                if (!new)
                        return -ENOMEM;
-               kasan_populate_pte(new, prot);
+               kasan_populate_pte(new, PAGE_KERNEL);
 
                smp_wmb(); /* See comment in __pte_alloc */
 
@@ -63,39 +59,27 @@ static int __ref kasan_init_shadow_page_tables(unsigned long k_start, unsigned l
                        new = NULL;
                }
                spin_unlock(&init_mm.page_table_lock);
-
-               if (new && slab_is_available())
-                       pte_free_kernel(&init_mm, new);
        }
        return 0;
 }
 
-static void __ref *kasan_get_one_page(void)
-{
-       if (slab_is_available())
-               return (void *)__get_free_page(GFP_KERNEL | __GFP_ZERO);
-
-       return memblock_alloc(PAGE_SIZE, PAGE_SIZE);
-}
-
-static int __ref kasan_init_region(void *start, size_t size)
+static int __init kasan_init_region(void *start, size_t size)
 {
        unsigned long k_start = (unsigned long)kasan_mem_to_shadow(start);
        unsigned long k_end = (unsigned long)kasan_mem_to_shadow(start + size);
        unsigned long k_cur;
        int ret;
-       void *block = NULL;
+       void *block;
 
        ret = kasan_init_shadow_page_tables(k_start, k_end);
        if (ret)
                return ret;
 
-       if (!slab_is_available())
-               block = memblock_alloc(k_end - k_start, PAGE_SIZE);
+       block = memblock_alloc(k_end - k_start, PAGE_SIZE);
 
        for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) {
                pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur);
-               void *va = block ? block + k_cur - k_start : kasan_get_one_page();
+               void *va = block + k_cur - k_start;
                pte_t pte = pfn_pte(PHYS_PFN(__pa(va)), PAGE_KERNEL);
 
                if (!va)
@@ -129,6 +113,31 @@ static void __init kasan_remap_early_shadow_ro(void)
        flush_tlb_kernel_range(KASAN_SHADOW_START, KASAN_SHADOW_END);
 }
 
+static void __init kasan_unmap_early_shadow_vmalloc(void)
+{
+       unsigned long k_start = (unsigned long)kasan_mem_to_shadow((void *)VMALLOC_START);
+       unsigned long k_end = (unsigned long)kasan_mem_to_shadow((void *)VMALLOC_END);
+       unsigned long k_cur;
+       phys_addr_t pa = __pa(kasan_early_shadow_page);
+
+       if (!early_mmu_has_feature(MMU_FTR_HPTE_TABLE)) {
+               int ret = kasan_init_shadow_page_tables(k_start, k_end);
+
+               if (ret)
+                       panic("kasan: kasan_init_shadow_page_tables() failed");
+       }
+       for (k_cur = k_start & PAGE_MASK; k_cur < k_end; k_cur += PAGE_SIZE) {
+               pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur);
+               pte_t *ptep = pte_offset_kernel(pmd, k_cur);
+
+               if ((pte_val(*ptep) & PTE_RPN_MASK) != pa)
+                       continue;
+
+               __set_pte_at(&init_mm, k_cur, ptep, __pte(0), 0);
+       }
+       flush_tlb_kernel_range(k_start, k_end);
+}
+
 void __init kasan_mmu_init(void)
 {
        int ret;
@@ -165,34 +174,22 @@ void __init kasan_init(void)
        pr_info("KASAN init done\n");
 }
 
-#ifdef CONFIG_MODULES
-void *module_alloc(unsigned long size)
+void __init kasan_late_init(void)
 {
-       void *base;
-
-       base = __vmalloc_node_range(size, MODULE_ALIGN, VMALLOC_START, VMALLOC_END,
-                                   GFP_KERNEL, PAGE_KERNEL_EXEC, VM_FLUSH_RESET_PERMS,
-                                   NUMA_NO_NODE, __builtin_return_address(0));
-
-       if (!base)
-               return NULL;
-
-       if (!kasan_init_region(base, size))
-               return base;
-
-       vfree(base);
-
-       return NULL;
+       if (IS_ENABLED(CONFIG_KASAN_VMALLOC))
+               kasan_unmap_early_shadow_vmalloc();
 }
-#endif
 
 #ifdef CONFIG_PPC_BOOK3S_32
 u8 __initdata early_hash[256 << 10] __aligned(256 << 10) = {0};
 
 static void __init kasan_early_hash_table(void)
 {
-       modify_instruction_site(&patch__hash_page_A0, 0xffff, __pa(early_hash) >> 16);
-       modify_instruction_site(&patch__flush_hash_A0, 0xffff, __pa(early_hash) >> 16);
+       unsigned int hash = IS_ENABLED(CONFIG_VMAP_STACK) ? (unsigned int)early_hash :
+                                                           __pa(early_hash);
+
+       modify_instruction_site(&patch__hash_page_A0, 0xffff, hash >> 16);
+       modify_instruction_site(&patch__flush_hash_A0, 0xffff, hash >> 16);
 
        Hash = (struct hash_pte *)early_hash;
 }
index f5535ea..ef7b111 100644 (file)
@@ -49,6 +49,7 @@
 #include <asm/fixmap.h>
 #include <asm/swiotlb.h>
 #include <asm/rtas.h>
+#include <asm/kasan.h>
 
 #include <mm/mmu_decl.h>
 
@@ -301,6 +302,9 @@ void __init mem_init(void)
 
        high_memory = (void *) __va(max_low_pfn * PAGE_SIZE);
        set_max_mapnr(max_pfn);
+
+       kasan_late_init();
+
        memblock_free_all();
 
 #ifdef CONFIG_HIGHMEM
index 8e99649..7097e07 100644 (file)
@@ -181,3 +181,9 @@ void mmu_mark_rodata_ro(void);
 static inline void mmu_mark_initmem_nx(void) { }
 static inline void mmu_mark_rodata_ro(void) { }
 #endif
+
+#ifdef CONFIG_PPC_DEBUG_WX
+void ptdump_check_wx(void);
+#else
+static inline void ptdump_check_wx(void) { }
+#endif
index 96eb8e4..3189308 100644 (file)
@@ -21,33 +21,34 @@ extern int __map_without_ltlbs;
 static unsigned long block_mapped_ram;
 
 /*
- * Return PA for this VA if it is in an area mapped with LTLBs.
+ * Return PA for this VA if it is in an area mapped with LTLBs or fixmap.
  * Otherwise, returns 0
  */
 phys_addr_t v_block_mapped(unsigned long va)
 {
        unsigned long p = PHYS_IMMR_BASE;
 
-       if (__map_without_ltlbs)
-               return 0;
        if (va >= VIRT_IMMR_BASE && va < VIRT_IMMR_BASE + IMMR_SIZE)
                return p + va - VIRT_IMMR_BASE;
+       if (__map_without_ltlbs)
+               return 0;
        if (va >= PAGE_OFFSET && va < PAGE_OFFSET + block_mapped_ram)
                return __pa(va);
        return 0;
 }
 
 /*
- * Return VA for a given PA mapped with LTLBs or 0 if not mapped
+ * Return VA for a given PA mapped with LTLBs or fixmap
+ * Return 0 if not mapped
  */
 unsigned long p_block_mapped(phys_addr_t pa)
 {
        unsigned long p = PHYS_IMMR_BASE;
 
-       if (__map_without_ltlbs)
-               return 0;
        if (pa >= p && pa < p + IMMR_SIZE)
                return VIRT_IMMR_BASE + pa - p;
+       if (__map_without_ltlbs)
+               return 0;
        if (pa < block_mapped_ram)
                return (unsigned long)__va(pa);
        return 0;
index 50d68d2..3c7dec7 100644 (file)
@@ -1616,11 +1616,11 @@ static ssize_t topology_write(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct file_operations topology_ops = {
-       .read = seq_read,
-       .write = topology_write,
-       .open = topology_open,
-       .release = single_release
+static const struct proc_ops topology_proc_ops = {
+       .proc_read      = seq_read,
+       .proc_write     = topology_write,
+       .proc_open      = topology_open,
+       .proc_release   = single_release,
 };
 
 static int topology_update_init(void)
@@ -1630,7 +1630,7 @@ static int topology_update_init(void)
        if (vphn_enabled)
                topology_schedule_update();
 
-       if (!proc_create("powerpc/topology_updates", 0644, NULL, &topology_ops))
+       if (!proc_create("powerpc/topology_updates", 0644, NULL, &topology_proc_ops))
                return -ENOMEM;
 
        topology_inited = 1;
index 73b8416..5fb90ed 100644 (file)
@@ -218,6 +218,7 @@ void mark_rodata_ro(void)
 
        if (v_block_mapped((unsigned long)_sinittext)) {
                mmu_mark_rodata_ro();
+               ptdump_check_wx();
                return;
        }
 
index 2f9ddc2..2061562 100644 (file)
@@ -24,6 +24,8 @@
 #include <asm/page.h>
 #include <asm/pgalloc.h>
 
+#include <mm/mmu_decl.h>
+
 #include "ptdump.h"
 
 /*
@@ -173,10 +175,12 @@ static void dump_addr(struct pg_state *st, unsigned long addr)
 
 static void note_prot_wx(struct pg_state *st, unsigned long addr)
 {
+       pte_t pte = __pte(st->current_flags);
+
        if (!IS_ENABLED(CONFIG_PPC_DEBUG_WX) || !st->check_wx)
                return;
 
-       if (!((st->current_flags & pgprot_val(PAGE_KERNEL_X)) == pgprot_val(PAGE_KERNEL_X)))
+       if (!pte_write(pte) || !pte_exec(pte))
                return;
 
        WARN_ONCE(1, "powerpc/mm: Found insecure W+X mapping at address %p/%pS\n",
index 6ffcb80..6f347fa 100644 (file)
@@ -28,15 +28,12 @@ static unsigned int user_getsp32(unsigned int sp, int is_first)
        unsigned int stack_frame[2];
        void __user *p = compat_ptr(sp);
 
-       if (!access_ok(p, sizeof(stack_frame)))
-               return 0;
-
        /*
         * The most likely reason for this is that we returned -EFAULT,
         * which means that we've done all that we can do from
         * interrupt context.
         */
-       if (__copy_from_user_inatomic(stack_frame, p, sizeof(stack_frame)))
+       if (probe_user_read(stack_frame, (void __user *)p, sizeof(stack_frame)))
                return 0;
 
        if (!is_first)
@@ -54,11 +51,7 @@ static unsigned long user_getsp64(unsigned long sp, int is_first)
 {
        unsigned long stack_frame[3];
 
-       if (!access_ok((void __user *)sp, sizeof(stack_frame)))
-               return 0;
-
-       if (__copy_from_user_inatomic(stack_frame, (void __user *)sp,
-                                       sizeof(stack_frame)))
+       if (probe_user_read(stack_frame, (void __user *)sp, sizeof(stack_frame)))
                return 0;
 
        if (!is_first)
@@ -103,7 +96,6 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
                        first_frame = 0;
                }
        } else {
-               pagefault_disable();
 #ifdef CONFIG_PPC64
                if (!is_32bit_task()) {
                        while (depth--) {
@@ -112,7 +104,6 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
                                        break;
                                first_frame = 0;
                        }
-                       pagefault_enable();
                        return;
                }
 #endif
@@ -123,6 +114,5 @@ void op_powerpc_backtrace(struct pt_regs * const regs, unsigned int depth)
                                break;
                        first_frame = 0;
                }
-               pagefault_enable();
        }
 }
index 19124b0..1ad03c5 100644 (file)
@@ -157,10 +157,6 @@ static void mpc8xx_pmu_read(struct perf_event *event)
 
 static void mpc8xx_pmu_del(struct perf_event *event, int flags)
 {
-       /* mfspr r10, SPRN_SPRG_SCRATCH0 */
-       unsigned int insn = PPC_INST_MFSPR | __PPC_RS(R10) |
-                           __PPC_SPR(SPRN_SPRG_SCRATCH0);
-
        mpc8xx_pmu_read(event);
 
        /* If it was the last user, stop counting to avoid useles overhead */
@@ -173,6 +169,10 @@ static void mpc8xx_pmu_del(struct perf_event *event, int flags)
                break;
        case PERF_8xx_ID_ITLB_LOAD_MISS:
                if (atomic_dec_return(&itlb_miss_ref) == 0) {
+                       /* mfspr r10, SPRN_SPRG_SCRATCH0 */
+                       unsigned int insn = PPC_INST_MFSPR | __PPC_RS(R10) |
+                                           __PPC_SPR(SPRN_SPRG_SCRATCH0);
+
                        patch_instruction_site(&patch__itlbmiss_exit_1, insn);
 #ifndef CONFIG_PIN_TLB_TEXT
                        patch_instruction_site(&patch__itlbmiss_exit_2, insn);
@@ -181,6 +181,10 @@ static void mpc8xx_pmu_del(struct perf_event *event, int flags)
                break;
        case PERF_8xx_ID_DTLB_LOAD_MISS:
                if (atomic_dec_return(&dtlb_miss_ref) == 0) {
+                       /* mfspr r10, SPRN_DAR */
+                       unsigned int insn = PPC_INST_MFSPR | __PPC_RS(R10) |
+                                           __PPC_SPR(SPRN_DAR);
+
                        patch_instruction_site(&patch__dtlbmiss_exit_1, insn);
                        patch_instruction_site(&patch__dtlbmiss_exit_2, insn);
                        patch_instruction_site(&patch__dtlbmiss_exit_3, insn);
index 35d5425..cbc2519 100644 (file)
@@ -155,12 +155,8 @@ static int read_user_stack_64(unsigned long __user *ptr, unsigned long *ret)
            ((unsigned long)ptr & 7))
                return -EFAULT;
 
-       pagefault_disable();
-       if (!__get_user_inatomic(*ret, ptr)) {
-               pagefault_enable();
+       if (!probe_user_read(ret, ptr, sizeof(*ret)))
                return 0;
-       }
-       pagefault_enable();
 
        return read_user_stack_slow(ptr, ret, 8);
 }
@@ -171,12 +167,8 @@ static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
            ((unsigned long)ptr & 3))
                return -EFAULT;
 
-       pagefault_disable();
-       if (!__get_user_inatomic(*ret, ptr)) {
-               pagefault_enable();
+       if (!probe_user_read(ret, ptr, sizeof(*ret)))
                return 0;
-       }
-       pagefault_enable();
 
        return read_user_stack_slow(ptr, ret, 4);
 }
@@ -293,17 +285,11 @@ static void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
  */
 static int read_user_stack_32(unsigned int __user *ptr, unsigned int *ret)
 {
-       int rc;
-
        if ((unsigned long)ptr > TASK_SIZE - sizeof(unsigned int) ||
            ((unsigned long)ptr & 3))
                return -EFAULT;
 
-       pagefault_disable();
-       rc = __get_user_inatomic(*ret, ptr);
-       pagefault_enable();
-
-       return rc;
+       return probe_user_read(ret, ptr, sizeof(*ret));
 }
 
 static inline void perf_callchain_user_64(struct perf_callchain_entry_ctx *entry,
index 4860462..3086055 100644 (file)
@@ -415,7 +415,6 @@ static void power_pmu_sched_task(struct perf_event_context *ctx, bool sched_in)
 static __u64 power_pmu_bhrb_to(u64 addr)
 {
        unsigned int instr;
-       int ret;
        __u64 target;
 
        if (is_kernel_addr(addr)) {
@@ -426,13 +425,8 @@ static __u64 power_pmu_bhrb_to(u64 addr)
        }
 
        /* Userspace: need copy instruction here then translate it */
-       pagefault_disable();
-       ret = __get_user_inatomic(instr, (unsigned int __user *)addr);
-       if (ret) {
-               pagefault_enable();
+       if (probe_user_read(&instr, (unsigned int __user *)addr, sizeof(instr)))
                return 0;
-       }
-       pagefault_enable();
 
        target = branch_target(&instr);
        if ((!target) || (instr & BRANCH_ABSOLUTE))
index 13631f3..04bf6ec 100644 (file)
@@ -434,9 +434,9 @@ static int mpc512x_lpbfifo_probe(struct platform_device *pdev)
        memset(&lpbfifo, 0, sizeof(struct lpbfifo_data));
        spin_lock_init(&lpbfifo.lock);
 
-       lpbfifo.chan = dma_request_slave_channel(&pdev->dev, "rx-tx");
-       if (lpbfifo.chan == NULL)
-               return -EPROBE_DEFER;
+       lpbfifo.chan = dma_request_chan(&pdev->dev, "rx-tx");
+       if (IS_ERR(lpbfifo.chan))
+               return PTR_ERR(lpbfifo.chan);
 
        if (of_address_to_resource(pdev->dev.of_node, 0, &r) != 0) {
                dev_err(&pdev->dev, "bad 'reg' in 'sclpc' device tree node\n");
index 273145a..ada42f0 100644 (file)
@@ -34,7 +34,6 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 #include <soc/fsl/qe/qe.h>
-#include <soc/fsl/qe/qe_ic.h>
 
 #include "mpc83xx.h"
 
@@ -64,7 +63,7 @@ static void quirk_mpc8360e_qe_enet10(void)
                return;
        }
 
-       base = ioremap(res.start, res.end - res.start + 1);
+       base = ioremap(res.start, resource_size(&res));
 
        /*
         * set output delay adjustments to default values according
@@ -178,7 +177,7 @@ define_machine(mpc83xx_km) {
        .name           = "mpc83xx-km-platform",
        .probe          = mpc83xx_km_probe,
        .setup_arch     = mpc83xx_km_setup_arch,
-       .init_IRQ       = mpc83xx_ipic_and_qe_init_IRQ,
+       .init_IRQ       = mpc83xx_ipic_init_IRQ,
        .get_irq        = ipic_get_irq,
        .restart        = mpc83xx_restart,
        .time_init      = mpc83xx_time_init,
index 6399865..a952e91 100644 (file)
@@ -14,7 +14,6 @@
 #include <asm/io.h>
 #include <asm/hw_irq.h>
 #include <asm/ipic.h>
-#include <soc/fsl/qe/qe_ic.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 
@@ -91,28 +90,6 @@ void __init mpc83xx_ipic_init_IRQ(void)
        ipic_set_default_priority();
 }
 
-#ifdef CONFIG_QUICC_ENGINE
-void __init mpc83xx_qe_init_IRQ(void)
-{
-       struct device_node *np;
-
-       np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
-       if (!np) {
-               np = of_find_node_by_type(NULL, "qeic");
-               if (!np)
-                       return;
-       }
-       qe_ic_init(np, 0, qe_ic_cascade_low_ipic, qe_ic_cascade_high_ipic);
-       of_node_put(np);
-}
-
-void __init mpc83xx_ipic_and_qe_init_IRQ(void)
-{
-       mpc83xx_ipic_init_IRQ();
-       mpc83xx_qe_init_IRQ();
-}
-#endif /* CONFIG_QUICC_ENGINE */
-
 static const struct of_device_id of_bus_ids[] __initconst = {
        { .type = "soc", },
        { .compatible = "soc", },
index b428835..6fa5402 100644 (file)
@@ -33,7 +33,6 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 #include <soc/fsl/qe/qe.h>
-#include <soc/fsl/qe/qe_ic.h>
 
 #include "mpc83xx.h"
 
@@ -102,7 +101,7 @@ define_machine(mpc832x_mds) {
        .name           = "MPC832x MDS",
        .probe          = mpc832x_sys_probe,
        .setup_arch     = mpc832x_sys_setup_arch,
-       .init_IRQ       = mpc83xx_ipic_and_qe_init_IRQ,
+       .init_IRQ       = mpc83xx_ipic_init_IRQ,
        .get_irq        = ipic_get_irq,
        .restart        = mpc83xx_restart,
        .time_init      = mpc83xx_time_init,
index 4588ce6..622c625 100644 (file)
@@ -22,7 +22,6 @@
 #include <asm/ipic.h>
 #include <asm/udbg.h>
 #include <soc/fsl/qe/qe.h>
-#include <soc/fsl/qe/qe_ic.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 
@@ -220,7 +219,7 @@ define_machine(mpc832x_rdb) {
        .name           = "MPC832x RDB",
        .probe          = mpc832x_rdb_probe,
        .setup_arch     = mpc832x_rdb_setup_arch,
-       .init_IRQ       = mpc83xx_ipic_and_qe_init_IRQ,
+       .init_IRQ       = mpc83xx_ipic_init_IRQ,
        .get_irq        = ipic_get_irq,
        .restart        = mpc83xx_restart,
        .time_init      = mpc83xx_time_init,
index 240a26d..90d9cbf 100644 (file)
@@ -40,7 +40,6 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 #include <soc/fsl/qe/qe.h>
-#include <soc/fsl/qe/qe_ic.h>
 
 #include "mpc83xx.h"
 
@@ -202,7 +201,7 @@ define_machine(mpc836x_mds) {
        .name           = "MPC836x MDS",
        .probe          = mpc836x_mds_probe,
        .setup_arch     = mpc836x_mds_setup_arch,
-       .init_IRQ       = mpc83xx_ipic_and_qe_init_IRQ,
+       .init_IRQ       = mpc83xx_ipic_init_IRQ,
        .get_irq        = ipic_get_irq,
        .restart        = mpc83xx_restart,
        .time_init      = mpc83xx_time_init,
index 9923059..b4aac2c 100644 (file)
@@ -17,7 +17,6 @@
 #include <asm/ipic.h>
 #include <asm/udbg.h>
 #include <soc/fsl/qe/qe.h>
-#include <soc/fsl/qe/qe_ic.h>
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 
@@ -42,7 +41,7 @@ define_machine(mpc836x_rdk) {
        .name           = "MPC836x RDK",
        .probe          = mpc836x_rdk_probe,
        .setup_arch     = mpc836x_rdk_setup_arch,
-       .init_IRQ       = mpc83xx_ipic_and_qe_init_IRQ,
+       .init_IRQ       = mpc83xx_ipic_init_IRQ,
        .get_irq        = ipic_get_irq,
        .restart        = mpc83xx_restart,
        .time_init      = mpc83xx_time_init,
index 4591456..f37d043 100644 (file)
@@ -72,13 +72,6 @@ extern int mpc837x_usb_cfg(void);
 extern int mpc834x_usb_cfg(void);
 extern int mpc831x_usb_cfg(void);
 extern void mpc83xx_ipic_init_IRQ(void);
-#ifdef CONFIG_QUICC_ENGINE
-extern void mpc83xx_qe_init_IRQ(void);
-extern void mpc83xx_ipic_and_qe_init_IRQ(void);
-#else
-static inline void __init mpc83xx_qe_init_IRQ(void) {}
-#define mpc83xx_ipic_and_qe_init_IRQ mpc83xx_ipic_init_IRQ
-#endif /* CONFIG_QUICC_ENGINE */
 
 #ifdef CONFIG_PCI
 extern void mpc83xx_setup_pci(void);
index a328a74..27ac38f 100644 (file)
@@ -24,7 +24,6 @@
 #include <asm/mpic.h>
 #include <asm/ehv_pic.h>
 #include <asm/swiotlb.h>
-#include <soc/fsl/qe/qe_ic.h>
 
 #include <linux/of_platform.h>
 #include <sysdev/fsl_soc.h>
@@ -38,8 +37,6 @@ void __init corenet_gen_pic_init(void)
        unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
                MPIC_NO_RESET;
 
-       struct device_node *np;
-
        if (ppc_md.get_irq == mpic_get_coreint_irq)
                flags |= MPIC_ENABLE_COREINT;
 
@@ -47,13 +44,6 @@ void __init corenet_gen_pic_init(void)
        BUG_ON(mpic == NULL);
 
        mpic_init(mpic);
-
-       np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
-       if (np) {
-               qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
-                               qe_ic_cascade_high_mpic);
-               of_node_put(np);
-       }
 }
 
 /*
index 381a6ac..7759eca 100644 (file)
@@ -44,7 +44,6 @@
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
 #include <soc/fsl/qe/qe.h>
-#include <soc/fsl/qe/qe_ic.h>
 #include <asm/mpic.h>
 #include <asm/swiotlb.h>
 #include "smp.h"
@@ -268,33 +267,8 @@ static void __init mpc85xx_mds_qe_init(void)
        }
 }
 
-static void __init mpc85xx_mds_qeic_init(void)
-{
-       struct device_node *np;
-
-       np = of_find_compatible_node(NULL, NULL, "fsl,qe");
-       if (!of_device_is_available(np)) {
-               of_node_put(np);
-               return;
-       }
-
-       np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
-       if (!np) {
-               np = of_find_node_by_type(NULL, "qeic");
-               if (!np)
-                       return;
-       }
-
-       if (machine_is(p1021_mds))
-               qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
-                               qe_ic_cascade_high_mpic);
-       else
-               qe_ic_init(np, 0, qe_ic_cascade_muxed_mpic, NULL);
-       of_node_put(np);
-}
 #else
 static void __init mpc85xx_mds_qe_init(void) { }
-static void __init mpc85xx_mds_qeic_init(void) { }
 #endif /* CONFIG_QUICC_ENGINE */
 
 static void __init mpc85xx_mds_setup_arch(void)
@@ -364,7 +338,6 @@ static void __init mpc85xx_mds_pic_init(void)
        BUG_ON(mpic == NULL);
 
        mpic_init(mpic);
-       mpc85xx_mds_qeic_init();
 }
 
 static int __init mpc85xx_mds_probe(void)
index 7f9a84f..80a8017 100644 (file)
@@ -23,7 +23,6 @@
 #include <asm/udbg.h>
 #include <asm/mpic.h>
 #include <soc/fsl/qe/qe.h>
-#include <soc/fsl/qe/qe_ic.h>
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
@@ -44,10 +43,6 @@ void __init mpc85xx_rdb_pic_init(void)
 {
        struct mpic *mpic;
 
-#ifdef CONFIG_QUICC_ENGINE
-       struct device_node *np;
-#endif
-
        if (of_machine_is_compatible("fsl,MPC85XXRDB-CAMP")) {
                mpic = mpic_alloc(NULL, 0, MPIC_NO_RESET |
                        MPIC_BIG_ENDIAN |
@@ -62,18 +57,6 @@ void __init mpc85xx_rdb_pic_init(void)
 
        BUG_ON(mpic == NULL);
        mpic_init(mpic);
-
-#ifdef CONFIG_QUICC_ENGINE
-       np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
-       if (np) {
-               qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
-                               qe_ic_cascade_high_mpic);
-               of_node_put(np);
-
-       } else
-               pr_err("%s: Could not find qe-ic node\n", __func__);
-#endif
-
 }
 
 /*
index 8c7ea24..48f7d96 100644 (file)
@@ -252,6 +252,15 @@ static int smp_85xx_start_cpu(int cpu)
        out_be64((u64 *)(&spin_table->addr_h),
                __pa(ppc_function_entry(generic_secondary_smp_init)));
 #else
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+       /*
+        * We need also to write addr_h to spin table for systems
+        * in which their physical memory start address was configured
+        * to above 4G, otherwise the secondary core can not get
+        * correct entry to start from.
+        */
+       out_be32(&spin_table->addr_h, __pa(__early_start) >> 32);
+#endif
        out_be32(&spin_table->addr_l, __pa(__early_start));
 #endif
        flush_spin_table(spin_table);
index 6c3c0cd..eaec099 100644 (file)
@@ -19,7 +19,6 @@
 #include <asm/udbg.h>
 #include <asm/mpic.h>
 #include <soc/fsl/qe/qe.h>
-#include <soc/fsl/qe/qe_ic.h>
 
 #include <sysdev/fsl_soc.h>
 #include <sysdev/fsl_pci.h>
@@ -31,26 +30,12 @@ static void __init twr_p1025_pic_init(void)
 {
        struct mpic *mpic;
 
-#ifdef CONFIG_QUICC_ENGINE
-       struct device_node *np;
-#endif
-
        mpic = mpic_alloc(NULL, 0, MPIC_BIG_ENDIAN |
                        MPIC_SINGLE_DEST_CPU,
                        0, 256, " OpenPIC  ");
 
        BUG_ON(mpic == NULL);
        mpic_init(mpic);
-
-#ifdef CONFIG_QUICC_ENGINE
-       np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
-       if (np) {
-               qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
-                               qe_ic_cascade_high_mpic);
-               of_node_put(np);
-       } else
-               pr_err("Could not find qe-ic node\n");
-#endif
 }
 
 /* ************************************************************************
@@ -60,10 +45,6 @@ static void __init twr_p1025_pic_init(void)
  */
 static void __init twr_p1025_setup_arch(void)
 {
-#ifdef CONFIG_QUICC_ENGINE
-       struct device_node *np;
-#endif
-
        if (ppc_md.progress)
                ppc_md.progress("twr_p1025_setup_arch()", 0);
 
@@ -77,6 +58,7 @@ static void __init twr_p1025_setup_arch(void)
 #if IS_ENABLED(CONFIG_UCC_GETH) || IS_ENABLED(CONFIG_SERIAL_QE)
        if (machine_is(twr_p1025)) {
                struct ccsr_guts __iomem *guts;
+               struct device_node *np;
 
                np = of_find_compatible_node(NULL, NULL, "fsl,p1021-guts");
                if (np) {
index e28df29..1f80253 100644 (file)
@@ -177,6 +177,10 @@ config PPC_970_NAP
 config PPC_P7_NAP
        bool
 
+config PPC_BOOK3S_IDLE
+       def_bool y
+       depends on (PPC_970_NAP || PPC_P7_NAP)
+
 config PPC_INDIRECT_PIO
        bool
        select GENERIC_IOMAP
index 8d7f9c3..6caedc8 100644 (file)
@@ -1,4 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0
+config PPC32
+       bool
+       default y if !PPC64
+       select KASAN_VMALLOC if KASAN && MODULES
+
 config PPC64
        bool "64-bit kernel"
        select ZLIB_DEFLATE
@@ -31,12 +36,14 @@ config PPC_BOOK3S_6xx
        select PPC_HAVE_PMU_SUPPORT
        select PPC_HAVE_KUEP
        select PPC_HAVE_KUAP
+       select HAVE_ARCH_VMAP_STACK
 
 config PPC_BOOK3S_601
        bool "PowerPC 601"
        select PPC_BOOK3S_32
        select PPC_FPU
        select PPC_HAVE_KUAP
+       select HAVE_ARCH_VMAP_STACK
 
 config PPC_85xx
        bool "Freescale 85xx"
@@ -49,6 +56,7 @@ config PPC_8xx
        select PPC_HAVE_KUEP
        select PPC_HAVE_KUAP
        select PPC_MM_SLICES if HUGETLB_PAGE
+       select HAVE_ARCH_VMAP_STACK
 
 config 40x
        bool "AMCC 40x"
index 9b1586b..2539056 100644 (file)
@@ -583,7 +583,7 @@ enum {
        Opt_uid, Opt_gid, Opt_mode, Opt_debug,
 };
 
-static const struct fs_parameter_spec spufs_param_specs[] = {
+static const struct fs_parameter_spec spufs_fs_parameters[] = {
        fsparam_u32     ("gid",                         Opt_gid),
        fsparam_u32oct  ("mode",                        Opt_mode),
        fsparam_u32     ("uid",                         Opt_uid),
@@ -591,11 +591,6 @@ static const struct fs_parameter_spec spufs_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description spufs_fs_parameters = {
-       .name           = "spufs",
-       .specs          = spufs_param_specs,
-};
-
 static int spufs_show_options(struct seq_file *m, struct dentry *root)
 {
        struct spufs_sb_info *sbi = spufs_get_sb_info(root->d_sb);
@@ -623,7 +618,7 @@ static int spufs_parse_param(struct fs_context *fc, struct fs_parameter *param)
        kgid_t gid;
        int opt;
 
-       opt = fs_parse(fc, &spufs_fs_parameters, param, &result);
+       opt = fs_parse(fc, spufs_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -774,7 +769,7 @@ static struct file_system_type spufs_type = {
        .owner = THIS_MODULE,
        .name = "spufs",
        .init_fs_context = spufs_init_fs_context,
-       .parameters     = &spufs_fs_parameters,
+       .parameters     = spufs_fs_parameters,
        .kill_sb = kill_litter_super,
 };
 MODULE_ALIAS_FS("spufs");
index 47f7310..6f019df 100644 (file)
@@ -229,7 +229,7 @@ static void __init maple_init_IRQ(void)
        root = of_find_node_by_path("/");
        naddr = of_n_addr_cells(root);
        opprop = of_get_property(root, "platform-open-pic", &opplen);
-       if (opprop != 0) {
+       if (opprop) {
                openpic_addr = of_read_number(opprop, naddr);
                has_isus = (opplen > naddr);
                printk(KERN_DEBUG "OpenPIC addr: %lx, has ISUs: %d\n",
index a6ee080..2b3dfd0 100644 (file)
@@ -790,48 +790,81 @@ static int opal_sysfs_init(void)
        return 0;
 }
 
-static ssize_t symbol_map_read(struct file *fp, struct kobject *kobj,
-                              struct bin_attribute *bin_attr,
-                              char *buf, loff_t off, size_t count)
+static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
+                               struct bin_attribute *bin_attr, char *buf,
+                               loff_t off, size_t count)
 {
        return memory_read_from_buffer(buf, count, &off, bin_attr->private,
                                       bin_attr->size);
 }
 
-static struct bin_attribute symbol_map_attr = {
-       .attr = {.name = "symbol_map", .mode = 0400},
-       .read = symbol_map_read
-};
-
-static void opal_export_symmap(void)
+static int opal_add_one_export(struct kobject *parent, const char *export_name,
+                              struct device_node *np, const char *prop_name)
 {
-       const __be64 *syms;
-       unsigned int size;
-       struct device_node *fw;
+       struct bin_attribute *attr = NULL;
+       const char *name = NULL;
+       u64 vals[2];
        int rc;
 
-       fw = of_find_node_by_path("/ibm,opal/firmware");
-       if (!fw)
-               return;
-       syms = of_get_property(fw, "symbol-map", &size);
-       if (!syms || size != 2 * sizeof(__be64))
-               return;
+       rc = of_property_read_u64_array(np, prop_name, &vals[0], 2);
+       if (rc)
+               goto out;
 
-       /* Setup attributes */
-       symbol_map_attr.private = __va(be64_to_cpu(syms[0]));
-       symbol_map_attr.size = be64_to_cpu(syms[1]);
+       attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+       name = kstrdup(export_name, GFP_KERNEL);
+       if (!name) {
+               rc = -ENOMEM;
+               goto out;
+       }
 
-       rc = sysfs_create_bin_file(opal_kobj, &symbol_map_attr);
-       if (rc)
-               pr_warn("Error %d creating OPAL symbols file\n", rc);
+       sysfs_bin_attr_init(attr);
+       attr->attr.name = name;
+       attr->attr.mode = 0400;
+       attr->read = export_attr_read;
+       attr->private = __va(vals[0]);
+       attr->size = vals[1];
+
+       rc = sysfs_create_bin_file(parent, attr);
+out:
+       if (rc) {
+               kfree(name);
+               kfree(attr);
+       }
+
+       return rc;
 }
 
-static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
-                               struct bin_attribute *bin_attr, char *buf,
-                               loff_t off, size_t count)
+static void opal_add_exported_attrs(struct device_node *np,
+                                   struct kobject *kobj)
 {
-       return memory_read_from_buffer(buf, count, &off, bin_attr->private,
-                                      bin_attr->size);
+       struct device_node *child;
+       struct property *prop;
+
+       for_each_property_of_node(np, prop) {
+               int rc;
+
+               if (!strcmp(prop->name, "name") ||
+                   !strcmp(prop->name, "phandle"))
+                       continue;
+
+               rc = opal_add_one_export(kobj, prop->name, np, prop->name);
+               if (rc) {
+                       pr_warn("Unable to add export %pOF/%s, rc = %d!\n",
+                               np, prop->name, rc);
+               }
+       }
+
+       for_each_child_of_node(np, child) {
+               struct kobject *child_kobj;
+
+               child_kobj = kobject_create_and_add(child->name, kobj);
+               if (!child_kobj) {
+                       pr_err("Unable to create export dir for %pOF\n", child);
+                       continue;
+               }
+
+               opal_add_exported_attrs(child, child_kobj);
+       }
 }
 
 /*
@@ -843,11 +876,8 @@ static ssize_t export_attr_read(struct file *fp, struct kobject *kobj,
  */
 static void opal_export_attrs(void)
 {
-       struct bin_attribute *attr;
        struct device_node *np;
-       struct property *prop;
        struct kobject *kobj;
-       u64 vals[2];
        int rc;
 
        np = of_find_node_by_path("/ibm,opal/firmware/exports");
@@ -861,41 +891,16 @@ static void opal_export_attrs(void)
                return;
        }
 
-       for_each_property_of_node(np, prop) {
-               if (!strcmp(prop->name, "name") || !strcmp(prop->name, "phandle"))
-                       continue;
-
-               if (of_property_read_u64_array(np, prop->name, &vals[0], 2))
-                       continue;
-
-               attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+       opal_add_exported_attrs(np, kobj);
 
-               if (attr == NULL) {
-                       pr_warn("Failed kmalloc for bin_attribute!");
-                       continue;
-               }
-
-               sysfs_bin_attr_init(attr);
-               attr->attr.name = kstrdup(prop->name, GFP_KERNEL);
-               attr->attr.mode = 0400;
-               attr->read = export_attr_read;
-               attr->private = __va(vals[0]);
-               attr->size = vals[1];
-
-               if (attr->attr.name == NULL) {
-                       pr_warn("Failed kstrdup for bin_attribute attr.name");
-                       kfree(attr);
-                       continue;
-               }
-
-               rc = sysfs_create_bin_file(kobj, attr);
-               if (rc) {
-                       pr_warn("Error %d creating OPAL sysfs exports/%s file\n",
-                                rc, prop->name);
-                       kfree(attr->attr.name);
-                       kfree(attr);
-               }
-       }
+       /*
+        * NB: symbol_map existed before the generic export interface so it
+        * lives under the top level opal_kobj.
+        */
+       rc = opal_add_one_export(opal_kobj, "symbol_map",
+                                np->parent, "symbol-map");
+       if (rc)
+               pr_warn("Error %d creating OPAL symbols file\n", rc);
 
        of_node_put(np);
 }
@@ -1042,8 +1047,6 @@ static int __init opal_init(void)
        /* Create "opal" kobject under /sys/firmware */
        rc = opal_sysfs_init();
        if (rc == 0) {
-               /* Export symbol map to userspace */
-               opal_export_symmap();
                /* Setup dump region interface */
                opal_dump_region_init();
                /* Setup error log interface */
@@ -1056,11 +1059,10 @@ static int __init opal_init(void)
                opal_sys_param_init();
                /* Setup message log sysfs interface. */
                opal_msglog_sysfs_init();
+               /* Add all export properties*/
+               opal_export_attrs();
        }
 
-       /* Export all properties */
-       opal_export_attrs();
-
        /* Initialize platform devices: IPMI backend, PRD & flash interface */
        opal_pdev_init("ibm,opal-ipmi");
        opal_pdev_init("ibm,opal-flash");
index da1068a..22c22cd 100644 (file)
@@ -188,7 +188,7 @@ static void pnv_ioda_free_pe(struct pnv_ioda_pe *pe)
        unsigned int pe_num = pe->pe_number;
 
        WARN_ON(pe->pdev);
-       WARN_ON(pe->npucomp); /* NPUs are not supposed to be freed */
+       WARN_ON(pe->npucomp); /* NPUs for nvlink are not supposed to be freed */
        kfree(pe->npucomp);
        memset(pe, 0, sizeof(struct pnv_ioda_pe));
        clear_bit(pe_num, phb->ioda.pe_alloc);
@@ -777,6 +777,34 @@ static int pnv_ioda_set_peltv(struct pnv_phb *phb,
        return 0;
 }
 
+static void pnv_ioda_unset_peltv(struct pnv_phb *phb,
+                                struct pnv_ioda_pe *pe,
+                                struct pci_dev *parent)
+{
+       int64_t rc;
+
+       while (parent) {
+               struct pci_dn *pdn = pci_get_pdn(parent);
+
+               if (pdn && pdn->pe_number != IODA_INVALID_PE) {
+                       rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number,
+                                               pe->pe_number,
+                                               OPAL_REMOVE_PE_FROM_DOMAIN);
+                       /* XXX What to do in case of error ? */
+               }
+               parent = parent->bus->self;
+       }
+
+       opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number,
+                                 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
+
+       /* Disassociate PE in PELT */
+       rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number,
+                               pe->pe_number, OPAL_REMOVE_PE_FROM_DOMAIN);
+       if (rc)
+               pe_warn(pe, "OPAL error %lld remove self from PELTV\n", rc);
+}
+
 static int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
 {
        struct pci_dev *parent;
@@ -792,7 +820,7 @@ static int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
                fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER;
                parent = pe->pbus->self;
                if (pe->flags & PNV_IODA_PE_BUS_ALL)
-                       count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1;
+                       count = resource_size(&pe->pbus->busn_res);
                else
                        count = 1;
 
@@ -827,25 +855,13 @@ static int pnv_ioda_deconfigure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
        for (rid = pe->rid; rid < rid_end; rid++)
                phb->ioda.pe_rmap[rid] = IODA_INVALID_PE;
 
-       /* Release from all parents PELT-V */
-       while (parent) {
-               struct pci_dn *pdn = pci_get_pdn(parent);
-               if (pdn && pdn->pe_number != IODA_INVALID_PE) {
-                       rc = opal_pci_set_peltv(phb->opal_id, pdn->pe_number,
-                                               pe->pe_number, OPAL_REMOVE_PE_FROM_DOMAIN);
-                       /* XXX What to do in case of error ? */
-               }
-               parent = parent->bus->self;
-       }
-
-       opal_pci_eeh_freeze_clear(phb->opal_id, pe->pe_number,
-                                 OPAL_EEH_ACTION_CLEAR_FREEZE_ALL);
+       /*
+        * Release from all parents PELT-V. NPUs don't have a PELTV
+        * table
+        */
+       if (phb->type != PNV_PHB_NPU_NVLINK && phb->type != PNV_PHB_NPU_OCAPI)
+               pnv_ioda_unset_peltv(phb, pe, parent);
 
-       /* Disassociate PE in PELT */
-       rc = opal_pci_set_peltv(phb->opal_id, pe->pe_number,
-                               pe->pe_number, OPAL_REMOVE_PE_FROM_DOMAIN);
-       if (rc)
-               pe_warn(pe, "OPAL error %lld remove self from PELTV\n", rc);
        rc = opal_pci_set_pe(phb->opal_id, pe->pe_number, pe->rid,
                             bcomp, dcomp, fcomp, OPAL_UNMAP_PE);
        if (rc)
@@ -874,7 +890,7 @@ static int pnv_ioda_configure_pe(struct pnv_phb *phb, struct pnv_ioda_pe *pe)
                fcomp = OPAL_IGNORE_RID_FUNCTION_NUMBER;
                parent = pe->pbus->self;
                if (pe->flags & PNV_IODA_PE_BUS_ALL)
-                       count = pe->pbus->busn_res.end - pe->pbus->busn_res.start + 1;
+                       count = resource_size(&pe->pbus->busn_res);
                else
                        count = 1;
 
@@ -1062,20 +1078,20 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
                return NULL;
        }
 
-       /* NOTE: We get only one ref to the pci_dev for the pdn, not for the
-        * pointer in the PE data structure, both should be destroyed at the
-        * same time. However, this needs to be looked at more closely again
-        * once we actually start removing things (Hotplug, SR-IOV, ...)
+       /* NOTE: We don't get a reference for the pointer in the PE
+        * data structure, both the device and PE structures should be
+        * destroyed at the same time. However, removing nvlink
+        * devices will need some work.
         *
         * At some point we want to remove the PDN completely anyways
         */
-       pci_dev_get(dev);
        pdn->pe_number = pe->pe_number;
        pe->flags = PNV_IODA_PE_DEV;
        pe->pdev = dev;
        pe->pbus = NULL;
        pe->mve_number = -1;
        pe->rid = dev->bus->number << 8 | pdn->devfn;
+       pe->device_count++;
 
        pe_info(pe, "Associated device to PE\n");
 
@@ -1084,13 +1100,13 @@ static struct pnv_ioda_pe *pnv_ioda_setup_dev_PE(struct pci_dev *dev)
                pnv_ioda_free_pe(pe);
                pdn->pe_number = IODA_INVALID_PE;
                pe->pdev = NULL;
-               pci_dev_put(dev);
                return NULL;
        }
 
        /* Put PE to the list */
+       mutex_lock(&phb->ioda.pe_list_mutex);
        list_add_tail(&pe->list, &phb->ioda.pe_list);
-
+       mutex_unlock(&phb->ioda.pe_list_mutex);
        return pe;
 }
 
@@ -1206,6 +1222,14 @@ static struct pnv_ioda_pe *pnv_ioda_setup_npu_PE(struct pci_dev *npu_pdev)
        struct pnv_phb *phb = hose->private_data;
 
        /*
+        * Intentionally leak a reference on the npu device (for
+        * nvlink only; this is not an opencapi path) to make sure it
+        * never goes away, as it's been the case all along and some
+        * work is needed otherwise.
+        */
+       pci_dev_get(npu_pdev);
+
+       /*
         * Due to a hardware errata PE#0 on the NPU is reserved for
         * error handling. This means we only have three PEs remaining
         * which need to be assigned to four links, implying some
@@ -1228,11 +1252,11 @@ static struct pnv_ioda_pe *pnv_ioda_setup_npu_PE(struct pci_dev *npu_pdev)
                         */
                        dev_info(&npu_pdev->dev,
                                "Associating to existing PE %x\n", pe_num);
-                       pci_dev_get(npu_pdev);
                        npu_pdn = pci_get_pdn(npu_pdev);
                        rid = npu_pdev->bus->number << 8 | npu_pdn->devfn;
                        npu_pdn->pe_number = pe_num;
                        phb->ioda.pe_rmap[rid] = pe->pe_number;
+                       pe->device_count++;
 
                        /* Map the PE to this link */
                        rc = opal_pci_set_pe(phb->opal_id, pe_num, rid,
@@ -1268,8 +1292,6 @@ static void pnv_pci_ioda_setup_PEs(void)
 {
        struct pci_controller *hose;
        struct pnv_phb *phb;
-       struct pci_bus *bus;
-       struct pci_dev *pdev;
        struct pnv_ioda_pe *pe;
 
        list_for_each_entry(hose, &hose_list, list_node) {
@@ -1281,11 +1303,6 @@ static void pnv_pci_ioda_setup_PEs(void)
                        if (phb->model == PNV_PHB_MODEL_NPU2)
                                WARN_ON_ONCE(pnv_npu2_init(hose));
                }
-               if (phb->type == PNV_PHB_NPU_OCAPI) {
-                       bus = hose->bus;
-                       list_for_each_entry(pdev, &bus->devices, bus_list)
-                               pnv_ioda_setup_dev_PE(pdev);
-               }
        }
        list_for_each_entry(hose, &hose_list, list_node) {
                phb = hose->private_data;
@@ -1558,6 +1575,10 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
 
        /* Reserve PE for each VF */
        for (vf_index = 0; vf_index < num_vfs; vf_index++) {
+               int vf_devfn = pci_iov_virtfn_devfn(pdev, vf_index);
+               int vf_bus = pci_iov_virtfn_bus(pdev, vf_index);
+               struct pci_dn *vf_pdn;
+
                if (pdn->m64_single_mode)
                        pe_num = pdn->pe_num_map[vf_index];
                else
@@ -1570,13 +1591,11 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
                pe->pbus = NULL;
                pe->parent_dev = pdev;
                pe->mve_number = -1;
-               pe->rid = (pci_iov_virtfn_bus(pdev, vf_index) << 8) |
-                          pci_iov_virtfn_devfn(pdev, vf_index);
+               pe->rid = (vf_bus << 8) | vf_devfn;
 
                pe_info(pe, "VF %04d:%02d:%02d.%d associated with PE#%x\n",
                        hose->global_number, pdev->bus->number,
-                       PCI_SLOT(pci_iov_virtfn_devfn(pdev, vf_index)),
-                       PCI_FUNC(pci_iov_virtfn_devfn(pdev, vf_index)), pe_num);
+                       PCI_SLOT(vf_devfn), PCI_FUNC(vf_devfn), pe_num);
 
                if (pnv_ioda_configure_pe(phb, pe)) {
                        /* XXX What do we do here ? */
@@ -1590,6 +1609,15 @@ static void pnv_ioda_setup_vf_PE(struct pci_dev *pdev, u16 num_vfs)
                list_add_tail(&pe->list, &phb->ioda.pe_list);
                mutex_unlock(&phb->ioda.pe_list_mutex);
 
+               /* associate this pe to it's pdn */
+               list_for_each_entry(vf_pdn, &pdn->parent->child_list, list) {
+                       if (vf_pdn->busno == vf_bus &&
+                           vf_pdn->devfn == vf_devfn) {
+                               vf_pdn->pe_number = pe_num;
+                               break;
+                       }
+               }
+
                pnv_pci_ioda2_setup_dma_pe(phb, pe);
 #ifdef CONFIG_IOMMU_API
                iommu_register_group(&pe->table_group,
@@ -1719,21 +1747,23 @@ int pnv_pcibios_sriov_disable(struct pci_dev *pdev)
        pnv_pci_sriov_disable(pdev);
 
        /* Release PCI data */
-       remove_dev_pci_data(pdev);
+       remove_sriov_vf_pdns(pdev);
        return 0;
 }
 
 int pnv_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
 {
        /* Allocate PCI data */
-       add_dev_pci_data(pdev);
+       add_sriov_vf_pdns(pdev);
 
        return pnv_pci_sriov_enable(pdev, num_vfs);
 }
 #endif /* CONFIG_PCI_IOV */
 
-static void pnv_pci_ioda_dma_dev_setup(struct pnv_phb *phb, struct pci_dev *pdev)
+static void pnv_pci_ioda_dma_dev_setup(struct pci_dev *pdev)
 {
+       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
+       struct pnv_phb *phb = hose->private_data;
        struct pci_dn *pdn = pci_get_pdn(pdev);
        struct pnv_ioda_pe *pe;
 
@@ -2889,9 +2919,6 @@ static void pnv_pci_ioda_fixup_iov_resources(struct pci_dev *pdev)
        struct pci_dn *pdn;
        int mul, total_vfs;
 
-       if (!pdev->is_physfn || pci_dev_is_added(pdev))
-               return;
-
        pdn = pci_get_pdn(pdev);
        pdn->vfs_expanded = 0;
        pdn->m64_single_mode = false;
@@ -2966,6 +2993,30 @@ truncate_iov:
                res->end = res->start - 1;
        }
 }
+
+static void pnv_pci_ioda_fixup_iov(struct pci_dev *pdev)
+{
+       if (WARN_ON(pci_dev_is_added(pdev)))
+               return;
+
+       if (pdev->is_virtfn) {
+               struct pnv_ioda_pe *pe = pnv_ioda_get_pe(pdev);
+
+               /*
+                * VF PEs are single-device PEs so their pdev pointer needs to
+                * be set. The pdev doesn't exist when the PE is allocated (in
+                * (pcibios_sriov_enable()) so we fix it up here.
+                */
+               pe->pdev = pdev;
+               WARN_ON(!(pe->flags & PNV_IODA_PE_VF));
+       } else if (pdev->is_physfn) {
+               /*
+                * For PFs adjust their allocated IOV resources to match what
+                * the PHB can support using it's M64 BAR table.
+                */
+               pnv_pci_ioda_fixup_iov_resources(pdev);
+       }
+}
 #endif /* CONFIG_PCI_IOV */
 
 static void pnv_ioda_setup_pe_res(struct pnv_ioda_pe *pe,
@@ -3062,19 +3113,9 @@ static void pnv_ioda_setup_pe_seg(struct pnv_ioda_pe *pe)
 #ifdef CONFIG_DEBUG_FS
 static int pnv_pci_diag_data_set(void *data, u64 val)
 {
-       struct pci_controller *hose;
-       struct pnv_phb *phb;
+       struct pnv_phb *phb = data;
        s64 ret;
 
-       if (val != 1ULL)
-               return -EINVAL;
-
-       hose = (struct pci_controller *)data;
-       if (!hose || !hose->private_data)
-               return -ENODEV;
-
-       phb = hose->private_data;
-
        /* Retrieve the diag data from firmware */
        ret = opal_pci_get_phb_diag_data2(phb->opal_id, phb->diag_data,
                                          phb->diag_data_size);
@@ -3089,6 +3130,33 @@ static int pnv_pci_diag_data_set(void *data, u64 val)
 DEFINE_DEBUGFS_ATTRIBUTE(pnv_pci_diag_data_fops, NULL, pnv_pci_diag_data_set,
                         "%llu\n");
 
+static int pnv_pci_ioda_pe_dump(void *data, u64 val)
+{
+       struct pnv_phb *phb = data;
+       int pe_num;
+
+       for (pe_num = 0; pe_num < phb->ioda.total_pe_num; pe_num++) {
+               struct pnv_ioda_pe *pe = &phb->ioda.pe_array[pe_num];
+
+               if (!test_bit(pe_num, phb->ioda.pe_alloc))
+                       continue;
+
+               pe_warn(pe, "rid: %04x dev count: %2d flags: %s%s%s%s%s%s\n",
+                       pe->rid, pe->device_count,
+                       (pe->flags & PNV_IODA_PE_DEV) ? "dev " : "",
+                       (pe->flags & PNV_IODA_PE_BUS) ? "bus " : "",
+                       (pe->flags & PNV_IODA_PE_BUS_ALL) ? "all " : "",
+                       (pe->flags & PNV_IODA_PE_MASTER) ? "master " : "",
+                       (pe->flags & PNV_IODA_PE_SLAVE) ? "slave " : "",
+                       (pe->flags & PNV_IODA_PE_VF) ? "vf " : "");
+       }
+
+       return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(pnv_pci_ioda_pe_dump_fops, NULL,
+                        pnv_pci_ioda_pe_dump, "%llu\n");
+
 #endif /* CONFIG_DEBUG_FS */
 
 static void pnv_pci_ioda_create_dbgfs(void)
@@ -3113,7 +3181,9 @@ static void pnv_pci_ioda_create_dbgfs(void)
                }
 
                debugfs_create_file_unsafe("dump_diag_regs", 0200, phb->dbgfs,
-                                          hose, &pnv_pci_diag_data_fops);
+                                          phb, &pnv_pci_diag_data_fops);
+               debugfs_create_file_unsafe("dump_ioda_pe_state", 0200, phb->dbgfs,
+                                          phb, &pnv_pci_ioda_pe_dump_fops);
        }
 #endif /* CONFIG_DEBUG_FS */
 }
@@ -3383,6 +3453,28 @@ static bool pnv_pci_enable_device_hook(struct pci_dev *dev)
        return true;
 }
 
+static bool pnv_ocapi_enable_device_hook(struct pci_dev *dev)
+{
+       struct pci_controller *hose = pci_bus_to_host(dev->bus);
+       struct pnv_phb *phb = hose->private_data;
+       struct pci_dn *pdn;
+       struct pnv_ioda_pe *pe;
+
+       if (!phb->initialized)
+               return true;
+
+       pdn = pci_get_pdn(dev);
+       if (!pdn)
+               return false;
+
+       if (pdn->pe_number == IODA_INVALID_PE) {
+               pe = pnv_ioda_setup_dev_PE(dev);
+               if (!pe)
+                       return false;
+       }
+       return true;
+}
+
 static long pnv_pci_ioda1_unset_window(struct iommu_table_group *table_group,
                                       int num)
 {
@@ -3512,7 +3604,10 @@ static void pnv_ioda_release_pe(struct pnv_ioda_pe *pe)
        struct pnv_phb *phb = pe->phb;
        struct pnv_ioda_pe *slave, *tmp;
 
+       mutex_lock(&phb->ioda.pe_list_mutex);
        list_del(&pe->list);
+       mutex_unlock(&phb->ioda.pe_list_mutex);
+
        switch (phb->type) {
        case PNV_PHB_IODA1:
                pnv_pci_ioda1_release_pe_dma(pe);
@@ -3520,6 +3615,8 @@ static void pnv_ioda_release_pe(struct pnv_ioda_pe *pe)
        case PNV_PHB_IODA2:
                pnv_pci_ioda2_release_pe_dma(pe);
                break;
+       case PNV_PHB_NPU_OCAPI:
+               break;
        default:
                WARN_ON(1);
        }
@@ -3594,9 +3691,29 @@ static void pnv_pci_ioda_shutdown(struct pci_controller *hose)
                       OPAL_ASSERT_RESET);
 }
 
+static void pnv_pci_ioda_dma_bus_setup(struct pci_bus *bus)
+{
+       struct pci_controller *hose = bus->sysdata;
+       struct pnv_phb *phb = hose->private_data;
+       struct pnv_ioda_pe *pe;
+
+       list_for_each_entry(pe, &phb->ioda.pe_list, list) {
+               if (!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)))
+                       continue;
+
+               if (!pe->pbus)
+                       continue;
+
+               if (bus->number == ((pe->rid >> 8) & 0xFF)) {
+                       pe->pbus = bus;
+                       break;
+               }
+       }
+}
+
 static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
-       .dma_dev_setup          = pnv_pci_dma_dev_setup,
-       .dma_bus_setup          = pnv_pci_dma_bus_setup,
+       .dma_dev_setup          = pnv_pci_ioda_dma_dev_setup,
+       .dma_bus_setup          = pnv_pci_ioda_dma_bus_setup,
        .iommu_bypass_supported = pnv_pci_ioda_iommu_bypass_supported,
        .setup_msi_irqs         = pnv_setup_msi_irqs,
        .teardown_msi_irqs      = pnv_teardown_msi_irqs,
@@ -3609,7 +3726,6 @@ static const struct pci_controller_ops pnv_pci_ioda_controller_ops = {
 };
 
 static const struct pci_controller_ops pnv_npu_ioda_controller_ops = {
-       .dma_dev_setup          = pnv_pci_dma_dev_setup,
        .setup_msi_irqs         = pnv_setup_msi_irqs,
        .teardown_msi_irqs      = pnv_teardown_msi_irqs,
        .enable_device_hook     = pnv_pci_enable_device_hook,
@@ -3620,7 +3736,8 @@ static const struct pci_controller_ops pnv_npu_ioda_controller_ops = {
 };
 
 static const struct pci_controller_ops pnv_npu_ocapi_ioda_controller_ops = {
-       .enable_device_hook     = pnv_pci_enable_device_hook,
+       .enable_device_hook     = pnv_ocapi_enable_device_hook,
+       .release_device         = pnv_pci_release_device,
        .window_alignment       = pnv_pci_window_alignment,
        .reset_secondary_bus    = pnv_pci_reset_secondary_bus,
        .shutdown               = pnv_pci_ioda_shutdown,
@@ -3855,14 +3972,13 @@ static void __init pnv_pci_init_ioda_phb(struct device_node *np,
                hose->controller_ops = pnv_npu_ocapi_ioda_controller_ops;
                break;
        default:
-               phb->dma_dev_setup = pnv_pci_ioda_dma_dev_setup;
                hose->controller_ops = pnv_pci_ioda_controller_ops;
        }
 
        ppc_md.pcibios_default_alignment = pnv_pci_default_alignment;
 
 #ifdef CONFIG_PCI_IOV
-       ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov_resources;
+       ppc_md.pcibios_fixup_sriov = pnv_pci_ioda_fixup_iov;
        ppc_md.pcibios_iov_resource_alignment = pnv_pci_iov_resource_alignment;
        ppc_md.pcibios_sriov_enable = pnv_pcibios_sriov_enable;
        ppc_md.pcibios_sriov_disable = pnv_pcibios_sriov_disable;
index c0bea75..5bf8182 100644 (file)
@@ -38,7 +38,7 @@ static DEFINE_MUTEX(tunnel_mutex);
 
 int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id)
 {
-       struct device_node *parent = np;
+       struct device_node *node = np;
        u32 bdfn;
        u64 phbid;
        int ret;
@@ -48,25 +48,29 @@ int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id)
                return -ENXIO;
 
        bdfn = ((bdfn & 0x00ffff00) >> 8);
-       while ((parent = of_get_parent(parent))) {
-               if (!PCI_DN(parent)) {
-                       of_node_put(parent);
+       for (node = np; node; node = of_get_parent(node)) {
+               if (!PCI_DN(node)) {
+                       of_node_put(node);
                        break;
                }
 
-               if (!of_device_is_compatible(parent, "ibm,ioda2-phb") &&
-                   !of_device_is_compatible(parent, "ibm,ioda3-phb")) {
-                       of_node_put(parent);
+               if (!of_device_is_compatible(node, "ibm,ioda2-phb") &&
+                   !of_device_is_compatible(node, "ibm,ioda3-phb") &&
+                   !of_device_is_compatible(node, "ibm,ioda2-npu2-opencapi-phb")) {
+                       of_node_put(node);
                        continue;
                }
 
-               ret = of_property_read_u64(parent, "ibm,opal-phbid", &phbid);
+               ret = of_property_read_u64(node, "ibm,opal-phbid", &phbid);
                if (ret) {
-                       of_node_put(parent);
+                       of_node_put(node);
                        return -ENXIO;
                }
 
-               *id = PCI_SLOT_ID(phbid, bdfn);
+               if (of_device_is_compatible(node, "ibm,ioda2-npu2-opencapi-phb"))
+                       *id = PCI_PHB_SLOT_ID(phbid);
+               else
+                       *id = PCI_SLOT_ID(phbid, bdfn);
                return 0;
        }
 
@@ -810,53 +814,6 @@ struct iommu_table *pnv_pci_table_alloc(int nid)
        return tbl;
 }
 
-void pnv_pci_dma_dev_setup(struct pci_dev *pdev)
-{
-       struct pci_controller *hose = pci_bus_to_host(pdev->bus);
-       struct pnv_phb *phb = hose->private_data;
-#ifdef CONFIG_PCI_IOV
-       struct pnv_ioda_pe *pe;
-       struct pci_dn *pdn;
-
-       /* Fix the VF pdn PE number */
-       if (pdev->is_virtfn) {
-               pdn = pci_get_pdn(pdev);
-               WARN_ON(pdn->pe_number != IODA_INVALID_PE);
-               list_for_each_entry(pe, &phb->ioda.pe_list, list) {
-                       if (pe->rid == ((pdev->bus->number << 8) |
-                           (pdev->devfn & 0xff))) {
-                               pdn->pe_number = pe->pe_number;
-                               pe->pdev = pdev;
-                               break;
-                       }
-               }
-       }
-#endif /* CONFIG_PCI_IOV */
-
-       if (phb && phb->dma_dev_setup)
-               phb->dma_dev_setup(phb, pdev);
-}
-
-void pnv_pci_dma_bus_setup(struct pci_bus *bus)
-{
-       struct pci_controller *hose = bus->sysdata;
-       struct pnv_phb *phb = hose->private_data;
-       struct pnv_ioda_pe *pe;
-
-       list_for_each_entry(pe, &phb->ioda.pe_list, list) {
-               if (!(pe->flags & (PNV_IODA_PE_BUS | PNV_IODA_PE_BUS_ALL)))
-                       continue;
-
-               if (!pe->pbus)
-                       continue;
-
-               if (bus->number == ((pe->rid >> 8) & 0xFF)) {
-                       pe->pbus = bus;
-                       break;
-               }
-       }
-}
-
 struct device_node *pnv_pci_get_phb_node(struct pci_dev *dev)
 {
        struct pci_controller *hose = pci_bus_to_host(dev->bus);
index f914f0b..d3bbdea 100644 (file)
@@ -108,7 +108,6 @@ struct pnv_phb {
        int (*msi_setup)(struct pnv_phb *phb, struct pci_dev *dev,
                         unsigned int hwirq, unsigned int virq,
                         unsigned int is_64, struct msi_msg *msg);
-       void (*dma_dev_setup)(struct pnv_phb *phb, struct pci_dev *pdev);
        int (*init_m64)(struct pnv_phb *phb);
        int (*get_pe_state)(struct pnv_phb *phb, int pe_no);
        void (*freeze_pe)(struct pnv_phb *phb, int pe_no);
@@ -189,8 +188,6 @@ extern void pnv_npu2_map_lpar(struct pnv_ioda_pe *gpe, unsigned long msr);
 extern void pnv_pci_reset_secondary_bus(struct pci_dev *dev);
 extern int pnv_eeh_phb_reset(struct pci_controller *hose, int option);
 
-extern void pnv_pci_dma_dev_setup(struct pci_dev *pdev);
-extern void pnv_pci_dma_bus_setup(struct pci_bus *bus);
 extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type);
 extern void pnv_teardown_msi_irqs(struct pci_dev *pdev);
 extern struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev);
index 8349860..11fdae8 100644 (file)
@@ -233,6 +233,10 @@ static void  __noreturn pnv_restart(char *cmd)
                        rc = opal_cec_reboot();
                else if (strcmp(cmd, "full") == 0)
                        rc = opal_cec_reboot2(OPAL_REBOOT_FULL_IPL, NULL);
+               else if (strcmp(cmd, "mpipl") == 0)
+                       rc = opal_cec_reboot2(OPAL_REBOOT_MPIPL, NULL);
+               else if (strcmp(cmd, "error") == 0)
+                       rc = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR, NULL);
                else
                        rc = OPAL_UNSUPPORTED;
 
index 595e9f8..24c1836 100644 (file)
@@ -21,7 +21,6 @@ config PPC_PSERIES
        select PPC_DOORBELL
        select HOTPLUG_CPU
        select ARCH_RANDOM
-       select PPC_DOORBELL
        select FORCE_SMP
        select SWIOTLB
        default y
index d4a8f17..3e49cc2 100644 (file)
@@ -22,6 +22,7 @@
 #include <asm/firmware.h>
 #include <asm/prom.h>
 #include <asm/udbg.h>
+#include <asm/svm.h>
 
 #include "pseries.h"
 
@@ -55,7 +56,8 @@ hypertas_fw_features_table[] = {
        {FW_FEATURE_LLAN,               "hcall-lLAN"},
        {FW_FEATURE_BULK_REMOVE,        "hcall-bulk"},
        {FW_FEATURE_XDABR,              "hcall-xdabr"},
-       {FW_FEATURE_MULTITCE,           "hcall-multi-tce"},
+       {FW_FEATURE_PUT_TCE_IND | FW_FEATURE_STUFF_TCE,
+                                       "hcall-multi-tce"},
        {FW_FEATURE_SPLPAR,             "hcall-splpar"},
        {FW_FEATURE_VPHN,               "hcall-vphn"},
        {FW_FEATURE_SET_MODE,           "hcall-set-mode"},
@@ -100,6 +102,12 @@ static void __init fw_hypertas_feature_init(const char *hypertas,
                }
        }
 
+       if (is_secure_guest() &&
+           (powerpc_firmware_features & FW_FEATURE_PUT_TCE_IND)) {
+               powerpc_firmware_features &= ~FW_FEATURE_PUT_TCE_IND;
+               pr_debug("SVM: disabling PUT_TCE_IND firmware feature\n");
+       }
+
        pr_debug(" <- fw_hypertas_feature_init()\n");
 }
 
index c126b94..a4d40a3 100644 (file)
@@ -360,8 +360,10 @@ static bool lmb_is_removable(struct drmem_lmb *lmb)
 
        for (i = 0; i < scns_per_block; i++) {
                pfn = PFN_DOWN(phys_addr);
-               if (!pfn_present(pfn))
+               if (!pfn_present(pfn)) {
+                       phys_addr += MIN_MEMORY_BLOCK_SIZE;
                        continue;
+               }
 
                rc = rc && is_mem_section_removable(pfn, PAGES_PER_SECTION);
                phys_addr += MIN_MEMORY_BLOCK_SIZE;
index 6ba081d..2e0a8ea 100644 (file)
@@ -36,7 +36,6 @@
 #include <asm/udbg.h>
 #include <asm/mmzone.h>
 #include <asm/plpar_wrappers.h>
-#include <asm/svm.h>
 
 #include "pseries.h"
 
@@ -133,10 +132,10 @@ static unsigned long tce_get_pseries(struct iommu_table *tbl, long index)
        return be64_to_cpu(*tcep);
 }
 
-static void tce_free_pSeriesLP(struct iommu_table*, long, long);
+static void tce_free_pSeriesLP(unsigned long liobn, long, long);
 static void tce_freemulti_pSeriesLP(struct iommu_table*, long, long);
 
-static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
+static int tce_build_pSeriesLP(unsigned long liobn, long tcenum, long tceshift,
                                long npages, unsigned long uaddr,
                                enum dma_data_direction direction,
                                unsigned long attrs)
@@ -147,25 +146,25 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum,
        int ret = 0;
        long tcenum_start = tcenum, npages_start = npages;
 
-       rpn = __pa(uaddr) >> TCE_SHIFT;
+       rpn = __pa(uaddr) >> tceshift;
        proto_tce = TCE_PCI_READ;
        if (direction != DMA_TO_DEVICE)
                proto_tce |= TCE_PCI_WRITE;
 
        while (npages--) {
-               tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT;
-               rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce);
+               tce = proto_tce | (rpn & TCE_RPN_MASK) << tceshift;
+               rc = plpar_tce_put((u64)liobn, (u64)tcenum << tceshift, tce);
 
                if (unlikely(rc == H_NOT_ENOUGH_RESOURCES)) {
                        ret = (int)rc;
-                       tce_free_pSeriesLP(tbl, tcenum_start,
+                       tce_free_pSeriesLP(liobn, tcenum_start,
                                           (npages_start - (npages + 1)));
                        break;
                }
 
                if (rc && printk_ratelimit()) {
                        printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
-                       printk("\tindex   = 0x%llx\n", (u64)tbl->it_index);
+                       printk("\tindex   = 0x%llx\n", (u64)liobn);
                        printk("\ttcenum  = 0x%llx\n", (u64)tcenum);
                        printk("\ttce val = 0x%llx\n", tce );
                        dump_stack();
@@ -193,8 +192,9 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
        int ret = 0;
        unsigned long flags;
 
-       if ((npages == 1) || !firmware_has_feature(FW_FEATURE_MULTITCE)) {
-               return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
+       if ((npages == 1) || !firmware_has_feature(FW_FEATURE_PUT_TCE_IND)) {
+               return tce_build_pSeriesLP(tbl->it_index, tcenum,
+                                          tbl->it_page_shift, npages, uaddr,
                                           direction, attrs);
        }
 
@@ -210,8 +210,9 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
                /* If allocation fails, fall back to the loop implementation */
                if (!tcep) {
                        local_irq_restore(flags);
-                       return tce_build_pSeriesLP(tbl, tcenum, npages, uaddr,
-                                           direction, attrs);
+                       return tce_build_pSeriesLP(tbl->it_index, tcenum,
+                                       tbl->it_page_shift,
+                                       npages, uaddr, direction, attrs);
                }
                __this_cpu_write(tce_page, tcep);
        }
@@ -262,16 +263,16 @@ static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum,
        return ret;
 }
 
-static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages)
+static void tce_free_pSeriesLP(unsigned long liobn, long tcenum, long npages)
 {
        u64 rc;
 
        while (npages--) {
-               rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0);
+               rc = plpar_tce_put((u64)liobn, (u64)tcenum << 12, 0);
 
                if (rc && printk_ratelimit()) {
                        printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%lld\n", rc);
-                       printk("\tindex   = 0x%llx\n", (u64)tbl->it_index);
+                       printk("\tindex   = 0x%llx\n", (u64)liobn);
                        printk("\ttcenum  = 0x%llx\n", (u64)tcenum);
                        dump_stack();
                }
@@ -285,8 +286,8 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n
 {
        u64 rc;
 
-       if (!firmware_has_feature(FW_FEATURE_MULTITCE))
-               return tce_free_pSeriesLP(tbl, tcenum, npages);
+       if (!firmware_has_feature(FW_FEATURE_STUFF_TCE))
+               return tce_free_pSeriesLP(tbl->it_index, tcenum, npages);
 
        rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages);
 
@@ -401,6 +402,19 @@ static int tce_setrange_multi_pSeriesLP(unsigned long start_pfn,
        u64 rc = 0;
        long l, limit;
 
+       if (!firmware_has_feature(FW_FEATURE_PUT_TCE_IND)) {
+               unsigned long tceshift = be32_to_cpu(maprange->tce_shift);
+               unsigned long dmastart = (start_pfn << PAGE_SHIFT) +
+                               be64_to_cpu(maprange->dma_base);
+               unsigned long tcenum = dmastart >> tceshift;
+               unsigned long npages = num_pfn << PAGE_SHIFT >> tceshift;
+               void *uaddr = __va(start_pfn << PAGE_SHIFT);
+
+               return tce_build_pSeriesLP(be32_to_cpu(maprange->liobn),
+                               tcenum, tceshift, npages, (unsigned long) uaddr,
+                               DMA_BIDIRECTIONAL, 0);
+       }
+
        local_irq_disable();    /* to protect tcep and the page behind it */
        tcep = __this_cpu_read(tce_page);
 
@@ -1320,24 +1334,18 @@ void iommu_init_early_pSeries(void)
        of_reconfig_notifier_register(&iommu_reconfig_nb);
        register_memory_notifier(&iommu_mem_nb);
 
-       /*
-        * Secure guest memory is inacessible to devices so regular DMA isn't
-        * possible.
-        *
-        * In that case keep devices' dma_map_ops as NULL so that the generic
-        * DMA code path will use SWIOTLB to bounce buffers for DMA.
-        */
-       if (!is_secure_guest())
-               set_pci_dma_ops(&dma_iommu_ops);
+       set_pci_dma_ops(&dma_iommu_ops);
 }
 
 static int __init disable_multitce(char *str)
 {
        if (strcmp(str, "off") == 0 &&
            firmware_has_feature(FW_FEATURE_LPAR) &&
-           firmware_has_feature(FW_FEATURE_MULTITCE)) {
+           (firmware_has_feature(FW_FEATURE_PUT_TCE_IND) ||
+            firmware_has_feature(FW_FEATURE_STUFF_TCE))) {
                printk(KERN_INFO "Disabling MULTITCE firmware feature\n");
-               powerpc_firmware_features &= ~FW_FEATURE_MULTITCE;
+               powerpc_firmware_features &=
+                       ~(FW_FEATURE_PUT_TCE_IND | FW_FEATURE_STUFF_TCE);
        }
        return 1;
 }
index 60cb29a..3c3da25 100644 (file)
@@ -582,12 +582,12 @@ static int vcpudispatch_stats_open(struct inode *inode, struct file *file)
        return single_open(file, vcpudispatch_stats_display, NULL);
 }
 
-static const struct file_operations vcpudispatch_stats_proc_ops = {
-       .open           = vcpudispatch_stats_open,
-       .read           = seq_read,
-       .write          = vcpudispatch_stats_write,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops vcpudispatch_stats_proc_ops = {
+       .proc_open      = vcpudispatch_stats_open,
+       .proc_read      = seq_read,
+       .proc_write     = vcpudispatch_stats_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 static ssize_t vcpudispatch_stats_freq_write(struct file *file,
@@ -626,12 +626,12 @@ static int vcpudispatch_stats_freq_open(struct inode *inode, struct file *file)
        return single_open(file, vcpudispatch_stats_freq_display, NULL);
 }
 
-static const struct file_operations vcpudispatch_stats_freq_proc_ops = {
-       .open           = vcpudispatch_stats_freq_open,
-       .read           = seq_read,
-       .write          = vcpudispatch_stats_freq_write,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops vcpudispatch_stats_freq_proc_ops = {
+       .proc_open      = vcpudispatch_stats_freq_open,
+       .proc_read      = seq_read,
+       .proc_write     = vcpudispatch_stats_freq_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 static int __init vcpudispatch_stats_procfs_init(void)
index e33e8bc..b8d28ab 100644 (file)
@@ -435,10 +435,10 @@ static void maxmem_data(struct seq_file *m)
 {
        unsigned long maxmem = 0;
 
-       maxmem += drmem_info->n_lmbs * drmem_info->lmb_size;
+       maxmem += (unsigned long)drmem_info->n_lmbs * drmem_info->lmb_size;
        maxmem += hugetlb_total_pages() * PAGE_SIZE;
 
-       seq_printf(m, "MaxMem=%ld\n", maxmem);
+       seq_printf(m, "MaxMem=%lu\n", maxmem);
 }
 
 static int pseries_lparcfg_data(struct seq_file *m, void *v)
@@ -698,12 +698,12 @@ static int lparcfg_open(struct inode *inode, struct file *file)
        return single_open(file, lparcfg_data, NULL);
 }
 
-static const struct file_operations lparcfg_fops = {
-       .read           = seq_read,
-       .write          = lparcfg_write,
-       .open           = lparcfg_open,
-       .release        = single_release,
-       .llseek         = seq_lseek,
+static const struct proc_ops lparcfg_proc_ops = {
+       .proc_read      = seq_read,
+       .proc_write     = lparcfg_write,
+       .proc_open      = lparcfg_open,
+       .proc_release   = single_release,
+       .proc_lseek     = seq_lseek,
 };
 
 static int __init lparcfg_init(void)
@@ -714,7 +714,7 @@ static int __init lparcfg_init(void)
        if (firmware_has_feature(FW_FEATURE_SPLPAR))
                mode |= 0200;
 
-       if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_fops)) {
+       if (!proc_create("powerpc/lparcfg", mode, NULL, &lparcfg_proc_ops)) {
                printk(KERN_ERR "Failed to create powerpc/lparcfg\n");
                return -EIO;
        }
index c2ef320..0b4467e 100644 (file)
@@ -69,7 +69,8 @@ static int drc_pmem_bind(struct papr_scm_priv *p)
                return rc;
 
        p->bound_addr = saved;
-       dev_dbg(&p->pdev->dev, "bound drc 0x%x to %pR\n", p->drc_index, &p->res);
+       dev_dbg(&p->pdev->dev, "bound drc 0x%x to 0x%lx\n",
+               p->drc_index, (unsigned long)saved);
        return rc;
 }
 
@@ -133,7 +134,7 @@ static int drc_pmem_query_n_bind(struct papr_scm_priv *p)
                goto err_out;
 
        p->bound_addr = start_addr;
-       dev_dbg(&p->pdev->dev, "bound drc 0x%x to %pR\n", p->drc_index, &p->res);
+       dev_dbg(&p->pdev->dev, "bound drc 0x%x to 0x%lx\n", p->drc_index, start_addr);
        return rc;
 
 err_out:
@@ -322,6 +323,7 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
        p->bus = nvdimm_bus_register(NULL, &p->bus_desc);
        if (!p->bus) {
                dev_err(dev, "Error creating nvdimm bus %pOF\n", p->dn);
+               kfree(p->bus_desc.provider_name);
                return -ENXIO;
        }
 
@@ -356,7 +358,6 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p)
        ndr_desc.mapping = &mapping;
        ndr_desc.num_mappings = 1;
        ndr_desc.nd_set = &p->nd_set;
-       set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags);
 
        if (p->is_volatile)
                p->region = nvdimm_volatile_region_create(p->bus, &ndr_desc);
@@ -477,6 +478,7 @@ static int papr_scm_remove(struct platform_device *pdev)
 
        nvdimm_bus_unregister(p->bus);
        drc_pmem_unbind(p);
+       kfree(p->bus_desc.provider_name);
        kfree(p);
 
        return 0;
index 7228309..911534b 100644 (file)
@@ -192,7 +192,7 @@ int pseries_pci_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
 int pseries_pcibios_sriov_enable(struct pci_dev *pdev, u16 num_vfs)
 {
        /* Allocate PCI data */
-       add_dev_pci_data(pdev);
+       add_sriov_vf_pdns(pdev);
        return pseries_pci_sriov_enable(pdev, num_vfs);
 }
 
@@ -204,7 +204,7 @@ int pseries_pcibios_sriov_disable(struct pci_dev *pdev)
        /* Releasing pe_num_map */
        kfree(pdn->pe_num_map);
        /* Release PCI data */
-       remove_dev_pci_data(pdev);
+       remove_sriov_vf_pdns(pdev);
        pci_vf_drivers_autoprobe(pdev, true);
        return 0;
 }
index 8a9c4fb..7f7369f 100644 (file)
@@ -391,9 +391,9 @@ out:
        return rv ? rv : count;
 }
 
-static const struct file_operations ofdt_fops = {
-       .write = ofdt_write,
-       .llseek = noop_llseek,
+static const struct proc_ops ofdt_proc_ops = {
+       .proc_write     = ofdt_write,
+       .proc_lseek     = noop_llseek,
 };
 
 /* create /proc/powerpc/ofdt write-only by root */
@@ -401,7 +401,7 @@ static int proc_ppc64_create_ofdt(void)
 {
        struct proc_dir_entry *ent;
 
-       ent = proc_create("powerpc/ofdt", 0200, NULL, &ofdt_fops);
+       ent = proc_create("powerpc/ofdt", 0200, NULL, &ofdt_proc_ops);
        if (ent)
                proc_set_size(ent, 0);
 
index a000128..2879c4f 100644 (file)
@@ -152,13 +152,12 @@ static int scanlog_release(struct inode * inode, struct file * file)
        return 0;
 }
 
-static const struct file_operations scanlog_fops = {
-       .owner          = THIS_MODULE,
-       .read           = scanlog_read,
-       .write          = scanlog_write,
-       .open           = scanlog_open,
-       .release        = scanlog_release,
-       .llseek         = noop_llseek,
+static const struct proc_ops scanlog_proc_ops = {
+       .proc_read      = scanlog_read,
+       .proc_write     = scanlog_write,
+       .proc_open      = scanlog_open,
+       .proc_release   = scanlog_release,
+       .proc_lseek     = noop_llseek,
 };
 
 static int __init scanlog_init(void)
@@ -176,7 +175,7 @@ static int __init scanlog_init(void)
                goto err;
 
        ent = proc_create("powerpc/rtas/scan-log-dump", 0400, NULL,
-                         &scanlog_fops);
+                         &scanlog_proc_ops);
        if (!ent)
                goto err;
        return 0;
index 79e2287..f682b7b 100644 (file)
@@ -1176,6 +1176,8 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
        if (tbl == NULL)
                return NULL;
 
+       kref_init(&tbl->it_kref);
+
        of_parse_dma_window(dev->dev.of_node, dma_window,
                            &tbl->it_index, &offset, &size);
 
index 617a443..4a8874b 100644 (file)
@@ -1065,13 +1065,11 @@ int fsl_pci_mcheck_exception(struct pt_regs *regs)
        addr += mfspr(SPRN_MCAR);
 
        if (is_in_pci_mem_space(addr)) {
-               if (user_mode(regs)) {
-                       pagefault_disable();
-                       ret = get_user(inst, (__u32 __user *)regs->nip);
-                       pagefault_enable();
-               } else {
+               if (user_mode(regs))
+                       ret = probe_user_read(&inst, (void __user *)regs->nip,
+                                             sizeof(inst));
+               else
                        ret = probe_kernel_address((void *)regs->nip, inst);
-               }
 
                if (!ret && mcheck_handle_load(regs, inst)) {
                        regs->nip += 4;
index 934a773..a3a72b7 100644 (file)
@@ -964,7 +964,7 @@ static struct irq_chip mpic_irq_chip = {
 };
 
 #ifdef CONFIG_SMP
-static struct irq_chip mpic_ipi_chip = {
+static const struct irq_chip mpic_ipi_chip = {
        .irq_mask       = mpic_mask_ipi,
        .irq_unmask     = mpic_unmask_ipi,
        .irq_eoi        = mpic_end_ipi,
@@ -978,7 +978,7 @@ static struct irq_chip mpic_tm_chip = {
 };
 
 #ifdef CONFIG_MPIC_U3_HT_IRQS
-static struct irq_chip mpic_irq_ht_chip = {
+static const struct irq_chip mpic_irq_ht_chip = {
        .irq_startup    = mpic_startup_ht_irq,
        .irq_shutdown   = mpic_shutdown_ht_irq,
        .irq_mask       = mpic_mask_irq,
index 7b9fe0a..014e00e 100755 (executable)
 # based on relocs_check.pl
 # Copyright © 2009 IBM Corporation
 
-if [ $# -lt 2 ]; then
-       echo "$0 [path to objdump] [path to vmlinux]" 1>&2
+if [ $# -lt 3 ]; then
+       echo "$0 [path to objdump] [path to nm] [path to vmlinux]" 1>&2
        exit 1
 fi
 
-# Have Kbuild supply the path to objdump so we handle cross compilation.
+# Have Kbuild supply the path to objdump and nm so we handle cross compilation.
 objdump="$1"
-vmlinux="$2"
+nm="$2"
+vmlinux="$3"
+
+# Remove from the bad relocations those that match an undefined weak symbol
+# which will result in an absolute relocation to 0.
+# Weak unresolved symbols are of that form in nm output:
+# "                  w _binary__btf_vmlinux_bin_end"
+undef_weak_symbols=$($nm "$vmlinux" | awk '$1 ~ /w/ { print $2 }')
 
 bad_relocs=$(
 $objdump -R "$vmlinux" |
@@ -26,8 +33,6 @@ $objdump -R "$vmlinux" |
        # These relocations are okay
        # On PPC64:
        #       R_PPC64_RELATIVE, R_PPC64_NONE
-       #       R_PPC64_ADDR64 mach_<name>
-       #       R_PPC64_ADDR64 __crc_<name>
        # On PPC:
        #       R_PPC_RELATIVE, R_PPC_ADDR16_HI,
        #       R_PPC_ADDR16_HA,R_PPC_ADDR16_LO,
@@ -39,8 +44,7 @@ R_PPC_ADDR16_HI
 R_PPC_ADDR16_HA
 R_PPC_RELATIVE
 R_PPC_NONE' |
-       grep -E -v '\<R_PPC64_ADDR64[[:space:]]+mach_' |
-       grep -E -v '\<R_PPC64_ADDR64[[:space:]]+__crc_'
+       ([ "$undef_weak_symbols" ] && grep -F -w -v "$undef_weak_symbols" || cat)
 )
 
 if [ -z "$bad_relocs" ]; then
index c4d246e..c4c982d 100644 (file)
@@ -13,13 +13,13 @@ extern int print_insn_spu(unsigned long insn, unsigned long memaddr);
 #else
 static inline int print_insn_powerpc(unsigned long insn, unsigned long memaddr)
 {
-       printf("%.8x", insn);
+       printf("%.8lx", insn);
        return 0;
 }
 
 static inline int print_insn_spu(unsigned long insn, unsigned long memaddr)
 {
-       printf("%.8x", insn);
+       printf("%.8lx", insn);
        return 0;
 }
 #endif
index a705604..e8c84d2 100644 (file)
@@ -1192,16 +1192,19 @@ static int do_step(struct pt_regs *regs)
 
 static void bootcmds(void)
 {
+       char tmp[64];
        int cmd;
 
        cmd = inchar();
-       if (cmd == 'r')
-               ppc_md.restart(NULL);
-       else if (cmd == 'h')
+       if (cmd == 'r') {
+               getstring(tmp, 64);
+               ppc_md.restart(tmp);
+       } else if (cmd == 'h') {
                ppc_md.halt();
-       else if (cmd == 'p')
+       } else if (cmd == 'p') {
                if (pm_power_off)
                        pm_power_off();
+       }
 }
 
 static int cpu_cmd(void)
@@ -1949,15 +1952,14 @@ static void dump_300_sprs(void)
 
        printf("pidr   = %.16lx  tidr  = %.16lx\n",
                mfspr(SPRN_PID), mfspr(SPRN_TIDR));
-       printf("asdr   = %.16lx  psscr = %.16lx\n",
-               mfspr(SPRN_ASDR), hv ? mfspr(SPRN_PSSCR)
-                                       : mfspr(SPRN_PSSCR_PR));
+       printf("psscr  = %.16lx\n",
+               hv ? mfspr(SPRN_PSSCR) : mfspr(SPRN_PSSCR_PR));
 
        if (!hv)
                return;
 
-       printf("ptcr   = %.16lx\n",
-               mfspr(SPRN_PTCR));
+       printf("ptcr   = %.16lx  asdr  = %.16lx\n",
+               mfspr(SPRN_PTCR), mfspr(SPRN_ASDR));
 #endif
 }
 
index 1efaedd..ec0ca8c 100644 (file)
@@ -7,7 +7,6 @@ generic-y += div64.h
 generic-y += extable.h
 generic-y += flat.h
 generic-y += dma.h
-generic-y += dma-contiguous.h
 generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
index 36e638d..b15f70a 100644 (file)
@@ -43,6 +43,13 @@ static inline int pud_bad(pud_t pud)
        return !pud_present(pud);
 }
 
+#define pud_leaf       pud_leaf
+static inline int pud_leaf(pud_t pud)
+{
+       return pud_present(pud) &&
+              (pud_val(pud) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
+}
+
 static inline void set_pud(pud_t *pudp, pud_t pud)
 {
        *pudp = pud;
index f66b873..e430415 100644 (file)
@@ -130,6 +130,13 @@ static inline int pmd_bad(pmd_t pmd)
        return !pmd_present(pmd);
 }
 
+#define pmd_leaf       pmd_leaf
+static inline int pmd_leaf(pmd_t pmd)
+{
+       return pmd_present(pmd) &&
+              (pmd_val(pmd) & (_PAGE_READ | _PAGE_WRITE | _PAGE_EXEC));
+}
+
 static inline void set_pmd(pmd_t *pmdp, pmd_t pmd)
 {
        *pmdp = pmd;
index 287714d..8abe775 100644 (file)
@@ -156,6 +156,7 @@ config S390
        select HAVE_KERNEL_UNCOMPRESSED
        select HAVE_KERNEL_XZ
        select HAVE_KPROBES
+       select HAVE_KPROBES_ON_FTRACE
        select HAVE_KRETPROBES
        select HAVE_KVM
        select HAVE_LIVEPATCH
@@ -163,13 +164,13 @@ config S390
        select HAVE_PERF_USER_STACK_DUMP
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_MEMBLOCK_PHYS_MAP
-       select HAVE_MMU_GATHER_NO_GATHER
+       select MMU_GATHER_NO_GATHER
        select HAVE_MOD_ARCH_SPECIFIC
        select HAVE_NOP_MCOUNT
        select HAVE_OPROFILE
        select HAVE_PCI
        select HAVE_PERF_EVENTS
-       select HAVE_RCU_TABLE_FREE
+       select MMU_GATHER_RCU_TABLE_FREE
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RELIABLE_STACKTRACE
        select HAVE_RSEQ
index e2a8578..f3caeb1 100644 (file)
@@ -5,7 +5,7 @@
  * s390 implementation of the AES Cipher Algorithm with protected keys.
  *
  * s390 Version:
- *   Copyright IBM Corp. 2017,2019
+ *   Copyright IBM Corp. 2017,2020
  *   Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com>
  *             Harald Freudenberger <freude@de.ibm.com>
  */
@@ -20,6 +20,7 @@
 #include <linux/module.h>
 #include <linux/cpufeature.h>
 #include <linux/init.h>
+#include <linux/mutex.h>
 #include <linux/spinlock.h>
 #include <crypto/internal/skcipher.h>
 #include <crypto/xts.h>
  * is called. As paes can handle different kinds of key blobs
  * and padding is also possible, the limits need to be generous.
  */
-#define PAES_MIN_KEYSIZE 64
-#define PAES_MAX_KEYSIZE 256
+#define PAES_MIN_KEYSIZE 16
+#define PAES_MAX_KEYSIZE 320
 
 static u8 *ctrblk;
-static DEFINE_SPINLOCK(ctrblk_lock);
+static DEFINE_MUTEX(ctrblk_lock);
 
 static cpacf_mask_t km_functions, kmc_functions, kmctr_functions;
 
@@ -53,19 +54,46 @@ struct key_blob {
        unsigned int keylen;
 };
 
-static inline int _copy_key_to_kb(struct key_blob *kb,
-                                 const u8 *key,
-                                 unsigned int keylen)
-{
-       if (keylen <= sizeof(kb->keybuf))
+static inline int _key_to_kb(struct key_blob *kb,
+                            const u8 *key,
+                            unsigned int keylen)
+{
+       struct clearkey_header {
+               u8  type;
+               u8  res0[3];
+               u8  version;
+               u8  res1[3];
+               u32 keytype;
+               u32 len;
+       } __packed * h;
+
+       switch (keylen) {
+       case 16:
+       case 24:
+       case 32:
+               /* clear key value, prepare pkey clear key token in keybuf */
+               memset(kb->keybuf, 0, sizeof(kb->keybuf));
+               h = (struct clearkey_header *) kb->keybuf;
+               h->version = 0x02; /* TOKVER_CLEAR_KEY */
+               h->keytype = (keylen - 8) >> 3;
+               h->len = keylen;
+               memcpy(kb->keybuf + sizeof(*h), key, keylen);
+               kb->keylen = sizeof(*h) + keylen;
                kb->key = kb->keybuf;
-       else {
-               kb->key = kmalloc(keylen, GFP_KERNEL);
-               if (!kb->key)
-                       return -ENOMEM;
+               break;
+       default:
+               /* other key material, let pkey handle this */
+               if (keylen <= sizeof(kb->keybuf))
+                       kb->key = kb->keybuf;
+               else {
+                       kb->key = kmalloc(keylen, GFP_KERNEL);
+                       if (!kb->key)
+                               return -ENOMEM;
+               }
+               memcpy(kb->key, key, keylen);
+               kb->keylen = keylen;
+               break;
        }
-       memcpy(kb->key, key, keylen);
-       kb->keylen = keylen;
 
        return 0;
 }
@@ -82,16 +110,18 @@ static inline void _free_kb_keybuf(struct key_blob *kb)
 struct s390_paes_ctx {
        struct key_blob kb;
        struct pkey_protkey pk;
+       spinlock_t pk_lock;
        unsigned long fc;
 };
 
 struct s390_pxts_ctx {
        struct key_blob kb[2];
        struct pkey_protkey pk[2];
+       spinlock_t pk_lock;
        unsigned long fc;
 };
 
-static inline int __paes_convert_key(struct key_blob *kb,
+static inline int __paes_keyblob2pkey(struct key_blob *kb,
                                     struct pkey_protkey *pk)
 {
        int i, ret;
@@ -106,22 +136,18 @@ static inline int __paes_convert_key(struct key_blob *kb,
        return ret;
 }
 
-static int __paes_set_key(struct s390_paes_ctx *ctx)
+static inline int __paes_convert_key(struct s390_paes_ctx *ctx)
 {
-       unsigned long fc;
+       struct pkey_protkey pkey;
 
-       if (__paes_convert_key(&ctx->kb, &ctx->pk))
+       if (__paes_keyblob2pkey(&ctx->kb, &pkey))
                return -EINVAL;
 
-       /* Pick the correct function code based on the protected key type */
-       fc = (ctx->pk.type == PKEY_KEYTYPE_AES_128) ? CPACF_KM_PAES_128 :
-               (ctx->pk.type == PKEY_KEYTYPE_AES_192) ? CPACF_KM_PAES_192 :
-               (ctx->pk.type == PKEY_KEYTYPE_AES_256) ? CPACF_KM_PAES_256 : 0;
-
-       /* Check if the function code is available */
-       ctx->fc = (fc && cpacf_test_func(&km_functions, fc)) ? fc : 0;
+       spin_lock_bh(&ctx->pk_lock);
+       memcpy(&ctx->pk, &pkey, sizeof(pkey));
+       spin_unlock_bh(&ctx->pk_lock);
 
-       return ctx->fc ? 0 : -EINVAL;
+       return 0;
 }
 
 static int ecb_paes_init(struct crypto_skcipher *tfm)
@@ -129,6 +155,7 @@ static int ecb_paes_init(struct crypto_skcipher *tfm)
        struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
 
        ctx->kb.key = NULL;
+       spin_lock_init(&ctx->pk_lock);
 
        return 0;
 }
@@ -140,6 +167,24 @@ static void ecb_paes_exit(struct crypto_skcipher *tfm)
        _free_kb_keybuf(&ctx->kb);
 }
 
+static inline int __ecb_paes_set_key(struct s390_paes_ctx *ctx)
+{
+       unsigned long fc;
+
+       if (__paes_convert_key(ctx))
+               return -EINVAL;
+
+       /* Pick the correct function code based on the protected key type */
+       fc = (ctx->pk.type == PKEY_KEYTYPE_AES_128) ? CPACF_KM_PAES_128 :
+               (ctx->pk.type == PKEY_KEYTYPE_AES_192) ? CPACF_KM_PAES_192 :
+               (ctx->pk.type == PKEY_KEYTYPE_AES_256) ? CPACF_KM_PAES_256 : 0;
+
+       /* Check if the function code is available */
+       ctx->fc = (fc && cpacf_test_func(&km_functions, fc)) ? fc : 0;
+
+       return ctx->fc ? 0 : -EINVAL;
+}
+
 static int ecb_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
                            unsigned int key_len)
 {
@@ -147,11 +192,11 @@ static int ecb_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
        struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
 
        _free_kb_keybuf(&ctx->kb);
-       rc = _copy_key_to_kb(&ctx->kb, in_key, key_len);
+       rc = _key_to_kb(&ctx->kb, in_key, key_len);
        if (rc)
                return rc;
 
-       return __paes_set_key(ctx);
+       return __ecb_paes_set_key(ctx);
 }
 
 static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
@@ -161,18 +206,31 @@ static int ecb_paes_crypt(struct skcipher_request *req, unsigned long modifier)
        struct skcipher_walk walk;
        unsigned int nbytes, n, k;
        int ret;
+       struct {
+               u8 key[MAXPROTKEYSIZE];
+       } param;
 
        ret = skcipher_walk_virt(&walk, req, false);
+       if (ret)
+               return ret;
+
+       spin_lock_bh(&ctx->pk_lock);
+       memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
+       spin_unlock_bh(&ctx->pk_lock);
+
        while ((nbytes = walk.nbytes) != 0) {
                /* only use complete blocks */
                n = nbytes & ~(AES_BLOCK_SIZE - 1);
-               k = cpacf_km(ctx->fc | modifier, ctx->pk.protkey,
+               k = cpacf_km(ctx->fc | modifier, &param,
                             walk.dst.virt.addr, walk.src.virt.addr, n);
                if (k)
                        ret = skcipher_walk_done(&walk, nbytes - k);
                if (k < n) {
-                       if (__paes_set_key(ctx) != 0)
+                       if (__paes_convert_key(ctx))
                                return skcipher_walk_done(&walk, -EIO);
+                       spin_lock_bh(&ctx->pk_lock);
+                       memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
+                       spin_unlock_bh(&ctx->pk_lock);
                }
        }
        return ret;
@@ -210,6 +268,7 @@ static int cbc_paes_init(struct crypto_skcipher *tfm)
        struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
 
        ctx->kb.key = NULL;
+       spin_lock_init(&ctx->pk_lock);
 
        return 0;
 }
@@ -221,11 +280,11 @@ static void cbc_paes_exit(struct crypto_skcipher *tfm)
        _free_kb_keybuf(&ctx->kb);
 }
 
-static int __cbc_paes_set_key(struct s390_paes_ctx *ctx)
+static inline int __cbc_paes_set_key(struct s390_paes_ctx *ctx)
 {
        unsigned long fc;
 
-       if (__paes_convert_key(&ctx->kb, &ctx->pk))
+       if (__paes_convert_key(ctx))
                return -EINVAL;
 
        /* Pick the correct function code based on the protected key type */
@@ -246,7 +305,7 @@ static int cbc_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
        struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
 
        _free_kb_keybuf(&ctx->kb);
-       rc = _copy_key_to_kb(&ctx->kb, in_key, key_len);
+       rc = _key_to_kb(&ctx->kb, in_key, key_len);
        if (rc)
                return rc;
 
@@ -268,8 +327,12 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
        ret = skcipher_walk_virt(&walk, req, false);
        if (ret)
                return ret;
+
        memcpy(param.iv, walk.iv, AES_BLOCK_SIZE);
+       spin_lock_bh(&ctx->pk_lock);
        memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
+       spin_unlock_bh(&ctx->pk_lock);
+
        while ((nbytes = walk.nbytes) != 0) {
                /* only use complete blocks */
                n = nbytes & ~(AES_BLOCK_SIZE - 1);
@@ -280,9 +343,11 @@ static int cbc_paes_crypt(struct skcipher_request *req, unsigned long modifier)
                        ret = skcipher_walk_done(&walk, nbytes - k);
                }
                if (k < n) {
-                       if (__cbc_paes_set_key(ctx) != 0)
+                       if (__paes_convert_key(ctx))
                                return skcipher_walk_done(&walk, -EIO);
+                       spin_lock_bh(&ctx->pk_lock);
                        memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
+                       spin_unlock_bh(&ctx->pk_lock);
                }
        }
        return ret;
@@ -322,6 +387,7 @@ static int xts_paes_init(struct crypto_skcipher *tfm)
 
        ctx->kb[0].key = NULL;
        ctx->kb[1].key = NULL;
+       spin_lock_init(&ctx->pk_lock);
 
        return 0;
 }
@@ -334,12 +400,27 @@ static void xts_paes_exit(struct crypto_skcipher *tfm)
        _free_kb_keybuf(&ctx->kb[1]);
 }
 
-static int __xts_paes_set_key(struct s390_pxts_ctx *ctx)
+static inline int __xts_paes_convert_key(struct s390_pxts_ctx *ctx)
+{
+       struct pkey_protkey pkey0, pkey1;
+
+       if (__paes_keyblob2pkey(&ctx->kb[0], &pkey0) ||
+           __paes_keyblob2pkey(&ctx->kb[1], &pkey1))
+               return -EINVAL;
+
+       spin_lock_bh(&ctx->pk_lock);
+       memcpy(&ctx->pk[0], &pkey0, sizeof(pkey0));
+       memcpy(&ctx->pk[1], &pkey1, sizeof(pkey1));
+       spin_unlock_bh(&ctx->pk_lock);
+
+       return 0;
+}
+
+static inline int __xts_paes_set_key(struct s390_pxts_ctx *ctx)
 {
        unsigned long fc;
 
-       if (__paes_convert_key(&ctx->kb[0], &ctx->pk[0]) ||
-           __paes_convert_key(&ctx->kb[1], &ctx->pk[1]))
+       if (__xts_paes_convert_key(ctx))
                return -EINVAL;
 
        if (ctx->pk[0].type != ctx->pk[1].type)
@@ -371,10 +452,10 @@ static int xts_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
 
        _free_kb_keybuf(&ctx->kb[0]);
        _free_kb_keybuf(&ctx->kb[1]);
-       rc = _copy_key_to_kb(&ctx->kb[0], in_key, key_len);
+       rc = _key_to_kb(&ctx->kb[0], in_key, key_len);
        if (rc)
                return rc;
-       rc = _copy_key_to_kb(&ctx->kb[1], in_key + key_len, key_len);
+       rc = _key_to_kb(&ctx->kb[1], in_key + key_len, key_len);
        if (rc)
                return rc;
 
@@ -416,15 +497,17 @@ static int xts_paes_crypt(struct skcipher_request *req, unsigned long modifier)
        ret = skcipher_walk_virt(&walk, req, false);
        if (ret)
                return ret;
+
        keylen = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? 48 : 64;
        offset = (ctx->pk[0].type == PKEY_KEYTYPE_AES_128) ? 16 : 0;
-retry:
+
        memset(&pcc_param, 0, sizeof(pcc_param));
        memcpy(pcc_param.tweak, walk.iv, sizeof(pcc_param.tweak));
+       spin_lock_bh(&ctx->pk_lock);
        memcpy(pcc_param.key + offset, ctx->pk[1].protkey, keylen);
-       cpacf_pcc(ctx->fc, pcc_param.key + offset);
-
        memcpy(xts_param.key + offset, ctx->pk[0].protkey, keylen);
+       spin_unlock_bh(&ctx->pk_lock);
+       cpacf_pcc(ctx->fc, pcc_param.key + offset);
        memcpy(xts_param.init, pcc_param.xts, 16);
 
        while ((nbytes = walk.nbytes) != 0) {
@@ -435,11 +518,15 @@ retry:
                if (k)
                        ret = skcipher_walk_done(&walk, nbytes - k);
                if (k < n) {
-                       if (__xts_paes_set_key(ctx) != 0)
+                       if (__xts_paes_convert_key(ctx))
                                return skcipher_walk_done(&walk, -EIO);
-                       goto retry;
+                       spin_lock_bh(&ctx->pk_lock);
+                       memcpy(xts_param.key + offset,
+                              ctx->pk[0].protkey, keylen);
+                       spin_unlock_bh(&ctx->pk_lock);
                }
        }
+
        return ret;
 }
 
@@ -476,6 +563,7 @@ static int ctr_paes_init(struct crypto_skcipher *tfm)
        struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
 
        ctx->kb.key = NULL;
+       spin_lock_init(&ctx->pk_lock);
 
        return 0;
 }
@@ -487,11 +575,11 @@ static void ctr_paes_exit(struct crypto_skcipher *tfm)
        _free_kb_keybuf(&ctx->kb);
 }
 
-static int __ctr_paes_set_key(struct s390_paes_ctx *ctx)
+static inline int __ctr_paes_set_key(struct s390_paes_ctx *ctx)
 {
        unsigned long fc;
 
-       if (__paes_convert_key(&ctx->kb, &ctx->pk))
+       if (__paes_convert_key(ctx))
                return -EINVAL;
 
        /* Pick the correct function code based on the protected key type */
@@ -513,7 +601,7 @@ static int ctr_paes_set_key(struct crypto_skcipher *tfm, const u8 *in_key,
        struct s390_paes_ctx *ctx = crypto_skcipher_ctx(tfm);
 
        _free_kb_keybuf(&ctx->kb);
-       rc = _copy_key_to_kb(&ctx->kb, in_key, key_len);
+       rc = _key_to_kb(&ctx->kb, in_key, key_len);
        if (rc)
                return rc;
 
@@ -543,49 +631,65 @@ static int ctr_paes_crypt(struct skcipher_request *req)
        struct skcipher_walk walk;
        unsigned int nbytes, n, k;
        int ret, locked;
-
-       locked = spin_trylock(&ctrblk_lock);
+       struct {
+               u8 key[MAXPROTKEYSIZE];
+       } param;
 
        ret = skcipher_walk_virt(&walk, req, false);
+       if (ret)
+               return ret;
+
+       spin_lock_bh(&ctx->pk_lock);
+       memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
+       spin_unlock_bh(&ctx->pk_lock);
+
+       locked = mutex_trylock(&ctrblk_lock);
+
        while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
                n = AES_BLOCK_SIZE;
                if (nbytes >= 2*AES_BLOCK_SIZE && locked)
                        n = __ctrblk_init(ctrblk, walk.iv, nbytes);
                ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk.iv;
-               k = cpacf_kmctr(ctx->fc, ctx->pk.protkey, walk.dst.virt.addr,
+               k = cpacf_kmctr(ctx->fc, &param, walk.dst.virt.addr,
                                walk.src.virt.addr, n, ctrptr);
                if (k) {
                        if (ctrptr == ctrblk)
                                memcpy(walk.iv, ctrptr + k - AES_BLOCK_SIZE,
                                       AES_BLOCK_SIZE);
                        crypto_inc(walk.iv, AES_BLOCK_SIZE);
-                       ret = skcipher_walk_done(&walk, nbytes - n);
+                       ret = skcipher_walk_done(&walk, nbytes - k);
                }
                if (k < n) {
-                       if (__ctr_paes_set_key(ctx) != 0) {
+                       if (__paes_convert_key(ctx)) {
                                if (locked)
-                                       spin_unlock(&ctrblk_lock);
+                                       mutex_unlock(&ctrblk_lock);
                                return skcipher_walk_done(&walk, -EIO);
                        }
+                       spin_lock_bh(&ctx->pk_lock);
+                       memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
+                       spin_unlock_bh(&ctx->pk_lock);
                }
        }
        if (locked)
-               spin_unlock(&ctrblk_lock);
+               mutex_unlock(&ctrblk_lock);
        /*
         * final block may be < AES_BLOCK_SIZE, copy only nbytes
         */
        if (nbytes) {
                while (1) {
-                       if (cpacf_kmctr(ctx->fc, ctx->pk.protkey, buf,
+                       if (cpacf_kmctr(ctx->fc, &param, buf,
                                        walk.src.virt.addr, AES_BLOCK_SIZE,
                                        walk.iv) == AES_BLOCK_SIZE)
                                break;
-                       if (__ctr_paes_set_key(ctx) != 0)
+                       if (__paes_convert_key(ctx))
                                return skcipher_walk_done(&walk, -EIO);
+                       spin_lock_bh(&ctx->pk_lock);
+                       memcpy(param.key, ctx->pk.protkey, MAXPROTKEYSIZE);
+                       spin_unlock_bh(&ctx->pk_lock);
                }
                memcpy(walk.dst.virt.addr, buf, nbytes);
                crypto_inc(walk.iv, AES_BLOCK_SIZE);
-               ret = skcipher_walk_done(&walk, 0);
+               ret = skcipher_walk_done(&walk, nbytes);
        }
 
        return ret;
@@ -618,12 +722,12 @@ static inline void __crypto_unregister_skcipher(struct skcipher_alg *alg)
 
 static void paes_s390_fini(void)
 {
-       if (ctrblk)
-               free_page((unsigned long) ctrblk);
        __crypto_unregister_skcipher(&ctr_paes_alg);
        __crypto_unregister_skcipher(&xts_paes_alg);
        __crypto_unregister_skcipher(&cbc_paes_alg);
        __crypto_unregister_skcipher(&ecb_paes_alg);
+       if (ctrblk)
+               free_page((unsigned long) ctrblk);
 }
 
 static int __init paes_s390_init(void)
@@ -661,14 +765,14 @@ static int __init paes_s390_init(void)
        if (cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_128) ||
            cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_192) ||
            cpacf_test_func(&kmctr_functions, CPACF_KMCTR_PAES_256)) {
-               ret = crypto_register_skcipher(&ctr_paes_alg);
-               if (ret)
-                       goto out_err;
                ctrblk = (u8 *) __get_free_page(GFP_KERNEL);
                if (!ctrblk) {
                        ret = -ENOMEM;
                        goto out_err;
                }
+               ret = crypto_register_skcipher(&ctr_paes_alg);
+               if (ret)
+                       goto out_err;
        }
 
        return 0;
index 70139d0..5c97f48 100644 (file)
@@ -209,17 +209,12 @@ static int hypfs_release(struct inode *inode, struct file *filp)
 
 enum { Opt_uid, Opt_gid, };
 
-static const struct fs_parameter_spec hypfs_param_specs[] = {
+static const struct fs_parameter_spec hypfs_fs_parameters[] = {
        fsparam_u32("gid", Opt_gid),
        fsparam_u32("uid", Opt_uid),
        {}
 };
 
-static const struct fs_parameter_description hypfs_fs_parameters = {
-       .name           = "hypfs",
-       .specs          = hypfs_param_specs,
-};
-
 static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct hypfs_sb_info *hypfs_info = fc->s_fs_info;
@@ -228,7 +223,7 @@ static int hypfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
        kgid_t gid;
        int opt;
 
-       opt = fs_parse(fc, &hypfs_fs_parameters, param, &result);
+       opt = fs_parse(fc, hypfs_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -455,7 +450,7 @@ static struct file_system_type hypfs_type = {
        .owner          = THIS_MODULE,
        .name           = "s390_hypfs",
        .init_fs_context = hypfs_init_fs_context,
-       .parameters     = &hypfs_fs_parameters,
+       .parameters     = hypfs_fs_parameters,
        .kill_sb        = hypfs_kill_super
 };
 
index 2531f67..1832ae6 100644 (file)
@@ -7,7 +7,6 @@ generated-y += unistd_nr.h
 generic-y += asm-offsets.h
 generic-y += cacheflush.h
 generic-y += device.h
-generic-y += dma-contiguous.h
 generic-y += dma-mapping.h
 generic-y += div64.h
 generic-y += emergency-restart.h
index b106aa2..09cdb63 100644 (file)
@@ -54,7 +54,6 @@ typedef u16 kprobe_opcode_t;
 struct arch_specific_insn {
        /* copy of original instruction */
        kprobe_opcode_t *insn;
-       unsigned int is_ftrace_insn : 1;
 };
 
 struct prev_kprobe {
index 11ecc40..1726224 100644 (file)
@@ -122,6 +122,11 @@ struct mcck_volatile_info {
        __u32 reserved;
 };
 
+#define CR0_INITIAL_MASK (CR0_UNUSED_56 | CR0_INTERRUPT_KEY_SUBMASK | \
+                         CR0_MEASUREMENT_ALERT_SUBMASK)
+#define CR14_INITIAL_MASK (CR14_UNUSED_32 | CR14_UNUSED_33 | \
+                          CR14_EXTERNAL_DAMAGE_SUBMASK)
+
 #define CPUSTAT_STOPPED    0x80000000
 #define CPUSTAT_WAIT       0x10000000
 #define CPUSTAT_ECALL_PEND 0x08000000
index a4d3809..85e944f 100644 (file)
@@ -33,6 +33,8 @@
 #define ARCH_HAS_PREPARE_HUGEPAGE
 #define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH
 
+#define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+
 #include <asm/setup.h>
 #ifndef __ASSEMBLY__
 
index 7b03037..137a392 100644 (file)
@@ -673,6 +673,7 @@ static inline int pud_none(pud_t pud)
        return pud_val(pud) == _REGION3_ENTRY_EMPTY;
 }
 
+#define pud_leaf       pud_large
 static inline int pud_large(pud_t pud)
 {
        if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) != _REGION_ENTRY_TYPE_R3)
@@ -690,6 +691,7 @@ static inline unsigned long pud_pfn(pud_t pud)
        return (pud_val(pud) & origin_mask) >> PAGE_SHIFT;
 }
 
+#define pmd_leaf       pmd_large
 static inline int pmd_large(pmd_t pmd)
 {
        return (pmd_val(pmd) & _SEGMENT_ENTRY_LARGE) != 0;
index e22f072..d27d7d3 100644 (file)
 #define MAXPROTKEYSIZE 64      /* a protected key blob may be up to 64 bytes */
 #define MAXCLRKEYSIZE  32         /* a clear key value may be up to 32 bytes */
 #define MAXAESCIPHERKEYSIZE 136  /* our aes cipher keys have always 136 bytes */
+#define MINEP11AESKEYBLOBSIZE 256  /* min EP11 AES key blob size  */
+#define MAXEP11AESKEYBLOBSIZE 320  /* max EP11 AES key blob size */
 
-/* Minimum and maximum size of a key blob */
+/* Minimum size of a key blob */
 #define MINKEYBLOBSIZE SECKEYBLOBSIZE
-#define MAXKEYBLOBSIZE MAXAESCIPHERKEYSIZE
 
 /* defines for the type field within the pkey_protkey struct */
 #define PKEY_KEYTYPE_AES_128                 1
@@ -39,6 +40,7 @@
 enum pkey_key_type {
        PKEY_TYPE_CCA_DATA   = (__u32) 1,
        PKEY_TYPE_CCA_CIPHER = (__u32) 2,
+       PKEY_TYPE_EP11       = (__u32) 3,
 };
 
 /* the newer ioctls use a pkey_key_size enum for key size information */
@@ -200,7 +202,7 @@ struct pkey_kblob2pkey {
 
 /*
  * Generate secure key, version 2.
- * Generate either a CCA AES secure key or a CCA AES cipher key.
+ * Generate CCA AES secure key, CCA AES cipher key or EP11 AES secure key.
  * There needs to be a list of apqns given with at least one entry in there.
  * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain
  * is not supported. The implementation walks through the list of apqns and
@@ -210,10 +212,13 @@ struct pkey_kblob2pkey {
  * (return -1 with errno ENODEV). You may use the PKEY_APQNS4KT ioctl to
  * generate a list of apqns based on the key type to generate.
  * The keygenflags argument is passed to the low level generation functions
- * individual for the key type and has a key type specific meaning. Currently
- * only CCA AES cipher keys react to this parameter: Use one or more of the
- * PKEY_KEYGEN_* flags to widen the export possibilities. By default a cipher
- * key is only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC).
+ * individual for the key type and has a key type specific meaning. When
+ * generating CCA cipher keys you can use one or more of the PKEY_KEYGEN_*
+ * flags to widen the export possibilities. By default a cipher key is
+ * only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC).
+ * The keygenflag argument for generating an EP11 AES key should either be 0
+ * to use the defaults which are XCP_BLOB_ENCRYPT, XCP_BLOB_DECRYPT and
+ * XCP_BLOB_PROTKEY_EXTRACTABLE or a valid combination of XCP_BLOB_* flags.
  */
 struct pkey_genseck2 {
        struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets*/
@@ -229,8 +234,8 @@ struct pkey_genseck2 {
 
 /*
  * Generate secure key from clear key value, version 2.
- * Construct a CCA AES secure key or CCA AES cipher key from a given clear key
- * value.
+ * Construct an CCA AES secure key, CCA AES cipher key or EP11 AES secure
+ * key from a given clear key value.
  * There needs to be a list of apqns given with at least one entry in there.
  * All apqns in the list need to be exact apqns, 0xFFFF as ANY card or domain
  * is not supported. The implementation walks through the list of apqns and
@@ -240,10 +245,13 @@ struct pkey_genseck2 {
  * (return -1 with errno ENODEV). You may use the PKEY_APQNS4KT ioctl to
  * generate a list of apqns based on the key type to generate.
  * The keygenflags argument is passed to the low level generation functions
- * individual for the key type and has a key type specific meaning. Currently
- * only CCA AES cipher keys react to this parameter: Use one or more of the
- * PKEY_KEYGEN_* flags to widen the export possibilities. By default a cipher
- * key is only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC).
+ * individual for the key type and has a key type specific meaning. When
+ * generating CCA cipher keys you can use one or more of the PKEY_KEYGEN_*
+ * flags to widen the export possibilities. By default a cipher key is
+ * only exportable for CPACF (PKEY_KEYGEN_XPRT_CPAC).
+ * The keygenflag argument for generating an EP11 AES key should either be 0
+ * to use the defaults which are XCP_BLOB_ENCRYPT, XCP_BLOB_DECRYPT and
+ * XCP_BLOB_PROTKEY_EXTRACTABLE or a valid combination of XCP_BLOB_* flags.
  */
 struct pkey_clr2seck2 {
        struct pkey_apqn __user *apqns; /* in: ptr to list of apqn targets */
@@ -266,14 +274,19 @@ struct pkey_clr2seck2 {
  * with one apqn able to handle this key.
  * The function also checks for the master key verification patterns
  * of the key matching to the current or alternate mkvp of the apqn.
- * Currently CCA AES secure keys and CCA AES cipher keys are supported.
- * The flags field is updated with some additional info about the apqn mkvp
+ * For CCA AES secure keys and CCA AES cipher keys this means to check
+ * the key's mkvp against the current or old mkvp of the apqns. The flags
+ * field is updated with some additional info about the apqn mkvp
  * match: If the current mkvp matches to the key's mkvp then the
  * PKEY_FLAGS_MATCH_CUR_MKVP bit is set, if the alternate mkvp matches to
  * the key's mkvp the PKEY_FLAGS_MATCH_ALT_MKVP is set. For CCA keys the
  * alternate mkvp is the old master key verification pattern.
  * CCA AES secure keys are also checked to have the CPACF export allowed
  * bit enabled (XPRTCPAC) in the kmf1 field.
+ * EP11 keys are also supported and the wkvp of the key is checked against
+ * the current wkvp of the apqns. There is no alternate for this type of
+ * key and so on a match the flag PKEY_FLAGS_MATCH_CUR_MKVP always is set.
+ * EP11 keys are also checked to have XCP_BLOB_PROTKEY_EXTRACTABLE set.
  * The ioctl returns 0 as long as the given or found apqn matches to
  * matches with the current or alternate mkvp to the key's mkvp. If the given
  * apqn does not match or there is no such apqn found, -1 with errno
@@ -313,16 +326,20 @@ struct pkey_kblob2pkey2 {
 /*
  * Build a list of APQNs based on a key blob given.
  * Is able to find out which type of secure key is given (CCA AES secure
- * key or CCA AES cipher key) and tries to find all matching crypto cards
- * based on the MKVP and maybe other criterias (like CCA AES cipher keys
- * need a CEX5C or higher). The list of APQNs is further filtered by the key's
- * mkvp which needs to match to either the current mkvp or the alternate mkvp
- * (which is the old mkvp on CCA adapters) of the apqns. The flags argument may
- * be used to limit the matching apqns. If the PKEY_FLAGS_MATCH_CUR_MKVP is
- * given, only the current mkvp of each apqn is compared. Likewise with the
- * PKEY_FLAGS_MATCH_ALT_MKVP. If both are given, it is assumed to
- * return apqns where either the current or the alternate mkvp
+ * key, CCA AES cipher key or EP11 AES key) and tries to find all matching
+ * crypto cards based on the MKVP and maybe other criterias (like CCA AES
+ * cipher keys need a CEX5C or higher, EP11 keys with BLOB_PKEY_EXTRACTABLE
+ * need a CEX7 and EP11 api version 4). The list of APQNs is further filtered
+ * by the key's mkvp which needs to match to either the current mkvp (CCA and
+ * EP11) or the alternate mkvp (old mkvp, CCA adapters only) of the apqns. The
+ * flags argument may be used to limit the matching apqns. If the
+ * PKEY_FLAGS_MATCH_CUR_MKVP is given, only the current mkvp of each apqn is
+ * compared. Likewise with the PKEY_FLAGS_MATCH_ALT_MKVP. If both are given, it
+ * is assumed to return apqns where either the current or the alternate mkvp
  * matches. At least one of the matching flags needs to be given.
+ * The flags argument for EP11 keys has no further action and is currently
+ * ignored (but needs to be given as PKEY_FLAGS_MATCH_CUR_MKVP) as there is only
+ * the wkvp from the key to match against the apqn's wkvp.
  * The list of matching apqns is stored into the space given by the apqns
  * argument and the number of stored entries goes into apqn_entries. If the list
  * is empty (apqn_entries is 0) the apqn_entries field is updated to the number
@@ -356,6 +373,10 @@ struct pkey_apqns4key {
  * If both are given, it is assumed to return apqns where either the
  * current or the alternate mkvp matches. If no match flag is given
  * (flags is 0) the mkvp values are ignored for the match process.
+ * For EP11 keys there is only the current wkvp. So if the apqns should also
+ * match to a given wkvp, then the PKEY_FLAGS_MATCH_CUR_MKVP flag should be
+ * set. The wkvp value is 32 bytes but only the leftmost 16 bytes are compared
+ * against the leftmost 16 byte of the wkvp of the apqn.
  * The list of matching apqns is stored into the space given by the apqns
  * argument and the number of stored entries goes into apqn_entries. If the list
  * is empty (apqn_entries is 0) the apqn_entries field is updated to the number
index f9e5e1f..5a2177e 100644 (file)
@@ -161,17 +161,17 @@ struct ica_xcRB {
  * @payload_len:       Payload length
  */
 struct ep11_cprb {
-       __u16           cprb_len;
-       unsigned char   cprb_ver_id;
-       unsigned char   pad_000[2];
-       unsigned char   flags;
-       unsigned char   func_id[2];
-       __u32           source_id;
-       __u32           target_id;
-       __u32           ret_code;
-       __u32           reserved1;
-       __u32           reserved2;
-       __u32           payload_len;
+       __u16   cprb_len;
+       __u8    cprb_ver_id;
+       __u8    pad_000[2];
+       __u8    flags;
+       __u8    func_id[2];
+       __u32   source_id;
+       __u32   target_id;
+       __u32   ret_code;
+       __u32   reserved1;
+       __u32   reserved2;
+       __u32   payload_len;
 } __attribute__((packed));
 
 /**
@@ -197,13 +197,13 @@ struct ep11_target_dev {
  */
 struct ep11_urb {
        __u16           targets_num;
-       __u64           targets;
+       __u8 __user    *targets;
        __u64           weight;
        __u64           req_no;
        __u64           req_len;
-       __u64           req;
+       __u8 __user    *req;
        __u64           resp_len;
-       __u64           resp;
+       __u8 __user    *resp;
 } __attribute__((packed));
 
 /**
@@ -237,7 +237,9 @@ struct zcrypt_device_matrix_ext {
        struct zcrypt_device_status_ext device[MAX_ZDEV_ENTRIES_EXT];
 };
 
-#define AUTOSELECT 0xFFFFFFFF
+#define AUTOSELECT  0xFFFFFFFF
+#define AUTOSEL_AP  ((__u16) 0xFFFF)
+#define AUTOSEL_DOM ((__u16) 0xFFFF)
 
 #define ZCRYPT_IOCTL_MAGIC 'z'
 
index 1bb85f6..4cd9b1a 100644 (file)
@@ -72,15 +72,6 @@ static inline void ftrace_generate_orig_insn(struct ftrace_insn *insn)
 #endif
 }
 
-static inline int is_kprobe_on_ftrace(struct ftrace_insn *insn)
-{
-#ifdef CONFIG_KPROBES
-       if (insn->opc == BREAKPOINT_INSTRUCTION)
-               return 1;
-#endif
-       return 0;
-}
-
 static inline void ftrace_generate_kprobe_nop_insn(struct ftrace_insn *insn)
 {
 #ifdef CONFIG_KPROBES
@@ -114,16 +105,6 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
                /* Initial code replacement */
                ftrace_generate_orig_insn(&orig);
                ftrace_generate_nop_insn(&new);
-       } else if (is_kprobe_on_ftrace(&old)) {
-               /*
-                * If we find a breakpoint instruction, a kprobe has been
-                * placed at the beginning of the function. We write the
-                * constant KPROBE_ON_FTRACE_NOP into the remaining four
-                * bytes of the original instruction so that the kprobes
-                * handler can execute a nop, if it reaches this breakpoint.
-                */
-               ftrace_generate_kprobe_call_insn(&orig);
-               ftrace_generate_kprobe_nop_insn(&new);
        } else {
                /* Replace ftrace call with a nop. */
                ftrace_generate_call_insn(&orig, rec->ip);
@@ -142,21 +123,10 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr)
 
        if (probe_kernel_read(&old, (void *) rec->ip, sizeof(old)))
                return -EFAULT;
-       if (is_kprobe_on_ftrace(&old)) {
-               /*
-                * If we find a breakpoint instruction, a kprobe has been
-                * placed at the beginning of the function. We write the
-                * constant KPROBE_ON_FTRACE_CALL into the remaining four
-                * bytes of the original instruction so that the kprobes
-                * handler can execute a brasl if it reaches this breakpoint.
-                */
-               ftrace_generate_kprobe_nop_insn(&orig);
-               ftrace_generate_kprobe_call_insn(&new);
-       } else {
-               /* Replace nop with an ftrace call. */
-               ftrace_generate_nop_insn(&orig);
-               ftrace_generate_call_insn(&new, rec->ip);
-       }
+       /* Replace nop with an ftrace call. */
+       ftrace_generate_nop_insn(&orig);
+       ftrace_generate_call_insn(&new, rec->ip);
+
        /* Verify that the to be replaced code matches what we expect. */
        if (memcmp(&orig, &old, sizeof(old)))
                return -EINVAL;
@@ -241,3 +211,45 @@ int ftrace_disable_ftrace_graph_caller(void)
 }
 
 #endif /* CONFIG_FUNCTION_GRAPH_TRACER */
+
+#ifdef CONFIG_KPROBES_ON_FTRACE
+void kprobe_ftrace_handler(unsigned long ip, unsigned long parent_ip,
+               struct ftrace_ops *ops, struct pt_regs *regs)
+{
+       struct kprobe_ctlblk *kcb;
+       struct kprobe *p = get_kprobe((kprobe_opcode_t *)ip);
+
+       if (unlikely(!p) || kprobe_disabled(p))
+               return;
+
+       if (kprobe_running()) {
+               kprobes_inc_nmissed_count(p);
+               return;
+       }
+
+       __this_cpu_write(current_kprobe, p);
+
+       kcb = get_kprobe_ctlblk();
+       kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+
+       instruction_pointer_set(regs, ip);
+
+       if (!p->pre_handler || !p->pre_handler(p, regs)) {
+
+               instruction_pointer_set(regs, ip + MCOUNT_INSN_SIZE);
+
+               if (unlikely(p->post_handler)) {
+                       kcb->kprobe_status = KPROBE_HIT_SSDONE;
+                       p->post_handler(p, regs, 0);
+               }
+       }
+       __this_cpu_write(current_kprobe, NULL);
+}
+NOKPROBE_SYMBOL(kprobe_ftrace_handler);
+
+int arch_prepare_kprobe_ftrace(struct kprobe *p)
+{
+       p->ainsn.insn = NULL;
+       return 0;
+}
+#endif
index 6f13883..548d0ea 100644 (file)
@@ -56,21 +56,10 @@ struct kprobe_insn_cache kprobe_s390_insn_slots = {
 
 static void copy_instruction(struct kprobe *p)
 {
-       unsigned long ip = (unsigned long) p->addr;
        s64 disp, new_disp;
        u64 addr, new_addr;
 
-       if (ftrace_location(ip) == ip) {
-               /*
-                * If kprobes patches the instruction that is morphed by
-                * ftrace make sure that kprobes always sees the branch
-                * "jg .+24" that skips the mcount block or the "brcl 0,0"
-                * in case of hotpatch.
-                */
-               ftrace_generate_nop_insn((struct ftrace_insn *)p->ainsn.insn);
-               p->ainsn.is_ftrace_insn = 1;
-       } else
-               memcpy(p->ainsn.insn, p->addr, insn_length(*p->addr >> 8));
+       memcpy(p->ainsn.insn, p->addr, insn_length(*p->addr >> 8));
        p->opcode = p->ainsn.insn[0];
        if (!probe_is_insn_relative_long(p->ainsn.insn))
                return;
@@ -136,11 +125,6 @@ int arch_prepare_kprobe(struct kprobe *p)
 }
 NOKPROBE_SYMBOL(arch_prepare_kprobe);
 
-int arch_check_ftrace_location(struct kprobe *p)
-{
-       return 0;
-}
-
 struct swap_insn_args {
        struct kprobe *p;
        unsigned int arm_kprobe : 1;
@@ -149,28 +133,11 @@ struct swap_insn_args {
 static int swap_instruction(void *data)
 {
        struct swap_insn_args *args = data;
-       struct ftrace_insn new_insn, *insn;
        struct kprobe *p = args->p;
-       size_t len;
-
-       new_insn.opc = args->arm_kprobe ? BREAKPOINT_INSTRUCTION : p->opcode;
-       len = sizeof(new_insn.opc);
-       if (!p->ainsn.is_ftrace_insn)
-               goto skip_ftrace;
-       len = sizeof(new_insn);
-       insn = (struct ftrace_insn *) p->addr;
-       if (args->arm_kprobe) {
-               if (is_ftrace_nop(insn))
-                       new_insn.disp = KPROBE_ON_FTRACE_NOP;
-               else
-                       new_insn.disp = KPROBE_ON_FTRACE_CALL;
-       } else {
-               ftrace_generate_call_insn(&new_insn, (unsigned long)p->addr);
-               if (insn->disp == KPROBE_ON_FTRACE_NOP)
-                       ftrace_generate_nop_insn(&new_insn);
-       }
-skip_ftrace:
-       s390_kernel_write(p->addr, &new_insn, len);
+       u16 opc;
+
+       opc = args->arm_kprobe ? BREAKPOINT_INSTRUCTION : p->opcode;
+       s390_kernel_write(p->addr, &opc, sizeof(opc));
        return 0;
 }
 NOKPROBE_SYMBOL(swap_instruction);
@@ -464,24 +431,6 @@ static void resume_execution(struct kprobe *p, struct pt_regs *regs)
        unsigned long ip = regs->psw.addr;
        int fixup = probe_get_fixup_type(p->ainsn.insn);
 
-       /* Check if the kprobes location is an enabled ftrace caller */
-       if (p->ainsn.is_ftrace_insn) {
-               struct ftrace_insn *insn = (struct ftrace_insn *) p->addr;
-               struct ftrace_insn call_insn;
-
-               ftrace_generate_call_insn(&call_insn, (unsigned long) p->addr);
-               /*
-                * A kprobe on an enabled ftrace call site actually single
-                * stepped an unconditional branch (ftrace nop equivalent).
-                * Now we need to fixup things and pretend that a brasl r0,...
-                * was executed instead.
-                */
-               if (insn->disp == KPROBE_ON_FTRACE_CALL) {
-                       ip += call_insn.disp * 2 - MCOUNT_INSN_SIZE;
-                       regs->gprs[0] = (unsigned long)p->addr + sizeof(*insn);
-               }
-       }
-
        if (fixup & FIXUP_PSW_NORMAL)
                ip += (unsigned long) p->addr - (unsigned long) p->ainsn.insn;
 
index f942341..7458dcf 100644 (file)
@@ -42,6 +42,9 @@ ENTRY(ftrace_caller)
        .globl  ftrace_regs_caller
        .set    ftrace_regs_caller,ftrace_caller
        stg     %r14,(__SF_GPRS+8*8)(%r15)      # save traced function caller
+       lghi    %r14,0                          # save condition code
+       ipm     %r14                            # don't put any instructions
+       sllg    %r14,%r14,16                    # clobbering CC before this point
        lgr     %r1,%r15
 #if !(defined(CC_USING_HOTPATCH) || defined(CC_USING_NOP_MCOUNT))
        aghi    %r0,MCOUNT_RETURN_FIXUP
@@ -54,6 +57,9 @@ ENTRY(ftrace_caller)
        # allocate pt_regs and stack frame for ftrace_trace_function
        aghi    %r15,-STACK_FRAME_SIZE
        stg     %r1,(STACK_PTREGS_GPRS+15*8)(%r15)
+       stg     %r14,(STACK_PTREGS_PSW)(%r15)
+       lg      %r14,(__SF_GPRS+8*8)(%r1)       # restore original return address
+       stosm   (STACK_PTREGS_PSW)(%r15),0
        aghi    %r1,-TRACED_FUNC_FRAME_SIZE
        stg     %r1,__SF_BACKCHAIN(%r15)
        stg     %r0,(STACK_PTREGS_PSW+8)(%r15)
index 165dea4..c06c89d 100644 (file)
@@ -2190,7 +2190,7 @@ static int flic_ais_mode_get_all(struct kvm *kvm, struct kvm_device_attr *attr)
                return -EINVAL;
 
        if (!test_kvm_facility(kvm, 72))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        mutex_lock(&fi->ais_lock);
        ais.simm = fi->simm;
@@ -2499,7 +2499,7 @@ static int modify_ais_mode(struct kvm *kvm, struct kvm_device_attr *attr)
        int ret = 0;
 
        if (!test_kvm_facility(kvm, 72))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        if (copy_from_user(&req, (void __user *)attr->addr, sizeof(req)))
                return -EFAULT;
@@ -2579,7 +2579,7 @@ static int flic_ais_mode_set_all(struct kvm *kvm, struct kvm_device_attr *attr)
        struct kvm_s390_ais_all ais;
 
        if (!test_kvm_facility(kvm, 72))
-               return -ENOTSUPP;
+               return -EOPNOTSUPP;
 
        if (copy_from_user(&ais, (void __user *)attr->addr, sizeof(ais)))
                return -EFAULT;
index 8646c99..d7ff30e 100644 (file)
@@ -529,6 +529,7 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
        case KVM_CAP_S390_CMMA_MIGRATION:
        case KVM_CAP_S390_AIS:
        case KVM_CAP_S390_AIS_MIGRATION:
+       case KVM_CAP_S390_VCPU_RESETS:
                r = 1;
                break;
        case KVM_CAP_S390_HPAGE_1M:
@@ -2808,35 +2809,6 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
 
 }
 
-static void kvm_s390_vcpu_initial_reset(struct kvm_vcpu *vcpu)
-{
-       /* this equals initial cpu reset in pop, but we don't switch to ESA */
-       vcpu->arch.sie_block->gpsw.mask = 0UL;
-       vcpu->arch.sie_block->gpsw.addr = 0UL;
-       kvm_s390_set_prefix(vcpu, 0);
-       kvm_s390_set_cpu_timer(vcpu, 0);
-       vcpu->arch.sie_block->ckc       = 0UL;
-       vcpu->arch.sie_block->todpr     = 0;
-       memset(vcpu->arch.sie_block->gcr, 0, 16 * sizeof(__u64));
-       vcpu->arch.sie_block->gcr[0]  = CR0_UNUSED_56 |
-                                       CR0_INTERRUPT_KEY_SUBMASK |
-                                       CR0_MEASUREMENT_ALERT_SUBMASK;
-       vcpu->arch.sie_block->gcr[14] = CR14_UNUSED_32 |
-                                       CR14_UNUSED_33 |
-                                       CR14_EXTERNAL_DAMAGE_SUBMASK;
-       /* make sure the new fpc will be lazily loaded */
-       save_fpu_regs();
-       current->thread.fpu.fpc = 0;
-       vcpu->arch.sie_block->gbea = 1;
-       vcpu->arch.sie_block->pp = 0;
-       vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
-       vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
-       kvm_clear_async_pf_completion_queue(vcpu);
-       if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
-               kvm_s390_vcpu_stop(vcpu);
-       kvm_s390_clear_local_irqs(vcpu);
-}
-
 void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
 {
        mutex_lock(&vcpu->kvm->lock);
@@ -3279,10 +3251,53 @@ static int kvm_arch_vcpu_ioctl_set_one_reg(struct kvm_vcpu *vcpu,
        return r;
 }
 
-static int kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
+static void kvm_arch_vcpu_ioctl_normal_reset(struct kvm_vcpu *vcpu)
 {
-       kvm_s390_vcpu_initial_reset(vcpu);
-       return 0;
+       vcpu->arch.sie_block->gpsw.mask &= ~PSW_MASK_RI;
+       vcpu->arch.pfault_token = KVM_S390_PFAULT_TOKEN_INVALID;
+       memset(vcpu->run->s.regs.riccb, 0, sizeof(vcpu->run->s.regs.riccb));
+
+       kvm_clear_async_pf_completion_queue(vcpu);
+       if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
+               kvm_s390_vcpu_stop(vcpu);
+       kvm_s390_clear_local_irqs(vcpu);
+}
+
+static void kvm_arch_vcpu_ioctl_initial_reset(struct kvm_vcpu *vcpu)
+{
+       /* Initial reset is a superset of the normal reset */
+       kvm_arch_vcpu_ioctl_normal_reset(vcpu);
+
+       /* this equals initial cpu reset in pop, but we don't switch to ESA */
+       vcpu->arch.sie_block->gpsw.mask = 0;
+       vcpu->arch.sie_block->gpsw.addr = 0;
+       kvm_s390_set_prefix(vcpu, 0);
+       kvm_s390_set_cpu_timer(vcpu, 0);
+       vcpu->arch.sie_block->ckc = 0;
+       vcpu->arch.sie_block->todpr = 0;
+       memset(vcpu->arch.sie_block->gcr, 0, sizeof(vcpu->arch.sie_block->gcr));
+       vcpu->arch.sie_block->gcr[0] = CR0_INITIAL_MASK;
+       vcpu->arch.sie_block->gcr[14] = CR14_INITIAL_MASK;
+       vcpu->run->s.regs.fpc = 0;
+       vcpu->arch.sie_block->gbea = 1;
+       vcpu->arch.sie_block->pp = 0;
+       vcpu->arch.sie_block->fpf &= ~FPF_BPBC;
+}
+
+static void kvm_arch_vcpu_ioctl_clear_reset(struct kvm_vcpu *vcpu)
+{
+       struct kvm_sync_regs *regs = &vcpu->run->s.regs;
+
+       /* Clear reset is a superset of the initial reset */
+       kvm_arch_vcpu_ioctl_initial_reset(vcpu);
+
+       memset(&regs->gprs, 0, sizeof(regs->gprs));
+       memset(&regs->vrs, 0, sizeof(regs->vrs));
+       memset(&regs->acrs, 0, sizeof(regs->acrs));
+       memset(&regs->gscb, 0, sizeof(regs->gscb));
+
+       regs->etoken = 0;
+       regs->etoken_extension = 0;
 }
 
 int kvm_arch_vcpu_ioctl_set_regs(struct kvm_vcpu *vcpu, struct kvm_regs *regs)
@@ -4343,7 +4358,7 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
        switch (ioctl) {
        case KVM_S390_STORE_STATUS:
                idx = srcu_read_lock(&vcpu->kvm->srcu);
-               r = kvm_s390_vcpu_store_status(vcpu, arg);
+               r = kvm_s390_store_status_unloaded(vcpu, arg);
                srcu_read_unlock(&vcpu->kvm->srcu, idx);
                break;
        case KVM_S390_SET_INITIAL_PSW: {
@@ -4355,8 +4370,17 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
                r = kvm_arch_vcpu_ioctl_set_initial_psw(vcpu, psw);
                break;
        }
+       case KVM_S390_CLEAR_RESET:
+               r = 0;
+               kvm_arch_vcpu_ioctl_clear_reset(vcpu);
+               break;
        case KVM_S390_INITIAL_RESET:
-               r = kvm_arch_vcpu_ioctl_initial_reset(vcpu);
+               r = 0;
+               kvm_arch_vcpu_ioctl_initial_reset(vcpu);
+               break;
+       case KVM_S390_NORMAL_RESET:
+               r = 0;
+               kvm_arch_vcpu_ioctl_normal_reset(vcpu);
                break;
        case KVM_SET_ONE_REG:
        case KVM_GET_ONE_REG: {
index b0246c7..5674710 100644 (file)
@@ -2,7 +2,7 @@
 /*
  *  IBM System z Huge TLB Page Support for Kernel.
  *
- *    Copyright IBM Corp. 2007,2016
+ *    Copyright IBM Corp. 2007,2020
  *    Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com>
  */
 
@@ -11,6 +11,9 @@
 
 #include <linux/mm.h>
 #include <linux/hugetlb.h>
+#include <linux/mman.h>
+#include <linux/sched/mm.h>
+#include <linux/security.h>
 
 /*
  * If the bit selected by single-bit bitmask "a" is set within "x", move
@@ -267,3 +270,98 @@ static __init int setup_hugepagesz(char *opt)
        return 1;
 }
 __setup("hugepagesz=", setup_hugepagesz);
+
+static unsigned long hugetlb_get_unmapped_area_bottomup(struct file *file,
+               unsigned long addr, unsigned long len,
+               unsigned long pgoff, unsigned long flags)
+{
+       struct hstate *h = hstate_file(file);
+       struct vm_unmapped_area_info info;
+
+       info.flags = 0;
+       info.length = len;
+       info.low_limit = current->mm->mmap_base;
+       info.high_limit = TASK_SIZE;
+       info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+       info.align_offset = 0;
+       return vm_unmapped_area(&info);
+}
+
+static unsigned long hugetlb_get_unmapped_area_topdown(struct file *file,
+               unsigned long addr0, unsigned long len,
+               unsigned long pgoff, unsigned long flags)
+{
+       struct hstate *h = hstate_file(file);
+       struct vm_unmapped_area_info info;
+       unsigned long addr;
+
+       info.flags = VM_UNMAPPED_AREA_TOPDOWN;
+       info.length = len;
+       info.low_limit = max(PAGE_SIZE, mmap_min_addr);
+       info.high_limit = current->mm->mmap_base;
+       info.align_mask = PAGE_MASK & ~huge_page_mask(h);
+       info.align_offset = 0;
+       addr = vm_unmapped_area(&info);
+
+       /*
+        * A failed mmap() very likely causes application failure,
+        * so fall back to the bottom-up function here. This scenario
+        * can happen with large stack limits and large mmap()
+        * allocations.
+        */
+       if (addr & ~PAGE_MASK) {
+               VM_BUG_ON(addr != -ENOMEM);
+               info.flags = 0;
+               info.low_limit = TASK_UNMAPPED_BASE;
+               info.high_limit = TASK_SIZE;
+               addr = vm_unmapped_area(&info);
+       }
+
+       return addr;
+}
+
+unsigned long hugetlb_get_unmapped_area(struct file *file, unsigned long addr,
+               unsigned long len, unsigned long pgoff, unsigned long flags)
+{
+       struct hstate *h = hstate_file(file);
+       struct mm_struct *mm = current->mm;
+       struct vm_area_struct *vma;
+       int rc;
+
+       if (len & ~huge_page_mask(h))
+               return -EINVAL;
+       if (len > TASK_SIZE - mmap_min_addr)
+               return -ENOMEM;
+
+       if (flags & MAP_FIXED) {
+               if (prepare_hugepage_range(file, addr, len))
+                       return -EINVAL;
+               goto check_asce_limit;
+       }
+
+       if (addr) {
+               addr = ALIGN(addr, huge_page_size(h));
+               vma = find_vma(mm, addr);
+               if (TASK_SIZE - len >= addr && addr >= mmap_min_addr &&
+                   (!vma || addr + len <= vm_start_gap(vma)))
+                       goto check_asce_limit;
+       }
+
+       if (mm->get_unmapped_area == arch_get_unmapped_area)
+               addr = hugetlb_get_unmapped_area_bottomup(file, addr, len,
+                               pgoff, flags);
+       else
+               addr = hugetlb_get_unmapped_area_topdown(file, addr, len,
+                               pgoff, flags);
+       if (addr & ~PAGE_MASK)
+               return addr;
+
+check_asce_limit:
+       if (addr + len > current->mm->context.asce_limit &&
+           addr + len <= TASK_SIZE) {
+               rc = crst_table_upgrade(mm, addr + len);
+               if (rc)
+                       return (unsigned long) rc;
+       }
+       return addr;
+}
index ec2b253..fb517b8 100644 (file)
@@ -152,13 +152,12 @@ static ssize_t alignment_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations alignment_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = alignment_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = alignment_proc_write,
+static const struct proc_ops alignment_proc_ops = {
+       .proc_open      = alignment_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = alignment_proc_write,
 };
 
 /*
@@ -176,12 +175,12 @@ static int __init alignment_init(void)
                return -ENOMEM;
 
        res = proc_create_data("alignment", S_IWUSR | S_IRUGO, dir,
-                              &alignment_proc_fops, &se_usermode);
+                              &alignment_proc_ops, &se_usermode);
        if (!res)
                return -ENOMEM;
 
         res = proc_create_data("kernel_alignment", S_IWUSR | S_IRUGO, dir,
-                              &alignment_proc_fops, &se_kernmode_warn);
+                              &alignment_proc_ops, &se_kernmode_warn);
         if (!res)
                 return -ENOMEM;
 
index e8c3ea0..c1dd6dd 100644 (file)
@@ -64,8 +64,7 @@ config SPARC64
        select HAVE_FUNCTION_GRAPH_TRACER
        select HAVE_KRETPROBES
        select HAVE_KPROBES
-       select HAVE_RCU_TABLE_FREE if SMP
-       select HAVE_RCU_TABLE_NO_INVALIDATE if HAVE_RCU_TABLE_FREE
+       select MMU_GATHER_RCU_TABLE_FREE if SMP
        select HAVE_MEMBLOCK_NODE_MAP
        select HAVE_ARCH_TRANSPARENT_HUGEPAGE
        select HAVE_DYNAMIC_FTRACE
index 34ff3b4..65494c3 100644 (file)
@@ -683,6 +683,7 @@ static inline unsigned long pte_special(pte_t pte)
        return pte_val(pte) & _PAGE_SPECIAL;
 }
 
+#define pmd_leaf       pmd_large
 static inline unsigned long pmd_large(pmd_t pmd)
 {
        pte_t pte = __pte(pmd_val(pmd));
@@ -867,6 +868,7 @@ static inline unsigned long pud_page_vaddr(pud_t pud)
 /* only used by the stubbed out hugetlb gup code, should never be called */
 #define p4d_page(p4d)                  NULL
 
+#define pud_leaf       pud_large
 static inline unsigned long pud_large(pud_t pud)
 {
        pte_t pte = __pte(pud_val(pud));
index a2f3fa6..6820d35 100644 (file)
@@ -28,6 +28,15 @@ void flush_tlb_pending(void);
 #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 #define tlb_flush(tlb) flush_tlb_pending()
 
+/*
+ * SPARC64's hardware TLB fill does not use the Linux page-tables
+ * and therefore we don't need a TLBI when freeing page-table pages.
+ */
+
+#ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE
+#define tlb_needs_table_invalidate()   (false)
+#endif
+
 #include <asm-generic/tlb.h>
 
 #endif /* _SPARC64_TLB_H */
index a6292f8..bd48575 100644 (file)
@@ -104,13 +104,12 @@ static ssize_t led_proc_write(struct file *file, const char __user *buffer,
        return count;
 }
 
-static const struct file_operations led_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = led_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = led_proc_write,
+static const struct proc_ops led_proc_ops = {
+       .proc_open      = led_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = led_proc_write,
 };
 
 static struct proc_dir_entry *led;
@@ -121,7 +120,7 @@ static int __init led_init(void)
 {
        timer_setup(&led_blink_timer, led_blink, 0);
 
-       led = proc_create("led", 0, NULL, &led_proc_fops);
+       led = proc_create("led", 0, NULL, &led_proc_ops);
        if (!led)
                return -ENOMEM;
 
index 3491761..6b92fad 100644 (file)
@@ -551,7 +551,7 @@ out_unlock:
 SYSCALL_DEFINE1(sparc_adjtimex, struct __kernel_timex __user *, txc_p)
 {
        struct __kernel_timex txc;
-       struct __kernel_old_timeval *tv = (void *)&txc_p->time;
+       struct __kernel_old_timeval *tv = (void *)&txc.time;
        int ret;
 
        /* Copy the user data space into the kernel copy
@@ -576,7 +576,7 @@ SYSCALL_DEFINE2(sparc_clock_adjtime, const clockid_t, which_clock,
                struct __kernel_timex __user *, txc_p)
 {
        struct __kernel_timex txc;
-       struct __kernel_old_timeval *tv = (void *)&txc_p->time;
+       struct __kernel_old_timeval *tv = (void *)&txc.time;
        int ret;
 
        if (!IS_ENABLED(CONFIG_POSIX_TIMERS)) {
index 0117489..b80a1d6 100644 (file)
@@ -752,10 +752,9 @@ static ssize_t mconsole_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations mconsole_proc_fops = {
-       .owner          = THIS_MODULE,
-       .write          = mconsole_proc_write,
-       .llseek         = noop_llseek,
+static const struct proc_ops mconsole_proc_ops = {
+       .proc_write     = mconsole_proc_write,
+       .proc_lseek     = noop_llseek,
 };
 
 static int create_proc_mconsole(void)
@@ -765,7 +764,7 @@ static int create_proc_mconsole(void)
        if (notify_socket == NULL)
                return 0;
 
-       ent = proc_create("mconsole", 0200, NULL, &mconsole_proc_fops);
+       ent = proc_create("mconsole", 0200, NULL, &mconsole_proc_ops);
        if (ent == NULL) {
                printk(KERN_INFO "create_proc_mconsole : proc_create failed\n");
                return 0;
index 369fd84..43edc2a 100644 (file)
@@ -55,20 +55,19 @@ static ssize_t exitcode_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations exitcode_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = exitcode_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = exitcode_proc_write,
+static const struct proc_ops exitcode_proc_ops = {
+       .proc_open      = exitcode_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = exitcode_proc_write,
 };
 
 static int make_proc_exitcode(void)
 {
        struct proc_dir_entry *ent;
 
-       ent = proc_create("exitcode", 0600, NULL, &exitcode_proc_fops);
+       ent = proc_create("exitcode", 0600, NULL, &exitcode_proc_ops);
        if (ent == NULL) {
                printk(KERN_WARNING "make_proc_exitcode : Failed to register "
                       "/proc/exitcode\n");
index 17045e7..56a0941 100644 (file)
@@ -348,13 +348,12 @@ static ssize_t sysemu_proc_write(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct file_operations sysemu_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = sysemu_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = sysemu_proc_write,
+static const struct proc_ops sysemu_proc_ops = {
+       .proc_open      = sysemu_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = sysemu_proc_write,
 };
 
 int __init make_proc_sysemu(void)
@@ -363,7 +362,7 @@ int __init make_proc_sysemu(void)
        if (!sysemu_supported)
                return 0;
 
-       ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_fops);
+       ent = proc_create("sysemu", 0600, NULL, &sysemu_proc_ops);
 
        if (ent == NULL)
        {
index 44d2796..beea770 100644 (file)
@@ -120,6 +120,7 @@ config X86
        select GENERIC_IRQ_RESERVATION_MODE
        select GENERIC_IRQ_SHOW
        select GENERIC_PENDING_IRQ              if SMP
+       select GENERIC_PTDUMP
        select GENERIC_SMP_IDLE_THREAD
        select GENERIC_STRNCPY_FROM_USER
        select GENERIC_STRNLEN_USER
@@ -202,7 +203,7 @@ config X86
        select HAVE_PCI
        select HAVE_PERF_REGS
        select HAVE_PERF_USER_STACK_DUMP
-       select HAVE_RCU_TABLE_FREE              if PARAVIRT
+       select MMU_GATHER_RCU_TABLE_FREE                if PARAVIRT
        select HAVE_REGS_AND_STACK_ACCESS_API
        select HAVE_RELIABLE_STACKTRACE         if X86_64 && (UNWINDER_FRAME_POINTER || UNWINDER_ORC) && STACK_VALIDATION
        select HAVE_FUNCTION_ARG_ACCESS_API
index c4eab8e..2e74690 100644 (file)
@@ -62,26 +62,10 @@ config EARLY_PRINTK_USB_XDBC
 config MCSAFE_TEST
        def_bool n
 
-config X86_PTDUMP_CORE
-       def_bool n
-
-config X86_PTDUMP
-       tristate "Export kernel pagetable layout to userspace via debugfs"
-       depends on DEBUG_KERNEL
-       select DEBUG_FS
-       select X86_PTDUMP_CORE
-       ---help---
-         Say Y here if you want to show the kernel pagetable layout in a
-         debugfs file. This information is only useful for kernel developers
-         who are working in architecture specific areas of the kernel.
-         It is probably not a good idea to enable this feature in a production
-         kernel.
-         If in doubt, say "N"
-
 config EFI_PGT_DUMP
        bool "Dump the EFI pagetable"
        depends on EFI
-       select X86_PTDUMP_CORE
+       select PTDUMP_CORE
        ---help---
          Enable this if you want to dump the EFI page table before
          enabling virtual mode. This can be used to debug miscellaneous
@@ -90,7 +74,7 @@ config EFI_PGT_DUMP
 
 config DEBUG_WX
        bool "Warn on W+X mappings at boot"
-       select X86_PTDUMP_CORE
+       select PTDUMP_CORE
        ---help---
          Generate a warning if any W+X mappings are found at boot.
 
index 25019d4..ef2ad72 100644 (file)
@@ -393,7 +393,13 @@ int count_immovable_mem_regions(void)
        table = table_addr + sizeof(struct acpi_table_srat);
 
        while (table + sizeof(struct acpi_subtable_header) < table_end) {
+
                sub_table = (struct acpi_subtable_header *)table;
+               if (!sub_table->length) {
+                       debug_putstr("Invalid zero length SRAT subtable.\n");
+                       return 0;
+               }
+
                if (sub_table->type == ACPI_SRAT_TYPE_MEMORY_AFFINITY) {
                        struct acpi_srat_mem_affinity *ma;
 
index caaf4dc..b0da532 100644 (file)
 #include <linux/hyperv.h>
 #include <linux/slab.h>
 #include <linux/cpuhotplug.h>
+#include <linux/syscore_ops.h>
 #include <clocksource/hyperv_timer.h>
 
 void *hv_hypercall_pg;
 EXPORT_SYMBOL_GPL(hv_hypercall_pg);
 
+/* Storage to save the hypercall page temporarily for hibernation */
+static void *hv_hypercall_pg_saved;
+
 u32 *hv_vp_index;
 EXPORT_SYMBOL_GPL(hv_vp_index);
 
@@ -246,6 +250,48 @@ static int __init hv_pci_init(void)
        return 1;
 }
 
+static int hv_suspend(void)
+{
+       union hv_x64_msr_hypercall_contents hypercall_msr;
+
+       /*
+        * Reset the hypercall page as it is going to be invalidated
+        * accross hibernation. Setting hv_hypercall_pg to NULL ensures
+        * that any subsequent hypercall operation fails safely instead of
+        * crashing due to an access of an invalid page. The hypercall page
+        * pointer is restored on resume.
+        */
+       hv_hypercall_pg_saved = hv_hypercall_pg;
+       hv_hypercall_pg = NULL;
+
+       /* Disable the hypercall page in the hypervisor */
+       rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+       hypercall_msr.enable = 0;
+       wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+
+       return 0;
+}
+
+static void hv_resume(void)
+{
+       union hv_x64_msr_hypercall_contents hypercall_msr;
+
+       /* Re-enable the hypercall page */
+       rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+       hypercall_msr.enable = 1;
+       hypercall_msr.guest_physical_address =
+               vmalloc_to_pfn(hv_hypercall_pg_saved);
+       wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64);
+
+       hv_hypercall_pg = hv_hypercall_pg_saved;
+       hv_hypercall_pg_saved = NULL;
+}
+
+static struct syscore_ops hv_syscore_ops = {
+       .suspend        = hv_suspend,
+       .resume         = hv_resume,
+};
+
 /*
  * This function is to be invoked early in the boot sequence after the
  * hypervisor has been detected.
@@ -330,6 +376,8 @@ void __init hyperv_init(void)
 
        x86_init.pci.arch_init = hv_pci_init;
 
+       register_syscore_ops(&hv_syscore_ops);
+
        return;
 
 remove_cpuhp_state:
@@ -349,6 +397,8 @@ void hyperv_cleanup(void)
 {
        union hv_x64_msr_hypercall_contents hypercall_msr;
 
+       unregister_syscore_ops(&hv_syscore_ops);
+
        /* Reset our OS id */
        wrmsrl(HV_X64_MSR_GUEST_OS_ID, 0);
 
index 8b52bc5..ea34464 100644 (file)
@@ -7,7 +7,6 @@ generated-y += unistd_32_ia32.h
 generated-y += unistd_64_x32.h
 generated-y += xen-hypercalls.h
 
-generic-y += dma-contiguous.h
 generic-y += early_ioremap.h
 generic-y += export.h
 generic-y += mcs_spinlock.h
index 2ebc17d..19e94af 100644 (file)
@@ -140,6 +140,7 @@ extern void apic_soft_disable(void);
 extern void lapic_shutdown(void);
 extern void sync_Arb_IDs(void);
 extern void init_bsp_APIC(void);
+extern void apic_intr_mode_select(void);
 extern void apic_intr_mode_init(void);
 extern void init_apic_mappings(void);
 void register_lapic_address(unsigned long address);
@@ -188,6 +189,7 @@ static inline void disable_local_APIC(void) { }
 # define setup_secondary_APIC_clock x86_init_noop
 static inline void lapic_update_tsc_freq(void) { }
 static inline void init_bsp_APIC(void) { }
+static inline void apic_intr_mode_select(void) { }
 static inline void apic_intr_mode_init(void) { }
 static inline void lapic_assign_system_vectors(void) { }
 static inline void lapic_assign_legacy_vector(unsigned int i, bool r) { }
@@ -452,6 +454,14 @@ static inline void ack_APIC_irq(void)
        apic_eoi();
 }
 
+
+static inline bool lapic_vector_set_in_irr(unsigned int vector)
+{
+       u32 irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
+
+       return !!(irr & (1U << (vector % 32)));
+}
+
 static inline unsigned default_get_apic_id(unsigned long x)
 {
        unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
index 329d01c..4dffbc1 100644 (file)
@@ -78,6 +78,8 @@
 #define KVM_REQ_HV_STIMER              KVM_ARCH_REQ(22)
 #define KVM_REQ_LOAD_EOI_EXITMAP       KVM_ARCH_REQ(23)
 #define KVM_REQ_GET_VMCS12_PAGES       KVM_ARCH_REQ(24)
+#define KVM_REQ_APICV_UPDATE \
+       KVM_ARCH_REQ_FLAGS(25, KVM_REQUEST_WAIT | KVM_REQUEST_NO_WAKEUP)
 
 #define CR0_RESERVED_BITS                                               \
        (~(unsigned long)(X86_CR0_PE | X86_CR0_MP | X86_CR0_EM | X86_CR0_TS \
@@ -873,6 +875,12 @@ enum kvm_irqchip_mode {
        KVM_IRQCHIP_SPLIT,        /* created with KVM_CAP_SPLIT_IRQCHIP */
 };
 
+#define APICV_INHIBIT_REASON_DISABLE    0
+#define APICV_INHIBIT_REASON_HYPERV     1
+#define APICV_INHIBIT_REASON_NESTED     2
+#define APICV_INHIBIT_REASON_IRQWIN     3
+#define APICV_INHIBIT_REASON_PIT_REINJ  4
+
 struct kvm_arch {
        unsigned long n_used_mmu_pages;
        unsigned long n_requested_mmu_pages;
@@ -904,6 +912,7 @@ struct kvm_arch {
        struct kvm_apic_map *apic_map;
 
        bool apic_access_page_done;
+       unsigned long apicv_inhibit_reasons;
 
        gpa_t wall_clock;
 
@@ -1118,7 +1127,8 @@ struct kvm_x86_ops {
        void (*enable_nmi_window)(struct kvm_vcpu *vcpu);
        void (*enable_irq_window)(struct kvm_vcpu *vcpu);
        void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr);
-       bool (*get_enable_apicv)(struct kvm *kvm);
+       bool (*check_apicv_inhibit_reasons)(ulong bit);
+       void (*pre_update_apicv_exec_ctrl)(struct kvm *kvm, bool activate);
        void (*refresh_apicv_exec_ctrl)(struct kvm_vcpu *vcpu);
        void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr);
        void (*hwapic_isr_update)(struct kvm_vcpu *vcpu, int isr);
@@ -1477,7 +1487,11 @@ gpa_t kvm_mmu_gva_to_gpa_write(struct kvm_vcpu *vcpu, gva_t gva,
 gpa_t kvm_mmu_gva_to_gpa_system(struct kvm_vcpu *vcpu, gva_t gva,
                                struct x86_exception *exception);
 
-void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu);
+bool kvm_apicv_activated(struct kvm *kvm);
+void kvm_apicv_init(struct kvm *kvm, bool enable);
+void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu);
+void kvm_request_apicv_update(struct kvm *kvm, bool activate,
+                             unsigned long bit);
 
 int kvm_emulate_hypercall(struct kvm_vcpu *vcpu);
 
index 40ac133..7ccb338 100644 (file)
@@ -33,13 +33,13 @@ extern int pci_routeirq;
 extern int noioapicquirk;
 extern int noioapicreroute;
 
-#ifdef CONFIG_PCI
-
 static inline struct pci_sysdata *to_pci_sysdata(const struct pci_bus *bus)
 {
        return bus->sysdata;
 }
 
+#ifdef CONFIG_PCI
+
 #ifdef CONFIG_PCI_DOMAINS
 static inline int pci_domain_nr(struct pci_bus *bus)
 {
index ad97dc1..7e11866 100644 (file)
@@ -29,8 +29,9 @@
 extern pgd_t early_top_pgt[PTRS_PER_PGD];
 int __init __early_make_pgtable(unsigned long address, pmdval_t pmd);
 
-void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd);
-void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user);
+void ptdump_walk_pgd_level(struct seq_file *m, struct mm_struct *mm);
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
+                                  bool user);
 void ptdump_walk_pgd_level_checkwx(void);
 void ptdump_walk_user_pgd_level_checkwx(void);
 
@@ -239,6 +240,7 @@ static inline unsigned long pgd_pfn(pgd_t pgd)
        return (pgd_val(pgd) & PTE_PFN_MASK) >> PAGE_SHIFT;
 }
 
+#define p4d_leaf       p4d_large
 static inline int p4d_large(p4d_t p4d)
 {
        /* No 512 GiB pages yet */
@@ -247,6 +249,7 @@ static inline int p4d_large(p4d_t p4d)
 
 #define pte_page(pte)  pfn_to_page(pte_pfn(pte))
 
+#define pmd_leaf       pmd_large
 static inline int pmd_large(pmd_t pte)
 {
        return pmd_flags(pte) & _PAGE_PSE;
@@ -874,6 +877,7 @@ static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address)
        return (pmd_t *)pud_page_vaddr(*pud) + pmd_index(address);
 }
 
+#define pud_leaf       pud_large
 static inline int pud_large(pud_t pud)
 {
        return (pud_val(pud) & (_PAGE_PSE | _PAGE_PRESENT)) ==
@@ -885,6 +889,7 @@ static inline int pud_bad(pud_t pud)
        return (pud_flags(pud) & ~(_KERNPG_TABLE | _PAGE_USER)) != 0;
 }
 #else
+#define pud_leaf       pud_large
 static inline int pud_large(pud_t pud)
 {
        return 0;
@@ -1233,6 +1238,7 @@ static inline bool pgdp_maps_userspace(void *__ptr)
        return (((ptr & ~PAGE_MASK) / sizeof(pgd_t)) < PGD_KERNEL_START);
 }
 
+#define pgd_leaf       pgd_large
 static inline int pgd_large(pgd_t pgd) { return 0; }
 
 #ifdef CONFIG_PAGE_TABLE_ISOLATION
index f23e7aa..820082b 100644 (file)
@@ -29,8 +29,8 @@ static inline void tlb_flush(struct mmu_gather *tlb)
  * shootdown, enablement code for several hypervisors overrides
  * .flush_tlb_others hook in pv_mmu_ops and implements it by issuing
  * a hypercall. To keep software pagetable walkers safe in this case we
- * switch to RCU based table free (HAVE_RCU_TABLE_FREE). See the comment
- * below 'ifdef CONFIG_HAVE_RCU_TABLE_FREE' in include/asm-generic/tlb.h
+ * switch to RCU based table free (MMU_GATHER_RCU_TABLE_FREE). See the comment
+ * below 'ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE' in include/asm-generic/tlb.h
  * for more details.
  */
 static inline void __tlb_remove_table(void *table)
index d380b3b..2a85287 100644 (file)
@@ -22,8 +22,8 @@
 /*
  * Definitions of Primary Processor-Based VM-Execution Controls.
  */
-#define CPU_BASED_INTR_WINDOW_EXITING           VMCS_CONTROL_BIT(VIRTUAL_INTR_PENDING)
-#define CPU_BASED_USE_TSC_OFFSETTING            VMCS_CONTROL_BIT(TSC_OFFSETTING)
+#define CPU_BASED_INTR_WINDOW_EXITING           VMCS_CONTROL_BIT(INTR_WINDOW_EXITING)
+#define CPU_BASED_USE_TSC_OFFSETTING            VMCS_CONTROL_BIT(USE_TSC_OFFSETTING)
 #define CPU_BASED_HLT_EXITING                   VMCS_CONTROL_BIT(HLT_EXITING)
 #define CPU_BASED_INVLPG_EXITING                VMCS_CONTROL_BIT(INVLPG_EXITING)
 #define CPU_BASED_MWAIT_EXITING                 VMCS_CONTROL_BIT(MWAIT_EXITING)
@@ -34,7 +34,7 @@
 #define CPU_BASED_CR8_LOAD_EXITING              VMCS_CONTROL_BIT(CR8_LOAD_EXITING)
 #define CPU_BASED_CR8_STORE_EXITING             VMCS_CONTROL_BIT(CR8_STORE_EXITING)
 #define CPU_BASED_TPR_SHADOW                    VMCS_CONTROL_BIT(VIRTUAL_TPR)
-#define CPU_BASED_NMI_WINDOW_EXITING           VMCS_CONTROL_BIT(VIRTUAL_NMI_PENDING)
+#define CPU_BASED_NMI_WINDOW_EXITING           VMCS_CONTROL_BIT(NMI_WINDOW_EXITING)
 #define CPU_BASED_MOV_DR_EXITING                VMCS_CONTROL_BIT(MOV_DR_EXITING)
 #define CPU_BASED_UNCOND_IO_EXITING             VMCS_CONTROL_BIT(UNCOND_IO_EXITING)
 #define CPU_BASED_USE_IO_BITMAPS                VMCS_CONTROL_BIT(USE_IO_BITMAPS)
index 0d04d8b..a50e4a0 100644 (file)
@@ -34,8 +34,8 @@
 #define VMX_FEATURE_EPTP_SWITCHING     ( 0*32+ 28) /* EPTP switching (in guest) */
 
 /* Primary Processor-Based VM-Execution Controls, word 1 */
-#define VMX_FEATURE_VIRTUAL_INTR_PENDING ( 1*32+  2) /* "" VM-Exit if INTRs are unblocked in guest */
-#define VMX_FEATURE_TSC_OFFSETTING     ( 1*32+  3) /* "tsc_offset" Offset hardware TSC when read in guest */
+#define VMX_FEATURE_INTR_WINDOW_EXITING ( 1*32+  2) /* "" VM-Exit if INTRs are unblocked in guest */
+#define VMX_FEATURE_USE_TSC_OFFSETTING ( 1*32+  3) /* "tsc_offset" Offset hardware TSC when read in guest */
 #define VMX_FEATURE_HLT_EXITING                ( 1*32+  7) /* "" VM-Exit on HLT */
 #define VMX_FEATURE_INVLPG_EXITING     ( 1*32+  9) /* "" VM-Exit on INVLPG */
 #define VMX_FEATURE_MWAIT_EXITING      ( 1*32+ 10) /* "" VM-Exit on MWAIT */
@@ -46,7 +46,7 @@
 #define VMX_FEATURE_CR8_LOAD_EXITING   ( 1*32+ 19) /* "" VM-Exit on writes to CR8 */
 #define VMX_FEATURE_CR8_STORE_EXITING  ( 1*32+ 20) /* "" VM-Exit on reads from CR8 */
 #define VMX_FEATURE_VIRTUAL_TPR                ( 1*32+ 21) /* "vtpr" TPR virtualization, a.k.a. TPR shadow */
-#define VMX_FEATURE_VIRTUAL_NMI_PENDING        ( 1*32+ 22) /* "" VM-Exit if NMIs are unblocked in guest */
+#define VMX_FEATURE_NMI_WINDOW_EXITING ( 1*32+ 22) /* "" VM-Exit if NMIs are unblocked in guest */
 #define VMX_FEATURE_MOV_DR_EXITING     ( 1*32+ 23) /* "" VM-Exit on accesses to debug registers */
 #define VMX_FEATURE_UNCOND_IO_EXITING  ( 1*32+ 24) /* "" VM-Exit on *all* IN{S} and OUT{S}*/
 #define VMX_FEATURE_USE_IO_BITMAPS     ( 1*32+ 25) /* "" VM-Exit based on I/O port */
index 1943585..96d9cd2 100644 (file)
@@ -51,12 +51,14 @@ struct x86_init_resources {
  *                             are set up.
  * @intr_init:                 interrupt init code
  * @trap_init:                 platform specific trap setup
+ * @intr_mode_select:          interrupt delivery mode selection
  * @intr_mode_init:            interrupt delivery mode setup
  */
 struct x86_init_irqs {
        void (*pre_vector_init)(void);
        void (*intr_init)(void);
        void (*trap_init)(void);
+       void (*intr_mode_select)(void);
        void (*intr_mode_init)(void);
 };
 
index 28446fa..5f973fe 100644 (file)
@@ -830,8 +830,17 @@ bool __init apic_needs_pit(void)
        if (!tsc_khz || !cpu_khz)
                return true;
 
-       /* Is there an APIC at all? */
-       if (!boot_cpu_has(X86_FEATURE_APIC))
+       /* Is there an APIC at all or is it disabled? */
+       if (!boot_cpu_has(X86_FEATURE_APIC) || disable_apic)
+               return true;
+
+       /*
+        * If interrupt delivery mode is legacy PIC or virtual wire without
+        * configuration, the local APIC timer wont be set up. Make sure
+        * that the PIT is initialized.
+        */
+       if (apic_intr_mode == APIC_PIC ||
+           apic_intr_mode == APIC_VIRTUAL_WIRE_NO_CONFIG)
                return true;
 
        /* Virt guests may lack ARAT, but still have DEADLINE */
@@ -1322,7 +1331,7 @@ void __init sync_Arb_IDs(void)
 
 enum apic_intr_mode_id apic_intr_mode __ro_after_init;
 
-static int __init apic_intr_mode_select(void)
+static int __init __apic_intr_mode_select(void)
 {
        /* Check kernel option */
        if (disable_apic) {
@@ -1384,6 +1393,12 @@ static int __init apic_intr_mode_select(void)
        return APIC_SYMMETRIC_IO;
 }
 
+/* Select the interrupt delivery mode for the BSP */
+void __init apic_intr_mode_select(void)
+{
+       apic_intr_mode = __apic_intr_mode_select();
+}
+
 /*
  * An initial setup of the virtual wire mode.
  */
@@ -1440,8 +1455,6 @@ void __init apic_intr_mode_init(void)
 {
        bool upmode = IS_ENABLED(CONFIG_UP_LATE_INIT);
 
-       apic_intr_mode = apic_intr_mode_select();
-
        switch (apic_intr_mode) {
        case APIC_PIC:
                pr_info("APIC: Keep in PIC mode(8259)\n");
@@ -2626,6 +2639,13 @@ static int lapic_suspend(void)
 #endif
 
        local_irq_save(flags);
+
+       /*
+        * Mask IOAPIC before disabling the local APIC to prevent stale IRR
+        * entries on some implementations.
+        */
+       mask_ioapic_entries();
+
        disable_local_APIC();
 
        irq_remapping_disable();
index 7f75334..159bd0c 100644 (file)
 
 static struct irq_domain *msi_default_domain;
 
-static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
+static void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg)
 {
-       struct irq_cfg *cfg = irqd_cfg(data);
-
        msg->address_hi = MSI_ADDR_BASE_HI;
 
        if (x2apic_enabled())
@@ -47,6 +45,127 @@ static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
                MSI_DATA_VECTOR(cfg->vector);
 }
 
+static void irq_msi_compose_msg(struct irq_data *data, struct msi_msg *msg)
+{
+       __irq_msi_compose_msg(irqd_cfg(data), msg);
+}
+
+static void irq_msi_update_msg(struct irq_data *irqd, struct irq_cfg *cfg)
+{
+       struct msi_msg msg[2] = { [1] = { }, };
+
+       __irq_msi_compose_msg(cfg, msg);
+       irq_data_get_irq_chip(irqd)->irq_write_msi_msg(irqd, msg);
+}
+
+static int
+msi_set_affinity(struct irq_data *irqd, const struct cpumask *mask, bool force)
+{
+       struct irq_cfg old_cfg, *cfg = irqd_cfg(irqd);
+       struct irq_data *parent = irqd->parent_data;
+       unsigned int cpu;
+       int ret;
+
+       /* Save the current configuration */
+       cpu = cpumask_first(irq_data_get_effective_affinity_mask(irqd));
+       old_cfg = *cfg;
+
+       /* Allocate a new target vector */
+       ret = parent->chip->irq_set_affinity(parent, mask, force);
+       if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE)
+               return ret;
+
+       /*
+        * For non-maskable and non-remapped MSI interrupts the migration
+        * to a different destination CPU and a different vector has to be
+        * done careful to handle the possible stray interrupt which can be
+        * caused by the non-atomic update of the address/data pair.
+        *
+        * Direct update is possible when:
+        * - The MSI is maskable (remapped MSI does not use this code path)).
+        *   The quirk bit is not set in this case.
+        * - The new vector is the same as the old vector
+        * - The old vector is MANAGED_IRQ_SHUTDOWN_VECTOR (interrupt starts up)
+        * - The new destination CPU is the same as the old destination CPU
+        */
+       if (!irqd_msi_nomask_quirk(irqd) ||
+           cfg->vector == old_cfg.vector ||
+           old_cfg.vector == MANAGED_IRQ_SHUTDOWN_VECTOR ||
+           cfg->dest_apicid == old_cfg.dest_apicid) {
+               irq_msi_update_msg(irqd, cfg);
+               return ret;
+       }
+
+       /*
+        * Paranoia: Validate that the interrupt target is the local
+        * CPU.
+        */
+       if (WARN_ON_ONCE(cpu != smp_processor_id())) {
+               irq_msi_update_msg(irqd, cfg);
+               return ret;
+       }
+
+       /*
+        * Redirect the interrupt to the new vector on the current CPU
+        * first. This might cause a spurious interrupt on this vector if
+        * the device raises an interrupt right between this update and the
+        * update to the final destination CPU.
+        *
+        * If the vector is in use then the installed device handler will
+        * denote it as spurious which is no harm as this is a rare event
+        * and interrupt handlers have to cope with spurious interrupts
+        * anyway. If the vector is unused, then it is marked so it won't
+        * trigger the 'No irq handler for vector' warning in do_IRQ().
+        *
+        * This requires to hold vector lock to prevent concurrent updates to
+        * the affected vector.
+        */
+       lock_vector_lock();
+
+       /*
+        * Mark the new target vector on the local CPU if it is currently
+        * unused. Reuse the VECTOR_RETRIGGERED state which is also used in
+        * the CPU hotplug path for a similar purpose. This cannot be
+        * undone here as the current CPU has interrupts disabled and
+        * cannot handle the interrupt before the whole set_affinity()
+        * section is done. In the CPU unplug case, the current CPU is
+        * about to vanish and will not handle any interrupts anymore. The
+        * vector is cleaned up when the CPU comes online again.
+        */
+       if (IS_ERR_OR_NULL(this_cpu_read(vector_irq[cfg->vector])))
+               this_cpu_write(vector_irq[cfg->vector], VECTOR_RETRIGGERED);
+
+       /* Redirect it to the new vector on the local CPU temporarily */
+       old_cfg.vector = cfg->vector;
+       irq_msi_update_msg(irqd, &old_cfg);
+
+       /* Now transition it to the target CPU */
+       irq_msi_update_msg(irqd, cfg);
+
+       /*
+        * All interrupts after this point are now targeted at the new
+        * vector/CPU.
+        *
+        * Drop vector lock before testing whether the temporary assignment
+        * to the local CPU was hit by an interrupt raised in the device,
+        * because the retrigger function acquires vector lock again.
+        */
+       unlock_vector_lock();
+
+       /*
+        * Check whether the transition raced with a device interrupt and
+        * is pending in the local APICs IRR. It is safe to do this outside
+        * of vector lock as the irq_desc::lock of this interrupt is still
+        * held and interrupts are disabled: The check is not accessing the
+        * underlying vector store. It's just checking the local APIC's
+        * IRR.
+        */
+       if (lapic_vector_set_in_irr(cfg->vector))
+               irq_data_get_irq_chip(irqd)->irq_retrigger(irqd);
+
+       return ret;
+}
+
 /*
  * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
  * which implement the MSI or MSI-X Capability Structure.
@@ -58,6 +177,7 @@ static struct irq_chip pci_msi_controller = {
        .irq_ack                = irq_chip_ack_parent,
        .irq_retrigger          = irq_chip_retrigger_hierarchy,
        .irq_compose_msi_msg    = irq_msi_compose_msg,
+       .irq_set_affinity       = msi_set_affinity,
        .flags                  = IRQCHIP_SKIP_SET_WAKE,
 };
 
@@ -146,6 +266,8 @@ void __init arch_init_msi_domain(struct irq_domain *parent)
        }
        if (!msi_default_domain)
                pr_warn("failed to initialize irqdomain for MSI/MSI-x.\n");
+       else
+               msi_default_domain->flags |= IRQ_DOMAIN_MSI_NOMASK_QUIRK;
 }
 
 #ifdef CONFIG_IRQ_REMAP
index da532f6..a5c506f 100644 (file)
@@ -396,15 +396,16 @@ static int mtrr_open(struct inode *inode, struct file *file)
        return single_open(file, mtrr_seq_show, NULL);
 }
 
-static const struct file_operations mtrr_fops = {
-       .owner                  = THIS_MODULE,
-       .open                   = mtrr_open,
-       .read                   = seq_read,
-       .llseek                 = seq_lseek,
-       .write                  = mtrr_write,
-       .unlocked_ioctl         = mtrr_ioctl,
-       .compat_ioctl           = mtrr_ioctl,
-       .release                = mtrr_close,
+static const struct proc_ops mtrr_proc_ops = {
+       .proc_open              = mtrr_open,
+       .proc_read              = seq_read,
+       .proc_lseek             = seq_lseek,
+       .proc_write             = mtrr_write,
+       .proc_ioctl             = mtrr_ioctl,
+#ifdef CONFIG_COMPAT
+       .proc_compat_ioctl      = mtrr_ioctl,
+#endif
+       .proc_release           = mtrr_close,
 };
 
 static int __init mtrr_if_init(void)
@@ -417,7 +418,7 @@ static int __init mtrr_if_init(void)
            (!cpu_has(c, X86_FEATURE_CENTAUR_MCR)))
                return -ENODEV;
 
-       proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_fops);
+       proc_create("mtrr", S_IWUSR | S_IRUGO, NULL, &mtrr_proc_ops);
        return 0;
 }
 arch_initcall(mtrr_if_init);
index 8ca5e51..064e9ef 100644 (file)
@@ -2127,25 +2127,20 @@ enum rdt_param {
        nr__rdt_params
 };
 
-static const struct fs_parameter_spec rdt_param_specs[] = {
+static const struct fs_parameter_spec rdt_fs_parameters[] = {
        fsparam_flag("cdp",             Opt_cdp),
        fsparam_flag("cdpl2",           Opt_cdpl2),
        fsparam_flag("mba_MBps",        Opt_mba_mbps),
        {}
 };
 
-static const struct fs_parameter_description rdt_fs_parameters = {
-       .name           = "rdt",
-       .specs          = rdt_param_specs,
-};
-
 static int rdt_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct rdt_fs_context *ctx = rdt_fc2context(fc);
        struct fs_parse_result result;
        int opt;
 
-       opt = fs_parse(fc, &rdt_fs_parameters, param, &result);
+       opt = fs_parse(fc, rdt_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -2378,7 +2373,7 @@ static void rdt_kill_sb(struct super_block *sb)
 static struct file_system_type rdt_fs_type = {
        .name                   = "resctrl",
        .init_fs_context        = rdt_init_fs_context,
-       .parameters             = &rdt_fs_parameters,
+       .parameters             = rdt_fs_parameters,
        .kill_sb                = rdt_kill_sb,
 };
 
index 81045aa..d817f25 100644 (file)
@@ -736,6 +736,9 @@ static __init int kvm_setup_pv_tlb_flush(void)
 {
        int cpu;
 
+       if (!kvm_para_available() || nopv)
+               return 0;
+
        if (kvm_para_has_feature(KVM_FEATURE_PV_TLB_FLUSH) &&
            !kvm_para_has_hint(KVM_HINTS_REALTIME) &&
            kvm_para_has_feature(KVM_FEATURE_STEAL_TIME)) {
index 7ce29ce..d8673d8 100644 (file)
@@ -91,10 +91,18 @@ void __init hpet_time_init(void)
 
 static __init void x86_late_time_init(void)
 {
+       /*
+        * Before PIT/HPET init, select the interrupt mode. This is required
+        * to make the decision whether PIT should be initialized correct.
+        */
+       x86_init.irqs.intr_mode_select();
+
+       /* Setup the legacy timers */
        x86_init.timers.timer_init();
+
        /*
-        * After PIT/HPET timers init, select and setup
-        * the final interrupt mode for delivering IRQs.
+        * After PIT/HPET timers init, set up the final interrupt mode for
+        * delivering IRQs.
         */
        x86_init.irqs.intr_mode_init();
        tsc_init();
index 23e25f3..85f1a90 100644 (file)
@@ -80,6 +80,7 @@ struct x86_init_ops x86_init __initdata = {
                .pre_vector_init        = init_ISA_irqs,
                .intr_init              = native_init_IRQ,
                .trap_init              = x86_init_noop,
+               .intr_mode_select       = apic_intr_mode_select,
                .intr_mode_init         = apic_intr_mode_init
        },
 
index 4df1c96..a86fda7 100644 (file)
@@ -776,9 +776,10 @@ int kvm_hv_activate_synic(struct kvm_vcpu *vcpu, bool dont_zero_synic_pages)
 
        /*
         * Hyper-V SynIC auto EOI SINT's are
-        * not compatible with APICV, so deactivate APICV
+        * not compatible with APICV, so request
+        * to deactivate APICV permanently.
         */
-       kvm_vcpu_deactivate_apicv(vcpu);
+       kvm_request_apicv_update(vcpu->kvm, false, APICV_INHIBIT_REASON_HYPERV);
        synic->active = true;
        synic->dont_zero_synic_pages = dont_zero_synic_pages;
        return 0;
index 4a6dc54..b24c606 100644 (file)
@@ -295,12 +295,24 @@ void kvm_pit_set_reinject(struct kvm_pit *pit, bool reinject)
        if (atomic_read(&ps->reinject) == reinject)
                return;
 
+       /*
+        * AMD SVM AVIC accelerates EOI write and does not trap.
+        * This cause in-kernel PIT re-inject mode to fail
+        * since it checks ps->irq_ack before kvm_set_irq()
+        * and relies on the ack notifier to timely queue
+        * the pt->worker work iterm and reinject the missed tick.
+        * So, deactivate APICv when PIT is in reinject mode.
+        */
        if (reinject) {
+               kvm_request_apicv_update(kvm, false,
+                                        APICV_INHIBIT_REASON_PIT_REINJ);
                /* The initial state is preserved while ps->reinject == 0. */
                kvm_pit_reset_reinject(pit);
                kvm_register_irq_ack_notifier(kvm, &ps->irq_ack_notifier);
                kvm_register_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
        } else {
+               kvm_request_apicv_update(kvm, true,
+                                        APICV_INHIBIT_REASON_PIT_REINJ);
                kvm_unregister_irq_ack_notifier(kvm, &ps->irq_ack_notifier);
                kvm_unregister_irq_mask_notifier(kvm, 0, &pit->mask_notifier);
        }
index 26aa22c..7668fed 100644 (file)
 static int ioapic_service(struct kvm_ioapic *vioapic, int irq,
                bool line_status);
 
+static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu,
+                                     struct kvm_ioapic *ioapic,
+                                     int trigger_mode,
+                                     int pin);
+
 static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic,
                                          unsigned long addr,
                                          unsigned long length)
@@ -154,10 +159,16 @@ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic)
            __rtc_irq_eoi_tracking_restore_one(vcpu);
 }
 
-static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu)
+static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu,
+                       int vector)
 {
-       if (test_and_clear_bit(vcpu->vcpu_id,
-                              ioapic->rtc_status.dest_map.map)) {
+       struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
+
+       /* RTC special handling */
+       if (test_bit(vcpu->vcpu_id, dest_map->map) &&
+           (vector == dest_map->vectors[vcpu->vcpu_id]) &&
+           (test_and_clear_bit(vcpu->vcpu_id,
+                               ioapic->rtc_status.dest_map.map))) {
                --ioapic->rtc_status.pending_eoi;
                rtc_status_pending_eoi_check_valid(ioapic);
        }
@@ -171,6 +182,31 @@ static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic)
        return false;
 }
 
+static void ioapic_lazy_update_eoi(struct kvm_ioapic *ioapic, int irq)
+{
+       int i;
+       struct kvm_vcpu *vcpu;
+       union kvm_ioapic_redirect_entry *entry = &ioapic->redirtbl[irq];
+
+       kvm_for_each_vcpu(i, vcpu, ioapic->kvm) {
+               if (!kvm_apic_match_dest(vcpu, NULL, APIC_DEST_NOSHORT,
+                                        entry->fields.dest_id,
+                                        entry->fields.dest_mode) ||
+                   kvm_apic_pending_eoi(vcpu, entry->fields.vector))
+                       continue;
+
+               /*
+                * If no longer has pending EOI in LAPICs, update
+                * EOI for this vetor.
+                */
+               rtc_irq_eoi(ioapic, vcpu, entry->fields.vector);
+               kvm_ioapic_update_eoi_one(vcpu, ioapic,
+                                         entry->fields.trig_mode,
+                                         irq);
+               break;
+       }
+}
+
 static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq,
                int irq_level, bool line_status)
 {
@@ -189,6 +225,15 @@ static int ioapic_set_irq(struct kvm_ioapic *ioapic, unsigned int irq,
        }
 
        /*
+        * AMD SVM AVIC accelerate EOI write and do not trap,
+        * in-kernel IOAPIC will not be able to receive the EOI.
+        * In this case, we do lazy update of the pending EOI when
+        * trying to set IOAPIC irq.
+        */
+       if (kvm_apicv_activated(ioapic->kvm))
+               ioapic_lazy_update_eoi(ioapic, irq);
+
+       /*
         * Return 0 for coalesced interrupts; for edge-triggered interrupts,
         * this only happens if a previous edge has not been delivered due
         * to masking.  For level interrupts, the remote_irr field tells
@@ -454,72 +499,68 @@ static void kvm_ioapic_eoi_inject_work(struct work_struct *work)
 }
 
 #define IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT 10000
-
-static void __kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu,
-                       struct kvm_ioapic *ioapic, int vector, int trigger_mode)
+static void kvm_ioapic_update_eoi_one(struct kvm_vcpu *vcpu,
+                                     struct kvm_ioapic *ioapic,
+                                     int trigger_mode,
+                                     int pin)
 {
-       struct dest_map *dest_map = &ioapic->rtc_status.dest_map;
        struct kvm_lapic *apic = vcpu->arch.apic;
-       int i;
-
-       /* RTC special handling */
-       if (test_bit(vcpu->vcpu_id, dest_map->map) &&
-           vector == dest_map->vectors[vcpu->vcpu_id])
-               rtc_irq_eoi(ioapic, vcpu);
-
-       for (i = 0; i < IOAPIC_NUM_PINS; i++) {
-               union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i];
-
-               if (ent->fields.vector != vector)
-                       continue;
+       union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[pin];
 
-               /*
-                * We are dropping lock while calling ack notifiers because ack
-                * notifier callbacks for assigned devices call into IOAPIC
-                * recursively. Since remote_irr is cleared only after call
-                * to notifiers if the same vector will be delivered while lock
-                * is dropped it will be put into irr and will be delivered
-                * after ack notifier returns.
-                */
-               spin_unlock(&ioapic->lock);
-               kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, i);
-               spin_lock(&ioapic->lock);
+       /*
+        * We are dropping lock while calling ack notifiers because ack
+        * notifier callbacks for assigned devices call into IOAPIC
+        * recursively. Since remote_irr is cleared only after call
+        * to notifiers if the same vector will be delivered while lock
+        * is dropped it will be put into irr and will be delivered
+        * after ack notifier returns.
+        */
+       spin_unlock(&ioapic->lock);
+       kvm_notify_acked_irq(ioapic->kvm, KVM_IRQCHIP_IOAPIC, pin);
+       spin_lock(&ioapic->lock);
 
-               if (trigger_mode != IOAPIC_LEVEL_TRIG ||
-                   kvm_lapic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)
-                       continue;
+       if (trigger_mode != IOAPIC_LEVEL_TRIG ||
+           kvm_lapic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)
+               return;
 
-               ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
-               ent->fields.remote_irr = 0;
-               if (!ent->fields.mask && (ioapic->irr & (1 << i))) {
-                       ++ioapic->irq_eoi[i];
-                       if (ioapic->irq_eoi[i] == IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT) {
-                               /*
-                                * Real hardware does not deliver the interrupt
-                                * immediately during eoi broadcast, and this
-                                * lets a buggy guest make slow progress
-                                * even if it does not correctly handle a
-                                * level-triggered interrupt.  Emulate this
-                                * behavior if we detect an interrupt storm.
-                                */
-                               schedule_delayed_work(&ioapic->eoi_inject, HZ / 100);
-                               ioapic->irq_eoi[i] = 0;
-                               trace_kvm_ioapic_delayed_eoi_inj(ent->bits);
-                       } else {
-                               ioapic_service(ioapic, i, false);
-                       }
+       ASSERT(ent->fields.trig_mode == IOAPIC_LEVEL_TRIG);
+       ent->fields.remote_irr = 0;
+       if (!ent->fields.mask && (ioapic->irr & (1 << pin))) {
+               ++ioapic->irq_eoi[pin];
+               if (ioapic->irq_eoi[pin] == IOAPIC_SUCCESSIVE_IRQ_MAX_COUNT) {
+                       /*
+                        * Real hardware does not deliver the interrupt
+                        * immediately during eoi broadcast, and this
+                        * lets a buggy guest make slow progress
+                        * even if it does not correctly handle a
+                        * level-triggered interrupt.  Emulate this
+                        * behavior if we detect an interrupt storm.
+                        */
+                       schedule_delayed_work(&ioapic->eoi_inject, HZ / 100);
+                       ioapic->irq_eoi[pin] = 0;
+                       trace_kvm_ioapic_delayed_eoi_inj(ent->bits);
                } else {
-                       ioapic->irq_eoi[i] = 0;
+                       ioapic_service(ioapic, pin, false);
                }
+       } else {
+               ioapic->irq_eoi[pin] = 0;
        }
 }
 
 void kvm_ioapic_update_eoi(struct kvm_vcpu *vcpu, int vector, int trigger_mode)
 {
+       int i;
        struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic;
 
        spin_lock(&ioapic->lock);
-       __kvm_ioapic_update_eoi(vcpu, ioapic, vector, trigger_mode);
+       rtc_irq_eoi(ioapic, vcpu, vector);
+       for (i = 0; i < IOAPIC_NUM_PINS; i++) {
+               union kvm_ioapic_redirect_entry *ent = &ioapic->redirtbl[i];
+
+               if (ent->fields.vector != vector)
+                       continue;
+               kvm_ioapic_update_eoi_one(vcpu, ioapic, trigger_mode, i);
+       }
        spin_unlock(&ioapic->lock);
 }
 
index cce1e6b..eafc631 100644 (file)
@@ -2187,6 +2187,21 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
                pr_warn_once("APIC base relocation is unsupported by KVM");
 }
 
+void kvm_apic_update_apicv(struct kvm_vcpu *vcpu)
+{
+       struct kvm_lapic *apic = vcpu->arch.apic;
+
+       if (vcpu->arch.apicv_active) {
+               /* irr_pending is always true when apicv is activated. */
+               apic->irr_pending = true;
+               apic->isr_count = 1;
+       } else {
+               apic->irr_pending = (apic_search_irr(apic) != -1);
+               apic->isr_count = count_vectors(apic->regs + APIC_ISR);
+       }
+}
+EXPORT_SYMBOL_GPL(kvm_apic_update_apicv);
+
 void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
 {
        struct kvm_lapic *apic = vcpu->arch.apic;
@@ -2229,8 +2244,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event)
                kvm_lapic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
                kvm_lapic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
        }
-       apic->irr_pending = vcpu->arch.apicv_active;
-       apic->isr_count = vcpu->arch.apicv_active ? 1 : 0;
+       kvm_apic_update_apicv(vcpu);
        apic->highest_isr_cache = -1;
        update_divide_count(apic);
        atomic_set(&apic->lapic_timer.pending, 0);
@@ -2487,9 +2501,7 @@ int kvm_apic_set_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s)
        apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0));
        update_divide_count(apic);
        start_apic_timer(apic);
-       apic->irr_pending = true;
-       apic->isr_count = vcpu->arch.apicv_active ?
-                               1 : count_vectors(apic->regs + APIC_ISR);
+       kvm_apic_update_apicv(vcpu);
        apic->highest_isr_cache = -1;
        if (vcpu->arch.apicv_active) {
                kvm_x86_ops->apicv_post_state_restore(vcpu);
index ec730ce..ec6fbfe 100644 (file)
@@ -91,6 +91,7 @@ void kvm_apic_update_ppr(struct kvm_vcpu *vcpu);
 int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct kvm_lapic_irq *irq,
                     struct dest_map *dest_map);
 int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type);
+void kvm_apic_update_apicv(struct kvm_vcpu *vcpu);
 
 bool kvm_irq_delivery_to_apic_fast(struct kvm *kvm, struct kvm_lapic *src,
                struct kvm_lapic_irq *irq, int *r, struct dest_map *dest_map);
index adc84f0..7011a4e 100644 (file)
@@ -451,9 +451,9 @@ static u64 get_mmio_spte_generation(u64 spte)
        return gen;
 }
 
-static void mark_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, u64 gfn,
-                          unsigned access)
+static u64 make_mmio_spte(struct kvm_vcpu *vcpu, u64 gfn, unsigned int access)
 {
+
        u64 gen = kvm_vcpu_memslots(vcpu)->generation & MMIO_SPTE_GEN_MASK;
        u64 mask = generation_mmio_spte_mask(gen);
        u64 gpa = gfn << PAGE_SHIFT;
@@ -464,6 +464,17 @@ static void mark_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, u64 gfn,
        mask |= (gpa & shadow_nonpresent_or_rsvd_mask)
                << shadow_nonpresent_or_rsvd_mask_len;
 
+       return mask;
+}
+
+static void mark_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, u64 gfn,
+                          unsigned int access)
+{
+       u64 mask = make_mmio_spte(vcpu, gfn, access);
+       unsigned int gen = get_mmio_spte_generation(mask);
+
+       access = mask & ACC_ALL;
+
        trace_mark_mmio_spte(sptep, gfn, access, gen);
        mmu_spte_set(sptep, mask);
 }
@@ -484,7 +495,7 @@ static unsigned get_mmio_spte_access(u64 spte)
 }
 
 static bool set_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, gfn_t gfn,
-                         kvm_pfn_t pfn, unsigned access)
+                         kvm_pfn_t pfn, unsigned int access)
 {
        if (unlikely(is_noslot_pfn(pfn))) {
                mark_mmio_spte(vcpu, sptep, gfn, access);
@@ -2475,7 +2486,7 @@ static struct kvm_mmu_page *kvm_mmu_get_page(struct kvm_vcpu *vcpu,
                                             gva_t gaddr,
                                             unsigned level,
                                             int direct,
-                                            unsigned access)
+                                            unsigned int access)
 {
        union kvm_mmu_page_role role;
        unsigned quadrant;
@@ -2990,7 +3001,7 @@ static bool kvm_is_mmio_pfn(kvm_pfn_t pfn)
 #define SET_SPTE_NEED_REMOTE_TLB_FLUSH BIT(1)
 
 static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
-                   unsigned pte_access, int level,
+                   unsigned int pte_access, int level,
                    gfn_t gfn, kvm_pfn_t pfn, bool speculative,
                    bool can_unsync, bool host_writable)
 {
@@ -3081,9 +3092,10 @@ set_pte:
        return ret;
 }
 
-static int mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep, unsigned pte_access,
-                       int write_fault, int level, gfn_t gfn, kvm_pfn_t pfn,
-                       bool speculative, bool host_writable)
+static int mmu_set_spte(struct kvm_vcpu *vcpu, u64 *sptep,
+                       unsigned int pte_access, int write_fault, int level,
+                       gfn_t gfn, kvm_pfn_t pfn, bool speculative,
+                       bool host_writable)
 {
        int was_rmapped = 0;
        int rmap_count;
@@ -3165,7 +3177,7 @@ static int direct_pte_prefetch_many(struct kvm_vcpu *vcpu,
 {
        struct page *pages[PTE_PREFETCH_NUM];
        struct kvm_memory_slot *slot;
-       unsigned access = sp->role.access;
+       unsigned int access = sp->role.access;
        int i, ret;
        gfn_t gfn;
 
@@ -3400,7 +3412,8 @@ static int kvm_handle_bad_page(struct kvm_vcpu *vcpu, gfn_t gfn, kvm_pfn_t pfn)
 }
 
 static bool handle_abnormal_pfn(struct kvm_vcpu *vcpu, gva_t gva, gfn_t gfn,
-                               kvm_pfn_t pfn, unsigned access, int *ret_val)
+                               kvm_pfn_t pfn, unsigned int access,
+                               int *ret_val)
 {
        /* The pfn is invalid, report the error! */
        if (unlikely(is_error_pfn(pfn))) {
@@ -4005,7 +4018,7 @@ static int handle_mmio_page_fault(struct kvm_vcpu *vcpu, u64 addr, bool direct)
 
        if (is_mmio_spte(spte)) {
                gfn_t gfn = get_mmio_spte_gfn(spte);
-               unsigned access = get_mmio_spte_access(spte);
+               unsigned int access = get_mmio_spte_access(spte);
 
                if (!check_mmio_spte(vcpu, spte))
                        return RET_PF_INVALID;
@@ -4349,7 +4362,7 @@ static void inject_page_fault(struct kvm_vcpu *vcpu,
 }
 
 static bool sync_mmio_spte(struct kvm_vcpu *vcpu, u64 *sptep, gfn_t gfn,
-                          unsigned access, int *nr_present)
+                          unsigned int access, int *nr_present)
 {
        if (unlikely(is_mmio_spte(*sptep))) {
                if (gfn != get_mmio_spte_gfn(*sptep)) {
index 9dbb990..a3e32d6 100644 (file)
@@ -387,6 +387,8 @@ static u8 rsm_ins_bytes[] = "\x0f\xaa";
 static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0);
 static void svm_flush_tlb(struct kvm_vcpu *vcpu, bool invalidate_gpa);
 static void svm_complete_interrupts(struct vcpu_svm *svm);
+static void svm_toggle_avic_for_irq_window(struct kvm_vcpu *vcpu, bool activate);
+static inline void avic_post_state_restore(struct kvm_vcpu *vcpu);
 
 static int nested_svm_exit_handled(struct vcpu_svm *svm);
 static int nested_svm_intercept(struct vcpu_svm *svm);
@@ -1545,7 +1547,10 @@ static void avic_init_vmcb(struct vcpu_svm *svm)
        vmcb->control.avic_logical_id = lpa & AVIC_HPA_MASK;
        vmcb->control.avic_physical_id = ppa & AVIC_HPA_MASK;
        vmcb->control.avic_physical_id |= AVIC_MAX_PHYSICAL_ID_COUNT;
-       vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
+       if (kvm_apicv_activated(svm->vcpu.kvm))
+               vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
+       else
+               vmcb->control.int_ctl &= ~AVIC_ENABLE_MASK;
 }
 
 static void init_vmcb(struct vcpu_svm *svm)
@@ -1729,23 +1734,28 @@ static u64 *avic_get_physical_id_entry(struct kvm_vcpu *vcpu,
  * field of the VMCB. Therefore, we set up the
  * APIC_ACCESS_PAGE_PRIVATE_MEMSLOT (4KB) here.
  */
-static int avic_init_access_page(struct kvm_vcpu *vcpu)
+static int avic_update_access_page(struct kvm *kvm, bool activate)
 {
-       struct kvm *kvm = vcpu->kvm;
        int ret = 0;
 
        mutex_lock(&kvm->slots_lock);
-       if (kvm->arch.apic_access_page_done)
+       /*
+        * During kvm_destroy_vm(), kvm_pit_set_reinject() could trigger
+        * APICv mode change, which update APIC_ACCESS_PAGE_PRIVATE_MEMSLOT
+        * memory region. So, we need to ensure that kvm->mm == current->mm.
+        */
+       if ((kvm->arch.apic_access_page_done == activate) ||
+           (kvm->mm != current->mm))
                goto out;
 
        ret = __x86_set_memory_region(kvm,
                                      APIC_ACCESS_PAGE_PRIVATE_MEMSLOT,
                                      APIC_DEFAULT_PHYS_BASE,
-                                     PAGE_SIZE);
+                                     activate ? PAGE_SIZE : 0);
        if (ret)
                goto out;
 
-       kvm->arch.apic_access_page_done = true;
+       kvm->arch.apic_access_page_done = activate;
 out:
        mutex_unlock(&kvm->slots_lock);
        return ret;
@@ -1753,21 +1763,24 @@ out:
 
 static int avic_init_backing_page(struct kvm_vcpu *vcpu)
 {
-       int ret;
        u64 *entry, new_entry;
        int id = vcpu->vcpu_id;
        struct vcpu_svm *svm = to_svm(vcpu);
 
-       ret = avic_init_access_page(vcpu);
-       if (ret)
-               return ret;
-
        if (id >= AVIC_MAX_PHYSICAL_ID_COUNT)
                return -EINVAL;
 
        if (!svm->vcpu.arch.apic->regs)
                return -EINVAL;
 
+       if (kvm_apicv_activated(vcpu->kvm)) {
+               int ret;
+
+               ret = avic_update_access_page(vcpu->kvm, true);
+               if (ret)
+                       return ret;
+       }
+
        svm->avic_backing_page = virt_to_page(svm->vcpu.arch.apic->regs);
 
        /* Setting AVIC backing page address in the phy APIC ID table */
@@ -2052,6 +2065,18 @@ free_avic:
        return err;
 }
 
+static int svm_vm_init(struct kvm *kvm)
+{
+       if (avic) {
+               int ret = avic_vm_init(kvm);
+               if (ret)
+                       return ret;
+       }
+
+       kvm_apicv_init(kvm, avic);
+       return 0;
+}
+
 static inline int
 avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, bool r)
 {
@@ -2223,7 +2248,8 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
        /* We initialize this flag to true to make sure that the is_running
         * bit would be set the first time the vcpu is loaded.
         */
-       svm->avic_is_running = true;
+       if (irqchip_in_kernel(vcpu->kvm) && kvm_apicv_activated(vcpu->kvm))
+               svm->avic_is_running = true;
 
        svm->nested.hsave = page_address(hsave_page);
 
@@ -2348,6 +2374,8 @@ static void svm_vcpu_blocking(struct kvm_vcpu *vcpu)
 
 static void svm_vcpu_unblocking(struct kvm_vcpu *vcpu)
 {
+       if (kvm_check_request(KVM_REQ_APICV_UPDATE, vcpu))
+               kvm_vcpu_update_apicv(vcpu);
        avic_set_running(vcpu, true);
 }
 
@@ -4197,6 +4225,8 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr_info->host_initiated &&
+                   !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) &&
+                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_STIBP) &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS) &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD))
                        return 1;
@@ -4282,6 +4312,8 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
                break;
        case MSR_IA32_SPEC_CTRL:
                if (!msr->host_initiated &&
+                   !guest_cpuid_has(vcpu, X86_FEATURE_SPEC_CTRL) &&
+                   !guest_cpuid_has(vcpu, X86_FEATURE_AMD_STIBP) &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_AMD_IBRS) &&
                    !guest_cpuid_has(vcpu, X86_FEATURE_AMD_SSBD))
                        return 1;
@@ -4440,6 +4472,14 @@ static int interrupt_window_interception(struct vcpu_svm *svm)
 {
        kvm_make_request(KVM_REQ_EVENT, &svm->vcpu);
        svm_clear_vintr(svm);
+
+       /*
+        * For AVIC, the only reason to end up here is ExtINTs.
+        * In this case AVIC was temporarily disabled for
+        * requesting the IRQ window and we have to re-enable it.
+        */
+       svm_toggle_avic_for_irq_window(&svm->vcpu, true);
+
        svm->vmcb->control.int_ctl &= ~V_IRQ_MASK;
        mark_dirty(svm->vmcb, VMCB_INTR);
        ++svm->vcpu.stat.irq_window_exits;
@@ -5135,30 +5175,79 @@ static void svm_set_virtual_apic_mode(struct kvm_vcpu *vcpu)
        return;
 }
 
-static bool svm_get_enable_apicv(struct kvm *kvm)
+static void svm_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
 {
-       return avic && irqchip_split(kvm);
 }
 
-static void svm_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr)
+static void svm_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
 {
 }
 
-static void svm_hwapic_isr_update(struct kvm_vcpu *vcpu, int max_isr)
+static void svm_toggle_avic_for_irq_window(struct kvm_vcpu *vcpu, bool activate)
 {
+       if (!avic || !lapic_in_kernel(vcpu))
+               return;
+
+       srcu_read_unlock(&vcpu->kvm->srcu, vcpu->srcu_idx);
+       kvm_request_apicv_update(vcpu->kvm, activate,
+                                APICV_INHIBIT_REASON_IRQWIN);
+       vcpu->srcu_idx = srcu_read_lock(&vcpu->kvm->srcu);
+}
+
+static int svm_set_pi_irte_mode(struct kvm_vcpu *vcpu, bool activate)
+{
+       int ret = 0;
+       unsigned long flags;
+       struct amd_svm_iommu_ir *ir;
+       struct vcpu_svm *svm = to_svm(vcpu);
+
+       if (!kvm_arch_has_assigned_device(vcpu->kvm))
+               return 0;
+
+       /*
+        * Here, we go through the per-vcpu ir_list to update all existing
+        * interrupt remapping table entry targeting this vcpu.
+        */
+       spin_lock_irqsave(&svm->ir_list_lock, flags);
+
+       if (list_empty(&svm->ir_list))
+               goto out;
+
+       list_for_each_entry(ir, &svm->ir_list, node) {
+               if (activate)
+                       ret = amd_iommu_activate_guest_mode(ir->data);
+               else
+                       ret = amd_iommu_deactivate_guest_mode(ir->data);
+               if (ret)
+                       break;
+       }
+out:
+       spin_unlock_irqrestore(&svm->ir_list_lock, flags);
+       return ret;
 }
 
-/* Note: Currently only used by Hyper-V. */
 static void svm_refresh_apicv_exec_ctrl(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
        struct vmcb *vmcb = svm->vmcb;
+       bool activated = kvm_vcpu_apicv_active(vcpu);
 
-       if (kvm_vcpu_apicv_active(vcpu))
+       if (activated) {
+               /**
+                * During AVIC temporary deactivation, guest could update
+                * APIC ID, DFR and LDR registers, which would not be trapped
+                * by avic_unaccelerated_access_interception(). In this case,
+                * we need to check and update the AVIC logical APIC ID table
+                * accordingly before re-activating.
+                */
+               avic_post_state_restore(vcpu);
                vmcb->control.int_ctl |= AVIC_ENABLE_MASK;
-       else
+       } else {
                vmcb->control.int_ctl &= ~AVIC_ENABLE_MASK;
+       }
        mark_dirty(vmcb, VMCB_AVIC);
+
+       svm_set_pi_irte_mode(vcpu, activated);
 }
 
 static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap)
@@ -5445,9 +5534,6 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
 {
        struct vcpu_svm *svm = to_svm(vcpu);
 
-       if (kvm_vcpu_apicv_active(vcpu))
-               return;
-
        /*
         * In case GIF=0 we can't rely on the CPU to tell us when GIF becomes
         * 1, because that's a separate STGI/VMRUN intercept.  The next time we
@@ -5457,6 +5543,13 @@ static void enable_irq_window(struct kvm_vcpu *vcpu)
         * window under the assumption that the hardware will set the GIF.
         */
        if ((vgif_enabled(svm) || gif_set(svm)) && nested_svm_intr(svm)) {
+               /*
+                * IRQ window is not needed when AVIC is enabled,
+                * unless we have pending ExtINT since it cannot be injected
+                * via AVIC. In such case, we need to temporarily disable AVIC,
+                * and fallback to injecting IRQ via V_IRQ.
+                */
+               svm_toggle_avic_for_irq_window(vcpu, false);
                svm_set_vintr(svm);
                svm_inject_irq(svm, 0x0);
        }
@@ -5929,6 +6022,14 @@ static void svm_cpuid_update(struct kvm_vcpu *vcpu)
                return;
 
        guest_cpuid_clear(vcpu, X86_FEATURE_X2APIC);
+
+       /*
+        * Currently, AVIC does not work with nested virtualization.
+        * So, we disable AVIC when cpuid for SVM is set in the L1 guest.
+        */
+       if (nested && guest_cpuid_has(vcpu, X86_FEATURE_SVM))
+               kvm_request_apicv_update(vcpu->kvm, false,
+                                        APICV_INHIBIT_REASON_NESTED);
 }
 
 #define F feature_bit
@@ -7257,6 +7358,22 @@ static bool svm_apic_init_signal_blocked(struct kvm_vcpu *vcpu)
                   (svm->vmcb->control.intercept & (1ULL << INTERCEPT_INIT));
 }
 
+static bool svm_check_apicv_inhibit_reasons(ulong bit)
+{
+       ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
+                         BIT(APICV_INHIBIT_REASON_HYPERV) |
+                         BIT(APICV_INHIBIT_REASON_NESTED) |
+                         BIT(APICV_INHIBIT_REASON_IRQWIN) |
+                         BIT(APICV_INHIBIT_REASON_PIT_REINJ);
+
+       return supported & BIT(bit);
+}
+
+static void svm_pre_update_apicv_exec_ctrl(struct kvm *kvm, bool activate)
+{
+       avic_update_access_page(kvm, activate);
+}
+
 static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
        .cpu_has_kvm_support = has_svm,
        .disabled_by_bios = is_disabled,
@@ -7274,7 +7391,7 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
 
        .vm_alloc = svm_vm_alloc,
        .vm_free = svm_vm_free,
-       .vm_init = avic_vm_init,
+       .vm_init = svm_vm_init,
        .vm_destroy = svm_vm_destroy,
 
        .prepare_guest_switch = svm_prepare_guest_switch,
@@ -7331,8 +7448,9 @@ static struct kvm_x86_ops svm_x86_ops __ro_after_init = {
        .enable_irq_window = enable_irq_window,
        .update_cr8_intercept = update_cr8_intercept,
        .set_virtual_apic_mode = svm_set_virtual_apic_mode,
-       .get_enable_apicv = svm_get_enable_apicv,
        .refresh_apicv_exec_ctrl = svm_refresh_apicv_exec_ctrl,
+       .check_apicv_inhibit_reasons = svm_check_apicv_inhibit_reasons,
+       .pre_update_apicv_exec_ctrl = svm_pre_update_apicv_exec_ctrl,
        .load_eoi_exitmap = svm_load_eoi_exitmap,
        .hwapic_irr_update = svm_hwapic_irr_update,
        .hwapic_isr_update = svm_hwapic_isr_update,
index 7c741a0..f194dd0 100644 (file)
@@ -1291,6 +1291,25 @@ TRACE_EVENT(kvm_hv_stimer_cleanup,
                  __entry->vcpu_id, __entry->timer_index)
 );
 
+TRACE_EVENT(kvm_apicv_update_request,
+           TP_PROTO(bool activate, unsigned long bit),
+           TP_ARGS(activate, bit),
+
+       TP_STRUCT__entry(
+               __field(bool, activate)
+               __field(unsigned long, bit)
+       ),
+
+       TP_fast_assign(
+               __entry->activate = activate;
+               __entry->bit = bit;
+       ),
+
+       TP_printk("%s bit=%lu",
+                 __entry->activate ? "activate" : "deactivate",
+                 __entry->bit)
+);
+
 /*
  * Tracepoint for AMD AVIC
  */
index 89c3e0c..3038134 100644 (file)
@@ -7,6 +7,7 @@
 #include "evmcs.h"
 #include "vmcs.h"
 #include "vmx.h"
+#include "trace.h"
 
 DEFINE_STATIC_KEY_FALSE(enable_evmcs);
 
@@ -346,6 +347,84 @@ uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu)
        return 0;
 }
 
+void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata)
+{
+       u32 ctl_low = (u32)*pdata;
+       u32 ctl_high = (u32)(*pdata >> 32);
+
+       /*
+        * Hyper-V 2016 and 2019 try using these features even when eVMCS
+        * is enabled but there are no corresponding fields.
+        */
+       switch (msr_index) {
+       case MSR_IA32_VMX_EXIT_CTLS:
+       case MSR_IA32_VMX_TRUE_EXIT_CTLS:
+               ctl_high &= ~VM_EXIT_LOAD_IA32_PERF_GLOBAL_CTRL;
+               break;
+       case MSR_IA32_VMX_ENTRY_CTLS:
+       case MSR_IA32_VMX_TRUE_ENTRY_CTLS:
+               ctl_high &= ~VM_ENTRY_LOAD_IA32_PERF_GLOBAL_CTRL;
+               break;
+       case MSR_IA32_VMX_PROCBASED_CTLS2:
+               ctl_high &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+               break;
+       }
+
+       *pdata = ctl_low | ((u64)ctl_high << 32);
+}
+
+int nested_evmcs_check_controls(struct vmcs12 *vmcs12)
+{
+       int ret = 0;
+       u32 unsupp_ctl;
+
+       unsupp_ctl = vmcs12->pin_based_vm_exec_control &
+               EVMCS1_UNSUPPORTED_PINCTRL;
+       if (unsupp_ctl) {
+               trace_kvm_nested_vmenter_failed(
+                       "eVMCS: unsupported pin-based VM-execution controls",
+                       unsupp_ctl);
+               ret = -EINVAL;
+       }
+
+       unsupp_ctl = vmcs12->secondary_vm_exec_control &
+               EVMCS1_UNSUPPORTED_2NDEXEC;
+       if (unsupp_ctl) {
+               trace_kvm_nested_vmenter_failed(
+                       "eVMCS: unsupported secondary VM-execution controls",
+                       unsupp_ctl);
+               ret = -EINVAL;
+       }
+
+       unsupp_ctl = vmcs12->vm_exit_controls &
+               EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
+       if (unsupp_ctl) {
+               trace_kvm_nested_vmenter_failed(
+                       "eVMCS: unsupported VM-exit controls",
+                       unsupp_ctl);
+               ret = -EINVAL;
+       }
+
+       unsupp_ctl = vmcs12->vm_entry_controls &
+               EVMCS1_UNSUPPORTED_VMENTRY_CTRL;
+       if (unsupp_ctl) {
+               trace_kvm_nested_vmenter_failed(
+                       "eVMCS: unsupported VM-entry controls",
+                       unsupp_ctl);
+               ret = -EINVAL;
+       }
+
+       unsupp_ctl = vmcs12->vm_function_control & EVMCS1_UNSUPPORTED_VMFUNC;
+       if (unsupp_ctl) {
+               trace_kvm_nested_vmenter_failed(
+                       "eVMCS: unsupported VM-function controls",
+                       unsupp_ctl);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
 int nested_enable_evmcs(struct kvm_vcpu *vcpu,
                        uint16_t *vmcs_version)
 {
@@ -356,11 +435,5 @@ int nested_enable_evmcs(struct kvm_vcpu *vcpu,
        if (vmcs_version)
                *vmcs_version = nested_get_evmcs_version(vcpu);
 
-       vmx->nested.msrs.pinbased_ctls_high &= ~EVMCS1_UNSUPPORTED_PINCTRL;
-       vmx->nested.msrs.entry_ctls_high &= ~EVMCS1_UNSUPPORTED_VMENTRY_CTRL;
-       vmx->nested.msrs.exit_ctls_high &= ~EVMCS1_UNSUPPORTED_VMEXIT_CTRL;
-       vmx->nested.msrs.secondary_ctls_high &= ~EVMCS1_UNSUPPORTED_2NDEXEC;
-       vmx->nested.msrs.vmfunc_controls &= ~EVMCS1_UNSUPPORTED_VMFUNC;
-
        return 0;
 }
index 07ebf68..6de47f2 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "capabilities.h"
 #include "vmcs.h"
+#include "vmcs12.h"
 
 struct vmcs_config;
 
@@ -201,5 +202,7 @@ bool nested_enlightened_vmentry(struct kvm_vcpu *vcpu, u64 *evmcs_gpa);
 uint16_t nested_get_evmcs_version(struct kvm_vcpu *vcpu);
 int nested_enable_evmcs(struct kvm_vcpu *vcpu,
                        uint16_t *vmcs_version);
+void nested_evmcs_filter_control_msr(u32 msr_index, u64 *pdata);
+int nested_evmcs_check_controls(struct vmcs12 *vmcs12);
 
 #endif /* __KVM_X86_VMX_EVMCS_H */
index 2db21d5..657c2ed 100644 (file)
@@ -1074,10 +1074,10 @@ static bool nested_cr3_valid(struct kvm_vcpu *vcpu, unsigned long val)
 }
 
 /*
- * Load guest's/host's cr3 at nested entry/exit. nested_ept is true if we are
- * emulating VM entry into a guest with EPT enabled.
- * Returns 0 on success, 1 on failure. Invalid state exit qualification code
- * is assigned to entry_failure_code on failure.
+ * Load guest's/host's cr3 at nested entry/exit.  @nested_ept is true if we are
+ * emulating VM-Entry into a guest with EPT enabled.  On failure, the expected
+ * Exit Qualification (for a VM-Entry consistency check VM-Exit) is assigned to
+ * @entry_failure_code.
  */
 static int nested_vmx_load_cr3(struct kvm_vcpu *vcpu, unsigned long cr3, bool nested_ept,
                               u32 *entry_failure_code)
@@ -2757,6 +2757,9 @@ static int nested_vmx_check_controls(struct kvm_vcpu *vcpu,
            nested_check_vm_entry_controls(vcpu, vmcs12))
                return -EINVAL;
 
+       if (to_vmx(vcpu)->nested.enlightened_vmcs_enabled)
+               return nested_evmcs_check_controls(vmcs12);
+
        return 0;
 }
 
@@ -4723,8 +4726,6 @@ static int handle_vmclear(struct kvm_vcpu *vcpu)
        return nested_vmx_succeed(vcpu);
 }
 
-static int nested_vmx_run(struct kvm_vcpu *vcpu, bool launch);
-
 /* Emulate the VMLAUNCH instruction */
 static int handle_vmlaunch(struct kvm_vcpu *vcpu)
 {
index 34a3a17..fd21cdb 100644 (file)
@@ -260,13 +260,12 @@ static int intel_pmu_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                break;
        default:
                if ((pmc = get_gp_pmc(pmu, msr, MSR_IA32_PERFCTR0))) {
-                       if (msr_info->host_initiated)
-                               pmc->counter = data;
-                       else
-                               pmc->counter = (s32)data;
+                       if (!msr_info->host_initiated)
+                               data = (s64)(s32)data;
+                       pmc->counter += data - pmc_read_counter(pmc);
                        return 0;
                } else if ((pmc = get_fixed_pmc(pmu, msr))) {
-                       pmc->counter = data;
+                       pmc->counter += data - pmc_read_counter(pmc);
                        return 0;
                } else if ((pmc = get_gp_pmc(pmu, msr, MSR_P6_EVNTSEL0))) {
                        if (data == pmc->eventsel)
index c475fa2..9a66648 100644 (file)
@@ -1428,8 +1428,6 @@ static bool emulation_required(struct kvm_vcpu *vcpu)
        return emulate_invalid_guest_state && !guest_state_valid(vcpu);
 }
 
-static void vmx_decache_cr0_guest_bits(struct kvm_vcpu *vcpu);
-
 unsigned long vmx_get_rflags(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -1853,8 +1851,20 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
        case MSR_IA32_VMX_BASIC ... MSR_IA32_VMX_VMFUNC:
                if (!nested_vmx_allowed(vcpu))
                        return 1;
-               return vmx_get_vmx_msr(&vmx->nested.msrs, msr_info->index,
-                                      &msr_info->data);
+               if (vmx_get_vmx_msr(&vmx->nested.msrs, msr_info->index,
+                                   &msr_info->data))
+                       return 1;
+               /*
+                * Enlightened VMCS v1 doesn't have certain fields, but buggy
+                * Hyper-V versions are still trying to use corresponding
+                * features when they are exposed. Filter out the essential
+                * minimum.
+                */
+               if (!msr_info->host_initiated &&
+                   vmx->nested.enlightened_vmcs_enabled)
+                       nested_evmcs_filter_control_msr(msr_info->index,
+                                                       &msr_info->data);
+               break;
        case MSR_IA32_RTIT_CTL:
                if (pt_mode != PT_MODE_HOST_GUEST)
                        return 1;
@@ -3719,11 +3729,6 @@ void pt_update_intercept_for_msr(struct vcpu_vmx *vmx)
        }
 }
 
-static bool vmx_get_enable_apicv(struct kvm *kvm)
-{
-       return enable_apicv;
-}
-
 static bool vmx_guest_apic_has_interrupt(struct kvm_vcpu *vcpu)
 {
        struct vcpu_vmx *vmx = to_vmx(vcpu);
@@ -6813,6 +6818,7 @@ static int vmx_vm_init(struct kvm *kvm)
                        break;
                }
        }
+       kvm_apicv_init(kvm, enable_apicv);
        return 0;
 }
 
@@ -7714,6 +7720,14 @@ static __exit void hardware_unsetup(void)
        free_kvm_area();
 }
 
+static bool vmx_check_apicv_inhibit_reasons(ulong bit)
+{
+       ulong supported = BIT(APICV_INHIBIT_REASON_DISABLE) |
+                         BIT(APICV_INHIBIT_REASON_HYPERV);
+
+       return supported & BIT(bit);
+}
+
 static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .cpu_has_kvm_support = cpu_has_kvm_support,
        .disabled_by_bios = vmx_disabled_by_bios,
@@ -7786,10 +7800,10 @@ static struct kvm_x86_ops vmx_x86_ops __ro_after_init = {
        .update_cr8_intercept = update_cr8_intercept,
        .set_virtual_apic_mode = vmx_set_virtual_apic_mode,
        .set_apic_access_page_addr = vmx_set_apic_access_page_addr,
-       .get_enable_apicv = vmx_get_enable_apicv,
        .refresh_apicv_exec_ctrl = vmx_refresh_apicv_exec_ctrl,
        .load_eoi_exitmap = vmx_load_eoi_exitmap,
        .apicv_post_state_restore = vmx_apicv_post_state_restore,
+       .check_apicv_inhibit_reasons = vmx_check_apicv_inhibit_reasons,
        .hwapic_irr_update = vmx_hwapic_irr_update,
        .hwapic_isr_update = vmx_hwapic_isr_update,
        .guest_apic_has_interrupt = vmx_guest_apic_has_interrupt,
index 2d3be7f..fbabb2f 100644 (file)
@@ -26,6 +26,7 @@
 #include "cpuid.h"
 #include "pmu.h"
 #include "hyperv.h"
+#include "lapic.h"
 
 #include <linux/clocksource.h>
 #include <linux/interrupt.h>
@@ -897,6 +898,8 @@ EXPORT_SYMBOL_GPL(kvm_set_xcr);
                __reserved_bits |= X86_CR4_PKE;         \
        if (!__cpu_has(__c, X86_FEATURE_LA57))          \
                __reserved_bits |= X86_CR4_LA57;        \
+       if (!__cpu_has(__c, X86_FEATURE_UMIP))          \
+               __reserved_bits |= X86_CR4_UMIP;        \
        __reserved_bits;                                \
 })
 
@@ -1609,6 +1612,8 @@ struct pvclock_clock {
        u64 mask;
        u32 mult;
        u32 shift;
+       u64 base_cycles;
+       u64 offset;
 };
 
 struct pvclock_gtod_data {
@@ -1617,11 +1622,8 @@ struct pvclock_gtod_data {
        struct pvclock_clock clock; /* extract of a clocksource struct */
        struct pvclock_clock raw_clock; /* extract of a clocksource struct */
 
-       u64             boot_ns_raw;
-       u64             boot_ns;
-       u64             nsec_base;
+       ktime_t         offs_boot;
        u64             wall_time_sec;
-       u64             monotonic_raw_nsec;
 };
 
 static struct pvclock_gtod_data pvclock_gtod_data;
@@ -1629,10 +1631,6 @@ static struct pvclock_gtod_data pvclock_gtod_data;
 static void update_pvclock_gtod(struct timekeeper *tk)
 {
        struct pvclock_gtod_data *vdata = &pvclock_gtod_data;
-       u64 boot_ns, boot_ns_raw;
-
-       boot_ns = ktime_to_ns(ktime_add(tk->tkr_mono.base, tk->offs_boot));
-       boot_ns_raw = ktime_to_ns(ktime_add(tk->tkr_raw.base, tk->offs_boot));
 
        write_seqcount_begin(&vdata->seq);
 
@@ -1642,23 +1640,35 @@ static void update_pvclock_gtod(struct timekeeper *tk)
        vdata->clock.mask               = tk->tkr_mono.mask;
        vdata->clock.mult               = tk->tkr_mono.mult;
        vdata->clock.shift              = tk->tkr_mono.shift;
+       vdata->clock.base_cycles        = tk->tkr_mono.xtime_nsec;
+       vdata->clock.offset             = tk->tkr_mono.base;
 
        vdata->raw_clock.vclock_mode    = tk->tkr_raw.clock->archdata.vclock_mode;
        vdata->raw_clock.cycle_last     = tk->tkr_raw.cycle_last;
        vdata->raw_clock.mask           = tk->tkr_raw.mask;
        vdata->raw_clock.mult           = tk->tkr_raw.mult;
        vdata->raw_clock.shift          = tk->tkr_raw.shift;
-
-       vdata->boot_ns                  = boot_ns;
-       vdata->nsec_base                = tk->tkr_mono.xtime_nsec;
+       vdata->raw_clock.base_cycles    = tk->tkr_raw.xtime_nsec;
+       vdata->raw_clock.offset         = tk->tkr_raw.base;
 
        vdata->wall_time_sec            = tk->xtime_sec;
 
-       vdata->boot_ns_raw              = boot_ns_raw;
-       vdata->monotonic_raw_nsec       = tk->tkr_raw.xtime_nsec;
+       vdata->offs_boot                = tk->offs_boot;
 
        write_seqcount_end(&vdata->seq);
 }
+
+static s64 get_kvmclock_base_ns(void)
+{
+       /* Count up from boot time, but with the frequency of the raw clock.  */
+       return ktime_to_ns(ktime_add(ktime_get_raw(), pvclock_gtod_data.offs_boot));
+}
+#else
+static s64 get_kvmclock_base_ns(void)
+{
+       /* Master clock not used, so we can just use CLOCK_BOOTTIME.  */
+       return ktime_get_boottime_ns();
+}
 #endif
 
 void kvm_set_pending_timer(struct kvm_vcpu *vcpu)
@@ -1672,7 +1682,7 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
        int version;
        int r;
        struct pvclock_wall_clock wc;
-       struct timespec64 boot;
+       u64 wall_nsec;
 
        if (!wall_clock)
                return;
@@ -1692,17 +1702,12 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock)
        /*
         * The guest calculates current wall clock time by adding
         * system time (updated by kvm_guest_time_update below) to the
-        * wall clock specified here.  guest system time equals host
-        * system time for us, thus we must fill in host boot time here.
+        * wall clock specified here.  We do the reverse here.
         */
-       getboottime64(&boot);
+       wall_nsec = ktime_get_real_ns() - get_kvmclock_ns(kvm);
 
-       if (kvm->arch.kvmclock_offset) {
-               struct timespec64 ts = ns_to_timespec64(kvm->arch.kvmclock_offset);
-               boot = timespec64_sub(boot, ts);
-       }
-       wc.sec = (u32)boot.tv_sec; /* overflow in 2106 guest time */
-       wc.nsec = boot.tv_nsec;
+       wc.nsec = do_div(wall_nsec, 1000000000);
+       wc.sec = (u32)wall_nsec; /* overflow in 2106 guest time */
        wc.version = version;
 
        kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc));
@@ -1950,7 +1955,7 @@ void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
 
        raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
        offset = kvm_compute_tsc_offset(vcpu, data);
-       ns = ktime_get_boottime_ns();
+       ns = get_kvmclock_base_ns();
        elapsed = ns - kvm->arch.last_tsc_nsec;
 
        if (vcpu->arch.virtual_tsc_khz) {
@@ -2125,10 +2130,10 @@ static int do_monotonic_raw(s64 *t, u64 *tsc_timestamp)
 
        do {
                seq = read_seqcount_begin(&gtod->seq);
-               ns = gtod->monotonic_raw_nsec;
+               ns = gtod->raw_clock.base_cycles;
                ns += vgettsc(&gtod->raw_clock, tsc_timestamp, &mode);
-               ns >>= gtod->clock.shift;
-               ns += gtod->boot_ns_raw;
+               ns >>= gtod->raw_clock.shift;
+               ns += ktime_to_ns(ktime_add(gtod->raw_clock.offset, gtod->offs_boot));
        } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
        *t = ns;
 
@@ -2145,7 +2150,7 @@ static int do_realtime(struct timespec64 *ts, u64 *tsc_timestamp)
        do {
                seq = read_seqcount_begin(&gtod->seq);
                ts->tv_sec = gtod->wall_time_sec;
-               ns = gtod->nsec_base;
+               ns = gtod->clock.base_cycles;
                ns += vgettsc(&gtod->clock, tsc_timestamp, &mode);
                ns >>= gtod->clock.shift;
        } while (unlikely(read_seqcount_retry(&gtod->seq, seq)));
@@ -2288,7 +2293,7 @@ u64 get_kvmclock_ns(struct kvm *kvm)
        spin_lock(&ka->pvclock_gtod_sync_lock);
        if (!ka->use_master_clock) {
                spin_unlock(&ka->pvclock_gtod_sync_lock);
-               return ktime_get_boottime_ns() + ka->kvmclock_offset;
+               return get_kvmclock_base_ns() + ka->kvmclock_offset;
        }
 
        hv_clock.tsc_timestamp = ka->master_cycle_now;
@@ -2304,7 +2309,7 @@ u64 get_kvmclock_ns(struct kvm *kvm)
                                   &hv_clock.tsc_to_system_mul);
                ret = __pvclock_read_cycles(&hv_clock, rdtsc());
        } else
-               ret = ktime_get_boottime_ns() + ka->kvmclock_offset;
+               ret = get_kvmclock_base_ns() + ka->kvmclock_offset;
 
        put_cpu();
 
@@ -2403,7 +2408,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
        }
        if (!use_master_clock) {
                host_tsc = rdtsc();
-               kernel_ns = ktime_get_boottime_ns();
+               kernel_ns = get_kvmclock_base_ns();
        }
 
        tsc_timestamp = kvm_read_l1_tsc(v, host_tsc);
@@ -2443,6 +2448,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v)
        vcpu->hv_clock.tsc_timestamp = tsc_timestamp;
        vcpu->hv_clock.system_time = kernel_ns + v->kvm->arch.kvmclock_offset;
        vcpu->last_guest_tsc = tsc_timestamp;
+       WARN_ON(vcpu->hv_clock.system_time < 0);
 
        /* If the host uses TSC clocksource, then it is stable */
        pvclock_flags = 0;
@@ -7456,18 +7462,22 @@ static void kvm_pv_kick_cpu_op(struct kvm *kvm, unsigned long flags, int apicid)
        kvm_irq_delivery_to_apic(kvm, NULL, &lapic_irq, NULL);
 }
 
-void kvm_vcpu_deactivate_apicv(struct kvm_vcpu *vcpu)
+bool kvm_apicv_activated(struct kvm *kvm)
 {
-       if (!lapic_in_kernel(vcpu)) {
-               WARN_ON_ONCE(vcpu->arch.apicv_active);
-               return;
-       }
-       if (!vcpu->arch.apicv_active)
-               return;
+       return (READ_ONCE(kvm->arch.apicv_inhibit_reasons) == 0);
+}
+EXPORT_SYMBOL_GPL(kvm_apicv_activated);
 
-       vcpu->arch.apicv_active = false;
-       kvm_x86_ops->refresh_apicv_exec_ctrl(vcpu);
+void kvm_apicv_init(struct kvm *kvm, bool enable)
+{
+       if (enable)
+               clear_bit(APICV_INHIBIT_REASON_DISABLE,
+                         &kvm->arch.apicv_inhibit_reasons);
+       else
+               set_bit(APICV_INHIBIT_REASON_DISABLE,
+                       &kvm->arch.apicv_inhibit_reasons);
 }
+EXPORT_SYMBOL_GPL(kvm_apicv_init);
 
 static void kvm_sched_yield(struct kvm *kvm, unsigned long dest_id)
 {
@@ -7996,6 +8006,47 @@ void kvm_make_scan_ioapic_request(struct kvm *kvm)
        kvm_make_all_cpus_request(kvm, KVM_REQ_SCAN_IOAPIC);
 }
 
+void kvm_vcpu_update_apicv(struct kvm_vcpu *vcpu)
+{
+       if (!lapic_in_kernel(vcpu))
+               return;
+
+       vcpu->arch.apicv_active = kvm_apicv_activated(vcpu->kvm);
+       kvm_apic_update_apicv(vcpu);
+       kvm_x86_ops->refresh_apicv_exec_ctrl(vcpu);
+}
+EXPORT_SYMBOL_GPL(kvm_vcpu_update_apicv);
+
+/*
+ * NOTE: Do not hold any lock prior to calling this.
+ *
+ * In particular, kvm_request_apicv_update() expects kvm->srcu not to be
+ * locked, because it calls __x86_set_memory_region() which does
+ * synchronize_srcu(&kvm->srcu).
+ */
+void kvm_request_apicv_update(struct kvm *kvm, bool activate, ulong bit)
+{
+       if (!kvm_x86_ops->check_apicv_inhibit_reasons ||
+           !kvm_x86_ops->check_apicv_inhibit_reasons(bit))
+               return;
+
+       if (activate) {
+               if (!test_and_clear_bit(bit, &kvm->arch.apicv_inhibit_reasons) ||
+                   !kvm_apicv_activated(kvm))
+                       return;
+       } else {
+               if (test_and_set_bit(bit, &kvm->arch.apicv_inhibit_reasons) ||
+                   kvm_apicv_activated(kvm))
+                       return;
+       }
+
+       trace_kvm_apicv_update_request(activate, bit);
+       if (kvm_x86_ops->pre_update_apicv_exec_ctrl)
+               kvm_x86_ops->pre_update_apicv_exec_ctrl(kvm, activate);
+       kvm_make_all_cpus_request(kvm, KVM_REQ_APICV_UPDATE);
+}
+EXPORT_SYMBOL_GPL(kvm_request_apicv_update);
+
 static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu)
 {
        if (!kvm_apic_present(vcpu))
@@ -8186,6 +8237,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
                 */
                if (kvm_check_request(KVM_REQ_HV_STIMER, vcpu))
                        kvm_hv_process_stimers(vcpu);
+               if (kvm_check_request(KVM_REQ_APICV_UPDATE, vcpu))
+                       kvm_vcpu_update_apicv(vcpu);
        }
 
        if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) {
@@ -9219,10 +9272,11 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
                return r;
 
        if (irqchip_in_kernel(vcpu->kvm)) {
-               vcpu->arch.apicv_active = kvm_x86_ops->get_enable_apicv(vcpu->kvm);
                r = kvm_create_lapic(vcpu, lapic_timer_advance_ns);
                if (r < 0)
                        goto fail_mmu_destroy;
+               if (kvm_apicv_activated(vcpu->kvm))
+                       vcpu->arch.apicv_active = true;
        } else
                static_key_slow_inc(&kvm_no_apic_vcpu);
 
@@ -9633,7 +9687,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
        mutex_init(&kvm->arch.apic_map_lock);
        spin_lock_init(&kvm->arch.pvclock_gtod_sync_lock);
 
-       kvm->arch.kvmclock_offset = -ktime_get_boottime_ns();
+       kvm->arch.kvmclock_offset = -get_kvmclock_base_ns();
        pvclock_update_vm_gtod_copy(kvm);
 
        kvm->arch.guest_can_read_msr_platform_info = true;
@@ -10448,3 +10502,4 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_pml_full);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_pi_irte_update);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_unaccelerated_access);
 EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_avic_incomplete_ipi);
+EXPORT_TRACEPOINT_SYMBOL_GPL(kvm_apicv_update_request);
index 2d2ff85..3624665 100644 (file)
@@ -357,7 +357,7 @@ static inline bool kvm_pat_valid(u64 data)
        return (data | ((data & 0x0202020202020202ull) << 1)) == data;
 }
 
-static inline bool kvm_dr7_valid(unsigned long data)
+static inline bool kvm_dr7_valid(u64 data)
 {
        /* Bits [63:32] are reserved */
        return !(data >> 32);
index 98aecb1..98f7c6f 100644 (file)
@@ -28,8 +28,8 @@ CFLAGS_fault.o := -I $(srctree)/$(src)/../include/asm/trace
 obj-$(CONFIG_X86_32)           += pgtable_32.o iomap_32.o
 
 obj-$(CONFIG_HUGETLB_PAGE)     += hugetlbpage.o
-obj-$(CONFIG_X86_PTDUMP_CORE)  += dump_pagetables.o
-obj-$(CONFIG_X86_PTDUMP)       += debug_pagetables.o
+obj-$(CONFIG_PTDUMP_CORE)      += dump_pagetables.o
+obj-$(CONFIG_PTDUMP_DEBUGFS)   += debug_pagetables.o
 
 obj-$(CONFIG_HIGHMEM)          += highmem_32.o
 
index 39001a4..4a3b62f 100644 (file)
@@ -7,7 +7,7 @@
 
 static int ptdump_show(struct seq_file *m, void *v)
 {
-       ptdump_walk_pgd_level_debugfs(m, NULL, false);
+       ptdump_walk_pgd_level_debugfs(m, &init_mm, false);
        return 0;
 }
 
@@ -15,11 +15,8 @@ DEFINE_SHOW_ATTRIBUTE(ptdump);
 
 static int ptdump_curknl_show(struct seq_file *m, void *v)
 {
-       if (current->mm->pgd) {
-               down_read(&current->mm->mmap_sem);
-               ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, false);
-               up_read(&current->mm->mmap_sem);
-       }
+       if (current->mm->pgd)
+               ptdump_walk_pgd_level_debugfs(m, current->mm, false);
        return 0;
 }
 
@@ -28,11 +25,8 @@ DEFINE_SHOW_ATTRIBUTE(ptdump_curknl);
 #ifdef CONFIG_PAGE_TABLE_ISOLATION
 static int ptdump_curusr_show(struct seq_file *m, void *v)
 {
-       if (current->mm->pgd) {
-               down_read(&current->mm->mmap_sem);
-               ptdump_walk_pgd_level_debugfs(m, current->mm->pgd, true);
-               up_read(&current->mm->mmap_sem);
-       }
+       if (current->mm->pgd)
+               ptdump_walk_pgd_level_debugfs(m, current->mm, true);
        return 0;
 }
 
@@ -43,7 +37,7 @@ DEFINE_SHOW_ATTRIBUTE(ptdump_curusr);
 static int ptdump_efi_show(struct seq_file *m, void *v)
 {
        if (efi_mm.pgd)
-               ptdump_walk_pgd_level_debugfs(m, efi_mm.pgd, false);
+               ptdump_walk_pgd_level_debugfs(m, &efi_mm, false);
        return 0;
 }
 
index ab67822..64229da 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/seq_file.h>
 #include <linux/highmem.h>
 #include <linux/pci.h>
+#include <linux/ptdump.h>
 
 #include <asm/e820/types.h>
 #include <asm/pgtable.h>
  * when a "break" in the continuity is found.
  */
 struct pg_state {
+       struct ptdump_state ptdump;
        int level;
-       pgprot_t current_prot;
+       pgprotval_t current_prot;
        pgprotval_t effective_prot;
+       pgprotval_t prot_levels[5];
        unsigned long start_address;
-       unsigned long current_address;
        const struct addr_marker *marker;
        unsigned long lines;
        bool to_dmesg;
        bool check_wx;
        unsigned long wx_pages;
+       struct seq_file *seq;
 };
 
 struct addr_marker {
@@ -174,11 +177,10 @@ static struct addr_marker address_markers[] = {
 /*
  * Print a readable form of a pgprot_t to the seq_file
  */
-static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg)
+static void printk_prot(struct seq_file *m, pgprotval_t pr, int level, bool dmsg)
 {
-       pgprotval_t pr = pgprot_val(prot);
        static const char * const level_name[] =
-               { "cr3", "pgd", "p4d", "pud", "pmd", "pte" };
+               { "pgd", "p4d", "pud", "pmd", "pte" };
 
        if (!(pr & _PAGE_PRESENT)) {
                /* Not present */
@@ -202,12 +204,12 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg)
                        pt_dump_cont_printf(m, dmsg, "    ");
 
                /* Bit 7 has a different meaning on level 3 vs 4 */
-               if (level <= 4 && pr & _PAGE_PSE)
+               if (level <= 3 && pr & _PAGE_PSE)
                        pt_dump_cont_printf(m, dmsg, "PSE ");
                else
                        pt_dump_cont_printf(m, dmsg, "    ");
-               if ((level == 5 && pr & _PAGE_PAT) ||
-                   ((level == 4 || level == 3) && pr & _PAGE_PAT_LARGE))
+               if ((level == 4 && pr & _PAGE_PAT) ||
+                   ((level == 3 || level == 2) && pr & _PAGE_PAT_LARGE))
                        pt_dump_cont_printf(m, dmsg, "PAT ");
                else
                        pt_dump_cont_printf(m, dmsg, "    ");
@@ -223,24 +225,11 @@ static void printk_prot(struct seq_file *m, pgprot_t prot, int level, bool dmsg)
        pt_dump_cont_printf(m, dmsg, "%s\n", level_name[level]);
 }
 
-/*
- * On 64 bits, sign-extend the 48 bit address to 64 bit
- */
-static unsigned long normalize_addr(unsigned long u)
-{
-       int shift;
-       if (!IS_ENABLED(CONFIG_X86_64))
-               return u;
-
-       shift = 64 - (__VIRTUAL_MASK_SHIFT + 1);
-       return (signed long)(u << shift) >> shift;
-}
-
-static void note_wx(struct pg_state *st)
+static void note_wx(struct pg_state *st, unsigned long addr)
 {
        unsigned long npages;
 
-       npages = (st->current_address - st->start_address) / PAGE_SIZE;
+       npages = (addr - st->start_address) / PAGE_SIZE;
 
 #ifdef CONFIG_PCI_BIOS
        /*
@@ -248,7 +237,7 @@ static void note_wx(struct pg_state *st)
         * Inform about it, but avoid the warning.
         */
        if (pcibios_enabled && st->start_address >= PAGE_OFFSET + BIOS_BEGIN &&
-           st->current_address <= PAGE_OFFSET + BIOS_END) {
+           addr <= PAGE_OFFSET + BIOS_END) {
                pr_warn_once("x86/mm: PCI BIOS W+X mapping %lu pages\n", npages);
                return;
        }
@@ -260,27 +249,47 @@ static void note_wx(struct pg_state *st)
                  (void *)st->start_address);
 }
 
+static inline pgprotval_t effective_prot(pgprotval_t prot1, pgprotval_t prot2)
+{
+       return (prot1 & prot2 & (_PAGE_USER | _PAGE_RW)) |
+              ((prot1 | prot2) & _PAGE_NX);
+}
+
 /*
  * This function gets called on a break in a continuous series
  * of PTE entries; the next one is different so we need to
  * print what we collected so far.
  */
-static void note_page(struct seq_file *m, struct pg_state *st,
-                     pgprot_t new_prot, pgprotval_t new_eff, int level)
+static void note_page(struct ptdump_state *pt_st, unsigned long addr, int level,
+                     unsigned long val)
 {
-       pgprotval_t prot, cur, eff;
+       struct pg_state *st = container_of(pt_st, struct pg_state, ptdump);
+       pgprotval_t new_prot, new_eff;
+       pgprotval_t cur, eff;
        static const char units[] = "BKMGTPE";
+       struct seq_file *m = st->seq;
+
+       new_prot = val & PTE_FLAGS_MASK;
+
+       if (level > 0) {
+               new_eff = effective_prot(st->prot_levels[level - 1],
+                                        new_prot);
+       } else {
+               new_eff = new_prot;
+       }
+
+       if (level >= 0)
+               st->prot_levels[level] = new_eff;
 
        /*
         * If we have a "break" in the series, we need to flush the state that
         * we have now. "break" is either changing perms, levels or
         * address space marker.
         */
-       prot = pgprot_val(new_prot);
-       cur = pgprot_val(st->current_prot);
+       cur = st->current_prot;
        eff = st->effective_prot;
 
-       if (!st->level) {
+       if (st->level == -1) {
                /* First entry */
                st->current_prot = new_prot;
                st->effective_prot = new_eff;
@@ -289,14 +298,14 @@ static void note_page(struct seq_file *m, struct pg_state *st,
                st->lines = 0;
                pt_dump_seq_printf(m, st->to_dmesg, "---[ %s ]---\n",
                                   st->marker->name);
-       } else if (prot != cur || new_eff != eff || level != st->level ||
-                  st->current_address >= st->marker[1].start_address) {
+       } else if (new_prot != cur || new_eff != eff || level != st->level ||
+                  addr >= st->marker[1].start_address) {
                const char *unit = units;
                unsigned long delta;
                int width = sizeof(unsigned long) * 2;
 
                if (st->check_wx && (eff & _PAGE_RW) && !(eff & _PAGE_NX))
-                       note_wx(st);
+                       note_wx(st, addr);
 
                /*
                 * Now print the actual finished series
@@ -306,9 +315,9 @@ static void note_page(struct seq_file *m, struct pg_state *st,
                        pt_dump_seq_printf(m, st->to_dmesg,
                                           "0x%0*lx-0x%0*lx   ",
                                           width, st->start_address,
-                                          width, st->current_address);
+                                          width, addr);
 
-                       delta = st->current_address - st->start_address;
+                       delta = addr - st->start_address;
                        while (!(delta & 1023) && unit[1]) {
                                delta >>= 10;
                                unit++;
@@ -325,7 +334,7 @@ static void note_page(struct seq_file *m, struct pg_state *st,
                 * such as the start of vmalloc space etc.
                 * This helps in the interpretation.
                 */
-               if (st->current_address >= st->marker[1].start_address) {
+               if (addr >= st->marker[1].start_address) {
                        if (st->marker->max_lines &&
                            st->lines > st->marker->max_lines) {
                                unsigned long nskip =
@@ -341,222 +350,45 @@ static void note_page(struct seq_file *m, struct pg_state *st,
                                           st->marker->name);
                }
 
-               st->start_address = st->current_address;
+               st->start_address = addr;
                st->current_prot = new_prot;
                st->effective_prot = new_eff;
                st->level = level;
        }
 }
 
-static inline pgprotval_t effective_prot(pgprotval_t prot1, pgprotval_t prot2)
-{
-       return (prot1 & prot2 & (_PAGE_USER | _PAGE_RW)) |
-              ((prot1 | prot2) & _PAGE_NX);
-}
-
-static void walk_pte_level(struct seq_file *m, struct pg_state *st, pmd_t addr,
-                          pgprotval_t eff_in, unsigned long P)
-{
-       int i;
-       pte_t *pte;
-       pgprotval_t prot, eff;
-
-       for (i = 0; i < PTRS_PER_PTE; i++) {
-               st->current_address = normalize_addr(P + i * PTE_LEVEL_MULT);
-               pte = pte_offset_map(&addr, st->current_address);
-               prot = pte_flags(*pte);
-               eff = effective_prot(eff_in, prot);
-               note_page(m, st, __pgprot(prot), eff, 5);
-               pte_unmap(pte);
-       }
-}
-#ifdef CONFIG_KASAN
-
-/*
- * This is an optimization for KASAN=y case. Since all kasan page tables
- * eventually point to the kasan_early_shadow_page we could call note_page()
- * right away without walking through lower level page tables. This saves
- * us dozens of seconds (minutes for 5-level config) while checking for
- * W+X mapping or reading kernel_page_tables debugfs file.
- */
-static inline bool kasan_page_table(struct seq_file *m, struct pg_state *st,
-                               void *pt)
-{
-       if (__pa(pt) == __pa(kasan_early_shadow_pmd) ||
-           (pgtable_l5_enabled() &&
-                       __pa(pt) == __pa(kasan_early_shadow_p4d)) ||
-           __pa(pt) == __pa(kasan_early_shadow_pud)) {
-               pgprotval_t prot = pte_flags(kasan_early_shadow_pte[0]);
-               note_page(m, st, __pgprot(prot), 0, 5);
-               return true;
-       }
-       return false;
-}
-#else
-static inline bool kasan_page_table(struct seq_file *m, struct pg_state *st,
-                               void *pt)
-{
-       return false;
-}
-#endif
-
-#if PTRS_PER_PMD > 1
-
-static void walk_pmd_level(struct seq_file *m, struct pg_state *st, pud_t addr,
-                          pgprotval_t eff_in, unsigned long P)
-{
-       int i;
-       pmd_t *start, *pmd_start;
-       pgprotval_t prot, eff;
-
-       pmd_start = start = (pmd_t *)pud_page_vaddr(addr);
-       for (i = 0; i < PTRS_PER_PMD; i++) {
-               st->current_address = normalize_addr(P + i * PMD_LEVEL_MULT);
-               if (!pmd_none(*start)) {
-                       prot = pmd_flags(*start);
-                       eff = effective_prot(eff_in, prot);
-                       if (pmd_large(*start) || !pmd_present(*start)) {
-                               note_page(m, st, __pgprot(prot), eff, 4);
-                       } else if (!kasan_page_table(m, st, pmd_start)) {
-                               walk_pte_level(m, st, *start, eff,
-                                              P + i * PMD_LEVEL_MULT);
-                       }
-               } else
-                       note_page(m, st, __pgprot(0), 0, 4);
-               start++;
-       }
-}
-
-#else
-#define walk_pmd_level(m,s,a,e,p) walk_pte_level(m,s,__pmd(pud_val(a)),e,p)
-#define pud_large(a) pmd_large(__pmd(pud_val(a)))
-#define pud_none(a)  pmd_none(__pmd(pud_val(a)))
-#endif
-
-#if PTRS_PER_PUD > 1
-
-static void walk_pud_level(struct seq_file *m, struct pg_state *st, p4d_t addr,
-                          pgprotval_t eff_in, unsigned long P)
-{
-       int i;
-       pud_t *start, *pud_start;
-       pgprotval_t prot, eff;
-
-       pud_start = start = (pud_t *)p4d_page_vaddr(addr);
-
-       for (i = 0; i < PTRS_PER_PUD; i++) {
-               st->current_address = normalize_addr(P + i * PUD_LEVEL_MULT);
-               if (!pud_none(*start)) {
-                       prot = pud_flags(*start);
-                       eff = effective_prot(eff_in, prot);
-                       if (pud_large(*start) || !pud_present(*start)) {
-                               note_page(m, st, __pgprot(prot), eff, 3);
-                       } else if (!kasan_page_table(m, st, pud_start)) {
-                               walk_pmd_level(m, st, *start, eff,
-                                              P + i * PUD_LEVEL_MULT);
-                       }
-               } else
-                       note_page(m, st, __pgprot(0), 0, 3);
-
-               start++;
-       }
-}
-
-#else
-#define walk_pud_level(m,s,a,e,p) walk_pmd_level(m,s,__pud(p4d_val(a)),e,p)
-#define p4d_large(a) pud_large(__pud(p4d_val(a)))
-#define p4d_none(a)  pud_none(__pud(p4d_val(a)))
-#endif
-
-static void walk_p4d_level(struct seq_file *m, struct pg_state *st, pgd_t addr,
-                          pgprotval_t eff_in, unsigned long P)
-{
-       int i;
-       p4d_t *start, *p4d_start;
-       pgprotval_t prot, eff;
-
-       if (PTRS_PER_P4D == 1)
-               return walk_pud_level(m, st, __p4d(pgd_val(addr)), eff_in, P);
-
-       p4d_start = start = (p4d_t *)pgd_page_vaddr(addr);
-
-       for (i = 0; i < PTRS_PER_P4D; i++) {
-               st->current_address = normalize_addr(P + i * P4D_LEVEL_MULT);
-               if (!p4d_none(*start)) {
-                       prot = p4d_flags(*start);
-                       eff = effective_prot(eff_in, prot);
-                       if (p4d_large(*start) || !p4d_present(*start)) {
-                               note_page(m, st, __pgprot(prot), eff, 2);
-                       } else if (!kasan_page_table(m, st, p4d_start)) {
-                               walk_pud_level(m, st, *start, eff,
-                                              P + i * P4D_LEVEL_MULT);
-                       }
-               } else
-                       note_page(m, st, __pgprot(0), 0, 2);
-
-               start++;
-       }
-}
-
-#define pgd_large(a) (pgtable_l5_enabled() ? pgd_large(a) : p4d_large(__p4d(pgd_val(a))))
-#define pgd_none(a)  (pgtable_l5_enabled() ? pgd_none(a) : p4d_none(__p4d(pgd_val(a))))
-
-static inline bool is_hypervisor_range(int idx)
-{
-#ifdef CONFIG_X86_64
-       /*
-        * A hole in the beginning of kernel address space reserved
-        * for a hypervisor.
-        */
-       return  (idx >= pgd_index(GUARD_HOLE_BASE_ADDR)) &&
-               (idx <  pgd_index(GUARD_HOLE_END_ADDR));
-#else
-       return false;
-#endif
-}
-
-static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
+static void ptdump_walk_pgd_level_core(struct seq_file *m,
+                                      struct mm_struct *mm, pgd_t *pgd,
                                       bool checkwx, bool dmesg)
 {
-       pgd_t *start = INIT_PGD;
-       pgprotval_t prot, eff;
-       int i;
-       struct pg_state st = {};
-
-       if (pgd) {
-               start = pgd;
-               st.to_dmesg = dmesg;
-       }
+       const struct ptdump_range ptdump_ranges[] = {
+#ifdef CONFIG_X86_64
 
-       st.check_wx = checkwx;
-       if (checkwx)
-               st.wx_pages = 0;
+#define normalize_addr_shift (64 - (__VIRTUAL_MASK_SHIFT + 1))
+#define normalize_addr(u) ((signed long)((u) << normalize_addr_shift) >> \
+                          normalize_addr_shift)
 
-       for (i = 0; i < PTRS_PER_PGD; i++) {
-               st.current_address = normalize_addr(i * PGD_LEVEL_MULT);
-               if (!pgd_none(*start) && !is_hypervisor_range(i)) {
-                       prot = pgd_flags(*start);
-#ifdef CONFIG_X86_PAE
-                       eff = _PAGE_USER | _PAGE_RW;
+       {0, PTRS_PER_PGD * PGD_LEVEL_MULT / 2},
+       {normalize_addr(PTRS_PER_PGD * PGD_LEVEL_MULT / 2), ~0UL},
 #else
-                       eff = prot;
+       {0, ~0UL},
 #endif
-                       if (pgd_large(*start) || !pgd_present(*start)) {
-                               note_page(m, &st, __pgprot(prot), eff, 1);
-                       } else {
-                               walk_p4d_level(m, &st, *start, eff,
-                                              i * PGD_LEVEL_MULT);
-                       }
-               } else
-                       note_page(m, &st, __pgprot(0), 0, 1);
+       {0, 0}
+};
 
-               cond_resched();
-               start++;
-       }
+       struct pg_state st = {
+               .ptdump = {
+                       .note_page      = note_page,
+                       .range          = ptdump_ranges
+               },
+               .level = -1,
+               .to_dmesg       = dmesg,
+               .check_wx       = checkwx,
+               .seq            = m
+       };
+
+       ptdump_walk_pgd(&st.ptdump, mm, pgd);
 
-       /* Flush out the last page */
-       st.current_address = normalize_addr(PTRS_PER_PGD*PGD_LEVEL_MULT);
-       note_page(m, &st, __pgprot(0), 0, 0);
        if (!checkwx)
                return;
        if (st.wx_pages)
@@ -566,18 +398,20 @@ static void ptdump_walk_pgd_level_core(struct seq_file *m, pgd_t *pgd,
                pr_info("x86/mm: Checked W+X mappings: passed, no W+X pages found.\n");
 }
 
-void ptdump_walk_pgd_level(struct seq_file *m, pgd_t *pgd)
+void ptdump_walk_pgd_level(struct seq_file *m, struct mm_struct *mm)
 {
-       ptdump_walk_pgd_level_core(m, pgd, false, true);
+       ptdump_walk_pgd_level_core(m, mm, mm->pgd, false, true);
 }
 
-void ptdump_walk_pgd_level_debugfs(struct seq_file *m, pgd_t *pgd, bool user)
+void ptdump_walk_pgd_level_debugfs(struct seq_file *m, struct mm_struct *mm,
+                                  bool user)
 {
+       pgd_t *pgd = mm->pgd;
 #ifdef CONFIG_PAGE_TABLE_ISOLATION
        if (user && boot_cpu_has(X86_FEATURE_PTI))
                pgd = kernel_to_user_pgdp(pgd);
 #endif
-       ptdump_walk_pgd_level_core(m, pgd, false, false);
+       ptdump_walk_pgd_level_core(m, mm, pgd, false, false);
 }
 EXPORT_SYMBOL_GPL(ptdump_walk_pgd_level_debugfs);
 
@@ -592,13 +426,13 @@ void ptdump_walk_user_pgd_level_checkwx(void)
 
        pr_info("x86/mm: Checking user space page tables\n");
        pgd = kernel_to_user_pgdp(pgd);
-       ptdump_walk_pgd_level_core(NULL, pgd, true, false);
+       ptdump_walk_pgd_level_core(NULL, &init_mm, pgd, true, false);
 #endif
 }
 
 void ptdump_walk_pgd_level_checkwx(void)
 {
-       ptdump_walk_pgd_level_core(NULL, NULL, true, false);
+       ptdump_walk_pgd_level_core(NULL, &init_mm, INIT_PGD, true, false);
 }
 
 static int __init pt_dump_init(void)
index 59f7f6d..ae923ee 100644 (file)
@@ -308,7 +308,7 @@ static void __init efi_clean_memmap(void)
                        .phys_map = efi.memmap.phys_map,
                        .desc_version = efi.memmap.desc_version,
                        .desc_size = efi.memmap.desc_size,
-                       .size = data.desc_size * (efi.memmap.nr_map - n_removal),
+                       .size = efi.memmap.desc_size * (efi.memmap.nr_map - n_removal),
                        .flags = 0,
                };
 
index 71dddd1..081d466 100644 (file)
@@ -49,7 +49,7 @@ void efi_sync_low_kernel_mappings(void) {}
 void __init efi_dump_pagetable(void)
 {
 #ifdef CONFIG_EFI_PGT_DUMP
-       ptdump_walk_pgd_level(NULL, swapper_pg_dir);
+       ptdump_walk_pgd_level(NULL, &init_mm);
 #endif
 }
 
index e2accfe..fa8506e 100644 (file)
@@ -471,9 +471,9 @@ void __init efi_dump_pagetable(void)
 {
 #ifdef CONFIG_EFI_PGT_DUMP
        if (efi_have_uv1_memmap())
-               ptdump_walk_pgd_level(NULL, swapper_pg_dir);
+               ptdump_walk_pgd_level(NULL, &init_mm);
        else
-               ptdump_walk_pgd_level(NULL, efi_mm.pgd);
+               ptdump_walk_pgd_level(NULL, &efi_mm);
 #endif
 }
 
index 5f0a96b..1fd321f 100644 (file)
@@ -1668,12 +1668,12 @@ static int tunables_open(struct inode *inode, struct file *file)
        return 0;
 }
 
-static const struct file_operations proc_uv_ptc_operations = {
-       .open           = ptc_proc_open,
-       .read           = seq_read,
-       .write          = ptc_proc_write,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops uv_ptc_proc_ops = {
+       .proc_open      = ptc_proc_open,
+       .proc_read      = seq_read,
+       .proc_write     = ptc_proc_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 static const struct file_operations tunables_fops = {
@@ -1691,7 +1691,7 @@ static int __init uv_ptc_init(void)
                return 0;
 
        proc_uv_ptc = proc_create(UV_PTC_BASENAME, 0444, NULL,
-                                 &proc_uv_ptc_operations);
+                                 &uv_ptc_proc_ops);
        if (!proc_uv_ptc) {
                pr_err("unable to create %s proc entry\n",
                       UV_PTC_BASENAME);
index ae4a41c..1f756ff 100644 (file)
@@ -1205,6 +1205,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
        x86_platform.get_nmi_reason = xen_get_nmi_reason;
 
        x86_init.resources.memory_setup = xen_memory_setup;
+       x86_init.irqs.intr_mode_select  = x86_init_noop;
        x86_init.irqs.intr_mode_init    = x86_init_noop;
        x86_init.oem.arch_setup = xen_arch_setup;
        x86_init.oem.banner = xen_banner;
index 1c64517..32ee759 100644 (file)
@@ -180,11 +180,11 @@ config HAVE_SMP
        depends on XTENSA_VARIANT_CUSTOM
        select XTENSA_MX
        help
-         This option is use to indicate that the system-on-a-chip (SOC)
+         This option is used to indicate that the system-on-a-chip (SOC)
          supports Multiprocessing. Multiprocessor support implemented above
          the CPU core definition and currently needs to be selected manually.
 
-         Multiprocessor support in implemented with external cache and
+         Multiprocessor support is implemented with external cache and
          interrupt controllers.
 
          The MX interrupt distributer adds Interprocessor Interrupts
@@ -572,15 +572,41 @@ config KERNEL_LOAD_ADDRESS
 
          If unsure, leave the default value here.
 
-config VECTORS_OFFSET
-       hex "Kernel vectors offset"
-       default 0x00003000
-       depends on !XIP_KERNEL
+choice
+       prompt "Relocatable vectors location"
+       default XTENSA_VECTORS_IN_TEXT
        help
-         This is the offset of the kernel image from the relocatable vectors
-         base.
+         Choose whether relocatable vectors are merged into the kernel .text
+         or placed separately at runtime. This option does not affect
+         configurations without VECBASE register where vectors are always
+         placed at their hardware-defined locations.
 
-         If unsure, leave the default value here.
+config XTENSA_VECTORS_IN_TEXT
+       bool "Merge relocatable vectors into kernel text"
+       depends on !MTD_XIP
+       help
+         This option puts relocatable vectors into the kernel .text section
+         with proper alignment.
+         This is a safe choice for most configurations.
+
+config XTENSA_VECTORS_SEPARATE
+       bool "Put relocatable vectors at fixed address"
+       help
+         This option puts relocatable vectors at specific virtual address.
+         Vectors are merged with the .init data in the kernel image and
+         are copied into their designated location during kernel startup.
+         Use it to put vectors into IRAM or out of FLASH on kernels with
+         XIP-aware MTD support.
+
+endchoice
+
+config VECTORS_ADDR
+       hex "Kernel vectors virtual address"
+       default 0x00000000
+       depends on XTENSA_VECTORS_SEPARATE
+       help
+         This is the virtual address of the (relocatable) vectors base.
+         It must be within KSEG if MMU is used.
 
 config XIP_DATA_ADDR
        hex "XIP kernel data virtual address"
index b6367af..eeb4c53 100644 (file)
@@ -21,8 +21,6 @@ CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_XTENSA_VARIANT_CUSTOM=y
 CONFIG_XTENSA_VARIANT_CUSTOM_NAME="test_kc705_hifi"
 CONFIG_XTENSA_UNALIGNED_USER=y
index f4eef6d..fc24073 100644 (file)
@@ -27,8 +27,6 @@ CONFIG_MODULES=y
 CONFIG_MODULE_FORCE_LOAD=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_XTENSA_VARIANT_CUSTOM=y
 CONFIG_XTENSA_VARIANT_CUSTOM_NAME="csp"
 CONFIG_XTENSA_UNALIGNED_USER=y
index c925165..412f611 100644 (file)
@@ -21,8 +21,6 @@ CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_XTENSA_VARIANT_DC233C=y
 CONFIG_XTENSA_UNALIGNED_USER=y
 CONFIG_PREEMPT=y
index d1c0174..32ce8fb 100644 (file)
@@ -1,8 +1,6 @@
 CONFIG_SYSVIPC=y
 CONFIG_LOG_BUF_SHIFT=14
 CONFIG_EXPERT=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 # CONFIG_PCI is not set
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="console=ttyS0,38400 eth0=tuntap,,tap0 ip=192.168.168.5:192.168.168.1 root=nfs nfsroot=192.168.168.1:/opt/montavista/pro/devkit/xtensa/linux_be/target memmap=128M@0"
index 380e366..88b2e22 100644 (file)
@@ -25,8 +25,6 @@ CONFIG_KALLSYMS_ALL=y
 CONFIG_PERF_EVENTS=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_XTENSA_VARIANT_CUSTOM=y
 CONFIG_XTENSA_VARIANT_CUSTOM_NAME="de212"
 # CONFIG_XTENSA_VARIANT_MMU is not set
index d46b58f..4f1c799 100644 (file)
@@ -21,8 +21,6 @@ CONFIG_PROFILING=y
 CONFIG_OPROFILE=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
 CONFIG_XTENSA_VARIANT_CUSTOM=y
 CONFIG_XTENSA_VARIANT_CUSTOM_NAME="test_mmuhifi_c3"
 CONFIG_XTENSA_UNALIGNED_USER=y
@@ -32,7 +30,6 @@ CONFIG_SMP=y
 CONFIG_HOTPLUG_CPU=y
 # CONFIG_INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX is not set
 # CONFIG_PCI is not set
-CONFIG_VECTORS_OFFSET=0x00002000
 CONFIG_XTENSA_PLATFORM_XTFPGA=y
 CONFIG_CMDLINE_BOOL=y
 CONFIG_CMDLINE="earlycon=uart8250,mmio32native,0xfd050020,115200n8 console=ttyS0,115200n8 ip=dhcp root=/dev/nfs rw debug memmap=96M@0"
index 4fddd85..6d1387d 100644 (file)
@@ -19,7 +19,6 @@ CONFIG_KALLSYMS_ALL=y
 CONFIG_PERF_EVENTS=y
 CONFIG_XTENSA_VARIANT_DC233C=y
 CONFIG_XTENSA_UNALIGNED_USER=y
-CONFIG_VECTORS_OFFSET=0x00002000
 CONFIG_XTENSA_KSEG_512M=y
 CONFIG_HIGHMEM=y
 CONFIG_CMDLINE_BOOL=y
index 3acc31e..271917c 100644 (file)
@@ -4,7 +4,6 @@ generic-y += bug.h
 generic-y += compat.h
 generic-y += device.h
 generic-y += div64.h
-generic-y += dma-contiguous.h
 generic-y += dma-mapping.h
 generic-y += emergency-restart.h
 generic-y += exec.h
index 71a7e84..bfc89e1 100644 (file)
 #error Unsupported Xtensa ABI
 #endif
 
+#define __XTENSA_HANDLER       .section ".exception.text", "ax"
+
 #endif /* _XTENSA_ASMMACRO_H */
index 5b4acb7..5590b0f 100644 (file)
 #define XCHAL_HAVE_EXCLUSIVE 0
 #endif
 
+#ifndef XCHAL_HAVE_EXTERN_REGS
+#define XCHAL_HAVE_EXTERN_REGS 0
+#endif
+
 #ifndef XCHAL_HAVE_MPU
 #define XCHAL_HAVE_MPU 0
 #endif
 
+#ifndef XCHAL_HAVE_VECBASE
+#define XCHAL_HAVE_VECBASE 0
+#endif
+
 #ifndef XCHAL_SPANNING_WAY
 #define XCHAL_SPANNING_WAY 0
 #endif
index f2c4852..354ca94 100644 (file)
@@ -12,8 +12,6 @@
 #define _XTENSA_PLATFORM_H
 
 #include <linux/types.h>
-#include <linux/pci.h>
-
 #include <asm/bootparam.h>
 
 /*
index 6fa903d..7f63aca 100644 (file)
@@ -237,10 +237,6 @@ extern unsigned long get_wchan(struct task_struct *p);
         v; \
         })
 
-#ifndef XCHAL_HAVE_EXTERN_REGS
-#define XCHAL_HAVE_EXTERN_REGS 0
-#endif
-
 #if XCHAL_HAVE_EXTERN_REGS
 
 static inline void set_er(unsigned long value, unsigned long addr)
index fd99b25..704286c 100644 (file)
 #endif
 
 #define RESET_VECTOR1_VADDR            (XCHAL_RESET_VECTOR1_VADDR)
-#ifdef CONFIG_VECTORS_OFFSET
-#define VECBASE_VADDR                  (KERNELOFFSET - CONFIG_VECTORS_OFFSET)
+#ifdef CONFIG_VECTORS_ADDR
+#define VECBASE_VADDR                  (CONFIG_VECTORS_ADDR)
 #else
 #define VECBASE_VADDR                  _vecbase
 #endif
 
-#if defined(XCHAL_HAVE_VECBASE) && XCHAL_HAVE_VECBASE
+#if XCHAL_HAVE_VECBASE
 
 #define VECTOR_VADDR(offset)           (VECBASE_VADDR + offset)
 
index 57e6c21..5356a5f 100644 (file)
@@ -14,6 +14,4 @@
 
 #define COMMAND_LINE_SIZE      256
 
-extern void set_except_vector(int n, void *addr);
-
 #endif
index bb8e499..c426b84 100644 (file)
@@ -58,6 +58,8 @@
        .endif;                                                         \
        .long THREAD_XTREGS_CP##x
 
+       __XTENSA_HANDLER
+
        SAVE_CP_REGS(0)
        SAVE_CP_REGS(1)
        SAVE_CP_REGS(2)
@@ -76,7 +78,6 @@
        LOAD_CP_REGS(6)
        LOAD_CP_REGS(7)
 
-       .section ".rodata", "a"
        .align 4
 .Lsave_cp_regs_jump_table:
        SAVE_CP_REGS_TAB(0)
@@ -98,8 +99,6 @@
        LOAD_CP_REGS_TAB(6)
        LOAD_CP_REGS_TAB(7)
 
-       .previous
-
 /*
  * coprocessor_flush(struct thread_info*, index)
  *                             a2        a3
@@ -145,13 +144,6 @@ ENDPROC(coprocessor_flush)
  *          <  VALID_DOUBLE_EXCEPTION_ADDRESS: regular exception
  */
 
-ENTRY(fast_coprocessor_double)
-
-       wsr     a0, excsave1
-       call0   unrecoverable_exception
-
-ENDPROC(fast_coprocessor_double)
-
 ENTRY(fast_coprocessor)
 
        /* Save remaining registers a1-a3 and SAR */
index 2c9e485..06fbb0a 100644 (file)
@@ -939,6 +939,9 @@ ENDPROC(unrecoverable_exception)
 
 /* -------------------------- FAST EXCEPTION HANDLERS ----------------------- */
 
+       __XTENSA_HANDLER
+       .literal_position
+
 /*
  * Fast-handler for alloca exceptions
  *
@@ -1024,7 +1027,7 @@ ENDPROC(fast_alloca)
 ENTRY(fast_illegal_instruction_user)
 
        rsr     a0, ps
-       bbsi.l  a0, PS_WOE_BIT, user_exception
+       bbsi.l  a0, PS_WOE_BIT, 1f
        s32i    a3, a2, PT_AREG3
        movi    a3, PS_WOE_MASK
        or      a0, a0, a3
@@ -1033,6 +1036,8 @@ ENTRY(fast_illegal_instruction_user)
        l32i    a0, a2, PT_AREG0
        rsr     a2, depc
        rfe
+1:
+       call0   user_exception
 
 ENDPROC(fast_illegal_instruction_user)
 #endif
@@ -1071,7 +1076,7 @@ ENTRY(fast_syscall_user)
        _beqz   a0, fast_syscall_spill_registers
        _beqi   a0, __NR_xtensa, fast_syscall_xtensa
 
-       j       user_exception
+       call0   user_exception
 
 ENDPROC(fast_syscall_user)
 
@@ -1762,8 +1767,8 @@ ENTRY(fast_second_level_miss)
 
        rsr     a2, ps
        bbsi.l  a2, PS_UM_BIT, 1f
-       j       _kernel_exception
-1:     j       _user_exception
+       call0   _kernel_exception
+1:     call0   _user_exception
 
 ENDPROC(fast_second_level_miss)
 
@@ -1859,13 +1864,14 @@ ENTRY(fast_store_prohibited)
 
        rsr     a2, ps
        bbsi.l  a2, PS_UM_BIT, 1f
-       j       _kernel_exception
-1:     j       _user_exception
+       call0   _kernel_exception
+1:     call0   _user_exception
 
 ENDPROC(fast_store_prohibited)
 
 #endif /* CONFIG_MMU */
 
+       .text
 /*
  * System Calls.
  *
index a95ba05..ac1e0e5 100644 (file)
  * Chris Zankel <chris@zankel.net>
  */
 
+#include <linux/printk.h>
 #include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/time.h>
 #include <asm/platform.h>
 #include <asm/timex.h>
-#include <asm/param.h>         /* HZ */
 
 #define _F(r,f,a,b)                                                    \
        r __platform_##f a b;                                           \
@@ -28,6 +26,7 @@
  * (Please, refer to include/asm-xtensa/platform.h for more information)
  */
 
+_F(void, init, (bp_tag_t *first), { });
 _F(void, setup, (char** cmd), { });
 _F(void, restart, (void), { while(1); });
 _F(void, halt, (void), { while(1); });
index adead45..3880c76 100644 (file)
@@ -284,6 +284,8 @@ extern char _UserExceptionVector_text_start;
 extern char _UserExceptionVector_text_end;
 extern char _DoubleExceptionVector_text_start;
 extern char _DoubleExceptionVector_text_end;
+extern char _exception_text_start;
+extern char _exception_text_end;
 #if XCHAL_EXCM_LEVEL >= 2
 extern char _Level2InterruptVector_text_start;
 extern char _Level2InterruptVector_text_end;
@@ -347,7 +349,7 @@ void __init setup_arch(char **cmdline_p)
        mem_reserve(__pa(_xip_start), __pa(_xip_end));
 #endif
 
-#ifdef CONFIG_VECTORS_OFFSET
+#ifdef CONFIG_VECTORS_ADDR
        mem_reserve(__pa(&_WindowVectors_text_start),
                    __pa(&_WindowVectors_text_end));
 
@@ -363,6 +365,8 @@ void __init setup_arch(char **cmdline_p)
        mem_reserve(__pa(&_DoubleExceptionVector_text_start),
                    __pa(&_DoubleExceptionVector_text_end));
 
+       mem_reserve(__pa(&_exception_text_start),
+                   __pa(&_exception_text_end));
 #if XCHAL_EXCM_LEVEL >= 2
        mem_reserve(__pa(&_Level2InterruptVector_text_start),
                    __pa(&_Level2InterruptVector_text_end));
@@ -384,7 +388,7 @@ void __init setup_arch(char **cmdline_p)
                    __pa(&_Level6InterruptVector_text_end));
 #endif
 
-#endif /* CONFIG_VECTORS_OFFSET */
+#endif /* CONFIG_VECTORS_ADDR */
 
 #ifdef CONFIG_SMP
        mem_reserve(__pa(&_SecondaryResetVector_text_start),
index 841503d..95ad1e7 100644 (file)
@@ -43,6 +43,7 @@
  */
 
 #include <linux/linkage.h>
+#include <asm/asmmacro.h>
 #include <asm/ptrace.h>
 #include <asm/current.h>
 #include <asm/asm-offsets.h>
@@ -477,7 +478,6 @@ _DoubleExceptionVector_handle_exception:
 
 ENDPROC(_DoubleExceptionVector)
 
-       .text
 /*
  * Fixup handler for TLB miss in double exception handler for window owerflow.
  * We get here with windowbase set to the window that was being spilled and
@@ -505,6 +505,7 @@ ENDPROC(_DoubleExceptionVector)
  * a3: exctable, original value in excsave1
  */
 
+       __XTENSA_HANDLER
        .literal_position
 
 ENTRY(window_overflow_restore_a0_fixup)
index 409c05c..d23a6e3 100644 (file)
@@ -47,15 +47,20 @@ jiffies = jiffies_64;
        LONG(sym ## _end);                      \
        LONG(LOADADDR(section))
 
+#if !defined(CONFIG_VECTORS_ADDR) && XCHAL_HAVE_VECBASE
+#define MERGED_VECTORS 1
+#else
+#define MERGED_VECTORS 0
+#endif
+
 /*
- * Macro to define a section for a vector. When CONFIG_VECTORS_OFFSET is
- * defined code for every vector is located with other init data. At startup
+ * Macro to define a section for a vector. When MERGED_VECTORS is 0
+ * code for every vector is located with other init data. At startup
  * time head.S copies code for every vector to its final position according
  * to description recorded in the corresponding RELOCATE_ENTRY.
  */
 
-#ifdef CONFIG_VECTORS_OFFSET
-#define SECTION_VECTOR(sym, section, addr, prevsec)                         \
+#define SECTION_VECTOR4(sym, section, addr, prevsec)                       \
   section addr : AT(((LOADADDR(prevsec) + SIZEOF(prevsec)) + 3) & ~ 3)      \
   {                                                                        \
     . = ALIGN(4);                                                          \
@@ -63,11 +68,10 @@ jiffies = jiffies_64;
     *(section)                                                             \
     sym ## _end = ABSOLUTE(.);                                             \
   }
-#else
-#define SECTION_VECTOR(section, addr)                                      \
+
+#define SECTION_VECTOR2(section, addr)                                     \
   . = addr;                                                                \
   *(section)
-#endif
 
 /*
  *  Mapping of input sections to output sections when linking.
@@ -86,30 +90,32 @@ SECTIONS
     /* The HEAD_TEXT section must be the first section! */
     HEAD_TEXT
 
-#ifndef CONFIG_VECTORS_OFFSET
-  . = ALIGN(PAGE_SIZE);
-  _vecbase = .;
+#if MERGED_VECTORS
+    . = ALIGN(PAGE_SIZE);
+    _vecbase = .;
 
-  SECTION_VECTOR (.WindowVectors.text, WINDOW_VECTORS_VADDR)
+    SECTION_VECTOR2 (.WindowVectors.text, WINDOW_VECTORS_VADDR)
 #if XCHAL_EXCM_LEVEL >= 2
-  SECTION_VECTOR (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR)
+    SECTION_VECTOR2 (.Level2InterruptVector.text, INTLEVEL2_VECTOR_VADDR)
 #endif
 #if XCHAL_EXCM_LEVEL >= 3
-  SECTION_VECTOR (.Level3InterruptVector.text, INTLEVEL3_VECTOR_VADDR)
+    SECTION_VECTOR2 (.Level3InterruptVector.text, INTLEVEL3_VECTOR_VADDR)
 #endif
 #if XCHAL_EXCM_LEVEL >= 4
-  SECTION_VECTOR (.Level4InterruptVector.text, INTLEVEL4_VECTOR_VADDR)
+    SECTION_VECTOR2 (.Level4InterruptVector.text, INTLEVEL4_VECTOR_VADDR)
 #endif
 #if XCHAL_EXCM_LEVEL >= 5
-  SECTION_VECTOR (.Level5InterruptVector.text, INTLEVEL5_VECTOR_VADDR)
+    SECTION_VECTOR2 (.Level5InterruptVector.text, INTLEVEL5_VECTOR_VADDR)
 #endif
 #if XCHAL_EXCM_LEVEL >= 6
-  SECTION_VECTOR (.Level6InterruptVector.text, INTLEVEL6_VECTOR_VADDR)
+    SECTION_VECTOR2 (.Level6InterruptVector.text, INTLEVEL6_VECTOR_VADDR)
 #endif
-  SECTION_VECTOR (.DebugInterruptVector.text, DEBUG_VECTOR_VADDR)
-  SECTION_VECTOR (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
-  SECTION_VECTOR (.UserExceptionVector.text, USER_VECTOR_VADDR)
-  SECTION_VECTOR (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
+    SECTION_VECTOR2 (.DebugInterruptVector.text, DEBUG_VECTOR_VADDR)
+    SECTION_VECTOR2 (.KernelExceptionVector.text, KERNEL_VECTOR_VADDR)
+    SECTION_VECTOR2 (.UserExceptionVector.text, USER_VECTOR_VADDR)
+    SECTION_VECTOR2 (.DoubleExceptionVector.text, DOUBLEEXC_VECTOR_VADDR)
+
+    *(.exception.text)
 #endif
 
     IRQENTRY_TEXT
@@ -159,7 +165,7 @@ SECTIONS
     . = ALIGN(16);
     __boot_reloc_table_start = ABSOLUTE(.);
 
-#ifdef CONFIG_VECTORS_OFFSET
+#if !MERGED_VECTORS
     RELOCATE_ENTRY(_WindowVectors_text,
                   .WindowVectors.text);
 #if XCHAL_EXCM_LEVEL >= 2
@@ -190,16 +196,17 @@ SECTIONS
                   .DoubleExceptionVector.text);
     RELOCATE_ENTRY(_DebugInterruptVector_text,
                   .DebugInterruptVector.text);
+    RELOCATE_ENTRY(_exception_text,
+                  .exception.text);
 #endif
 #ifdef CONFIG_XIP_KERNEL
     RELOCATE_ENTRY(_xip_data, .data);
     RELOCATE_ENTRY(_xip_init_data, .init.data);
-#else
+#endif
 #if defined(CONFIG_SMP)
     RELOCATE_ENTRY(_SecondaryResetVector_text,
                   .SecondaryResetVector.text);
 #endif
-#endif
 
     __boot_reloc_table_end = ABSOLUTE(.) ;
 
@@ -216,21 +223,24 @@ SECTIONS
   . = ALIGN(4);
   .dummy : { LONG(0) }
 
-#ifdef CONFIG_VECTORS_OFFSET
+#undef LAST
+#define LAST   .dummy
+
+#if !MERGED_VECTORS
   /* The vectors are relocated to the real position at startup time */
 
-  SECTION_VECTOR (_WindowVectors_text,
+  SECTION_VECTOR4 (_WindowVectors_text,
                  .WindowVectors.text,
                  WINDOW_VECTORS_VADDR,
                  .dummy)
-  SECTION_VECTOR (_DebugInterruptVector_text,
+  SECTION_VECTOR4 (_DebugInterruptVector_text,
                  .DebugInterruptVector.text,
                  DEBUG_VECTOR_VADDR,
                  .WindowVectors.text)
 #undef LAST
 #define LAST   .DebugInterruptVector.text
 #if XCHAL_EXCM_LEVEL >= 2
-  SECTION_VECTOR (_Level2InterruptVector_text,
+  SECTION_VECTOR4 (_Level2InterruptVector_text,
                  .Level2InterruptVector.text,
                  INTLEVEL2_VECTOR_VADDR,
                  LAST)
@@ -238,7 +248,7 @@ SECTIONS
 # define LAST  .Level2InterruptVector.text
 #endif
 #if XCHAL_EXCM_LEVEL >= 3
-  SECTION_VECTOR (_Level3InterruptVector_text,
+  SECTION_VECTOR4 (_Level3InterruptVector_text,
                  .Level3InterruptVector.text,
                  INTLEVEL3_VECTOR_VADDR,
                  LAST)
@@ -246,7 +256,7 @@ SECTIONS
 # define LAST  .Level3InterruptVector.text
 #endif
 #if XCHAL_EXCM_LEVEL >= 4
-  SECTION_VECTOR (_Level4InterruptVector_text,
+  SECTION_VECTOR4 (_Level4InterruptVector_text,
                  .Level4InterruptVector.text,
                  INTLEVEL4_VECTOR_VADDR,
                  LAST)
@@ -254,7 +264,7 @@ SECTIONS
 # define LAST  .Level4InterruptVector.text
 #endif
 #if XCHAL_EXCM_LEVEL >= 5
-  SECTION_VECTOR (_Level5InterruptVector_text,
+  SECTION_VECTOR4 (_Level5InterruptVector_text,
                  .Level5InterruptVector.text,
                  INTLEVEL5_VECTOR_VADDR,
                  LAST)
@@ -262,41 +272,51 @@ SECTIONS
 # define LAST  .Level5InterruptVector.text
 #endif
 #if XCHAL_EXCM_LEVEL >= 6
-  SECTION_VECTOR (_Level6InterruptVector_text,
+  SECTION_VECTOR4 (_Level6InterruptVector_text,
                  .Level6InterruptVector.text,
                  INTLEVEL6_VECTOR_VADDR,
                  LAST)
 # undef LAST
 # define LAST  .Level6InterruptVector.text
 #endif
-  SECTION_VECTOR (_KernelExceptionVector_text,
+  SECTION_VECTOR4 (_KernelExceptionVector_text,
                  .KernelExceptionVector.text,
                  KERNEL_VECTOR_VADDR,
                  LAST)
 #undef LAST
-  SECTION_VECTOR (_UserExceptionVector_text,
+  SECTION_VECTOR4 (_UserExceptionVector_text,
                  .UserExceptionVector.text,
                  USER_VECTOR_VADDR,
                  .KernelExceptionVector.text)
-  SECTION_VECTOR (_DoubleExceptionVector_text,
+  SECTION_VECTOR4 (_DoubleExceptionVector_text,
                  .DoubleExceptionVector.text,
                  DOUBLEEXC_VECTOR_VADDR,
                  .UserExceptionVector.text)
-
-  . = (LOADADDR( .DoubleExceptionVector.text ) + SIZEOF( .DoubleExceptionVector.text ) + 3) & ~ 3;
+#define LAST .DoubleExceptionVector.text
 
 #endif
-#if !defined(CONFIG_XIP_KERNEL) && defined(CONFIG_SMP)
+#if defined(CONFIG_SMP)
 
-  SECTION_VECTOR (_SecondaryResetVector_text,
+  SECTION_VECTOR4 (_SecondaryResetVector_text,
                  .SecondaryResetVector.text,
                  RESET_VECTOR1_VADDR,
-                 .DoubleExceptionVector.text)
+                 LAST)
+#undef LAST
+#define LAST .SecondaryResetVector.text
 
-  . = LOADADDR(.SecondaryResetVector.text)+SIZEOF(.SecondaryResetVector.text);
+#endif
+#if !MERGED_VECTORS
+  SECTION_VECTOR4 (_exception_text,
+                 .exception.text,
+                 ,
+                 LAST)
+#undef LAST
+#define LAST .exception.text
 
 #endif
+  . = (LOADADDR(LAST) + SIZEOF(LAST) + 3) & ~ 3;
 
+  .dummy1 : AT(ADDR(.dummy1)) { LONG(0) }
   . = ALIGN(PAGE_SIZE);
 
 #ifndef CONFIG_XIP_KERNEL
@@ -314,7 +334,7 @@ SECTIONS
 
 #undef LOAD_OFFSET
 #define LOAD_OFFSET \
-  (CONFIG_XIP_DATA_ADDR - (LOADADDR(.dummy) + SIZEOF(.dummy) + 3) & ~ 3)
+  (CONFIG_XIP_DATA_ADDR - (LOADADDR(.dummy1) + SIZEOF(.dummy1) + 3) & ~ 3)
 
   _xip_data_start = .;
   _sdata = .;
index 4e2a483..f42870a 100644 (file)
@@ -66,19 +66,17 @@ static int errno;
 
 static inline int __simc(int a, int b, int c, int d)
 {
-       int ret;
        register int a1 asm("a2") = a;
        register int b1 asm("a3") = b;
        register int c1 asm("a4") = c;
        register int d1 asm("a5") = d;
        __asm__ __volatile__ (
                        "simcall\n"
-                       "mov %0, a2\n"
-                       "mov %1, a3\n"
-                       : "=a" (ret), "=a" (errno), "+r"(a1), "+r"(b1)
+                       : "+r"(a1), "+r"(b1)
                        : "r"(c1), "r"(d1)
                        : "memory");
-       return ret;
+       errno = b1;
+       return a1;
 }
 
 static inline int simc_exit(int exit_code)
index e28dd53..ed519ae 100644 (file)
  * Copyright 2001 - 2005 Tensilica Inc.
  * Copyright 2017 Cadence Design Systems Inc.
  */
-#include <linux/memblock.h>
-#include <linux/stddef.h>
-#include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/reboot.h>
-#include <linux/kdev_t.h>
-#include <linux/types.h>
-#include <linux/major.h>
-#include <linux/blkdev.h>
-#include <linux/console.h>
-#include <linux/delay.h>
-#include <linux/stringify.h>
+#include <linux/kernel.h>
 #include <linux/notifier.h>
+#include <linux/printk.h>
+#include <linux/string.h>
 
 #include <asm/platform.h>
-#include <asm/bootparam.h>
 #include <asm/setup.h>
 
 #include <platform/simcall.h>
 
 
-void __init platform_init(bp_tag_t* bootparam)
-{
-}
-
 void platform_halt(void)
 {
        pr_info(" ** Called platform_halt() **\n");
@@ -48,6 +34,7 @@ void platform_power_off(void)
        pr_info(" ** Called platform_power_off() **\n");
        simc_exit(0);
 }
+
 void platform_restart(void)
 {
        /* Flush and reset the mmu, simulate a processor reset, and
@@ -56,10 +43,6 @@ void platform_restart(void)
        /* control never gets here */
 }
 
-void platform_heartbeat(void)
-{
-}
-
 static int
 iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
 {
index f9cd458..8331098 100644 (file)
@@ -251,10 +251,10 @@ out_free:
        return err;
 }
 
-static const struct file_operations fops = {
-       .read = proc_read_simdisk,
-       .write = proc_write_simdisk,
-       .llseek = default_llseek,
+static const struct proc_ops simdisk_proc_ops = {
+       .proc_read      = proc_read_simdisk,
+       .proc_write     = proc_write_simdisk,
+       .proc_lseek     = default_llseek,
 };
 
 static int __init simdisk_setup(struct simdisk *dev, int which,
@@ -290,7 +290,7 @@ static int __init simdisk_setup(struct simdisk *dev, int which,
        set_capacity(dev->gd, 0);
        add_disk(dev->gd);
 
-       dev->procfile = proc_create_data(tmp, 0644, procdir, &fops, dev);
+       dev->procfile = proc_create_data(tmp, 0644, procdir, &simdisk_proc_ops, dev);
        return 0;
 
 out_alloc_disk:
index 829115b..4f7d614 100644 (file)
@@ -24,6 +24,7 @@
 #include <linux/of.h>
 #include <linux/clk-provider.h>
 #include <linux/of_address.h>
+#include <linux/slab.h>
 
 #include <asm/timex.h>
 #include <asm/processor.h>
@@ -56,22 +57,6 @@ void platform_restart(void)
        /* control never gets here */
 }
 
-void __init platform_setup(char **cmdline)
-{
-}
-
-/* early initialization */
-
-void __init platform_init(bp_tag_t *first)
-{
-}
-
-/* Heartbeat. */
-
-void platform_heartbeat(void)
-{
-}
-
 #ifdef CONFIG_XTENSA_CALIBRATE_CCOUNT
 
 void __init platform_calibrate_ccount(void)
index e1419ed..09b69a3 100644 (file)
@@ -332,7 +332,7 @@ static void bfqg_put(struct bfq_group *bfqg)
                kfree(bfqg);
 }
 
-static void bfqg_and_blkg_get(struct bfq_group *bfqg)
+void bfqg_and_blkg_get(struct bfq_group *bfqg)
 {
        /* see comments in bfq_bic_update_cgroup for why refcounting bfqg */
        bfqg_get(bfqg);
@@ -651,9 +651,15 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
                bfq_bfqq_expire(bfqd, bfqd->in_service_queue,
                                false, BFQQE_PREEMPTED);
 
+       /*
+        * get extra reference to prevent bfqq from being freed in
+        * next possible deactivate
+        */
+       bfqq->ref++;
+
        if (bfq_bfqq_busy(bfqq))
                bfq_deactivate_bfqq(bfqd, bfqq, false, false);
-       else if (entity->on_st)
+       else if (entity->on_st_or_in_serv)
                bfq_put_idle_entity(bfq_entity_service_tree(entity), entity);
        bfqg_and_blkg_put(bfqq_group(bfqq));
 
@@ -670,6 +676,8 @@ void bfq_bfqq_move(struct bfq_data *bfqd, struct bfq_queue *bfqq,
 
        if (!bfqd->in_service_queue && !bfqd->rq_in_driver)
                bfq_schedule_dispatch(bfqd);
+       /* release extra ref taken above */
+       bfq_put_queue(bfqq);
 }
 
 /**
@@ -1398,6 +1406,10 @@ struct bfq_group *bfqq_group(struct bfq_queue *bfqq)
        return bfqq->bfqd->root_group;
 }
 
+void bfqg_and_blkg_get(struct bfq_group *bfqg) {}
+
+void bfqg_and_blkg_put(struct bfq_group *bfqg) {}
+
 struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node)
 {
        struct bfq_group *bfqg;
index 4686b68..8c436ab 100644 (file)
@@ -613,6 +613,10 @@ bfq_pos_tree_add_move(struct bfq_data *bfqd, struct bfq_queue *bfqq)
                bfqq->pos_root = NULL;
        }
 
+       /* oom_bfqq does not participate in queue merging */
+       if (bfqq == &bfqd->oom_bfqq)
+               return;
+
        /*
         * bfqq cannot be merged any longer (see comments in
         * bfq_setup_cooperator): no point in adding bfqq into the
@@ -1055,7 +1059,7 @@ bfq_bfqq_resume_state(struct bfq_queue *bfqq, struct bfq_data *bfqd,
 
 static int bfqq_process_refs(struct bfq_queue *bfqq)
 {
-       return bfqq->ref - bfqq->allocated - bfqq->entity.on_st -
+       return bfqq->ref - bfqq->allocated - bfqq->entity.on_st_or_in_serv -
                (bfqq->weight_counter != NULL);
 }
 
@@ -3443,6 +3447,10 @@ static void bfq_dispatch_remove(struct request_queue *q, struct request *rq)
 static bool idling_needed_for_service_guarantees(struct bfq_data *bfqd,
                                                 struct bfq_queue *bfqq)
 {
+       /* No point in idling for bfqq if it won't get requests any longer */
+       if (unlikely(!bfqq_process_refs(bfqq)))
+               return false;
+
        return (bfqq->wr_coeff > 1 &&
                (bfqd->wr_busy_queues <
                 bfq_tot_busy_queues(bfqd) ||
@@ -4076,6 +4084,10 @@ static bool idling_boosts_thr_without_issues(struct bfq_data *bfqd,
                bfqq_sequential_and_IO_bound,
                idling_boosts_thr;
 
+       /* No point in idling for bfqq if it won't get requests any longer */
+       if (unlikely(!bfqq_process_refs(bfqq)))
+               return false;
+
        bfqq_sequential_and_IO_bound = !BFQQ_SEEKY(bfqq) &&
                bfq_bfqq_IO_bound(bfqq) && bfq_bfqq_has_short_ttime(bfqq);
 
@@ -4169,6 +4181,10 @@ static bool bfq_better_to_idle(struct bfq_queue *bfqq)
        struct bfq_data *bfqd = bfqq->bfqd;
        bool idling_boosts_thr_with_no_issue, idling_needed_for_service_guar;
 
+       /* No point in idling for bfqq if it won't get requests any longer */
+       if (unlikely(!bfqq_process_refs(bfqq)))
+               return false;
+
        if (unlikely(bfqd->strict_guarantees))
                return true;
 
@@ -4809,9 +4825,7 @@ void bfq_put_queue(struct bfq_queue *bfqq)
 {
        struct bfq_queue *item;
        struct hlist_node *n;
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
        struct bfq_group *bfqg = bfqq_group(bfqq);
-#endif
 
        if (bfqq->bfqd)
                bfq_log_bfqq(bfqq->bfqd, bfqq, "put_queue: %p %d",
@@ -4884,9 +4898,7 @@ void bfq_put_queue(struct bfq_queue *bfqq)
                bfqq->bfqd->last_completed_rq_bfqq = NULL;
 
        kmem_cache_free(bfq_pool, bfqq);
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
        bfqg_and_blkg_put(bfqg);
-#endif
 }
 
 static void bfq_put_cooperator(struct bfq_queue *bfqq)
@@ -5967,6 +5979,8 @@ static void bfq_finish_requeue_request(struct request *rq)
 }
 
 /*
+ * Removes the association between the current task and bfqq, assuming
+ * that bic points to the bfq iocontext of the task.
  * Returns NULL if a new bfqq should be allocated, or the old bfqq if this
  * was the last process referring to that bfqq.
  */
@@ -6374,10 +6388,10 @@ static void bfq_exit_queue(struct elevator_queue *e)
 
        hrtimer_cancel(&bfqd->idle_slice_timer);
 
-#ifdef CONFIG_BFQ_GROUP_IOSCHED
        /* release oom-queue reference to root group */
        bfqg_and_blkg_put(bfqd->root_group);
 
+#ifdef CONFIG_BFQ_GROUP_IOSCHED
        blkcg_deactivate_policy(bfqd->queue, &blkcg_policy_bfq);
 #else
        spin_lock_irq(&bfqd->lock);
index 8526f20..d1233af 100644 (file)
@@ -150,7 +150,7 @@ struct bfq_entity {
         * Flag, true if the entity is on a tree (either the active or
         * the idle one of its service_tree) or is in service.
         */
-       bool on_st;
+       bool on_st_or_in_serv;
 
        /* B-WF2Q+ start and finish timestamps [sectors/weight] */
        u64 start, finish;
@@ -921,6 +921,7 @@ struct bfq_group {
 
 #else
 struct bfq_group {
+       struct bfq_entity entity;
        struct bfq_sched_data sched_data;
 
        struct bfq_queue *async_bfqq[2][IOPRIO_BE_NR];
@@ -984,6 +985,7 @@ struct bfq_group *bfq_find_set_group(struct bfq_data *bfqd,
 struct blkcg_gq *bfqg_to_blkg(struct bfq_group *bfqg);
 struct bfq_group *bfqq_group(struct bfq_queue *bfqq);
 struct bfq_group *bfq_create_group_hierarchy(struct bfq_data *bfqd, int node);
+void bfqg_and_blkg_get(struct bfq_group *bfqg);
 void bfqg_and_blkg_put(struct bfq_group *bfqg);
 
 #ifdef CONFIG_BFQ_GROUP_IOSCHED
index ffe9ce9..eb0e2a6 100644 (file)
@@ -533,7 +533,9 @@ static void bfq_get_entity(struct bfq_entity *entity)
                bfqq->ref++;
                bfq_log_bfqq(bfqq->bfqd, bfqq, "get_entity: %p %d",
                             bfqq, bfqq->ref);
-       }
+       } else
+               bfqg_and_blkg_get(container_of(entity, struct bfq_group,
+                                              entity));
 }
 
 /**
@@ -645,10 +647,16 @@ static void bfq_forget_entity(struct bfq_service_tree *st,
 {
        struct bfq_queue *bfqq = bfq_entity_to_bfqq(entity);
 
-       entity->on_st = false;
+       entity->on_st_or_in_serv = false;
        st->wsum -= entity->weight;
-       if (bfqq && !is_in_service)
+       if (is_in_service)
+               return;
+
+       if (bfqq)
                bfq_put_queue(bfqq);
+       else
+               bfqg_and_blkg_put(container_of(entity, struct bfq_group,
+                                              entity));
 }
 
 /**
@@ -999,7 +1007,7 @@ static void __bfq_activate_entity(struct bfq_entity *entity,
                 */
                bfq_get_entity(entity);
 
-               entity->on_st = true;
+               entity->on_st_or_in_serv = true;
        }
 
 #ifdef CONFIG_BFQ_GROUP_IOSCHED
@@ -1165,7 +1173,10 @@ bool __bfq_deactivate_entity(struct bfq_entity *entity, bool ins_into_idle_tree)
        struct bfq_service_tree *st;
        bool is_in_service;
 
-       if (!entity->on_st) /* entity never activated, or already inactive */
+       if (!entity->on_st_or_in_serv) /*
+                                       * entity never activated, or
+                                       * already inactive
+                                       */
                return false;
 
        /*
@@ -1620,7 +1631,7 @@ bool __bfq_bfqd_reset_in_service(struct bfq_data *bfqd)
         * service tree either, then release the service reference to
         * the queue it represents (taken with bfq_get_entity).
         */
-       if (!in_serv_entity->on_st) {
+       if (!in_serv_entity->on_st_or_in_serv) {
                /*
                 * If no process is referencing in_serv_bfqq any
                 * longer, then the service reference may be the only
index 3d8e530..439367a 100644 (file)
@@ -171,7 +171,7 @@ static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        sa->salg_name[sizeof(sa->salg_name) + addr_len - sizeof(*sa) - 1] = 0;
 
        type = alg_get_type(sa->salg_type);
-       if (IS_ERR(type) && PTR_ERR(type) == -ENOENT) {
+       if (PTR_ERR(type) == -ENOENT) {
                request_module("algif-%s", sa->salg_type);
                type = alg_get_type(sa->salg_type);
        }
index 71511ae..ba2612e 100644 (file)
@@ -161,6 +161,11 @@ static const struct apd_device_desc hip08_i2c_desc = {
        .fixed_clk_rate = 250000000,
 };
 
+static const struct apd_device_desc hip08_lite_i2c_desc = {
+       .setup = acpi_apd_setup,
+       .fixed_clk_rate = 125000000,
+};
+
 static const struct apd_device_desc thunderx2_i2c_desc = {
        .setup = acpi_apd_setup,
        .fixed_clk_rate = 125000000,
@@ -243,6 +248,7 @@ static const struct acpi_device_id acpi_apd_device_ids[] = {
        { "CAV9007",  APD_ADDR(thunderx2_i2c_desc) },
        { "HISI02A1", APD_ADDR(hip07_i2c_desc) },
        { "HISI02A2", APD_ADDR(hip08_i2c_desc) },
+       { "HISI02A3", APD_ADDR(hip08_lite_i2c_desc) },
        { "HISI0173", APD_ADDR(hip08_spi_desc) },
        { "NXP0001", APD_ADDR(nxp_i2c_desc) },
 #endif
index 6078064..ed3d2d1 100644 (file)
@@ -11,6 +11,7 @@
 #define pr_fmt(fmt)    "ACPI: IORT: " fmt
 
 #include <linux/acpi_iort.h>
+#include <linux/bitfield.h>
 #include <linux/iommu.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -902,9 +903,9 @@ static inline bool iort_iommu_driver_enabled(u8 type)
 {
        switch (type) {
        case ACPI_IORT_NODE_SMMU_V3:
-               return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
+               return IS_ENABLED(CONFIG_ARM_SMMU_V3);
        case ACPI_IORT_NODE_SMMU:
-               return IS_BUILTIN(CONFIG_ARM_SMMU);
+               return IS_ENABLED(CONFIG_ARM_SMMU);
        default:
                pr_warn("IORT node type %u does not describe an SMMU\n", type);
                return false;
@@ -976,6 +977,20 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
        return iort_iommu_xlate(info->dev, parent, streamid);
 }
 
+static void iort_named_component_init(struct device *dev,
+                                     struct acpi_iort_node *node)
+{
+       struct acpi_iort_named_component *nc;
+       struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev);
+
+       if (!fwspec)
+               return;
+
+       nc = (struct acpi_iort_named_component *)node->node_data;
+       fwspec->num_pasid_bits = FIELD_GET(ACPI_IORT_NC_PASID_BITS,
+                                          nc->node_flags);
+}
+
 /**
  * iort_iommu_configure - Set-up IOMMU configuration for a device.
  *
@@ -1030,6 +1045,9 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev)
                        if (parent)
                                err = iort_iommu_xlate(dev, parent, streamid);
                } while (parent && !err);
+
+               if (!err)
+                       iort_named_component_init(dev, node);
        }
 
        /*
index 15cc7d5..111a407 100644 (file)
@@ -1202,13 +1202,12 @@ static int acpi_battery_alarm_proc_open(struct inode *inode, struct file *file)
        return single_open(file, acpi_battery_alarm_proc_show, PDE_DATA(inode));
 }
 
-static const struct file_operations acpi_battery_alarm_fops = {
-       .owner          = THIS_MODULE,
-       .open           = acpi_battery_alarm_proc_open,
-       .read           = seq_read,
-       .write          = acpi_battery_write_alarm,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops acpi_battery_alarm_proc_ops = {
+       .proc_open      = acpi_battery_alarm_proc_open,
+       .proc_read      = seq_read,
+       .proc_write     = acpi_battery_write_alarm,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 static int acpi_battery_add_fs(struct acpi_device *device)
@@ -1228,7 +1227,7 @@ static int acpi_battery_add_fs(struct acpi_device *device)
                        acpi_battery_state_proc_show, acpi_driver_data(device)))
                return -ENODEV;
        if (!proc_create_data("alarm", S_IFREG | S_IRUGO | S_IWUSR,
-                       acpi_device_dir(device), &acpi_battery_alarm_fops,
+                       acpi_device_dir(device), &acpi_battery_alarm_proc_ops,
                        acpi_driver_data(device)))
                return -ENODEV;
        return 0;
index 652f19e..0e62ef2 100644 (file)
@@ -136,18 +136,17 @@ acpi_system_wakeup_device_open_fs(struct inode *inode, struct file *file)
                           PDE_DATA(inode));
 }
 
-static const struct file_operations acpi_system_wakeup_device_fops = {
-       .owner = THIS_MODULE,
-       .open = acpi_system_wakeup_device_open_fs,
-       .read = seq_read,
-       .write = acpi_system_write_wakeup_device,
-       .llseek = seq_lseek,
-       .release = single_release,
+static const struct proc_ops acpi_system_wakeup_device_proc_ops = {
+       .proc_open      = acpi_system_wakeup_device_open_fs,
+       .proc_read      = seq_read,
+       .proc_write     = acpi_system_write_wakeup_device,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 void __init acpi_sleep_proc_init(void)
 {
        /* 'wakeup device' [R/W] */
        proc_create("wakeup", S_IFREG | S_IRUGO | S_IWUSR,
-                   acpi_root_dir, &acpi_system_wakeup_device_fops);
+                   acpi_root_dir, &acpi_system_wakeup_device_proc_ops);
 }
index 915650b..6d34488 100644 (file)
@@ -1462,7 +1462,7 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr)
        iort_dma_setup(dev, &dma_addr, &size);
 
        iommu = iort_iommu_configure(dev);
-       if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
+       if (PTR_ERR(iommu) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
        arch_setup_dma_ops(dev, dma_addr, size,
index 4bfd1b1..11ea1af 100644 (file)
@@ -81,6 +81,7 @@ enum board_ids {
 
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void ahci_remove_one(struct pci_dev *dev);
+static void ahci_shutdown_one(struct pci_dev *dev);
 static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
                                 unsigned long deadline);
 static int ahci_avn_hardreset(struct ata_link *link, unsigned int *class,
@@ -606,6 +607,7 @@ static struct pci_driver ahci_pci_driver = {
        .id_table               = ahci_pci_tbl,
        .probe                  = ahci_init_one,
        .remove                 = ahci_remove_one,
+       .shutdown               = ahci_shutdown_one,
        .driver = {
                .pm             = &ahci_pci_pm_ops,
        },
@@ -1877,6 +1879,11 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
        return 0;
 }
 
+static void ahci_shutdown_one(struct pci_dev *pdev)
+{
+       ata_pci_shutdown_one(pdev);
+}
+
 static void ahci_remove_one(struct pci_dev *pdev)
 {
        pm_runtime_get_noresume(&pdev->dev);
index 6f4ab5c..42c8728 100644 (file)
@@ -6767,6 +6767,26 @@ void ata_pci_remove_one(struct pci_dev *pdev)
        ata_host_detach(host);
 }
 
+void ata_pci_shutdown_one(struct pci_dev *pdev)
+{
+       struct ata_host *host = pci_get_drvdata(pdev);
+       int i;
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+
+               ap->pflags |= ATA_PFLAG_FROZEN;
+
+               /* Disable port interrupts */
+               if (ap->ops->freeze)
+                       ap->ops->freeze(ap);
+
+               /* Stop the port DMA engines */
+               if (ap->ops->port_stop)
+                       ap->ops->port_stop(ap);
+       }
+}
+
 /* move to PCI subsystem */
 int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits)
 {
@@ -7387,6 +7407,7 @@ EXPORT_SYMBOL_GPL(ata_timing_cycle2mode);
 
 #ifdef CONFIG_PCI
 EXPORT_SYMBOL_GPL(pci_test_config_bits);
+EXPORT_SYMBOL_GPL(ata_pci_shutdown_one);
 EXPORT_SYMBOL_GPL(ata_pci_remove_one);
 #ifdef CONFIG_PM
 EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
index 391dff0..e9cf31f 100644 (file)
@@ -526,9 +526,10 @@ static void data_xfer(struct work_struct *work)
 
        /* request dma channels */
        /* dma_request_channel may sleep, so calling from process context */
-       acdev->dma_chan = dma_request_slave_channel(acdev->host->dev, "data");
-       if (!acdev->dma_chan) {
+       acdev->dma_chan = dma_request_chan(acdev->host->dev, "data");
+       if (IS_ERR(acdev->dma_chan)) {
                dev_err(acdev->host->dev, "Unable to get dma_chan\n");
+               acdev->dma_chan = NULL;
                goto chan_request_fail;
        }
 
@@ -539,6 +540,7 @@ static void data_xfer(struct work_struct *work)
        }
 
        dma_release_channel(acdev->dma_chan);
+       acdev->dma_chan = NULL;
 
        /* data xferred successfully */
        if (!ret) {
index 3fe0754..8eb066a 100644 (file)
@@ -309,6 +309,7 @@ static const struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
        PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
        PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
+       PCMCIA_DEVICE_MANF_CARD(0x00f1, 0x0101),        /* SanDisk High (>8G) CFA */
        PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),        /* Hitachi */
        PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
        PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100),        /* Viking CFA */
index 5995c43..c9017e0 100644 (file)
@@ -67,10 +67,10 @@ static struct file_system_type internal_fs_type = {
        .name = "devtmpfs",
 #ifdef CONFIG_TMPFS
        .init_fs_context = shmem_init_fs_context,
-       .parameters     = &shmem_fs_parameters,
+       .parameters     = shmem_fs_parameters,
 #else
        .init_fs_context = ramfs_init_fs_context,
-       .parameters     = &ramfs_fs_parameters,
+       .parameters     = ramfs_fs_parameters,
 #endif
        .kill_sb = kill_litter_super,
 };
index 1565930..b9f474c 100644 (file)
@@ -376,7 +376,6 @@ static ssize_t valid_zones_show(struct device *dev,
        struct memory_block *mem = to_memory_block(dev);
        unsigned long start_pfn = section_nr_to_pfn(mem->start_section_nr);
        unsigned long nr_pages = PAGES_PER_SECTION * sections_per_block;
-       unsigned long valid_start_pfn, valid_end_pfn;
        struct zone *default_zone;
        int nid;
 
@@ -389,11 +388,11 @@ static ssize_t valid_zones_show(struct device *dev,
                 * The block contains more than one zone can not be offlined.
                 * This can happen e.g. for ZONE_DMA and ZONE_DMA32
                 */
-               if (!test_pages_in_a_zone(start_pfn, start_pfn + nr_pages,
-                                         &valid_start_pfn, &valid_end_pfn))
+               default_zone = test_pages_in_a_zone(start_pfn,
+                                                   start_pfn + nr_pages);
+               if (!default_zone)
                        return sprintf(buf, "none\n");
-               start_pfn = valid_start_pfn;
-               strcat(buf, page_zone(pfn_to_page(start_pfn))->name);
+               strcat(buf, default_zone->name);
                goto out;
        }
 
index 8e5725b..959d6d5 100644 (file)
@@ -2303,6 +2303,44 @@ out:
 EXPORT_SYMBOL_GPL(of_genpd_add_subdomain);
 
 /**
+ * of_genpd_remove_subdomain - Remove a subdomain from an I/O PM domain.
+ * @parent_spec: OF phandle args to use for parent PM domain look-up
+ * @subdomain_spec: OF phandle args to use for subdomain look-up
+ *
+ * Looks-up a parent PM domain and subdomain based upon phandle args
+ * provided and removes the subdomain from the parent PM domain. Returns a
+ * negative error code on failure.
+ */
+int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
+                             struct of_phandle_args *subdomain_spec)
+{
+       struct generic_pm_domain *parent, *subdomain;
+       int ret;
+
+       mutex_lock(&gpd_list_lock);
+
+       parent = genpd_get_from_provider(parent_spec);
+       if (IS_ERR(parent)) {
+               ret = PTR_ERR(parent);
+               goto out;
+       }
+
+       subdomain = genpd_get_from_provider(subdomain_spec);
+       if (IS_ERR(subdomain)) {
+               ret = PTR_ERR(subdomain);
+               goto out;
+       }
+
+       ret = pm_genpd_remove_subdomain(parent, subdomain);
+
+out:
+       mutex_unlock(&gpd_list_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(of_genpd_remove_subdomain);
+
+/**
  * of_genpd_remove_last - Remove the last PM domain registered for a provider
  * @provider: Pointer to device structure associated with provider
  *
index 1bb8ec5..025b1b7 100644 (file)
@@ -432,16 +432,6 @@ config VIRTIO_BLK
          This is the virtual block driver for virtio.  It can be used with
           QEMU based VMMs (like KVM or Xen).  Say Y or M.
 
-config VIRTIO_BLK_SCSI
-       bool "SCSI passthrough request for the Virtio block driver"
-       depends on VIRTIO_BLK
-       select BLK_SCSI_REQUEST
-       ---help---
-         Enable support for SCSI passthrough (e.g. the SG_IO ioctl) on
-         virtio-blk devices.  This is only supported for the legacy
-         virtio protocol and not enabled by default by any hypervisor.
-         You probably want to use virtio-scsi instead.
-
 config BLK_DEV_RBD
        tristate "Rados block device (RBD)"
        depends on INET && BLOCK
index a8730cc..220c5e1 100644 (file)
@@ -473,6 +473,25 @@ static struct kobject *brd_probe(dev_t dev, int *part, void *data)
        return kobj;
 }
 
+static inline void brd_check_and_reset_par(void)
+{
+       if (unlikely(!max_part))
+               max_part = 1;
+
+       /*
+        * make sure 'max_part' can be divided exactly by (1U << MINORBITS),
+        * otherwise, it is possiable to get same dev_t when adding partitions.
+        */
+       if ((1U << MINORBITS) % max_part != 0)
+               max_part = 1UL << fls(max_part);
+
+       if (max_part > DISK_MAX_PARTS) {
+               pr_info("brd: max_part can't be larger than %d, reset max_part = %d.\n",
+                       DISK_MAX_PARTS, DISK_MAX_PARTS);
+               max_part = DISK_MAX_PARTS;
+       }
+}
+
 static int __init brd_init(void)
 {
        struct brd_device *brd, *next;
@@ -496,8 +515,7 @@ static int __init brd_init(void)
        if (register_blkdev(RAMDISK_MAJOR, "ramdisk"))
                return -EIO;
 
-       if (unlikely(!max_part))
-               max_part = 1;
+       brd_check_and_reset_par();
 
        for (i = 0; i < rd_nr; i++) {
                brd = brd_alloc(i);
index ddbf560..aae99a2 100644 (file)
@@ -622,7 +622,7 @@ struct fifo_buffer {
        int total; /* sum of all values */
        int values[0];
 };
-extern struct fifo_buffer *fifo_alloc(int fifo_size);
+extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size);
 
 /* flag bits per connection */
 enum {
index de2f94d..da4a3eb 100644 (file)
@@ -1575,7 +1575,8 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
        struct drbd_device *device;
        struct disk_conf *new_disk_conf, *old_disk_conf;
        struct fifo_buffer *old_plan = NULL, *new_plan = NULL;
-       int err, fifo_size;
+       int err;
+       unsigned int fifo_size;
 
        retcode = drbd_adm_prepare(&adm_ctx, skb, info, DRBD_ADM_NEED_MINOR);
        if (!adm_ctx.reply_skb)
index 2b3103c..79e2164 100644 (file)
@@ -3887,7 +3887,7 @@ static int receive_SyncParam(struct drbd_connection *connection, struct packet_i
        struct disk_conf *old_disk_conf = NULL, *new_disk_conf = NULL;
        const int apv = connection->agreed_pro_version;
        struct fifo_buffer *old_plan = NULL, *new_plan = NULL;
-       int fifo_size = 0;
+       unsigned int fifo_size = 0;
        int err;
 
        peer_device = conn_peer_device(connection, pi->vnr);
index 5bdcc70..b7f605c 100644 (file)
@@ -482,11 +482,11 @@ static void fifo_add_val(struct fifo_buffer *fb, int value)
                fb->values[i] += value;
 }
 
-struct fifo_buffer *fifo_alloc(int fifo_size)
+struct fifo_buffer *fifo_alloc(unsigned int fifo_size)
 {
        struct fifo_buffer *fb;
 
-       fb = kzalloc(sizeof(struct fifo_buffer) + sizeof(int) * fifo_size, GFP_NOIO);
+       fb = kzalloc(struct_size(fb, values, fifo_size), GFP_NOIO);
        if (!fb)
                return NULL;
 
index b4607dd..7818190 100644 (file)
@@ -1265,6 +1265,16 @@ static int nbd_start_device(struct nbd_device *nbd)
                args = kzalloc(sizeof(*args), GFP_KERNEL);
                if (!args) {
                        sock_shutdown(nbd);
+                       /*
+                        * If num_connections is m (2 < m),
+                        * and NO.1 ~ NO.n(1 < n < m) kzallocs are successful.
+                        * But NO.(n + 1) failed. We still have n recv threads.
+                        * So, add flush_workqueue here to prevent recv threads
+                        * dropping the last config_refs and trying to destroy
+                        * the workqueue from inside the workqueue.
+                        */
+                       if (i)
+                               flush_workqueue(nbd->recv_workq);
                        return -ENOMEM;
                }
                sk_set_memalloc(config->socks[i]->sock->sk);
index ae8d4bc..1651079 100644 (file)
@@ -263,34 +263,34 @@ static ssize_t nullb_device_bool_attr_store(bool *val, const char *page,
 }
 
 /* The following macro should only be used with TYPE = {uint, ulong, bool}. */
-#define NULLB_DEVICE_ATTR(NAME, TYPE, APPLY)                                   \
-static ssize_t                                                                 \
-nullb_device_##NAME##_show(struct config_item *item, char *page)               \
-{                                                                              \
-       return nullb_device_##TYPE##_attr_show(                                 \
-                               to_nullb_device(item)->NAME, page);             \
-}                                                                              \
-static ssize_t                                                                 \
-nullb_device_##NAME##_store(struct config_item *item, const char *page,                \
-                           size_t count)                                       \
-{                                                                              \
-       int (*apply_fn)(struct nullb_device *dev, TYPE new_value) = APPLY;      \
-       struct nullb_device *dev = to_nullb_device(item);                       \
-       TYPE new_value;                                                         \
-       int ret;                                                                \
-                                                                               \
-       ret = nullb_device_##TYPE##_attr_store(&new_value, page, count);        \
-       if (ret < 0)                                                            \
-               return ret;                                                     \
-       if (apply_fn)                                                           \
-               ret = apply_fn(dev, new_value);                                 \
-       else if (test_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags))                \
-               ret = -EBUSY;                                                   \
-       if (ret < 0)                                                            \
-               return ret;                                                     \
-       dev->NAME = new_value;                                                  \
-       return count;                                                           \
-}                                                                              \
+#define NULLB_DEVICE_ATTR(NAME, TYPE, APPLY)                           \
+static ssize_t                                                         \
+nullb_device_##NAME##_show(struct config_item *item, char *page)       \
+{                                                                      \
+       return nullb_device_##TYPE##_attr_show(                         \
+                               to_nullb_device(item)->NAME, page);     \
+}                                                                      \
+static ssize_t                                                         \
+nullb_device_##NAME##_store(struct config_item *item, const char *page,        \
+                           size_t count)                               \
+{                                                                      \
+       int (*apply_fn)(struct nullb_device *dev, TYPE new_value) = APPLY;\
+       struct nullb_device *dev = to_nullb_device(item);               \
+       TYPE uninitialized_var(new_value);                              \
+       int ret;                                                        \
+                                                                       \
+       ret = nullb_device_##TYPE##_attr_store(&new_value, page, count);\
+       if (ret < 0)                                                    \
+               return ret;                                             \
+       if (apply_fn)                                                   \
+               ret = apply_fn(dev, new_value);                         \
+       else if (test_bit(NULLB_DEV_FL_CONFIGURED, &dev->flags))        \
+               ret = -EBUSY;                                           \
+       if (ret < 0)                                                    \
+               return ret;                                             \
+       dev->NAME = new_value;                                          \
+       return count;                                                   \
+}                                                                      \
 CONFIGFS_ATTR(nullb_device_, NAME);
 
 static int nullb_apply_submit_queues(struct nullb_device *dev,
index 2b18456..6343402 100644 (file)
@@ -848,7 +848,7 @@ enum {
        Opt_notrim,
 };
 
-static const struct fs_parameter_spec rbd_param_specs[] = {
+static const struct fs_parameter_spec rbd_parameters[] = {
        fsparam_u32     ("alloc_size",                  Opt_alloc_size),
        fsparam_flag    ("exclusive",                   Opt_exclusive),
        fsparam_flag    ("lock_on_read",                Opt_lock_on_read),
@@ -863,11 +863,6 @@ static const struct fs_parameter_spec rbd_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description rbd_parameters = {
-       .name           = "rbd",
-       .specs          = rbd_param_specs,
-};
-
 struct rbd_options {
        int     queue_depth;
        int     alloc_size;
@@ -2662,7 +2657,7 @@ static int rbd_img_fill_nodata(struct rbd_img_request *img_req,
                               u64 off, u64 len)
 {
        struct ceph_file_extent ex = { off, len };
-       union rbd_img_fill_iter dummy;
+       union rbd_img_fill_iter dummy = {};
        struct rbd_img_fill_ctx fctx = {
                .pos_type = OBJ_REQUEST_NODATA,
                .pos = &dummy,
@@ -6353,19 +6348,19 @@ static int rbd_parse_param(struct fs_parameter *param,
 {
        struct rbd_options *opt = pctx->opts;
        struct fs_parse_result result;
+       struct p_log log = {.prefix = "rbd"};
        int token, ret;
 
        ret = ceph_parse_param(param, pctx->copts, NULL);
        if (ret != -ENOPARAM)
                return ret;
 
-       token = fs_parse(NULL, &rbd_parameters, param, &result);
+       token = __fs_parse(&log, 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);
-               }
+               if (token == -ENOPARAM)
+                       return inval_plog(&log, "Unknown parameter '%s'",
+                                         param->key);
                return token;
        }
 
@@ -6378,9 +6373,8 @@ static int rbd_parse_param(struct fs_parameter *param,
        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");
-               }
+               if (!is_power_of_2(result.uint_32))
+                       return inval_plog(&log, "alloc_size must be a power of 2");
                opt->alloc_size = result.uint_32;
                break;
        case Opt_lock_timeout:
@@ -6416,7 +6410,7 @@ static int rbd_parse_param(struct fs_parameter *param,
        return 0;
 
 out_of_range:
-       return invalf(NULL, "rbd: %s out of range", param->key);
+       return inval_plog(&log, "%s out of range", param->key);
 }
 
 /*
@@ -6433,7 +6427,7 @@ static int rbd_parse_options(char *options, struct rbd_parse_opts_ctx *pctx)
                if (*key) {
                        struct fs_parameter param = {
                                .key    = key,
-                               .type   = fs_value_is_string,
+                               .type   = fs_value_is_flag,
                        };
                        char *value = strchr(key, '=');
                        size_t v_len = 0;
@@ -6443,14 +6437,11 @@ static int rbd_parse_options(char *options, struct rbd_parse_opts_ctx *pctx)
                                        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.type = fs_value_is_string;
                        }
                        param.size = v_len;
 
@@ -7143,7 +7134,7 @@ static ssize_t do_rbd_add(struct bus_type *bus,
        if (rc)
                goto err_out_image_lock;
 
-       add_disk(rbd_dev->disk);
+       device_add_disk(&rbd_dev->dev, rbd_dev->disk, NULL);
        /* see rbd_init_disk() */
        blk_put_queue(rbd_dev->disk->queue);
 
index fbbf18a..5415876 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/virtio_blk.h>
 #include <linux/scatterlist.h>
 #include <linux/string_helpers.h>
-#include <scsi/scsi_cmnd.h>
 #include <linux/idr.h>
 #include <linux/blk-mq.h>
 #include <linux/blk-mq-virtio.h>
@@ -56,11 +55,6 @@ struct virtio_blk {
 };
 
 struct virtblk_req {
-#ifdef CONFIG_VIRTIO_BLK_SCSI
-       struct scsi_request sreq;       /* for SCSI passthrough, must be first */
-       u8 sense[SCSI_SENSE_BUFFERSIZE];
-       struct virtio_scsi_inhdr in_hdr;
-#endif
        struct virtio_blk_outhdr out_hdr;
        u8 status;
        struct scatterlist sg[];
@@ -78,80 +72,6 @@ static inline blk_status_t virtblk_result(struct virtblk_req *vbr)
        }
 }
 
-/*
- * If this is a packet command we need a couple of additional headers.  Behind
- * the normal outhdr we put a segment with the scsi command block, and before
- * the normal inhdr we put the sense data and the inhdr with additional status
- * information.
- */
-#ifdef CONFIG_VIRTIO_BLK_SCSI
-static int virtblk_add_req_scsi(struct virtqueue *vq, struct virtblk_req *vbr,
-               struct scatterlist *data_sg, bool have_data)
-{
-       struct scatterlist hdr, status, cmd, sense, inhdr, *sgs[6];
-       unsigned int num_out = 0, num_in = 0;
-
-       sg_init_one(&hdr, &vbr->out_hdr, sizeof(vbr->out_hdr));
-       sgs[num_out++] = &hdr;
-       sg_init_one(&cmd, vbr->sreq.cmd, vbr->sreq.cmd_len);
-       sgs[num_out++] = &cmd;
-
-       if (have_data) {
-               if (vbr->out_hdr.type & cpu_to_virtio32(vq->vdev, VIRTIO_BLK_T_OUT))
-                       sgs[num_out++] = data_sg;
-               else
-                       sgs[num_out + num_in++] = data_sg;
-       }
-
-       sg_init_one(&sense, vbr->sense, SCSI_SENSE_BUFFERSIZE);
-       sgs[num_out + num_in++] = &sense;
-       sg_init_one(&inhdr, &vbr->in_hdr, sizeof(vbr->in_hdr));
-       sgs[num_out + num_in++] = &inhdr;
-       sg_init_one(&status, &vbr->status, sizeof(vbr->status));
-       sgs[num_out + num_in++] = &status;
-
-       return virtqueue_add_sgs(vq, sgs, num_out, num_in, vbr, GFP_ATOMIC);
-}
-
-static inline void virtblk_scsi_request_done(struct request *req)
-{
-       struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
-       struct virtio_blk *vblk = req->q->queuedata;
-       struct scsi_request *sreq = &vbr->sreq;
-
-       sreq->resid_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.residual);
-       sreq->sense_len = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.sense_len);
-       sreq->result = virtio32_to_cpu(vblk->vdev, vbr->in_hdr.errors);
-}
-
-static int virtblk_ioctl(struct block_device *bdev, fmode_t mode,
-                            unsigned int cmd, unsigned long data)
-{
-       struct gendisk *disk = bdev->bd_disk;
-       struct virtio_blk *vblk = disk->private_data;
-
-       /*
-        * Only allow the generic SCSI ioctls if the host can support it.
-        */
-       if (!virtio_has_feature(vblk->vdev, VIRTIO_BLK_F_SCSI))
-               return -ENOTTY;
-
-       return scsi_cmd_blk_ioctl(bdev, mode, cmd,
-                                 (void __user *)data);
-}
-#else
-static inline int virtblk_add_req_scsi(struct virtqueue *vq,
-               struct virtblk_req *vbr, struct scatterlist *data_sg,
-               bool have_data)
-{
-       return -EIO;
-}
-static inline void virtblk_scsi_request_done(struct request *req)
-{
-}
-#define virtblk_ioctl  NULL
-#endif /* CONFIG_VIRTIO_BLK_SCSI */
-
 static int virtblk_add_req(struct virtqueue *vq, struct virtblk_req *vbr,
                struct scatterlist *data_sg, bool have_data)
 {
@@ -216,13 +136,6 @@ static inline void virtblk_request_done(struct request *req)
                      req->special_vec.bv_offset);
        }
 
-       switch (req_op(req)) {
-       case REQ_OP_SCSI_IN:
-       case REQ_OP_SCSI_OUT:
-               virtblk_scsi_request_done(req);
-               break;
-       }
-
        blk_mq_end_request(req, virtblk_result(vbr));
 }
 
@@ -299,10 +212,6 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
                type = VIRTIO_BLK_T_WRITE_ZEROES;
                unmap = !(req->cmd_flags & REQ_NOUNMAP);
                break;
-       case REQ_OP_SCSI_IN:
-       case REQ_OP_SCSI_OUT:
-               type = VIRTIO_BLK_T_SCSI_CMD;
-               break;
        case REQ_OP_DRV_IN:
                type = VIRTIO_BLK_T_GET_ID;
                break;
@@ -333,10 +242,7 @@ static blk_status_t virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
        }
 
        spin_lock_irqsave(&vblk->vqs[qid].lock, flags);
-       if (blk_rq_is_scsi(req))
-               err = virtblk_add_req_scsi(vblk->vqs[qid].vq, vbr, vbr->sg, num);
-       else
-               err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
+       err = virtblk_add_req(vblk->vqs[qid].vq, vbr, vbr->sg, num);
        if (err) {
                virtqueue_kick(vblk->vqs[qid].vq);
                blk_mq_stop_hw_queue(hctx);
@@ -404,10 +310,6 @@ static int virtblk_getgeo(struct block_device *bd, struct hd_geometry *geo)
 }
 
 static const struct block_device_operations virtblk_fops = {
-       .ioctl  = virtblk_ioctl,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl = blkdev_compat_ptr_ioctl,
-#endif
        .owner  = THIS_MODULE,
        .getgeo = virtblk_getgeo,
 };
@@ -686,9 +588,6 @@ static int virtblk_init_request(struct blk_mq_tag_set *set, struct request *rq,
        struct virtio_blk *vblk = set->driver_data;
        struct virtblk_req *vbr = blk_mq_rq_to_pdu(rq);
 
-#ifdef CONFIG_VIRTIO_BLK_SCSI
-       vbr->sreq.sense = vbr->sense;
-#endif
        sg_init_table(vbr->sg, vblk->sg_elems);
        return 0;
 }
@@ -701,23 +600,11 @@ static int virtblk_map_queues(struct blk_mq_tag_set *set)
                                        vblk->vdev, 0);
 }
 
-#ifdef CONFIG_VIRTIO_BLK_SCSI
-static void virtblk_initialize_rq(struct request *req)
-{
-       struct virtblk_req *vbr = blk_mq_rq_to_pdu(req);
-
-       scsi_req_init(&vbr->sreq);
-}
-#endif
-
 static const struct blk_mq_ops virtio_mq_ops = {
        .queue_rq       = virtio_queue_rq,
        .commit_rqs     = virtio_commit_rqs,
        .complete       = virtblk_request_done,
        .init_request   = virtblk_init_request,
-#ifdef CONFIG_VIRTIO_BLK_SCSI
-       .initialize_rq_fn = virtblk_initialize_rq,
-#endif
        .map_queues     = virtblk_map_queues,
 };
 
@@ -994,9 +881,6 @@ static const struct virtio_device_id id_table[] = {
 static unsigned int features_legacy[] = {
        VIRTIO_BLK_F_SEG_MAX, VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_GEOMETRY,
        VIRTIO_BLK_F_RO, VIRTIO_BLK_F_BLK_SIZE,
-#ifdef CONFIG_VIRTIO_BLK_SCSI
-       VIRTIO_BLK_F_SCSI,
-#endif
        VIRTIO_BLK_F_FLUSH, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_CONFIG_WCE,
        VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_WRITE_ZEROES,
 }
index 716b99a..c2f7126 100644 (file)
@@ -62,8 +62,8 @@
  * IO workloads.
  */
 
-static int xen_blkif_max_buffer_pages = 1024;
-module_param_named(max_buffer_pages, xen_blkif_max_buffer_pages, int, 0644);
+static int max_buffer_pages = 1024;
+module_param_named(max_buffer_pages, max_buffer_pages, int, 0644);
 MODULE_PARM_DESC(max_buffer_pages,
 "Maximum number of free pages to keep in each block backend buffer");
 
@@ -78,8 +78,8 @@ MODULE_PARM_DESC(max_buffer_pages,
  * algorithm.
  */
 
-static int xen_blkif_max_pgrants = 1056;
-module_param_named(max_persistent_grants, xen_blkif_max_pgrants, int, 0644);
+static int max_pgrants = 1056;
+module_param_named(max_persistent_grants, max_pgrants, int, 0644);
 MODULE_PARM_DESC(max_persistent_grants,
                  "Maximum number of grants to map persistently");
 
@@ -88,8 +88,8 @@ MODULE_PARM_DESC(max_persistent_grants,
  * use. The time is in seconds, 0 means indefinitely long.
  */
 
-static unsigned int xen_blkif_pgrant_timeout = 60;
-module_param_named(persistent_grant_unused_seconds, xen_blkif_pgrant_timeout,
+static unsigned int pgrant_timeout = 60;
+module_param_named(persistent_grant_unused_seconds, pgrant_timeout,
                   uint, 0644);
 MODULE_PARM_DESC(persistent_grant_unused_seconds,
                 "Time in seconds an unused persistent grant is allowed to "
@@ -137,9 +137,8 @@ module_param(log_stats, int, 0644);
 
 static inline bool persistent_gnt_timeout(struct persistent_gnt *persistent_gnt)
 {
-       return xen_blkif_pgrant_timeout &&
-              (jiffies - persistent_gnt->last_used >=
-               HZ * xen_blkif_pgrant_timeout);
+       return pgrant_timeout && (jiffies - persistent_gnt->last_used >=
+                       HZ * pgrant_timeout);
 }
 
 static inline int get_free_page(struct xen_blkif_ring *ring, struct page **page)
@@ -234,7 +233,7 @@ static int add_persistent_gnt(struct xen_blkif_ring *ring,
        struct persistent_gnt *this;
        struct xen_blkif *blkif = ring->blkif;
 
-       if (ring->persistent_gnt_c >= xen_blkif_max_pgrants) {
+       if (ring->persistent_gnt_c >= max_pgrants) {
                if (!blkif->vbd.overflow_max_grants)
                        blkif->vbd.overflow_max_grants = 1;
                return -EBUSY;
@@ -397,14 +396,13 @@ static void purge_persistent_gnt(struct xen_blkif_ring *ring)
                goto out;
        }
 
-       if (ring->persistent_gnt_c < xen_blkif_max_pgrants ||
-           (ring->persistent_gnt_c == xen_blkif_max_pgrants &&
+       if (ring->persistent_gnt_c < max_pgrants ||
+           (ring->persistent_gnt_c == max_pgrants &&
            !ring->blkif->vbd.overflow_max_grants)) {
                num_clean = 0;
        } else {
-               num_clean = (xen_blkif_max_pgrants / 100) * LRU_PERCENT_CLEAN;
-               num_clean = ring->persistent_gnt_c - xen_blkif_max_pgrants +
-                           num_clean;
+               num_clean = (max_pgrants / 100) * LRU_PERCENT_CLEAN;
+               num_clean = ring->persistent_gnt_c - max_pgrants + num_clean;
                num_clean = min(ring->persistent_gnt_c, num_clean);
                pr_debug("Going to purge at least %u persistent grants\n",
                         num_clean);
@@ -599,8 +597,7 @@ static void print_stats(struct xen_blkif_ring *ring)
                 current->comm, ring->st_oo_req,
                 ring->st_rd_req, ring->st_wr_req,
                 ring->st_f_req, ring->st_ds_req,
-                ring->persistent_gnt_c,
-                xen_blkif_max_pgrants);
+                ring->persistent_gnt_c, max_pgrants);
        ring->st_print = jiffies + msecs_to_jiffies(10 * 1000);
        ring->st_rd_req = 0;
        ring->st_wr_req = 0;
@@ -656,8 +653,11 @@ purge_gnt_list:
                        ring->next_lru = jiffies + msecs_to_jiffies(LRU_INTERVAL);
                }
 
-               /* Shrink if we have more than xen_blkif_max_buffer_pages */
-               shrink_free_pagepool(ring, xen_blkif_max_buffer_pages);
+               /* Shrink the free pages pool if it is too large. */
+               if (time_before(jiffies, blkif->buffer_squeeze_end))
+                       shrink_free_pagepool(ring, 0);
+               else
+                       shrink_free_pagepool(ring, max_buffer_pages);
 
                if (log_stats && time_after(jiffies, ring->st_print))
                        print_stats(ring);
@@ -884,7 +884,7 @@ again:
                        continue;
                }
                if (use_persistent_gnts &&
-                   ring->persistent_gnt_c < xen_blkif_max_pgrants) {
+                   ring->persistent_gnt_c < max_pgrants) {
                        /*
                         * We are using persistent grants, the grant is
                         * not mapped but we might have room for it.
@@ -911,7 +911,7 @@ again:
                        pages[seg_idx]->persistent_gnt = persistent_gnt;
                        pr_debug("grant %u added to the tree of persistent grants, using %u/%u\n",
                                 persistent_gnt->gnt, ring->persistent_gnt_c,
-                                xen_blkif_max_pgrants);
+                                max_pgrants);
                        goto next;
                }
                if (use_persistent_gnts && !blkif->vbd.overflow_max_grants) {
index 49132b0..a3eeccf 100644 (file)
@@ -319,6 +319,7 @@ struct xen_blkif {
        /* All rings for this device. */
        struct xen_blkif_ring   *rings;
        unsigned int            nr_rings;
+       unsigned long           buffer_squeeze_end;
 };
 
 struct seg_buf {
index 4c5d99f..42944d4 100644 (file)
@@ -467,7 +467,6 @@ static void xenvbd_sysfs_delif(struct xenbus_device *dev)
        device_remove_file(&dev->dev, &dev_attr_physical_device);
 }
 
-
 static void xen_vbd_free(struct xen_vbd *vbd)
 {
        if (vbd->bdev)
@@ -524,6 +523,7 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
                handle, blkif->domid);
        return 0;
 }
+
 static int xen_blkbk_remove(struct xenbus_device *dev)
 {
        struct backend_info *be = dev_get_drvdata(&dev->dev);
@@ -607,6 +607,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info
        if (err)
                dev_warn(&dev->dev, "writing feature-discard (%d)", err);
 }
+
 int xen_blkbk_barrier(struct xenbus_transaction xbt,
                      struct backend_info *be, int state)
 {
@@ -691,7 +692,6 @@ fail:
        return err;
 }
 
-
 /*
  * Callback received when the hotplug scripts have placed the physical-device
  * node.  Read it and the mode node, and create a vbd.  If the frontend is
@@ -783,7 +783,6 @@ static void backend_changed(struct xenbus_watch *watch,
        }
 }
 
-
 /*
  * Callback received when the frontend's state changes.
  */
@@ -858,9 +857,27 @@ static void frontend_changed(struct xenbus_device *dev,
        }
 }
 
+/* Once a memory pressure is detected, squeeze free page pools for a while. */
+static unsigned int buffer_squeeze_duration_ms = 10;
+module_param_named(buffer_squeeze_duration_ms,
+               buffer_squeeze_duration_ms, int, 0644);
+MODULE_PARM_DESC(buffer_squeeze_duration_ms,
+"Duration in ms to squeeze pages buffer when a memory pressure is detected");
 
-/* ** Connection ** */
+/*
+ * Callback received when the memory pressure is detected.
+ */
+static void reclaim_memory(struct xenbus_device *dev)
+{
+       struct backend_info *be = dev_get_drvdata(&dev->dev);
 
+       if (!be)
+               return;
+       be->blkif->buffer_squeeze_end = jiffies +
+               msecs_to_jiffies(buffer_squeeze_duration_ms);
+}
+
+/* ** Connection ** */
 
 /*
  * Write the physical details regarding the block device to the store, and
@@ -1152,6 +1169,7 @@ static struct xenbus_driver xen_blkbk_driver = {
        .remove = xen_blkbk_remove,
        .otherend_changed = frontend_changed,
        .allow_rebind = true,
+       .reclaim_memory = reclaim_memory,
 };
 
 int xen_blkif_xenbus_init(void)
index 57d50c5..e2ad6bb 100644 (file)
@@ -151,9 +151,6 @@ MODULE_PARM_DESC(max_ring_page_order, "Maximum order of pages to be used for the
 #define BLK_RING_SIZE(info)    \
        __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * (info)->nr_ring_pages)
 
-#define BLK_MAX_RING_SIZE      \
-       __CONST_RING_SIZE(blkif, XEN_PAGE_SIZE * XENBUS_MAX_RING_GRANTS)
-
 /*
  * ring-ref%u i=(-1UL) would take 11 characters + 'ring-ref' is 8, so 19
  * characters are enough. Define to 20 to keep consistent with backend.
@@ -177,12 +174,12 @@ struct blkfront_ring_info {
        unsigned int evtchn, irq;
        struct work_struct work;
        struct gnttab_free_callback callback;
-       struct blk_shadow shadow[BLK_MAX_RING_SIZE];
        struct list_head indirect_pages;
        struct list_head grants;
        unsigned int persistent_gnts_c;
        unsigned long shadow_free;
        struct blkfront_info *dev_info;
+       struct blk_shadow shadow[];
 };
 
 /*
@@ -1915,7 +1912,8 @@ static int negotiate_mq(struct blkfront_info *info)
                info->nr_rings = 1;
 
        info->rinfo = kvcalloc(info->nr_rings,
-                              sizeof(struct blkfront_ring_info),
+                              struct_size(info->rinfo, shadow,
+                                          BLK_RING_SIZE(info)),
                               GFP_KERNEL);
        if (!info->rinfo) {
                xenbus_dev_fatal(info->xbdev, -ENOMEM, "allocating ring_info structure");
index 50200d1..6095b6d 100644 (file)
@@ -139,7 +139,6 @@ config TEGRA_ACONNECT
        tristate "Tegra ACONNECT Bus Driver"
        depends on ARCH_TEGRA_210_SOC
        depends on OF && PM
-       select PM_CLK
        help
          Driver for the Tegra ACONNECT bus which is used to interface with
          the devices inside the Audio Processing Engine (APE) for Tegra210.
index 36cf13e..15fa293 100644 (file)
@@ -102,12 +102,11 @@ static int moxtet_match(struct device *dev, struct device_driver *drv)
        return 0;
 }
 
-struct bus_type moxtet_bus_type = {
+static struct bus_type moxtet_bus_type = {
        .name           = "moxtet",
        .dev_groups     = moxtet_dev_groups,
        .match          = moxtet_match,
 };
-EXPORT_SYMBOL_GPL(moxtet_bus_type);
 
 int __moxtet_register_driver(struct module *owner,
                             struct moxtet_driver *mdrv)
index ccb44fe..f702c85 100644 (file)
@@ -479,7 +479,7 @@ static void sysc_clkdm_deny_idle(struct sysc *ddata)
 {
        struct ti_sysc_platform_data *pdata;
 
-       if (ddata->legacy_mode)
+       if (ddata->legacy_mode || (ddata->cfg.quirks & SYSC_QUIRK_CLKDM_NOAUTO))
                return;
 
        pdata = dev_get_platdata(ddata->dev);
@@ -491,7 +491,7 @@ static void sysc_clkdm_allow_idle(struct sysc *ddata)
 {
        struct ti_sysc_platform_data *pdata;
 
-       if (ddata->legacy_mode)
+       if (ddata->legacy_mode || (ddata->cfg.quirks & SYSC_QUIRK_CLKDM_NOAUTO))
                return;
 
        pdata = dev_get_platdata(ddata->dev);
@@ -509,10 +509,8 @@ static int sysc_init_resets(struct sysc *ddata)
 {
        ddata->rsts =
                devm_reset_control_get_optional_shared(ddata->dev, "rstctrl");
-       if (IS_ERR(ddata->rsts))
-               return PTR_ERR(ddata->rsts);
 
-       return 0;
+       return PTR_ERR_OR_ZERO(ddata->rsts);
 }
 
 /**
@@ -1216,10 +1214,6 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        /* These drivers need to be fixed to not use pm_runtime_irq_safe() */
        SYSC_QUIRK("gpio", 0, 0, 0x10, 0x114, 0x50600801, 0xffff00ff,
                   SYSC_QUIRK_LEGACY_IDLE | SYSC_QUIRK_OPT_CLKS_IN_RESET),
-       SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000020, 0xffffffff,
-                  SYSC_QUIRK_LEGACY_IDLE),
-       SYSC_QUIRK("mmu", 0, 0, 0x10, 0x14, 0x00000030, 0xffffffff,
-                  SYSC_QUIRK_LEGACY_IDLE),
        SYSC_QUIRK("sham", 0, 0x100, 0x110, 0x114, 0x40000c03, 0xffffffff,
                   SYSC_QUIRK_LEGACY_IDLE),
        SYSC_QUIRK("smartreflex", 0, -1, 0x24, -1, 0x00000000, 0xffffffff,
@@ -1251,6 +1245,12 @@ static const struct sysc_revision_quirk sysc_revision_quirks[] = {
        /* 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("dcan", 0x48480000, 0x20, -1, -1, 0xa3170504, 0xffffffff,
+                  SYSC_QUIRK_CLKDM_NOAUTO),
+       SYSC_QUIRK("dwc3", 0x48880000, 0, 0x10, -1, 0x500a0200, 0xffffffff,
+                  SYSC_QUIRK_CLKDM_NOAUTO),
+       SYSC_QUIRK("dwc3", 0x488c0000, 0, 0x10, -1, 0x500a0200, 0xffffffff,
+                  SYSC_QUIRK_CLKDM_NOAUTO),
        SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x00000006, 0xffffffff,
                   SYSC_MODULE_QUIRK_HDQ1W),
        SYSC_QUIRK("hdq1w", 0, 0, 0x14, 0x18, 0x0000000a, 0xffffffff,
index aed2c45..ed3b7da 100644 (file)
@@ -855,7 +855,7 @@ int hpet_alloc(struct hpet_data *hdp)
                return 0;
        }
 
-       hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs - 1),
+       hpetp = kzalloc(struct_size(hpetp, hp_dev, hdp->hd_nirqs),
                        GFP_KERNEL);
 
        if (!hpetp)
index d2a5791..cbf5eae 100644 (file)
@@ -157,7 +157,7 @@ static int bcm2835_rng_probe(struct platform_device *pdev)
 
        /* Clock is optional on most platforms */
        priv->clk = devm_clk_get(dev, NULL);
-       if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER)
+       if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
        priv->rng.name = pdev->name;
index 0ed07d1..6595239 100644 (file)
@@ -476,7 +476,7 @@ static int omap_rng_probe(struct platform_device *pdev)
        }
 
        priv->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(priv->clk) && PTR_ERR(priv->clk) == -EPROBE_DEFER)
+       if (PTR_ERR(priv->clk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
        if (!IS_ERR(priv->clk)) {
                ret = clk_prepare_enable(priv->clk);
@@ -488,7 +488,7 @@ static int omap_rng_probe(struct platform_device *pdev)
        }
 
        priv->clk_reg = devm_clk_get(&pdev->dev, "reg");
-       if (IS_ERR(priv->clk_reg) && PTR_ERR(priv->clk_reg) == -EPROBE_DEFER)
+       if (PTR_ERR(priv->clk_reg) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
        if (!IS_ERR(priv->clk_reg)) {
                ret = clk_prepare_enable(priv->clk_reg);
index 45653a0..bcb257b 100644 (file)
@@ -27,7 +27,7 @@ config COMMON_CLK_WM831X
        tristate "Clock driver for WM831x/2x PMICs"
        depends on MFD_WM831X
        ---help---
-          Supports the clocking subsystem of the WM831x/2x series of
+         Supports the clocking subsystem of the WM831x/2x series of
          PMICs from Wolfson Microelectronics.
 
 source "drivers/clk/versatile/Kconfig"
@@ -174,6 +174,18 @@ config COMMON_CLK_CS2000_CP
        help
          If you say yes here you get support for the CS2000 clock multiplier.
 
+config COMMON_CLK_FSL_SAI
+       bool "Clock driver for BCLK of Freescale SAI cores"
+       depends on ARCH_LAYERSCAPE || COMPILE_TEST
+       help
+         This driver supports the Freescale SAI (Synchronous Audio Interface)
+         to be used as a generic clock output. Some SoCs have restrictions
+         regarding the possible pin multiplexer settings. Eg. on some SoCs
+         two SAI interfaces can only be enabled together. If just one is
+         needed, the BCLK pin of the second one can be used as general
+         purpose clock output. Ideally, it can be used to drive an audio
+         codec (sometimes known as MCLK).
+
 config COMMON_CLK_GEMINI
        bool "Clock driver for Cortina Systems Gemini SoC"
        depends on ARCH_GEMINI || COMPILE_TEST
@@ -225,6 +237,16 @@ config CLK_QORIQ
          This adds the clock driver support for Freescale QorIQ platforms
          using common clock framework.
 
+config CLK_LS1028A_PLLDIG
+        tristate "Clock driver for LS1028A Display output"
+        depends on ARCH_LAYERSCAPE || COMPILE_TEST
+        default ARCH_LAYERSCAPE
+        help
+          This driver support the Display output interfaces(LCD, DPHY) pixel clocks
+          of the QorIQ Layerscape LS1028A, as implemented TSMC CLN28HPM PLL. Not all
+          features of the PLL are currently supported by the driver. By default,
+          configured bypass mode with this PLL.
+
 config COMMON_CLK_XGENE
        bool "Clock driver for APM XGene SoC"
        default ARCH_XGENE
@@ -305,10 +327,10 @@ config COMMON_CLK_MMP2
          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
+       tristate "Clock driver for 32K clk gates on ROHM PMICs"
+       depends on MFD_ROHM_BD718XX || MFD_ROHM_BD70528 || MFD_ROHM_BD71828
        help
-         This driver supports ROHM BD71837, ROHM BD71847 and
+         This driver supports ROHM BD71837, ROHM BD71847, ROHM BD71828 and
          ROHM BD70528 PMICs clock gates.
 
 config COMMON_CLK_FIXED_MMIO
index 0696a0c..f4169cc 100644 (file)
@@ -29,6 +29,7 @@ obj-$(CONFIG_ARCH_CLPS711X)           += clk-clps711x.o
 obj-$(CONFIG_COMMON_CLK_CS2000_CP)     += clk-cs2000-cp.o
 obj-$(CONFIG_ARCH_EFM32)               += clk-efm32gg.o
 obj-$(CONFIG_COMMON_CLK_FIXED_MMIO)    += clk-fixed-mmio.o
+obj-$(CONFIG_COMMON_CLK_FSL_SAI)       += clk-fsl-sai.o
 obj-$(CONFIG_COMMON_CLK_GEMINI)                += clk-gemini.o
 obj-$(CONFIG_COMMON_CLK_ASPEED)                += clk-aspeed.o
 obj-$(CONFIG_MACH_ASPEED_G6)           += clk-ast2600.o
@@ -44,6 +45,7 @@ obj-$(CONFIG_ARCH_NPCM7XX)            += clk-npcm7xx.o
 obj-$(CONFIG_ARCH_NSPIRE)              += clk-nspire.o
 obj-$(CONFIG_COMMON_CLK_OXNAS)         += clk-oxnas.o
 obj-$(CONFIG_COMMON_CLK_PALMAS)                += clk-palmas.o
+obj-$(CONFIG_CLK_LS1028A_PLLDIG)       += clk-plldig.o
 obj-$(CONFIG_COMMON_CLK_PWM)           += clk-pwm.o
 obj-$(CONFIG_CLK_QORIQ)                        += clk-qoriq.o
 obj-$(CONFIG_COMMON_CLK_RK808)         += clk-rk808.o
index 34b8178..dfb354a 100644 (file)
@@ -25,7 +25,8 @@
 #define                PMC_PLL_CTRL1_MUL_MSK           GENMASK(30, 24)
 
 #define PMC_PLL_ACR    0x18
-#define                PMC_PLL_ACR_DEFAULT             0x1b040010UL
+#define                PMC_PLL_ACR_DEFAULT_UPLL        0x12020010UL
+#define                PMC_PLL_ACR_DEFAULT_PLLA        0x00020010UL
 #define                PMC_PLL_ACR_UTMIVR              BIT(12)
 #define                PMC_PLL_ACR_UTMIBG              BIT(13)
 #define                PMC_PLL_ACR_LOOP_FILTER_MSK     GENMASK(31, 24)
@@ -88,7 +89,10 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
        }
 
        /* Recommended value for PMC_PLL_ACR */
-       val = PMC_PLL_ACR_DEFAULT;
+       if (pll->characteristics->upll)
+               val = PMC_PLL_ACR_DEFAULT_UPLL;
+       else
+               val = PMC_PLL_ACR_DEFAULT_PLLA;
        regmap_write(regmap, PMC_PLL_ACR, val);
 
        regmap_write(regmap, PMC_PLL_CTRL1,
index 86238d5..77398ae 100644 (file)
@@ -47,6 +47,7 @@ static const struct clk_programmable_layout sam9x60_programmable_layout = {
        .pres_shift = 8,
        .css_mask = 0x1f,
        .have_slck_mck = 0,
+       .is_pres_direct = 1,
 };
 
 static const struct clk_pcr_layout sam9x60_pcr_layout = {
index dd0f90c..536b59a 100644 (file)
@@ -260,7 +260,6 @@ static void __init asm9260_acc_init(struct device_node *np)
        const char *ref_clk, *pll_clk = "pll";
        u32 rate;
        int n;
-       u32 accuracy = 0;
 
        clk_data = kzalloc(struct_size(clk_data, hws, MAX_CLKS), GFP_KERNEL);
        if (!clk_data)
@@ -275,10 +274,11 @@ static void __init asm9260_acc_init(struct device_node *np)
        /* register pll */
        rate = (ioread32(base + HW_SYSPLLCTRL) & 0xffff) * 1000000;
 
+       /* TODO: Convert to DT parent scheme */
        ref_clk = of_clk_get_parent_name(np, 0);
-       accuracy = clk_get_accuracy(__clk_lookup(ref_clk));
-       hw = clk_hw_register_fixed_rate_with_accuracy(NULL, pll_clk,
-                       ref_clk, 0, rate, accuracy);
+       hw = __clk_hw_register_fixed_rate_with_accuracy(NULL, NULL, pll_clk,
+                       ref_clk, NULL, NULL, 0, rate, 0,
+                       CLK_FIXED_RATE_PARENT_ACCURACY);
 
        if (IS_ERR(hw))
                panic("%pOFn: can't register REFCLK. Check DT!", np);
index 00926c5..b52e8d6 100644 (file)
@@ -7,12 +7,25 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/mfd/rohm-bd718x7.h>
-#include <linux/mfd/rohm-bd70528.h>
+#include <linux/mfd/rohm-generic.h>
 #include <linux/clk-provider.h>
 #include <linux/clkdev.h>
 #include <linux/regmap.h>
 
+/* clk control registers */
+/* BD70528 */
+#define BD70528_REG_OUT32K     0x2c
+/* BD71828 */
+#define BD71828_REG_OUT32K     0x4B
+/* BD71837 and BD71847 */
+#define BD718XX_REG_OUT32K     0x2E
+
+/*
+ * BD71837, BD71847, BD70528 and BD71828 all use bit [0] to clk output control
+ */
+#define CLK_OUT_EN_MASK                BIT(0)
+
+
 struct bd718xx_clk {
        struct clk_hw hw;
        u8 reg;
@@ -21,10 +34,8 @@ struct bd718xx_clk {
        struct rohm_regmap_dev *mfd;
 };
 
-static int bd71837_clk_set(struct clk_hw *hw, int status)
+static int bd71837_clk_set(struct bd718xx_clk *c, unsigned int status)
 {
-       struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
-
        return regmap_update_bits(c->mfd->regmap, c->reg, c->mask, status);
 }
 
@@ -33,14 +44,16 @@ static void bd71837_clk_disable(struct clk_hw *hw)
        int rv;
        struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
 
-       rv = bd71837_clk_set(hw, 0);
+       rv = bd71837_clk_set(c, 0);
        if (rv)
                dev_dbg(&c->pdev->dev, "Failed to disable 32K clk (%d)\n", rv);
 }
 
 static int bd71837_clk_enable(struct clk_hw *hw)
 {
-       return bd71837_clk_set(hw, 1);
+       struct bd718xx_clk *c = container_of(hw, struct bd718xx_clk, hw);
+
+       return bd71837_clk_set(c, 0xffffffff);
 }
 
 static int bd71837_clk_is_enabled(struct clk_hw *hw)
@@ -74,6 +87,7 @@ static int bd71837_clk_probe(struct platform_device *pdev)
                .name = "bd718xx-32k-out",
                .ops = &bd71837_clk_ops,
        };
+       enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
 
        c = devm_kzalloc(&pdev->dev, sizeof(*c), GFP_KERNEL);
        if (!c)
@@ -87,15 +101,19 @@ static int bd71837_clk_probe(struct platform_device *pdev)
                dev_err(&pdev->dev, "No parent clk found\n");
                return -EINVAL;
        }
-       switch (mfd->chip_type) {
+       switch (chip) {
        case ROHM_CHIP_TYPE_BD71837:
        case ROHM_CHIP_TYPE_BD71847:
                c->reg = BD718XX_REG_OUT32K;
-               c->mask = BD718XX_OUT32K_EN;
+               c->mask = CLK_OUT_EN_MASK;
+               break;
+       case ROHM_CHIP_TYPE_BD71828:
+               c->reg = BD71828_REG_OUT32K;
+               c->mask = CLK_OUT_EN_MASK;
                break;
        case ROHM_CHIP_TYPE_BD70528:
-               c->reg = BD70528_REG_CLK_OUT;
-               c->mask = BD70528_CLK_OUT_EN_MASK;
+               c->reg = BD70528_REG_OUT32K;
+               c->mask = CLK_OUT_EN_MASK;
                break;
        default:
                dev_err(&pdev->dev, "Unknown clk chip\n");
@@ -121,11 +139,21 @@ static int bd71837_clk_probe(struct platform_device *pdev)
        return rval;
 }
 
+static const struct platform_device_id bd718x7_clk_id[] = {
+       { "bd71837-clk", ROHM_CHIP_TYPE_BD71837 },
+       { "bd71847-clk", ROHM_CHIP_TYPE_BD71847 },
+       { "bd70528-clk", ROHM_CHIP_TYPE_BD70528 },
+       { "bd71828-clk", ROHM_CHIP_TYPE_BD71828 },
+       { },
+};
+MODULE_DEVICE_TABLE(platform, bd718x7_clk_id);
+
 static struct platform_driver bd71837_clk = {
        .driver = {
                .name = "bd718xx-clk",
        },
        .probe = bd71837_clk_probe,
+       .id_table = bd718x7_clk_id,
 };
 
 module_platform_driver(bd71837_clk);
index 4cd175a..e6d6599 100644 (file)
@@ -474,11 +474,10 @@ static struct bm1880_composite_clock bm1880_composite_clks[] = {
 static unsigned long bm1880_pll_rate_calc(u32 regval, unsigned long parent_rate)
 {
        u64 numerator;
-       u32 fbdiv, fref, refdiv;
+       u32 fbdiv, refdiv;
        u32 postdiv1, postdiv2, denominator;
 
        fbdiv = (regval >> 16) & 0xfff;
-       fref = parent_rate;
        refdiv = regval & 0x1f;
        postdiv1 = (regval >> 8) & 0x7;
        postdiv2 = (regval >> 12) & 0x7;
index 3e9c3e6..7376f57 100644 (file)
@@ -199,8 +199,9 @@ static void clk_composite_disable(struct clk_hw *hw)
        gate_ops->disable(gate_hw);
 }
 
-struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
-                       const char * const *parent_names, int num_parents,
+static struct clk_hw *__clk_hw_register_composite(struct device *dev,
+                       const char *name, const char * const *parent_names,
+                       const struct clk_parent_data *pdata, int num_parents,
                        struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
                        struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
                        struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
@@ -218,7 +219,10 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
 
        init.name = name;
        init.flags = flags;
-       init.parent_names = parent_names;
+       if (parent_names)
+               init.parent_names = parent_names;
+       else
+               init.parent_data = pdata;
        init.num_parents = num_parents;
        hw = &composite->hw;
 
@@ -312,6 +316,34 @@ err:
        return hw;
 }
 
+struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
+                       const char * const *parent_names, int num_parents,
+                       struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+                       struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+                       struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+                       unsigned long flags)
+{
+       return __clk_hw_register_composite(dev, name, parent_names, NULL,
+                                          num_parents, mux_hw, mux_ops,
+                                          rate_hw, rate_ops, gate_hw,
+                                          gate_ops, flags);
+}
+
+struct clk_hw *clk_hw_register_composite_pdata(struct device *dev,
+                       const char *name,
+                       const struct clk_parent_data *parent_data,
+                       int num_parents,
+                       struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+                       struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+                       struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+                       unsigned long flags)
+{
+       return __clk_hw_register_composite(dev, name, NULL, parent_data,
+                                          num_parents, mux_hw, mux_ops,
+                                          rate_hw, rate_ops, gate_hw,
+                                          gate_ops, flags);
+}
+
 struct clk *clk_register_composite(struct device *dev, const char *name,
                        const char * const *parent_names, int num_parents,
                        struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
@@ -329,6 +361,24 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
        return hw->clk;
 }
 
+struct clk *clk_register_composite_pdata(struct device *dev, const char *name,
+                       const struct clk_parent_data *parent_data,
+                       int num_parents,
+                       struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+                       struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+                       struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+                       unsigned long flags)
+{
+       struct clk_hw *hw;
+
+       hw = clk_hw_register_composite_pdata(dev, name, parent_data,
+                       num_parents, mux_hw, mux_ops, rate_hw, rate_ops,
+                       gate_hw, gate_ops, flags);
+       if (IS_ERR(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
+}
+
 void clk_unregister_composite(struct clk *clk)
 {
        struct clk_composite *composite;
index 098b2b0..8de12cb 100644 (file)
@@ -463,11 +463,12 @@ const struct clk_ops clk_divider_ro_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_divider_ro_ops);
 
-static struct clk_hw *_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, const struct clk_div_table *table,
-               spinlock_t *lock)
+struct clk_hw *__clk_hw_register_divider(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags,
+               const struct clk_div_table *table, spinlock_t *lock)
 {
        struct clk_divider *div;
        struct clk_hw *hw;
@@ -514,55 +515,7 @@ static struct clk_hw *_register_divider(struct device *dev, const char *name,
 
        return hw;
 }
-
-/**
- * clk_register_divider - register a divider clock with the clock framework
- * @dev: device registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @reg: register address to adjust divider
- * @shift: number of bits to shift the bitfield
- * @width: width of the bitfield
- * @clk_divider_flags: divider-specific flags for this clock
- * @lock: shared register lock for this clock
- */
-struct clk *clk_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, spinlock_t *lock)
-{
-       struct clk_hw *hw;
-
-       hw =  _register_divider(dev, name, parent_name, flags, reg, shift,
-                       width, clk_divider_flags, NULL, lock);
-       if (IS_ERR(hw))
-               return ERR_CAST(hw);
-       return hw->clk;
-}
-EXPORT_SYMBOL_GPL(clk_register_divider);
-
-/**
- * clk_hw_register_divider - register a divider clock with the clock framework
- * @dev: device registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @reg: register address to adjust divider
- * @shift: number of bits to shift the bitfield
- * @width: width of the bitfield
- * @clk_divider_flags: divider-specific flags for this clock
- * @lock: shared register lock for this clock
- */
-struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, spinlock_t *lock)
-{
-       return _register_divider(dev, name, parent_name, flags, reg, shift,
-                       width, clk_divider_flags, NULL, lock);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_divider);
+EXPORT_SYMBOL_GPL(__clk_hw_register_divider);
 
 /**
  * clk_register_divider_table - register a table based divider clock with
@@ -586,39 +539,15 @@ struct clk *clk_register_divider_table(struct device *dev, const char *name,
 {
        struct clk_hw *hw;
 
-       hw =  _register_divider(dev, name, parent_name, flags, reg, shift,
-                       width, clk_divider_flags, table, lock);
+       hw =  __clk_hw_register_divider(dev, NULL, name, parent_name, NULL,
+                       NULL, flags, reg, shift, width, clk_divider_flags,
+                       table, lock);
        if (IS_ERR(hw))
                return ERR_CAST(hw);
        return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_divider_table);
 
-/**
- * clk_hw_register_divider_table - register a table based divider clock with
- * the clock framework
- * @dev: device registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @reg: register address to adjust divider
- * @shift: number of bits to shift the bitfield
- * @width: width of the bitfield
- * @clk_divider_flags: divider-specific flags for this clock
- * @table: array of divider/value pairs ending with a div set to 0
- * @lock: shared register lock for this clock
- */
-struct clk_hw *clk_hw_register_divider_table(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, const struct clk_div_table *table,
-               spinlock_t *lock)
-{
-       return _register_divider(dev, name, parent_name, flags, reg, shift,
-                       width, clk_divider_flags, table, lock);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_divider_table);
-
 void clk_unregister_divider(struct clk *clk)
 {
        struct clk_divider *div;
index 2c4486c..77499a2 100644 (file)
@@ -24,6 +24,8 @@
  * parent - fixed parent.  No clk_set_parent support
  */
 
+#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
+
 static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
                unsigned long parent_rate)
 {
@@ -33,7 +35,12 @@ static unsigned long clk_fixed_rate_recalc_rate(struct clk_hw *hw,
 static unsigned long clk_fixed_rate_recalc_accuracy(struct clk_hw *hw,
                unsigned long parent_accuracy)
 {
-       return to_clk_fixed_rate(hw)->fixed_accuracy;
+       struct clk_fixed_rate *fixed = to_clk_fixed_rate(hw);
+
+       if (fixed->flags & CLK_FIXED_RATE_PARENT_ACCURACY)
+               return parent_accuracy;
+
+       return fixed->fixed_accuracy;
 }
 
 const struct clk_ops clk_fixed_rate_ops = {
@@ -42,24 +49,17 @@ const struct clk_ops clk_fixed_rate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_fixed_rate_ops);
 
-/**
- * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
- * the clock framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @fixed_rate: non-adjustable clock rate
- * @fixed_accuracy: non-adjustable clock rate
- */
-struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate, unsigned long fixed_accuracy)
+struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data, unsigned long flags,
+               unsigned long fixed_rate, unsigned long fixed_accuracy,
+               unsigned long clk_fixed_flags)
 {
        struct clk_fixed_rate *fixed;
        struct clk_hw *hw;
        struct clk_init_data init = {};
-       int ret;
+       int ret = -EINVAL;
 
        /* allocate fixed-rate clock */
        fixed = kzalloc(sizeof(*fixed), GFP_KERNEL);
@@ -69,17 +69,26 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
        init.name = name;
        init.ops = &clk_fixed_rate_ops;
        init.flags = flags;
-       init.parent_names = (parent_name ? &parent_name: NULL);
-       init.num_parents = (parent_name ? 1 : 0);
+       init.parent_names = parent_name ? &parent_name : NULL;
+       init.parent_hws = parent_hw ? &parent_hw : NULL;
+       init.parent_data = parent_data;
+       if (parent_name || parent_hw || parent_data)
+               init.num_parents = 1;
+       else
+               init.num_parents = 0;
 
        /* struct clk_fixed_rate assignments */
+       fixed->flags = clk_fixed_flags;
        fixed->fixed_rate = fixed_rate;
        fixed->fixed_accuracy = fixed_accuracy;
        fixed->hw.init = &init;
 
        /* register the clock */
        hw = &fixed->hw;
-       ret = clk_hw_register(dev, hw);
+       if (dev || !np)
+               ret = clk_hw_register(dev, hw);
+       else if (np)
+               ret = of_clk_hw_register(np, hw);
        if (ret) {
                kfree(fixed);
                hw = ERR_PTR(ret);
@@ -87,47 +96,20 @@ struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
 
        return hw;
 }
-EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate_with_accuracy);
+EXPORT_SYMBOL_GPL(__clk_hw_register_fixed_rate);
 
-struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate, unsigned long fixed_accuracy)
+struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
+               const char *parent_name, unsigned long flags,
+               unsigned long fixed_rate)
 {
        struct clk_hw *hw;
 
        hw = clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
-                       flags, fixed_rate, fixed_accuracy);
+                                                     flags, fixed_rate, 0);
        if (IS_ERR(hw))
                return ERR_CAST(hw);
        return hw->clk;
 }
-EXPORT_SYMBOL_GPL(clk_register_fixed_rate_with_accuracy);
-
-/**
- * clk_hw_register_fixed_rate - register fixed-rate clock with the clock
- * framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_name: name of clock's parent
- * @flags: framework-specific flags
- * @fixed_rate: non-adjustable clock rate
- */
-struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate)
-{
-       return clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,
-                                                    flags, fixed_rate, 0);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_fixed_rate);
-
-struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate)
-{
-       return clk_register_fixed_rate_with_accuracy(dev, name, parent_name,
-                                                    flags, fixed_rate, 0);
-}
 EXPORT_SYMBOL_GPL(clk_register_fixed_rate);
 
 void clk_unregister_fixed_rate(struct clk *clk)
@@ -155,9 +137,9 @@ void clk_hw_unregister_fixed_rate(struct clk_hw *hw)
 EXPORT_SYMBOL_GPL(clk_hw_unregister_fixed_rate);
 
 #ifdef CONFIG_OF
-static struct clk *_of_fixed_clk_setup(struct device_node *node)
+static struct clk_hw *_of_fixed_clk_setup(struct device_node *node)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
        const char *clk_name = node->name;
        u32 rate;
        u32 accuracy = 0;
@@ -170,18 +152,18 @@ static struct clk *_of_fixed_clk_setup(struct device_node *node)
 
        of_property_read_string(node, "clock-output-names", &clk_name);
 
-       clk = clk_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
+       hw = clk_hw_register_fixed_rate_with_accuracy(NULL, clk_name, NULL,
                                                    0, rate, accuracy);
-       if (IS_ERR(clk))
-               return clk;
+       if (IS_ERR(hw))
+               return hw;
 
-       ret = of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       ret = of_clk_add_hw_provider(node, of_clk_hw_simple_get, hw);
        if (ret) {
-               clk_unregister(clk);
+               clk_hw_unregister_fixed_rate(hw);
                return ERR_PTR(ret);
        }
 
-       return clk;
+       return hw;
 }
 
 /**
@@ -195,27 +177,27 @@ CLK_OF_DECLARE(fixed_clk, "fixed-clock", of_fixed_clk_setup);
 
 static int of_fixed_clk_remove(struct platform_device *pdev)
 {
-       struct clk *clk = platform_get_drvdata(pdev);
+       struct clk_hw *hw = platform_get_drvdata(pdev);
 
        of_clk_del_provider(pdev->dev.of_node);
-       clk_unregister_fixed_rate(clk);
+       clk_hw_unregister_fixed_rate(hw);
 
        return 0;
 }
 
 static int of_fixed_clk_probe(struct platform_device *pdev)
 {
-       struct clk *clk;
+       struct clk_hw *hw;
 
        /*
         * This function is not executed when of_fixed_clk_setup
         * succeeded.
         */
-       clk = _of_fixed_clk_setup(pdev->dev.of_node);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+       hw = _of_fixed_clk_setup(pdev->dev.of_node);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
 
-       platform_set_drvdata(pdev, clk);
+       platform_set_drvdata(pdev, hw);
 
        return 0;
 }
@@ -224,7 +206,6 @@ static const struct of_device_id of_fixed_clk_ids[] = {
        { .compatible = "fixed-clock" },
        { }
 };
-MODULE_DEVICE_TABLE(of, of_fixed_clk_ids);
 
 static struct platform_driver of_fixed_clk_driver = {
        .driver = {
diff --git a/drivers/clk/clk-fsl-sai.c b/drivers/clk/clk-fsl-sai.c
new file mode 100644 (file)
index 0000000..0221180
--- /dev/null
@@ -0,0 +1,92 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Freescale SAI BCLK as a generic clock driver
+ *
+ * Copyright 2020 Michael Walle <michael@walle.cc>
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+
+#define I2S_CSR                0x00
+#define I2S_CR2                0x08
+#define CSR_BCE_BIT    28
+#define CR2_BCD                BIT(24)
+#define CR2_DIV_SHIFT  0
+#define CR2_DIV_WIDTH  8
+
+struct fsl_sai_clk {
+       struct clk_divider div;
+       struct clk_gate gate;
+       spinlock_t lock;
+};
+
+static int fsl_sai_clk_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct fsl_sai_clk *sai_clk;
+       struct clk_parent_data pdata = { .index = 0 };
+       void __iomem *base;
+       struct clk_hw *hw;
+       struct resource *res;
+
+       sai_clk = devm_kzalloc(dev, sizeof(*sai_clk), GFP_KERNEL);
+       if (!sai_clk)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       base = devm_ioremap_resource(dev, res);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       spin_lock_init(&sai_clk->lock);
+
+       sai_clk->gate.reg = base + I2S_CSR;
+       sai_clk->gate.bit_idx = CSR_BCE_BIT;
+       sai_clk->gate.lock = &sai_clk->lock;
+
+       sai_clk->div.reg = base + I2S_CR2;
+       sai_clk->div.shift = CR2_DIV_SHIFT;
+       sai_clk->div.width = CR2_DIV_WIDTH;
+       sai_clk->div.lock = &sai_clk->lock;
+
+       /* set clock direction, we are the BCLK master */
+       writel(CR2_BCD, base + I2S_CR2);
+
+       hw = clk_hw_register_composite_pdata(dev, dev->of_node->name,
+                                            &pdata, 1, NULL, NULL,
+                                            &sai_clk->div.hw,
+                                            &clk_divider_ops,
+                                            &sai_clk->gate.hw,
+                                            &clk_gate_ops,
+                                            CLK_SET_RATE_GATE);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
+
+       return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
+}
+
+static const struct of_device_id of_fsl_sai_clk_ids[] = {
+       { .compatible = "fsl,vf610-sai-clock" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, of_fsl_sai_clk_ids);
+
+static struct platform_driver fsl_sai_clk_driver = {
+       .probe = fsl_sai_clk_probe,
+       .driver         = {
+               .name   = "fsl-sai-clk",
+               .of_match_table = of_fsl_sai_clk_ids,
+       },
+};
+module_platform_driver(fsl_sai_clk_driver);
+
+MODULE_DESCRIPTION("Freescale SAI bitclock-as-a-clock driver");
+MODULE_AUTHOR("Michael Walle <michael@walle.cc>");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:fsl-sai-clk");
index 670053c..2ca1f2a 100644 (file)
@@ -123,26 +123,18 @@ const struct clk_ops clk_gate_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_gate_ops);
 
-/**
- * clk_hw_register_gate - register a gate clock with the clock framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_name: name of this clock's parent
- * @flags: framework-specific flags for this clock
- * @reg: register address to control gating of this clock
- * @bit_idx: which bit in the register controls gating of this clock
- * @clk_gate_flags: gate-specific flags for this clock
- * @lock: shared register lock for this clock
- */
-struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
+struct clk_hw *__clk_hw_register_gate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock)
 {
        struct clk_gate *gate;
        struct clk_hw *hw;
        struct clk_init_data init = {};
-       int ret;
+       int ret = -EINVAL;
 
        if (clk_gate_flags & CLK_GATE_HIWORD_MASK) {
                if (bit_idx > 15) {
@@ -160,7 +152,12 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
        init.ops = &clk_gate_ops;
        init.flags = flags;
        init.parent_names = parent_name ? &parent_name : NULL;
-       init.num_parents = parent_name ? 1 : 0;
+       init.parent_hws = parent_hw ? &parent_hw : NULL;
+       init.parent_data = parent_data;
+       if (parent_name || parent_hw || parent_data)
+               init.num_parents = 1;
+       else
+               init.num_parents = 0;
 
        /* struct clk_gate assignments */
        gate->reg = reg;
@@ -170,15 +167,19 @@ struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
        gate->hw.init = &init;
 
        hw = &gate->hw;
-       ret = clk_hw_register(dev, hw);
+       if (dev || !np)
+               ret = clk_hw_register(dev, hw);
+       else if (np)
+               ret = of_clk_hw_register(np, hw);
        if (ret) {
                kfree(gate);
                hw = ERR_PTR(ret);
        }
 
        return hw;
+
 }
-EXPORT_SYMBOL_GPL(clk_hw_register_gate);
+EXPORT_SYMBOL_GPL(__clk_hw_register_gate);
 
 struct clk *clk_register_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
index 13304cf..70397b4 100644 (file)
  * parent - fixed parent.  No clk_set_parent support
  */
 
+/**
+ * struct clk_gpio - gpio gated clock
+ *
+ * @hw:                handle between common and hardware-specific interfaces
+ * @gpiod:     gpio descriptor
+ *
+ * Clock with a gpio control for enabling and disabling the parent clock
+ * or switching between two parents by asserting or deasserting the gpio.
+ *
+ * Implements .enable, .disable and .is_enabled or
+ * .get_parent, .set_parent and .determine_rate depending on which clk_ops
+ * is used.
+ */
+struct clk_gpio {
+       struct clk_hw   hw;
+       struct gpio_desc *gpiod;
+};
+
+#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw)
+
 static int clk_gpio_gate_enable(struct clk_hw *hw)
 {
        struct clk_gpio *clk = to_clk_gpio(hw);
@@ -51,12 +71,11 @@ static int clk_gpio_gate_is_enabled(struct clk_hw *hw)
        return gpiod_get_value(clk->gpiod);
 }
 
-const struct clk_ops clk_gpio_gate_ops = {
+static const struct clk_ops clk_gpio_gate_ops = {
        .enable = clk_gpio_gate_enable,
        .disable = clk_gpio_gate_disable,
        .is_enabled = clk_gpio_gate_is_enabled,
 };
-EXPORT_SYMBOL_GPL(clk_gpio_gate_ops);
 
 static int clk_sleeping_gpio_gate_prepare(struct clk_hw *hw)
 {
@@ -111,67 +130,49 @@ static int clk_gpio_mux_set_parent(struct clk_hw *hw, u8 index)
        return 0;
 }
 
-const struct clk_ops clk_gpio_mux_ops = {
+static const struct clk_ops clk_gpio_mux_ops = {
        .get_parent = clk_gpio_mux_get_parent,
        .set_parent = clk_gpio_mux_set_parent,
        .determine_rate = __clk_mux_determine_rate,
 };
-EXPORT_SYMBOL_GPL(clk_gpio_mux_ops);
 
-static struct clk_hw *clk_register_gpio(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags, const struct clk_ops *clk_gpio_ops)
+static struct clk_hw *clk_register_gpio(struct device *dev, u8 num_parents,
+                                       struct gpio_desc *gpiod,
+                                       const struct clk_ops *clk_gpio_ops)
 {
        struct clk_gpio *clk_gpio;
        struct clk_hw *hw;
        struct clk_init_data init = {};
        int err;
+       const struct clk_parent_data gpio_parent_data[] = {
+               { .index = 0 },
+               { .index = 1 },
+       };
 
-       if (dev)
-               clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL);
-       else
-               clk_gpio = kzalloc(sizeof(*clk_gpio), GFP_KERNEL);
-
+       clk_gpio = devm_kzalloc(dev, sizeof(*clk_gpio), GFP_KERNEL);
        if (!clk_gpio)
                return ERR_PTR(-ENOMEM);
 
-       init.name = name;
+       init.name = dev->of_node->name;
        init.ops = clk_gpio_ops;
-       init.flags = flags;
-       init.parent_names = parent_names;
+       init.parent_data = gpio_parent_data;
        init.num_parents = num_parents;
+       init.flags = CLK_SET_RATE_PARENT;
 
        clk_gpio->gpiod = gpiod;
        clk_gpio->hw.init = &init;
 
        hw = &clk_gpio->hw;
-       if (dev)
-               err = devm_clk_hw_register(dev, hw);
-       else
-               err = clk_hw_register(NULL, hw);
-
-       if (!err)
-               return hw;
-
-       if (!dev) {
-               kfree(clk_gpio);
-       }
+       err = devm_clk_hw_register(dev, hw);
+       if (err)
+               return ERR_PTR(err);
 
-       return ERR_PTR(err);
+       return hw;
 }
 
-/**
- * clk_hw_register_gpio_gate - register a gpio clock gate with the clock
- * framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_name: name of this clock's parent
- * @gpiod: gpio descriptor to gate this clock
- * @flags: clock flags
- */
-struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, struct gpio_desc *gpiod,
-               unsigned long flags)
+static struct clk_hw *clk_hw_register_gpio_gate(struct device *dev,
+                                               int num_parents,
+                                               struct gpio_desc *gpiod)
 {
        const struct clk_ops *ops;
 
@@ -180,88 +181,36 @@ struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
        else
                ops = &clk_gpio_gate_ops;
 
-       return clk_register_gpio(dev, name,
-                       (parent_name ? &parent_name : NULL),
-                       (parent_name ? 1 : 0), gpiod, flags, ops);
+       return clk_register_gpio(dev, num_parents, gpiod, ops);
 }
-EXPORT_SYMBOL_GPL(clk_hw_register_gpio_gate);
 
-struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, struct gpio_desc *gpiod,
-               unsigned long flags)
+static struct clk_hw *clk_hw_register_gpio_mux(struct device *dev,
+                                              struct gpio_desc *gpiod)
 {
-       struct clk_hw *hw;
-
-       hw = clk_hw_register_gpio_gate(dev, name, parent_name, gpiod, flags);
-       if (IS_ERR(hw))
-               return ERR_CAST(hw);
-       return hw->clk;
+       return clk_register_gpio(dev, 2, gpiod, &clk_gpio_mux_ops);
 }
-EXPORT_SYMBOL_GPL(clk_register_gpio_gate);
-
-/**
- * clk_hw_register_gpio_mux - register a gpio clock mux with the clock framework
- * @dev: device that is registering this clock
- * @name: name of this clock
- * @parent_names: names of this clock's parents
- * @num_parents: number of parents listed in @parent_names
- * @gpiod: gpio descriptor to gate this clock
- * @flags: clock flags
- */
-struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags)
-{
-       if (num_parents != 2) {
-               pr_err("mux-clock %s must have 2 parents\n", name);
-               return ERR_PTR(-EINVAL);
-       }
-
-       return clk_register_gpio(dev, name, parent_names, num_parents,
-                       gpiod, flags, &clk_gpio_mux_ops);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_gpio_mux);
-
-struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags)
-{
-       struct clk_hw *hw;
-
-       hw = clk_hw_register_gpio_mux(dev, name, parent_names, num_parents,
-                       gpiod, flags);
-       if (IS_ERR(hw))
-               return ERR_CAST(hw);
-       return hw->clk;
-}
-EXPORT_SYMBOL_GPL(clk_register_gpio_mux);
 
 static int gpio_clk_driver_probe(struct platform_device *pdev)
 {
-       struct device_node *node = pdev->dev.of_node;
-       const char **parent_names, *gpio_name;
+       struct device *dev = &pdev->dev;
+       struct device_node *node = dev->of_node;
+       const char *gpio_name;
        unsigned int num_parents;
        struct gpio_desc *gpiod;
-       struct clk *clk;
+       struct clk_hw *hw;
        bool is_mux;
        int ret;
 
+       is_mux = of_device_is_compatible(node, "gpio-mux-clock");
+
        num_parents = of_clk_get_parent_count(node);
-       if (num_parents) {
-               parent_names = devm_kcalloc(&pdev->dev, num_parents,
-                                           sizeof(char *), GFP_KERNEL);
-               if (!parent_names)
-                       return -ENOMEM;
-
-               of_clk_parent_fill(node, parent_names, num_parents);
-       } else {
-               parent_names = NULL;
+       if (is_mux && num_parents != 2) {
+               dev_err(dev, "mux-clock must have 2 parents\n");
+               return -EINVAL;
        }
 
-       is_mux = of_device_is_compatible(node, "gpio-mux-clock");
-
        gpio_name = is_mux ? "select" : "enable";
-       gpiod = devm_gpiod_get(&pdev->dev, gpio_name, GPIOD_OUT_LOW);
+       gpiod = devm_gpiod_get(dev, gpio_name, GPIOD_OUT_LOW);
        if (IS_ERR(gpiod)) {
                ret = PTR_ERR(gpiod);
                if (ret == -EPROBE_DEFER)
@@ -275,16 +224,13 @@ static int gpio_clk_driver_probe(struct platform_device *pdev)
        }
 
        if (is_mux)
-               clk = clk_register_gpio_mux(&pdev->dev, node->name,
-                               parent_names, num_parents, gpiod, 0);
+               hw = clk_hw_register_gpio_mux(dev, gpiod);
        else
-               clk = clk_register_gpio_gate(&pdev->dev, node->name,
-                               parent_names ?  parent_names[0] : NULL, gpiod,
-                               CLK_SET_RATE_PARENT);
-       if (IS_ERR(clk))
-               return PTR_ERR(clk);
+               hw = clk_hw_register_gpio_gate(dev, num_parents, gpiod);
+       if (IS_ERR(hw))
+               return PTR_ERR(hw);
 
-       return of_clk_add_provider(node, of_clk_src_simple_get, clk);
+       return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, hw);
 }
 
 static const struct of_device_id gpio_clk_match_table[] = {
index 570b6e5..e54e797 100644 (file)
@@ -145,17 +145,19 @@ const struct clk_ops clk_mux_ro_ops = {
 };
 EXPORT_SYMBOL_GPL(clk_mux_ro_ops);
 
-struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
+struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np,
+               const char *name, u8 num_parents,
+               const char * const *parent_names,
+               const struct clk_hw **parent_hws,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock)
 {
        struct clk_mux *mux;
        struct clk_hw *hw;
        struct clk_init_data init = {};
        u8 width = 0;
-       int ret;
+       int ret = -EINVAL;
 
        if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
                width = fls(mask) - ffs(mask) + 1;
@@ -177,6 +179,8 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
                init.ops = &clk_mux_ops;
        init.flags = flags;
        init.parent_names = parent_names;
+       init.parent_data = parent_data;
+       init.parent_hws = parent_hws;
        init.num_parents = num_parents;
 
        /* struct clk_mux assignments */
@@ -189,7 +193,10 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
        mux->hw.init = &init;
 
        hw = &mux->hw;
-       ret = clk_hw_register(dev, hw);
+       if (dev || !np)
+               ret = clk_hw_register(dev, hw);
+       else if (np)
+               ret = of_clk_hw_register(np, hw);
        if (ret) {
                kfree(mux);
                hw = ERR_PTR(ret);
@@ -197,53 +204,24 @@ struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
 
        return hw;
 }
-EXPORT_SYMBOL_GPL(clk_hw_register_mux_table);
+EXPORT_SYMBOL_GPL(__clk_hw_register_mux);
 
 struct clk *clk_register_mux_table(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
+               unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock)
 {
        struct clk_hw *hw;
 
-       hw = clk_hw_register_mux_table(dev, name, parent_names, num_parents,
-                                      flags, reg, shift, mask, clk_mux_flags,
-                                      table, lock);
+       hw = clk_hw_register_mux_table(dev, name, parent_names,
+                                      num_parents, flags, reg, shift, mask,
+                                      clk_mux_flags, table, lock);
        if (IS_ERR(hw))
                return ERR_CAST(hw);
        return hw->clk;
 }
 EXPORT_SYMBOL_GPL(clk_register_mux_table);
 
-struct clk *clk_register_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock)
-{
-       u32 mask = BIT(width) - 1;
-
-       return clk_register_mux_table(dev, name, parent_names, num_parents,
-                                     flags, reg, shift, mask, clk_mux_flags,
-                                     NULL, lock);
-}
-EXPORT_SYMBOL_GPL(clk_register_mux);
-
-struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock)
-{
-       u32 mask = BIT(width) - 1;
-
-       return clk_hw_register_mux_table(dev, name, parent_names, num_parents,
-                                     flags, reg, shift, mask, clk_mux_flags,
-                                     NULL, lock);
-}
-EXPORT_SYMBOL_GPL(clk_hw_register_mux);
-
 void clk_unregister_mux(struct clk *clk)
 {
        struct clk_mux *mux;
diff --git a/drivers/clk/clk-plldig.c b/drivers/clk/clk-plldig.c
new file mode 100644 (file)
index 0000000..2502016
--- /dev/null
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP
+ *
+ * Clock driver for LS1028A Display output interfaces(LCD, DPHY).
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/iopoll.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/bitfield.h>
+
+/* PLLDIG register offsets and bit masks */
+#define PLLDIG_REG_PLLSR            0x24
+#define PLLDIG_LOCK_MASK            BIT(2)
+#define PLLDIG_REG_PLLDV            0x28
+#define PLLDIG_MFD_MASK             GENMASK(7, 0)
+#define PLLDIG_RFDPHI1_MASK         GENMASK(30, 25)
+#define PLLDIG_REG_PLLFM            0x2c
+#define PLLDIG_SSCGBYP_ENABLE       BIT(30)
+#define PLLDIG_REG_PLLFD            0x30
+#define PLLDIG_FDEN                 BIT(30)
+#define PLLDIG_FRAC_MASK            GENMASK(15, 0)
+#define PLLDIG_REG_PLLCAL1          0x38
+#define PLLDIG_REG_PLLCAL2          0x3c
+
+/* Range of the VCO frequencies, in Hz */
+#define PLLDIG_MIN_VCO_FREQ         650000000
+#define PLLDIG_MAX_VCO_FREQ         1300000000
+
+/* Range of the output frequencies, in Hz */
+#define PHI1_MIN_FREQ               27000000UL
+#define PHI1_MAX_FREQ               600000000UL
+
+/* Maximum value of the reduced frequency divider */
+#define MAX_RFDPHI1          63UL
+
+/* Best value of multiplication factor divider */
+#define PLLDIG_DEFAULT_MFD   44
+
+/*
+ * Denominator part of the fractional part of the
+ * loop multiplication factor.
+ */
+#define MFDEN          20480
+
+static const struct clk_parent_data parent_data[] = {
+       { .index = 0 },
+};
+
+struct clk_plldig {
+       struct clk_hw hw;
+       void __iomem *regs;
+       unsigned int vco_freq;
+};
+
+#define to_clk_plldig(_hw)     container_of(_hw, struct clk_plldig, hw)
+
+static int plldig_enable(struct clk_hw *hw)
+{
+       struct clk_plldig *data = to_clk_plldig(hw);
+       u32 val;
+
+       val = readl(data->regs + PLLDIG_REG_PLLFM);
+       /*
+        * Use Bypass mode with PLL off by default, the frequency overshoot
+        * detector output was disable. SSCG Bypass mode should be enable.
+        */
+       val |= PLLDIG_SSCGBYP_ENABLE;
+       writel(val, data->regs + PLLDIG_REG_PLLFM);
+
+       return 0;
+}
+
+static void plldig_disable(struct clk_hw *hw)
+{
+       struct clk_plldig *data = to_clk_plldig(hw);
+       u32 val;
+
+       val = readl(data->regs + PLLDIG_REG_PLLFM);
+
+       val &= ~PLLDIG_SSCGBYP_ENABLE;
+       val |= FIELD_PREP(PLLDIG_SSCGBYP_ENABLE, 0x0);
+
+       writel(val, data->regs + PLLDIG_REG_PLLFM);
+}
+
+static int plldig_is_enabled(struct clk_hw *hw)
+{
+       struct clk_plldig *data = to_clk_plldig(hw);
+
+       return readl(data->regs + PLLDIG_REG_PLLFM) &
+                             PLLDIG_SSCGBYP_ENABLE;
+}
+
+static unsigned long plldig_recalc_rate(struct clk_hw *hw,
+                                       unsigned long parent_rate)
+{
+       struct clk_plldig *data = to_clk_plldig(hw);
+       u32 val, rfdphi1;
+
+       val = readl(data->regs + PLLDIG_REG_PLLDV);
+
+       /* Check if PLL is bypassed */
+       if (val & PLLDIG_SSCGBYP_ENABLE)
+               return parent_rate;
+
+       rfdphi1 = FIELD_GET(PLLDIG_RFDPHI1_MASK, val);
+
+       /*
+        * If RFDPHI1 has a value of 1 the VCO frequency is also divided by
+        * one.
+        */
+       if (!rfdphi1)
+               rfdphi1 = 1;
+
+       return DIV_ROUND_UP(data->vco_freq, rfdphi1);
+}
+
+static unsigned long plldig_calc_target_div(unsigned long vco_freq,
+                                           unsigned long target_rate)
+{
+       unsigned long div;
+
+       div = DIV_ROUND_CLOSEST(vco_freq, target_rate);
+       div = clamp(div, 1UL, MAX_RFDPHI1);
+
+       return div;
+}
+
+static int plldig_determine_rate(struct clk_hw *hw,
+                                struct clk_rate_request *req)
+{
+       struct clk_plldig *data = to_clk_plldig(hw);
+       unsigned int div;
+
+       req->rate = clamp(req->rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ);
+       div = plldig_calc_target_div(data->vco_freq, req->rate);
+       req->rate = DIV_ROUND_UP(data->vco_freq, div);
+
+       return 0;
+}
+
+static int plldig_set_rate(struct clk_hw *hw, unsigned long rate,
+               unsigned long parent_rate)
+{
+       struct clk_plldig *data = to_clk_plldig(hw);
+       unsigned int val, cond;
+       unsigned int rfdphi1;
+
+       rate = clamp(rate, PHI1_MIN_FREQ, PHI1_MAX_FREQ);
+       rfdphi1 = plldig_calc_target_div(data->vco_freq, rate);
+
+       /* update the divider value */
+       val = readl(data->regs + PLLDIG_REG_PLLDV);
+       val &= ~PLLDIG_RFDPHI1_MASK;
+       val |= FIELD_PREP(PLLDIG_RFDPHI1_MASK, rfdphi1);
+       writel(val, data->regs + PLLDIG_REG_PLLDV);
+
+       /* waiting for old lock state to clear */
+       udelay(200);
+
+       /* Wait until PLL is locked or timeout */
+       return readl_poll_timeout_atomic(data->regs + PLLDIG_REG_PLLSR, cond,
+                                        cond & PLLDIG_LOCK_MASK, 0,
+                                        USEC_PER_MSEC);
+}
+
+static const struct clk_ops plldig_clk_ops = {
+       .enable = plldig_enable,
+       .disable = plldig_disable,
+       .is_enabled = plldig_is_enabled,
+       .recalc_rate = plldig_recalc_rate,
+       .determine_rate = plldig_determine_rate,
+       .set_rate = plldig_set_rate,
+};
+
+static int plldig_init(struct clk_hw *hw)
+{
+       struct clk_plldig *data = to_clk_plldig(hw);
+       struct clk_hw *parent = clk_hw_get_parent(hw);
+       unsigned long parent_rate;
+       unsigned long val;
+       unsigned long long lltmp;
+       unsigned int mfd, fracdiv = 0;
+
+       if (!parent)
+               return -EINVAL;
+
+       parent_rate = clk_hw_get_rate(parent);
+
+       if (data->vco_freq) {
+               mfd = data->vco_freq / parent_rate;
+               lltmp = data->vco_freq % parent_rate;
+               lltmp *= MFDEN;
+               do_div(lltmp, parent_rate);
+               fracdiv = lltmp;
+       } else {
+               mfd = PLLDIG_DEFAULT_MFD;
+               data->vco_freq = parent_rate * mfd;
+       }
+
+       val = FIELD_PREP(PLLDIG_MFD_MASK, mfd);
+       writel(val, data->regs + PLLDIG_REG_PLLDV);
+
+       /* Enable fractional divider */
+       if (fracdiv) {
+               val = FIELD_PREP(PLLDIG_FRAC_MASK, fracdiv);
+               val |= PLLDIG_FDEN;
+               writel(val, data->regs + PLLDIG_REG_PLLFD);
+       }
+
+       return 0;
+}
+
+static int plldig_clk_probe(struct platform_device *pdev)
+{
+       struct clk_plldig *data;
+       struct device *dev = &pdev->dev;
+       int ret;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(data->regs))
+               return PTR_ERR(data->regs);
+
+       data->hw.init = CLK_HW_INIT_PARENTS_DATA("dpclk",
+                                                parent_data,
+                                                &plldig_clk_ops,
+                                                0);
+
+       ret = devm_clk_hw_register(dev, &data->hw);
+       if (ret) {
+               dev_err(dev, "failed to register %s clock\n",
+                                               dev->of_node->name);
+               return ret;
+       }
+
+       ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
+                                         &data->hw);
+       if (ret) {
+               dev_err(dev, "unable to add clk provider\n");
+               return ret;
+       }
+
+       /*
+        * The frequency of the VCO cannot be changed during runtime.
+        * Therefore, let the user specify a desired frequency.
+        */
+       if (!of_property_read_u32(dev->of_node, "fsl,vco-hz",
+                                 &data->vco_freq)) {
+               if (data->vco_freq < PLLDIG_MIN_VCO_FREQ ||
+                   data->vco_freq > PLLDIG_MAX_VCO_FREQ)
+                       return -EINVAL;
+       }
+
+       return plldig_init(&data->hw);
+}
+
+static const struct of_device_id plldig_clk_id[] = {
+       { .compatible = "fsl,ls1028a-plldig" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, plldig_clk_id);
+
+static struct platform_driver plldig_clk_driver = {
+       .driver = {
+               .name = "plldig-clock",
+               .of_match_table = plldig_clk_id,
+       },
+       .probe = plldig_clk_probe,
+};
+module_platform_driver(plldig_clk_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Wen He <wen.he_1@nxp.com>");
+MODULE_DESCRIPTION("LS1028A Display output interface pixel clock driver");
index bed140f..d5946f7 100644 (file)
@@ -342,6 +342,32 @@ static const struct clockgen_muxinfo ls1046a_hwa2 = {
        },
 };
 
+static const struct clockgen_muxinfo ls1088a_hwa1 = {
+       {
+               {},
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV4 },
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+       },
+};
+
+static const struct clockgen_muxinfo ls1088a_hwa2 = {
+       {
+               {},
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV1 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV3 },
+               { CLKSEL_VALID, CGA_PLL2, PLL_DIV4 },
+               {},
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV2 },
+               { CLKSEL_VALID, CGA_PLL1, PLL_DIV3 },
+       },
+};
+
 static const struct clockgen_muxinfo ls1012a_cmux = {
        {
                [0] = { CLKSEL_VALID, CGA_PLL1, PLL_DIV1 },
@@ -607,6 +633,9 @@ static const struct clockgen_chipinfo chipinfo[] = {
                .cmux_groups = {
                        &clockgen2_cmux_cga12
                },
+               .hwaccel = {
+                       &ls1088a_hwa1, &ls1088a_hwa2
+               },
                .cmux_to_group = {
                        0, 0, -1
                },
index 886f7c5..c491f5d 100644 (file)
@@ -176,7 +176,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev)
 }
 
 static const struct scmi_device_id scmi_id_table[] = {
-       { SCMI_PROTOCOL_CLOCK },
+       { SCMI_PROTOCOL_CLOCK, "clocks" },
        { },
 };
 MODULE_DEVICE_TABLE(scmi, scmi_id_table);
index 772258d..f0f2b59 100644 (file)
@@ -429,7 +429,7 @@ static void clk_core_fill_parent_index(struct clk_core *core, u8 index)
                        parent = ERR_PTR(-EPROBE_DEFER);
        } else {
                parent = clk_core_get(core, index);
-               if (IS_ERR(parent) && PTR_ERR(parent) == -ENOENT && entry->name)
+               if (PTR_ERR(parent) == -ENOENT && entry->name)
                        parent = clk_core_lookup(entry->name);
        }
 
@@ -2996,6 +2996,41 @@ static int clk_dump_show(struct seq_file *s, void *data)
 }
 DEFINE_SHOW_ATTRIBUTE(clk_dump);
 
+#undef CLOCK_ALLOW_WRITE_DEBUGFS
+#ifdef CLOCK_ALLOW_WRITE_DEBUGFS
+/*
+ * This can be dangerous, therefore don't provide any real compile time
+ * configuration option for this feature.
+ * People who want to use this will need to modify the source code directly.
+ */
+static int clk_rate_set(void *data, u64 val)
+{
+       struct clk_core *core = data;
+       int ret;
+
+       clk_prepare_lock();
+       ret = clk_core_set_rate_nolock(core, val);
+       clk_prepare_unlock();
+
+       return ret;
+}
+
+#define clk_rate_mode  0644
+#else
+#define clk_rate_set   NULL
+#define clk_rate_mode  0444
+#endif
+
+static int clk_rate_get(void *data, u64 *val)
+{
+       struct clk_core *core = data;
+
+       *val = core->rate;
+       return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n");
+
 static const struct {
        unsigned long flag;
        const char *name;
@@ -3145,7 +3180,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
        root = debugfs_create_dir(core->name, pdentry);
        core->dentry = root;
 
-       debugfs_create_ulong("clk_rate", 0444, root, &core->rate);
+       debugfs_create_file("clk_rate", clk_rate_mode, root, core,
+                           &clk_rate_fops);
        debugfs_create_file("clk_min_rate", 0444, root, core, &clk_min_rate_fops);
        debugfs_create_file("clk_max_rate", 0444, root, core, &clk_max_rate_fops);
        debugfs_create_ulong("clk_accuracy", 0444, root, &core->accuracy);
@@ -3338,6 +3374,26 @@ static int __clk_core_init(struct clk_core *core)
                goto out;
        }
 
+       /*
+        * optional platform-specific magic
+        *
+        * The .init callback is not used by any of the basic clock types, but
+        * exists for weird hardware that must perform initialization magic for
+        * CCF to get an accurate view of clock for any other callbacks. It may
+        * also be used needs to perform dynamic allocations. Such allocation
+        * must be freed in the terminate() callback.
+        * This callback shall not be used to initialize the parameters state,
+        * such as rate, parent, etc ...
+        *
+        * If it exist, this callback should called before any other callback of
+        * the clock
+        */
+       if (core->ops->init) {
+               ret = core->ops->init(core->hw);
+               if (ret)
+                       goto out;
+       }
+
        core->parent = __clk_init_parent(core);
 
        /*
@@ -3363,17 +3419,6 @@ static int __clk_core_init(struct clk_core *core)
        }
 
        /*
-        * optional platform-specific magic
-        *
-        * The .init callback is not used by any of the basic clock types, but
-        * exists for weird hardware that must perform initialization magic.
-        * Please consider other ways of solving initialization problems before
-        * using this callback, as its use is discouraged.
-        */
-       if (core->ops->init)
-               core->ops->init(core->hw);
-
-       /*
         * Set clk's accuracy.  The preferred method is to use
         * .recalc_accuracy. For simple clocks and lazy developers the default
         * fallback is to use the parent's accuracy.  If a clock doesn't have a
@@ -3427,13 +3472,18 @@ static int __clk_core_init(struct clk_core *core)
                unsigned long flags;
 
                ret = clk_core_prepare(core);
-               if (ret)
+               if (ret) {
+                       pr_warn("%s: critical clk '%s' failed to prepare\n",
+                              __func__, core->name);
                        goto out;
+               }
 
                flags = clk_enable_lock();
                ret = clk_core_enable(core);
                clk_enable_unlock(flags);
                if (ret) {
+                       pr_warn("%s: critical clk '%s' failed to enable\n",
+                              __func__, core->name);
                        clk_core_unprepare(core);
                        goto out;
                }
@@ -3733,6 +3783,28 @@ fail_out:
 }
 
 /**
+ * dev_or_parent_of_node() - Get device node of @dev or @dev's parent
+ * @dev: Device to get device node of
+ *
+ * Return: device node pointer of @dev, or the device node pointer of
+ * @dev->parent if dev doesn't have a device node, or NULL if neither
+ * @dev or @dev->parent have a device node.
+ */
+static struct device_node *dev_or_parent_of_node(struct device *dev)
+{
+       struct device_node *np;
+
+       if (!dev)
+               return NULL;
+
+       np = dev_of_node(dev);
+       if (!np)
+               np = dev_of_node(dev->parent);
+
+       return np;
+}
+
+/**
  * clk_register - allocate a new clock, register it and return an opaque cookie
  * @dev: device that is registering this clock
  * @hw: link to hardware-specific clock data
@@ -3747,7 +3819,7 @@ fail_out:
  */
 struct clk *clk_register(struct device *dev, struct clk_hw *hw)
 {
-       return __clk_register(dev, dev_of_node(dev), hw);
+       return __clk_register(dev, dev_or_parent_of_node(dev), hw);
 }
 EXPORT_SYMBOL_GPL(clk_register);
 
@@ -3763,7 +3835,8 @@ EXPORT_SYMBOL_GPL(clk_register);
  */
 int clk_hw_register(struct device *dev, struct clk_hw *hw)
 {
-       return PTR_ERR_OR_ZERO(__clk_register(dev, dev_of_node(dev), hw));
+       return PTR_ERR_OR_ZERO(__clk_register(dev, dev_or_parent_of_node(dev),
+                              hw));
 }
 EXPORT_SYMBOL_GPL(clk_hw_register);
 
@@ -3866,6 +3939,7 @@ static void clk_core_evict_parent_cache(struct clk_core *core)
 void clk_unregister(struct clk *clk)
 {
        unsigned long flags;
+       const struct clk_ops *ops;
 
        if (!clk || WARN_ON_ONCE(IS_ERR(clk)))
                return;
@@ -3874,7 +3948,8 @@ void clk_unregister(struct clk *clk)
 
        clk_prepare_lock();
 
-       if (clk->core->ops == &clk_nodrv_ops) {
+       ops = clk->core->ops;
+       if (ops == &clk_nodrv_ops) {
                pr_err("%s: unregistered clock: %s\n", __func__,
                       clk->core->name);
                goto unlock;
@@ -3887,6 +3962,9 @@ void clk_unregister(struct clk *clk)
        clk->core->ops = &clk_nodrv_ops;
        clk_enable_unlock(flags);
 
+       if (ops->terminate)
+               ops->terminate(clk->core->hw);
+
        if (!hlist_empty(&clk->core->children)) {
                struct clk_core *child;
                struct hlist_node *t;
index 1ac0c79..01eadee 100644 (file)
@@ -20,6 +20,12 @@ config CLK_IMX8MN
        help
            Build the driver for i.MX8MN CCM Clock Driver
 
+config CLK_IMX8MP
+       bool "IMX8MP CCM Clock Driver"
+       depends on ARCH_MXC && ARM64
+       help
+           Build the driver for i.MX8MP CCM Clock Driver
+
 config CLK_IMX8MQ
        bool "IMX8MQ CCM Clock Driver"
        depends on ARCH_MXC && ARM64
index 77a3d71..928f874 100644 (file)
@@ -18,7 +18,7 @@ obj-$(CONFIG_MXC_CLK) += \
        clk-pllv2.o \
        clk-pllv3.o \
        clk-pllv4.o \
-       clk-sccg-pll.o \
+       clk-sscg-pll.o \
        clk-pll14xx.o
 
 obj-$(CONFIG_MXC_CLK_SCU) += \
@@ -27,6 +27,7 @@ obj-$(CONFIG_MXC_CLK_SCU) += \
 
 obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
 obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
+obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
 obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
 obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
 
index 060f860..b9efcc8 100644 (file)
@@ -21,7 +21,7 @@
 #define PCG_PCD_WIDTH  3
 #define PCG_PCD_MASK   0x7
 
-struct clk_hw *imx7ulp_clk_composite(const char *name,
+struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
                                     const char * const *parent_names,
                                     int num_parents, bool mux_present,
                                     bool rate_present, bool gate_present,
index d3486ee..20f7c91 100644 (file)
@@ -123,7 +123,7 @@ static const struct clk_ops imx8m_clk_composite_divider_ops = {
        .set_rate = imx8m_clk_composite_divider_set_rate,
 };
 
-struct clk *imx8m_clk_composite_flags(const char *name,
+struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
                                        const char * const *parent_names,
                                        int num_parents, void __iomem *reg,
                                        unsigned long flags)
@@ -171,7 +171,7 @@ struct clk *imx8m_clk_composite_flags(const char *name,
        if (IS_ERR(hw))
                goto fail;
 
-       return hw->clk;
+       return hw;
 
 fail:
        kfree(gate);
index 2a8352a..0322a84 100644 (file)
@@ -43,7 +43,7 @@ static unsigned long clk_divider_gate_recalc_rate(struct clk_hw *hw,
 {
        struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
        struct clk_divider *div = to_clk_divider(hw);
-       unsigned long flags = 0;
+       unsigned long flags;
        unsigned int val;
 
        spin_lock_irqsave(div->lock, flags);
@@ -75,7 +75,7 @@ static int clk_divider_gate_set_rate(struct clk_hw *hw, unsigned long rate,
 {
        struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
        struct clk_divider *div = to_clk_divider(hw);
-       unsigned long flags = 0;
+       unsigned long flags;
        int value;
        u32 val;
 
@@ -104,7 +104,7 @@ static int clk_divider_enable(struct clk_hw *hw)
 {
        struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
        struct clk_divider *div = to_clk_divider(hw);
-       unsigned long flags = 0;
+       unsigned long flags;
        u32 val;
 
        if (!div_gate->cached_val) {
@@ -127,7 +127,7 @@ static void clk_divider_disable(struct clk_hw *hw)
 {
        struct clk_divider_gate *div_gate = to_clk_divider_gate(hw);
        struct clk_divider *div = to_clk_divider(hw);
-       unsigned long flags = 0;
+       unsigned long flags;
        u32 val;
 
        spin_lock_irqsave(div->lock, flags);
@@ -167,13 +167,13 @@ static const struct clk_ops clk_divider_gate_ops = {
 };
 
 /*
- * NOTE: In order to resue the most code from the common divider,
+ * NOTE: In order to reuse the most code from the common divider,
  * we also design our divider following the way that provids an extra
  * clk_divider_flags, however it's fixed to CLK_DIVIDER_ONE_BASED by
  * default as our HW is. Besides that it supports only CLK_DIVIDER_READ_ONLY
  * flag which can be specified by user flexibly.
  */
-struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
+struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
                                    unsigned long flags, void __iomem *reg,
                                    u8 shift, u8 width, u8 clk_divider_flags,
                                    const struct clk_div_table *table,
index fece503..101e0a3 100644 (file)
@@ -201,8 +201,9 @@ static const struct clk_ops clk_frac_pll_ops = {
        .set_rate       = clk_pll_set_rate,
 };
 
-struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
-                            void __iomem *base)
+struct clk_hw *imx_clk_hw_frac_pll(const char *name,
+                                  const char *parent_name,
+                                  void __iomem *base)
 {
        struct clk_init_data init;
        struct clk_frac_pll *pll;
@@ -230,5 +231,5 @@ struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
                return ERR_PTR(ret);
        }
 
-       return hw->clk;
+       return hw;
 }
index 60f2de8..ba33c79 100644 (file)
@@ -598,7 +598,10 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
        }
 
        hws[IMX6QDL_CLK_PLL4_POST_DIV] = clk_hw_register_divider_table(NULL, "pll4_post_div", "pll4_audio", CLK_SET_RATE_PARENT, base + 0x70, 19, 2, 0, post_div_table, &imx_ccm_lock);
-       hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
+       if (clk_on_imx6q() || clk_on_imx6qp())
+               hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = imx_clk_hw_fixed_factor("pll4_audio_div", "pll4_post_div", 1, 1);
+       else
+               hws[IMX6QDL_CLK_PLL4_AUDIO_DIV] = clk_hw_register_divider(NULL, "pll4_audio_div", "pll4_post_div", CLK_SET_RATE_PARENT, base + 0x170, 15, 1, 0, &imx_ccm_lock);
        hws[IMX6QDL_CLK_PLL5_POST_DIV] = clk_hw_register_divider_table(NULL, "pll5_post_div", "pll5_video", CLK_SET_RATE_PARENT, base + 0xa0, 19, 2, 0, post_div_table, &imx_ccm_lock);
        hws[IMX6QDL_CLK_PLL5_VIDEO_DIV] = clk_hw_register_divider_table(NULL, "pll5_video_div", "pll5_post_div", CLK_SET_RATE_PARENT, base + 0x170, 30, 2, 0, video_div_table, &imx_ccm_lock);
 
index 281191b..0620d6c 100644 (file)
@@ -59,7 +59,7 @@ static struct clk **pcc3_uart_clks[ARRAY_SIZE(pcc3_uart_clk_ids) + 1] __initdata
 static void __init imx7ulp_clk_scg1_init(struct device_node *np)
 {
        struct clk_hw_onecell_data *clk_data;
-       struct clk_hw **clks;
+       struct clk_hw **hws;
        void __iomem *base;
 
        clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SCG1_END),
@@ -68,76 +68,76 @@ static void __init imx7ulp_clk_scg1_init(struct device_node *np)
                return;
 
        clk_data->num = IMX7ULP_CLK_SCG1_END;
-       clks = clk_data->hws;
+       hws = clk_data->hws;
 
-       clks[IMX7ULP_CLK_DUMMY]         = imx_clk_hw_fixed("dummy", 0);
+       hws[IMX7ULP_CLK_DUMMY]          = imx_clk_hw_fixed("dummy", 0);
 
-       clks[IMX7ULP_CLK_ROSC]          = imx_obtain_fixed_clk_hw(np, "rosc");
-       clks[IMX7ULP_CLK_SOSC]          = imx_obtain_fixed_clk_hw(np, "sosc");
-       clks[IMX7ULP_CLK_SIRC]          = imx_obtain_fixed_clk_hw(np, "sirc");
-       clks[IMX7ULP_CLK_FIRC]          = imx_obtain_fixed_clk_hw(np, "firc");
-       clks[IMX7ULP_CLK_UPLL]          = imx_obtain_fixed_clk_hw(np, "upll");
+       hws[IMX7ULP_CLK_ROSC]           = imx_obtain_fixed_clk_hw(np, "rosc");
+       hws[IMX7ULP_CLK_SOSC]           = imx_obtain_fixed_clk_hw(np, "sosc");
+       hws[IMX7ULP_CLK_SIRC]           = imx_obtain_fixed_clk_hw(np, "sirc");
+       hws[IMX7ULP_CLK_FIRC]           = imx_obtain_fixed_clk_hw(np, "firc");
+       hws[IMX7ULP_CLK_UPLL]           = imx_obtain_fixed_clk_hw(np, "upll");
 
        /* SCG1 */
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
        /* NOTE: xPLL config can't be changed when xPLL is enabled */
-       clks[IMX7ULP_CLK_APLL_PRE_SEL]  = imx_clk_hw_mux_flags("apll_pre_sel", base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
-       clks[IMX7ULP_CLK_SPLL_PRE_SEL]  = imx_clk_hw_mux_flags("spll_pre_sel", base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
+       hws[IMX7ULP_CLK_APLL_PRE_SEL]   = imx_clk_hw_mux_flags("apll_pre_sel", base + 0x508, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
+       hws[IMX7ULP_CLK_SPLL_PRE_SEL]   = imx_clk_hw_mux_flags("spll_pre_sel", base + 0x608, 0, 1, pll_pre_sels, ARRAY_SIZE(pll_pre_sels), CLK_SET_PARENT_GATE);
 
        /*                                                         name             parent_name    reg                  shift   width   flags */
-       clks[IMX7ULP_CLK_APLL_PRE_DIV]  = imx_clk_hw_divider_flags("apll_pre_div", "apll_pre_sel", base + 0x508,        8,      3,      CLK_SET_RATE_GATE);
-       clks[IMX7ULP_CLK_SPLL_PRE_DIV]  = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608,        8,      3,      CLK_SET_RATE_GATE);
+       hws[IMX7ULP_CLK_APLL_PRE_DIV]   = imx_clk_hw_divider_flags("apll_pre_div", "apll_pre_sel", base + 0x508,        8,      3,      CLK_SET_RATE_GATE);
+       hws[IMX7ULP_CLK_SPLL_PRE_DIV]   = imx_clk_hw_divider_flags("spll_pre_div", "spll_pre_sel", base + 0x608,        8,      3,      CLK_SET_RATE_GATE);
 
        /*                                              name     parent_name     base */
-       clks[IMX7ULP_CLK_APLL]          = imx_clk_pllv4("apll",  "apll_pre_div", base + 0x500);
-       clks[IMX7ULP_CLK_SPLL]          = imx_clk_pllv4("spll",  "spll_pre_div", base + 0x600);
+       hws[IMX7ULP_CLK_APLL]           = imx_clk_hw_pllv4("apll",  "apll_pre_div", base + 0x500);
+       hws[IMX7ULP_CLK_SPLL]           = imx_clk_hw_pllv4("spll",  "spll_pre_div", base + 0x600);
 
        /* APLL PFDs */
-       clks[IMX7ULP_CLK_APLL_PFD0]     = imx_clk_pfdv2("apll_pfd0", "apll", base + 0x50c, 0);
-       clks[IMX7ULP_CLK_APLL_PFD1]     = imx_clk_pfdv2("apll_pfd1", "apll", base + 0x50c, 1);
-       clks[IMX7ULP_CLK_APLL_PFD2]     = imx_clk_pfdv2("apll_pfd2", "apll", base + 0x50c, 2);
-       clks[IMX7ULP_CLK_APLL_PFD3]     = imx_clk_pfdv2("apll_pfd3", "apll", base + 0x50c, 3);
+       hws[IMX7ULP_CLK_APLL_PFD0]      = imx_clk_hw_pfdv2("apll_pfd0", "apll", base + 0x50c, 0);
+       hws[IMX7ULP_CLK_APLL_PFD1]      = imx_clk_hw_pfdv2("apll_pfd1", "apll", base + 0x50c, 1);
+       hws[IMX7ULP_CLK_APLL_PFD2]      = imx_clk_hw_pfdv2("apll_pfd2", "apll", base + 0x50c, 2);
+       hws[IMX7ULP_CLK_APLL_PFD3]      = imx_clk_hw_pfdv2("apll_pfd3", "apll", base + 0x50c, 3);
 
        /* SPLL PFDs */
-       clks[IMX7ULP_CLK_SPLL_PFD0]     = imx_clk_pfdv2("spll_pfd0", "spll", base + 0x60C, 0);
-       clks[IMX7ULP_CLK_SPLL_PFD1]     = imx_clk_pfdv2("spll_pfd1", "spll", base + 0x60C, 1);
-       clks[IMX7ULP_CLK_SPLL_PFD2]     = imx_clk_pfdv2("spll_pfd2", "spll", base + 0x60C, 2);
-       clks[IMX7ULP_CLK_SPLL_PFD3]     = imx_clk_pfdv2("spll_pfd3", "spll", base + 0x60C, 3);
+       hws[IMX7ULP_CLK_SPLL_PFD0]      = imx_clk_hw_pfdv2("spll_pfd0", "spll", base + 0x60C, 0);
+       hws[IMX7ULP_CLK_SPLL_PFD1]      = imx_clk_hw_pfdv2("spll_pfd1", "spll", base + 0x60C, 1);
+       hws[IMX7ULP_CLK_SPLL_PFD2]      = imx_clk_hw_pfdv2("spll_pfd2", "spll", base + 0x60C, 2);
+       hws[IMX7ULP_CLK_SPLL_PFD3]      = imx_clk_hw_pfdv2("spll_pfd3", "spll", base + 0x60C, 3);
 
        /* PLL Mux */
-       clks[IMX7ULP_CLK_APLL_PFD_SEL]  = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
-       clks[IMX7ULP_CLK_SPLL_PFD_SEL]  = imx_clk_hw_mux_flags("spll_pfd_sel", base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
-       clks[IMX7ULP_CLK_APLL_SEL]      = imx_clk_hw_mux_flags("apll_sel", base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
-       clks[IMX7ULP_CLK_SPLL_SEL]      = imx_clk_hw_mux_flags("spll_sel", base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
+       hws[IMX7ULP_CLK_APLL_PFD_SEL]   = imx_clk_hw_mux_flags("apll_pfd_sel", base + 0x508, 14, 2, apll_pfd_sels, ARRAY_SIZE(apll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
+       hws[IMX7ULP_CLK_SPLL_PFD_SEL]   = imx_clk_hw_mux_flags("spll_pfd_sel", base + 0x608, 14, 2, spll_pfd_sels, ARRAY_SIZE(spll_pfd_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
+       hws[IMX7ULP_CLK_APLL_SEL]       = imx_clk_hw_mux_flags("apll_sel", base + 0x508, 1, 1, apll_sels, ARRAY_SIZE(apll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
+       hws[IMX7ULP_CLK_SPLL_SEL]       = imx_clk_hw_mux_flags("spll_sel", base + 0x608, 1, 1, spll_sels, ARRAY_SIZE(spll_sels), CLK_SET_RATE_PARENT | CLK_SET_PARENT_GATE);
 
-       clks[IMX7ULP_CLK_SPLL_BUS_CLK]  = imx_clk_divider_gate("spll_bus_clk", "spll_sel", CLK_SET_RATE_GATE, base + 0x604, 8, 3, 0, ulp_div_table, &imx_ccm_lock);
+       hws[IMX7ULP_CLK_SPLL_BUS_CLK]   = imx_clk_hw_divider_gate("spll_bus_clk", "spll_sel", CLK_SET_RATE_GATE, base + 0x604, 8, 3, 0, ulp_div_table, &imx_ccm_lock);
 
        /* scs/ddr/nic select different clock source requires that clock to be enabled first */
-       clks[IMX7ULP_CLK_SYS_SEL]       = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
-       clks[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel", base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
-       clks[IMX7ULP_CLK_NIC_SEL]       = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels));
-       clks[IMX7ULP_CLK_DDR_SEL]       = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
+       hws[IMX7ULP_CLK_SYS_SEL]        = imx_clk_hw_mux2("scs_sel", base + 0x14, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
+       hws[IMX7ULP_CLK_HSRUN_SYS_SEL] = imx_clk_hw_mux2("hsrun_scs_sel", base + 0x1c, 24, 4, scs_sels, ARRAY_SIZE(scs_sels));
+       hws[IMX7ULP_CLK_NIC_SEL]        = imx_clk_hw_mux2("nic_sel", base + 0x40, 28, 1, nic_sels, ARRAY_SIZE(nic_sels));
+       hws[IMX7ULP_CLK_DDR_SEL]        = imx_clk_hw_mux_flags("ddr_sel", base + 0x30, 24, 2, ddr_sels, ARRAY_SIZE(ddr_sels), CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
 
-       clks[IMX7ULP_CLK_CORE_DIV]      = imx_clk_hw_divider_flags("divcore",   "scs_sel",  base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
-       clks[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
+       hws[IMX7ULP_CLK_CORE_DIV]       = imx_clk_hw_divider_flags("divcore",   "scs_sel",  base + 0x14, 16, 4, CLK_SET_RATE_PARENT);
+       hws[IMX7ULP_CLK_HSRUN_CORE_DIV] = imx_clk_hw_divider_flags("hsrun_divcore", "hsrun_scs_sel", base + 0x1c, 16, 4, CLK_SET_RATE_PARENT);
 
-       clks[IMX7ULP_CLK_DDR_DIV]       = imx_clk_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
+       hws[IMX7ULP_CLK_DDR_DIV]        = imx_clk_hw_divider_gate("ddr_clk", "ddr_sel", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL, base + 0x30, 0, 3,
                                                               0, ulp_div_table, &imx_ccm_lock);
 
-       clks[IMX7ULP_CLK_NIC0_DIV]      = imx_clk_hw_divider_flags("nic0_clk",          "nic_sel",  base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
-       clks[IMX7ULP_CLK_NIC1_DIV]      = imx_clk_hw_divider_flags("nic1_clk",          "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
-       clks[IMX7ULP_CLK_NIC1_BUS_DIV]  = imx_clk_hw_divider_flags("nic1_bus_clk",      "nic0_clk", base + 0x40, 4,  4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+       hws[IMX7ULP_CLK_NIC0_DIV]       = imx_clk_hw_divider_flags("nic0_clk",          "nic_sel",  base + 0x40, 24, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+       hws[IMX7ULP_CLK_NIC1_DIV]       = imx_clk_hw_divider_flags("nic1_clk",          "nic0_clk", base + 0x40, 16, 4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
+       hws[IMX7ULP_CLK_NIC1_BUS_DIV]   = imx_clk_hw_divider_flags("nic1_bus_clk",      "nic0_clk", base + 0x40, 4,  4, CLK_SET_RATE_PARENT | CLK_IS_CRITICAL);
 
-       clks[IMX7ULP_CLK_GPU_DIV]       = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4);
+       hws[IMX7ULP_CLK_GPU_DIV]        = imx_clk_hw_divider("gpu_clk", "nic0_clk", base + 0x40, 20, 4);
 
-       clks[IMX7ULP_CLK_SOSC_BUS_CLK]  = imx_clk_divider_gate("sosc_bus_clk", "sosc", 0, base + 0x104, 8, 3,
+       hws[IMX7ULP_CLK_SOSC_BUS_CLK]   = imx_clk_hw_divider_gate("sosc_bus_clk", "sosc", 0, base + 0x104, 8, 3,
                                                               CLK_DIVIDER_READ_ONLY, ulp_div_table, &imx_ccm_lock);
-       clks[IMX7ULP_CLK_FIRC_BUS_CLK]  = imx_clk_divider_gate("firc_bus_clk", "firc", 0, base + 0x304, 8, 3,
+       hws[IMX7ULP_CLK_FIRC_BUS_CLK]   = imx_clk_hw_divider_gate("firc_bus_clk", "firc", 0, base + 0x304, 8, 3,
                                                               CLK_DIVIDER_READ_ONLY, ulp_div_table, &imx_ccm_lock);
 
-       imx_check_clk_hws(clks, clk_data->num);
+       imx_check_clk_hws(hws, clk_data->num);
 
        of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
 }
@@ -146,7 +146,7 @@ CLK_OF_DECLARE(imx7ulp_clk_scg1, "fsl,imx7ulp-scg1", imx7ulp_clk_scg1_init);
 static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
 {
        struct clk_hw_onecell_data *clk_data;
-       struct clk_hw **clks;
+       struct clk_hw **hws;
        void __iomem *base;
        int i;
 
@@ -156,42 +156,42 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
                return;
 
        clk_data->num = IMX7ULP_CLK_PCC2_END;
-       clks = clk_data->hws;
+       hws = clk_data->hws;
 
        /* PCC2 */
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
-       clks[IMX7ULP_CLK_DMA1]          = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30);
-       clks[IMX7ULP_CLK_RGPIO2P1]      = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30);
-       clks[IMX7ULP_CLK_DMA_MUX1]      = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30);
-       clks[IMX7ULP_CLK_CAAM]          = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30);
-       clks[IMX7ULP_CLK_LPTPM4]        = imx7ulp_clk_composite("lptpm4",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
-       clks[IMX7ULP_CLK_LPTPM5]        = imx7ulp_clk_composite("lptpm5",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
-       clks[IMX7ULP_CLK_LPIT1]         = imx7ulp_clk_composite("lpit1",   periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
-       clks[IMX7ULP_CLK_LPSPI2]        = imx7ulp_clk_composite("lpspi2",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa4);
-       clks[IMX7ULP_CLK_LPSPI3]        = imx7ulp_clk_composite("lpspi3",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa8);
-       clks[IMX7ULP_CLK_LPI2C4]        = imx7ulp_clk_composite("lpi2c4",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xac);
-       clks[IMX7ULP_CLK_LPI2C5]        = imx7ulp_clk_composite("lpi2c5",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb0);
-       clks[IMX7ULP_CLK_LPUART4]       = imx7ulp_clk_composite("lpuart4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb4);
-       clks[IMX7ULP_CLK_LPUART5]       = imx7ulp_clk_composite("lpuart5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb8);
-       clks[IMX7ULP_CLK_FLEXIO1]       = imx7ulp_clk_composite("flexio1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xc4);
-       clks[IMX7ULP_CLK_USB0]          = imx7ulp_clk_composite("usb0",    periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xcc);
-       clks[IMX7ULP_CLK_USB1]          = imx7ulp_clk_composite("usb1",    periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xd0);
-       clks[IMX7ULP_CLK_USB_PHY]       = imx_clk_hw_gate("usb_phy", "nic1_bus_clk", base + 0xd4, 30);
-       clks[IMX7ULP_CLK_USDHC0]        = imx7ulp_clk_composite("usdhc0",  periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xdc);
-       clks[IMX7ULP_CLK_USDHC1]        = imx7ulp_clk_composite("usdhc1",  periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xe0);
-       clks[IMX7ULP_CLK_WDG1]          = imx7ulp_clk_composite("wdg1",    periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true,  true, base + 0xf4);
-       clks[IMX7ULP_CLK_WDG2]          = imx7ulp_clk_composite("sdg2",    periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true,  true, base + 0x10c);
-
-       imx_check_clk_hws(clks, clk_data->num);
+       hws[IMX7ULP_CLK_DMA1]           = imx_clk_hw_gate("dma1", "nic1_clk", base + 0x20, 30);
+       hws[IMX7ULP_CLK_RGPIO2P1]       = imx_clk_hw_gate("rgpio2p1", "nic1_bus_clk", base + 0x3c, 30);
+       hws[IMX7ULP_CLK_DMA_MUX1]       = imx_clk_hw_gate("dma_mux1", "nic1_bus_clk", base + 0x84, 30);
+       hws[IMX7ULP_CLK_CAAM]           = imx_clk_hw_gate("caam", "nic1_clk", base + 0x90, 30);
+       hws[IMX7ULP_CLK_LPTPM4]         = imx7ulp_clk_hw_composite("lptpm4",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
+       hws[IMX7ULP_CLK_LPTPM5]         = imx7ulp_clk_hw_composite("lptpm5",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
+       hws[IMX7ULP_CLK_LPIT1]          = imx7ulp_clk_hw_composite("lpit1",   periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
+       hws[IMX7ULP_CLK_LPSPI2]         = imx7ulp_clk_hw_composite("lpspi2",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa4);
+       hws[IMX7ULP_CLK_LPSPI3]         = imx7ulp_clk_hw_composite("lpspi3",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xa8);
+       hws[IMX7ULP_CLK_LPI2C4]         = imx7ulp_clk_hw_composite("lpi2c4",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xac);
+       hws[IMX7ULP_CLK_LPI2C5]         = imx7ulp_clk_hw_composite("lpi2c5",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb0);
+       hws[IMX7ULP_CLK_LPUART4]        = imx7ulp_clk_hw_composite("lpuart4", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb4);
+       hws[IMX7ULP_CLK_LPUART5]        = imx7ulp_clk_hw_composite("lpuart5", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xb8);
+       hws[IMX7ULP_CLK_FLEXIO1]        = imx7ulp_clk_hw_composite("flexio1", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0xc4);
+       hws[IMX7ULP_CLK_USB0]           = imx7ulp_clk_hw_composite("usb0",    periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xcc);
+       hws[IMX7ULP_CLK_USB1]           = imx7ulp_clk_hw_composite("usb1",    periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xd0);
+       hws[IMX7ULP_CLK_USB_PHY]        = imx_clk_hw_gate("usb_phy", "nic1_bus_clk", base + 0xd4, 30);
+       hws[IMX7ULP_CLK_USDHC0]         = imx7ulp_clk_hw_composite("usdhc0",  periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xdc);
+       hws[IMX7ULP_CLK_USDHC1]         = imx7ulp_clk_hw_composite("usdhc1",  periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xe0);
+       hws[IMX7ULP_CLK_WDG1]           = imx7ulp_clk_hw_composite("wdg1",    periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true,  true, base + 0xf4);
+       hws[IMX7ULP_CLK_WDG2]           = imx7ulp_clk_hw_composite("wdg2",    periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true,  true, base + 0x10c);
+
+       imx_check_clk_hws(hws, clk_data->num);
 
        of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
 
        for (i = 0; i < ARRAY_SIZE(pcc2_uart_clk_ids); i++) {
                int index = pcc2_uart_clk_ids[i];
 
-               pcc2_uart_clks[i] = &clks[index]->clk;
+               pcc2_uart_clks[i] = &hws[index]->clk;
        }
 
        imx_register_uart_clocks(pcc2_uart_clks);
@@ -201,7 +201,7 @@ CLK_OF_DECLARE(imx7ulp_clk_pcc2, "fsl,imx7ulp-pcc2", imx7ulp_clk_pcc2_init);
 static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
 {
        struct clk_hw_onecell_data *clk_data;
-       struct clk_hw **clks;
+       struct clk_hw **hws;
        void __iomem *base;
        int i;
 
@@ -211,41 +211,41 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
                return;
 
        clk_data->num = IMX7ULP_CLK_PCC3_END;
-       clks = clk_data->hws;
+       hws = clk_data->hws;
 
        /* PCC3 */
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
-       clks[IMX7ULP_CLK_LPTPM6]        = imx7ulp_clk_composite("lptpm6",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x84);
-       clks[IMX7ULP_CLK_LPTPM7]        = imx7ulp_clk_composite("lptpm7",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x88);
+       hws[IMX7ULP_CLK_LPTPM6] = imx7ulp_clk_hw_composite("lptpm6",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x84);
+       hws[IMX7ULP_CLK_LPTPM7] = imx7ulp_clk_hw_composite("lptpm7",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x88);
 
-       clks[IMX7ULP_CLK_MMDC]          = clk_hw_register_gate(NULL, "mmdc", "nic1_clk", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
+       hws[IMX7ULP_CLK_MMDC]           = clk_hw_register_gate(NULL, "mmdc", "nic1_clk", CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
                                                               base + 0xac, 30, 0, &imx_ccm_lock);
-       clks[IMX7ULP_CLK_LPI2C6]        = imx7ulp_clk_composite("lpi2c6",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x90);
-       clks[IMX7ULP_CLK_LPI2C7]        = imx7ulp_clk_composite("lpi2c7",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
-       clks[IMX7ULP_CLK_LPUART6]       = imx7ulp_clk_composite("lpuart6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
-       clks[IMX7ULP_CLK_LPUART7]       = imx7ulp_clk_composite("lpuart7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
-       clks[IMX7ULP_CLK_DSI]           = imx7ulp_clk_composite("dsi",     periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true,  true, base + 0xa4);
-       clks[IMX7ULP_CLK_LCDIF]         = imx7ulp_clk_composite("lcdif",   periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xa8);
+       hws[IMX7ULP_CLK_LPI2C6] = imx7ulp_clk_hw_composite("lpi2c6",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x90);
+       hws[IMX7ULP_CLK_LPI2C7] = imx7ulp_clk_hw_composite("lpi2c7",  periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x94);
+       hws[IMX7ULP_CLK_LPUART6]        = imx7ulp_clk_hw_composite("lpuart6", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x98);
+       hws[IMX7ULP_CLK_LPUART7]        = imx7ulp_clk_hw_composite("lpuart7", periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, false, true, base + 0x9c);
+       hws[IMX7ULP_CLK_DSI]            = imx7ulp_clk_hw_composite("dsi",     periph_bus_sels, ARRAY_SIZE(periph_bus_sels), true, true,  true, base + 0xa4);
+       hws[IMX7ULP_CLK_LCDIF]          = imx7ulp_clk_hw_composite("lcdif",   periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, true,  true, base + 0xa8);
 
-       clks[IMX7ULP_CLK_VIU]           = imx_clk_hw_gate("viu",   "nic1_clk",     base + 0xa0, 30);
-       clks[IMX7ULP_CLK_PCTLC]         = imx_clk_hw_gate("pctlc", "nic1_bus_clk", base + 0xb8, 30);
-       clks[IMX7ULP_CLK_PCTLD]         = imx_clk_hw_gate("pctld", "nic1_bus_clk", base + 0xbc, 30);
-       clks[IMX7ULP_CLK_PCTLE]         = imx_clk_hw_gate("pctle", "nic1_bus_clk", base + 0xc0, 30);
-       clks[IMX7ULP_CLK_PCTLF]         = imx_clk_hw_gate("pctlf", "nic1_bus_clk", base + 0xc4, 30);
+       hws[IMX7ULP_CLK_VIU]            = imx_clk_hw_gate("viu",   "nic1_clk",     base + 0xa0, 30);
+       hws[IMX7ULP_CLK_PCTLC]          = imx_clk_hw_gate("pctlc", "nic1_bus_clk", base + 0xb8, 30);
+       hws[IMX7ULP_CLK_PCTLD]          = imx_clk_hw_gate("pctld", "nic1_bus_clk", base + 0xbc, 30);
+       hws[IMX7ULP_CLK_PCTLE]          = imx_clk_hw_gate("pctle", "nic1_bus_clk", base + 0xc0, 30);
+       hws[IMX7ULP_CLK_PCTLF]          = imx_clk_hw_gate("pctlf", "nic1_bus_clk", base + 0xc4, 30);
 
-       clks[IMX7ULP_CLK_GPU3D]         = imx7ulp_clk_composite("gpu3d",   periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x140);
-       clks[IMX7ULP_CLK_GPU2D]         = imx7ulp_clk_composite("gpu2d",   periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x144);
+       hws[IMX7ULP_CLK_GPU3D]          = imx7ulp_clk_hw_composite("gpu3d",   periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x140);
+       hws[IMX7ULP_CLK_GPU2D]          = imx7ulp_clk_hw_composite("gpu2d",   periph_plat_sels, ARRAY_SIZE(periph_plat_sels), true, false, true, base + 0x144);
 
-       imx_check_clk_hws(clks, clk_data->num);
+       imx_check_clk_hws(hws, clk_data->num);
 
        of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
 
        for (i = 0; i < ARRAY_SIZE(pcc3_uart_clk_ids); i++) {
                int index = pcc3_uart_clk_ids[i];
 
-               pcc3_uart_clks[i] = &clks[index]->clk;
+               pcc3_uart_clks[i] = &hws[index]->clk;
        }
 
        imx_register_uart_clocks(pcc3_uart_clks);
@@ -255,7 +255,7 @@ CLK_OF_DECLARE(imx7ulp_clk_pcc3, "fsl,imx7ulp-pcc3", imx7ulp_clk_pcc3_init);
 static void __init imx7ulp_clk_smc1_init(struct device_node *np)
 {
        struct clk_hw_onecell_data *clk_data;
-       struct clk_hw **clks;
+       struct clk_hw **hws;
        void __iomem *base;
 
        clk_data = kzalloc(struct_size(clk_data, hws, IMX7ULP_CLK_SMC1_END),
@@ -264,15 +264,15 @@ static void __init imx7ulp_clk_smc1_init(struct device_node *np)
                return;
 
        clk_data->num = IMX7ULP_CLK_SMC1_END;
-       clks = clk_data->hws;
+       hws = clk_data->hws;
 
        /* SMC1 */
        base = of_iomap(np, 0);
        WARN_ON(!base);
 
-       clks[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL);
+       hws[IMX7ULP_CLK_ARM] = imx_clk_hw_mux_flags("arm", base + 0x10, 8, 2, arm_sels, ARRAY_SIZE(arm_sels), CLK_IS_CRITICAL);
 
-       imx_check_clk_hws(clks, clk_data->num);
+       imx_check_clk_hws(hws, clk_data->num);
 
        of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
 }
index 030b15d..2ed93fc 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "clk.h"
@@ -285,118 +286,126 @@ static const char *imx8mm_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }
 static const char *imx8mm_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", "sys_pll1_200m", "audio_pll2_out",
                                         "vpu_pll", "sys_pll1_80m", };
 
-static struct clk *clks[IMX8MM_CLK_END];
-static struct clk_onecell_data clk_data;
+static struct clk_hw_onecell_data *clk_hw_data;
+static struct clk_hw **hws;
 
-static struct clk ** const uart_clks[] = {
-       &clks[IMX8MM_CLK_UART1_ROOT],
-       &clks[IMX8MM_CLK_UART2_ROOT],
-       &clks[IMX8MM_CLK_UART3_ROOT],
-       &clks[IMX8MM_CLK_UART4_ROOT],
-       NULL
+static const int uart_clk_ids[] = {
+       IMX8MM_CLK_UART1_ROOT,
+       IMX8MM_CLK_UART2_ROOT,
+       IMX8MM_CLK_UART3_ROOT,
+       IMX8MM_CLK_UART4_ROOT,
 };
+static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1];
 
 static int imx8mm_clocks_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
        void __iomem *base;
-       int ret;
+       int ret, i;
 
-       clks[IMX8MM_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
-       clks[IMX8MM_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
-       clks[IMX8MM_CLK_32K] = of_clk_get_by_name(np, "osc_32k");
-       clks[IMX8MM_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
-       clks[IMX8MM_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
-       clks[IMX8MM_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
-       clks[IMX8MM_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
+       clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+                                         IMX8MM_CLK_END), GFP_KERNEL);
+       if (WARN_ON(!clk_hw_data))
+               return -ENOMEM;
+
+       clk_hw_data->num = IMX8MM_CLK_END;
+       hws = clk_hw_data->hws;
+
+       hws[IMX8MM_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
+       hws[IMX8MM_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m");
+       hws[IMX8MM_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k");
+       hws[IMX8MM_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
+       hws[IMX8MM_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2");
+       hws[IMX8MM_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3");
+       hws[IMX8MM_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
 
        np = of_find_compatible_node(NULL, NULL, "fsl,imx8mm-anatop");
        base = of_iomap(np, 0);
        if (WARN_ON(!base))
                return -ENOMEM;
 
-       clks[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-
-       clks[IMX8MM_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
-       clks[IMX8MM_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
-       clks[IMX8MM_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
-       clks[IMX8MM_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll);
-       clks[IMX8MM_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
-       clks[IMX8MM_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
-       clks[IMX8MM_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
-       clks[IMX8MM_SYS_PLL1] = imx_clk_fixed("sys_pll1", 800000000);
-       clks[IMX8MM_SYS_PLL2] = imx_clk_fixed("sys_pll2", 1000000000);
-       clks[IMX8MM_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
+       hws[IMX8MM_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MM_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MM_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MM_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MM_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MM_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MM_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MM_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+       hws[IMX8MM_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
+       hws[IMX8MM_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
+       hws[IMX8MM_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
+       hws[IMX8MM_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
+       hws[IMX8MM_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
+       hws[IMX8MM_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
+       hws[IMX8MM_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
+       hws[IMX8MM_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
+       hws[IMX8MM_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
+       hws[IMX8MM_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
 
        /* PLL bypass out */
-       clks[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MM_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MM_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MM_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MM_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MM_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MM_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MM_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MM_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
 
        /* PLL out gate */
-       clks[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
-       clks[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
-       clks[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
-       clks[IMX8MM_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
-       clks[IMX8MM_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
-       clks[IMX8MM_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
-       clks[IMX8MM_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
-       clks[IMX8MM_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
+       hws[IMX8MM_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+       hws[IMX8MM_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+       hws[IMX8MM_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+       hws[IMX8MM_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+       hws[IMX8MM_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
+       hws[IMX8MM_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
+       hws[IMX8MM_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
+       hws[IMX8MM_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
 
        /* SYS PLL1 fixed output */
-       clks[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27);
-       clks[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25);
-       clks[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23);
-       clks[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21);
-       clks[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19);
-       clks[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17);
-       clks[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15);
-       clks[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13);
-       clks[IMX8MM_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
-
-       clks[IMX8MM_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
-       clks[IMX8MM_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
-       clks[IMX8MM_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
-       clks[IMX8MM_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
-       clks[IMX8MM_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
-       clks[IMX8MM_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
-       clks[IMX8MM_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
-       clks[IMX8MM_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
-       clks[IMX8MM_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+       hws[IMX8MM_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27);
+       hws[IMX8MM_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25);
+       hws[IMX8MM_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23);
+       hws[IMX8MM_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21);
+       hws[IMX8MM_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19);
+       hws[IMX8MM_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17);
+       hws[IMX8MM_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15);
+       hws[IMX8MM_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13);
+       hws[IMX8MM_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
+
+       hws[IMX8MM_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
+       hws[IMX8MM_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
+       hws[IMX8MM_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
+       hws[IMX8MM_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
+       hws[IMX8MM_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
+       hws[IMX8MM_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
+       hws[IMX8MM_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
+       hws[IMX8MM_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
+       hws[IMX8MM_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
 
        /* SYS PLL2 fixed output */
-       clks[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27);
-       clks[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25);
-       clks[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23);
-       clks[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21);
-       clks[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19);
-       clks[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17);
-       clks[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15);
-       clks[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13);
-       clks[IMX8MM_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
-
-       clks[IMX8MM_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
-       clks[IMX8MM_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
-       clks[IMX8MM_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
-       clks[IMX8MM_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
-       clks[IMX8MM_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
-       clks[IMX8MM_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
-       clks[IMX8MM_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
-       clks[IMX8MM_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
-       clks[IMX8MM_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+       hws[IMX8MM_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27);
+       hws[IMX8MM_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25);
+       hws[IMX8MM_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23);
+       hws[IMX8MM_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21);
+       hws[IMX8MM_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19);
+       hws[IMX8MM_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17);
+       hws[IMX8MM_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15);
+       hws[IMX8MM_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13);
+       hws[IMX8MM_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
+
+       hws[IMX8MM_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
+       hws[IMX8MM_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
+       hws[IMX8MM_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
+       hws[IMX8MM_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
+       hws[IMX8MM_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
+       hws[IMX8MM_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
+       hws[IMX8MM_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
+       hws[IMX8MM_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
+       hws[IMX8MM_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
 
        np = dev->of_node;
        base = devm_platform_ioremap_resource(pdev, 0);
@@ -404,204 +413,213 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
                return PTR_ERR(base);
 
        /* Core Slice */
-       clks[IMX8MM_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
-       clks[IMX8MM_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
-       clks[IMX8MM_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
-       clks[IMX8MM_CLK_GPU3D_SRC] = imx_clk_mux2("gpu3d_src", base + 0x8180, 24, 3,  imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
-       clks[IMX8MM_CLK_GPU2D_SRC] = imx_clk_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels,  ARRAY_SIZE(imx8mm_gpu2d_sels));
-       clks[IMX8MM_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
-       clks[IMX8MM_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
-       clks[IMX8MM_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
-       clks[IMX8MM_CLK_GPU3D_CG] = imx_clk_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
-       clks[IMX8MM_CLK_GPU2D_CG] = imx_clk_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
-       clks[IMX8MM_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
-       clks[IMX8MM_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
-       clks[IMX8MM_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
-       clks[IMX8MM_CLK_GPU3D_DIV] = imx_clk_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
-       clks[IMX8MM_CLK_GPU2D_DIV] = imx_clk_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
+       hws[IMX8MM_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mm_a53_sels, ARRAY_SIZE(imx8mm_a53_sels));
+       hws[IMX8MM_CLK_M4_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mm_m4_sels, ARRAY_SIZE(imx8mm_m4_sels));
+       hws[IMX8MM_CLK_VPU_SRC] = imx_clk_hw_mux2("vpu_src", base + 0x8100, 24, 3, imx8mm_vpu_sels, ARRAY_SIZE(imx8mm_vpu_sels));
+       hws[IMX8MM_CLK_GPU3D_SRC] = imx_clk_hw_mux2("gpu3d_src", base + 0x8180, 24, 3,  imx8mm_gpu3d_sels, ARRAY_SIZE(imx8mm_gpu3d_sels));
+       hws[IMX8MM_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", base + 0x8200, 24, 3, imx8mm_gpu2d_sels,  ARRAY_SIZE(imx8mm_gpu2d_sels));
+       hws[IMX8MM_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
+       hws[IMX8MM_CLK_M4_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
+       hws[IMX8MM_CLK_VPU_CG] = imx_clk_hw_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
+       hws[IMX8MM_CLK_GPU3D_CG] = imx_clk_hw_gate3("gpu3d_cg", "gpu3d_src", base + 0x8180, 28);
+       hws[IMX8MM_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", base + 0x8200, 28);
+       hws[IMX8MM_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+       hws[IMX8MM_CLK_M4_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
+       hws[IMX8MM_CLK_VPU_DIV] = imx_clk_hw_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
+       hws[IMX8MM_CLK_GPU3D_DIV] = imx_clk_hw_divider2("gpu3d_div", "gpu3d_cg", base + 0x8180, 0, 3);
+       hws[IMX8MM_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", base + 0x8200, 0, 3);
 
        /* BUS */
-       clks[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi",  imx8mm_main_axi_sels, base + 0x8800);
-       clks[IMX8MM_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
-       clks[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
-       clks[IMX8MM_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
-       clks[IMX8MM_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
-       clks[IMX8MM_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
-       clks[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
-       clks[IMX8MM_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
-       clks[IMX8MM_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
-       clks[IMX8MM_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
-       clks[IMX8MM_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
-       clks[IMX8MM_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
+       hws[IMX8MM_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi",  imx8mm_main_axi_sels, base + 0x8800);
+       hws[IMX8MM_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mm_enet_axi_sels, base + 0x8880);
+       hws[IMX8MM_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mm_nand_usdhc_sels, base + 0x8900);
+       hws[IMX8MM_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mm_vpu_bus_sels, base + 0x8980);
+       hws[IMX8MM_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mm_disp_axi_sels, base + 0x8a00);
+       hws[IMX8MM_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mm_disp_apb_sels, base + 0x8a80);
+       hws[IMX8MM_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mm_disp_rtrm_sels, base + 0x8b00);
+       hws[IMX8MM_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mm_usb_bus_sels, base + 0x8b80);
+       hws[IMX8MM_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mm_gpu_axi_sels, base + 0x8c00);
+       hws[IMX8MM_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mm_gpu_ahb_sels, base + 0x8c80);
+       hws[IMX8MM_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mm_noc_sels, base + 0x8d00);
+       hws[IMX8MM_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mm_noc_apb_sels, base + 0x8d80);
 
        /* AHB */
-       clks[IMX8MM_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
-       clks[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
+       hws[IMX8MM_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mm_ahb_sels, base + 0x9000);
+       hws[IMX8MM_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mm_audio_ahb_sels, base + 0x9100);
 
        /* IPG */
-       clks[IMX8MM_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
-       clks[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+       hws[IMX8MM_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
+       hws[IMX8MM_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+
+       /*
+        * DRAM clocks are manipulated from TF-A outside clock framework.
+        * Mark with GET_RATE_NOCACHE to always read div value from hardware
+        */
+       hws[IMX8MM_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
+       hws[IMX8MM_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mm_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
 
        /* IP */
-       clks[IMX8MM_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mm_dram_alt_sels, base + 0xa000);
-       clks[IMX8MM_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mm_dram_apb_sels, base + 0xa080);
-       clks[IMX8MM_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
-       clks[IMX8MM_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180);
-       clks[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200);
-       clks[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280);
-       clks[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300);
-       clks[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380);
-       clks[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400);
-       clks[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480);
-       clks[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500);
-       clks[IMX8MM_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mm_sai1_sels, base + 0xa580);
-       clks[IMX8MM_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mm_sai2_sels, base + 0xa600);
-       clks[IMX8MM_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mm_sai3_sels, base + 0xa680);
-       clks[IMX8MM_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mm_sai4_sels, base + 0xa700);
-       clks[IMX8MM_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mm_sai5_sels, base + 0xa780);
-       clks[IMX8MM_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mm_sai6_sels, base + 0xa800);
-       clks[IMX8MM_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880);
-       clks[IMX8MM_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900);
-       clks[IMX8MM_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980);
-       clks[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00);
-       clks[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80);
-       clks[IMX8MM_CLK_NAND] = imx8m_clk_composite("nand", imx8mm_nand_sels, base + 0xab00);
-       clks[IMX8MM_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mm_qspi_sels, base + 0xab80);
-       clks[IMX8MM_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00);
-       clks[IMX8MM_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80);
-       clks[IMX8MM_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00);
-       clks[IMX8MM_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80);
-       clks[IMX8MM_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00);
-       clks[IMX8MM_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80);
-       clks[IMX8MM_CLK_UART1] = imx8m_clk_composite("uart1", imx8mm_uart1_sels, base + 0xaf00);
-       clks[IMX8MM_CLK_UART2] = imx8m_clk_composite("uart2", imx8mm_uart2_sels, base + 0xaf80);
-       clks[IMX8MM_CLK_UART3] = imx8m_clk_composite("uart3", imx8mm_uart3_sels, base + 0xb000);
-       clks[IMX8MM_CLK_UART4] = imx8m_clk_composite("uart4", imx8mm_uart4_sels, base + 0xb080);
-       clks[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100);
-       clks[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180);
-       clks[IMX8MM_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mm_gic_sels, base + 0xb200);
-       clks[IMX8MM_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280);
-       clks[IMX8MM_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300);
-       clks[IMX8MM_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380);
-       clks[IMX8MM_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400);
-       clks[IMX8MM_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480);
-       clks[IMX8MM_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500);
-       clks[IMX8MM_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580);
-       clks[IMX8MM_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mm_wdog_sels, base + 0xb900);
-       clks[IMX8MM_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980);
-       clks[IMX8MM_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mm_clko1_sels, base + 0xba00);
-       clks[IMX8MM_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00);
-       clks[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80);
-       clks[IMX8MM_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00);
-       clks[IMX8MM_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80);
-       clks[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00);
-       clks[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80);
-       clks[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00);
-       clks[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80);
-       clks[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00);
-       clks[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80);
-       clks[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000);
-       clks[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080);
-       clks[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100);
-       clks[IMX8MM_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180);
-       clks[IMX8MM_CLK_PDM] = imx8m_clk_composite("pdm", imx8mm_pdm_sels, base + 0xc200);
-       clks[IMX8MM_CLK_VPU_H1] = imx8m_clk_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280);
+       hws[IMX8MM_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mm_vpu_g1_sels, base + 0xa100);
+       hws[IMX8MM_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mm_vpu_g2_sels, base + 0xa180);
+       hws[IMX8MM_CLK_DISP_DTRC] = imx8m_clk_hw_composite("disp_dtrc", imx8mm_disp_dtrc_sels, base + 0xa200);
+       hws[IMX8MM_CLK_DISP_DC8000] = imx8m_clk_hw_composite("disp_dc8000", imx8mm_disp_dc8000_sels, base + 0xa280);
+       hws[IMX8MM_CLK_PCIE1_CTRL] = imx8m_clk_hw_composite("pcie1_ctrl", imx8mm_pcie1_ctrl_sels, base + 0xa300);
+       hws[IMX8MM_CLK_PCIE1_PHY] = imx8m_clk_hw_composite("pcie1_phy", imx8mm_pcie1_phy_sels, base + 0xa380);
+       hws[IMX8MM_CLK_PCIE1_AUX] = imx8m_clk_hw_composite("pcie1_aux", imx8mm_pcie1_aux_sels, base + 0xa400);
+       hws[IMX8MM_CLK_DC_PIXEL] = imx8m_clk_hw_composite("dc_pixel", imx8mm_dc_pixel_sels, base + 0xa480);
+       hws[IMX8MM_CLK_LCDIF_PIXEL] = imx8m_clk_hw_composite("lcdif_pixel", imx8mm_lcdif_pixel_sels, base + 0xa500);
+       hws[IMX8MM_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mm_sai1_sels, base + 0xa580);
+       hws[IMX8MM_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mm_sai2_sels, base + 0xa600);
+       hws[IMX8MM_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mm_sai3_sels, base + 0xa680);
+       hws[IMX8MM_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mm_sai4_sels, base + 0xa700);
+       hws[IMX8MM_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mm_sai5_sels, base + 0xa780);
+       hws[IMX8MM_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mm_sai6_sels, base + 0xa800);
+       hws[IMX8MM_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mm_spdif1_sels, base + 0xa880);
+       hws[IMX8MM_CLK_SPDIF2] = imx8m_clk_hw_composite("spdif2", imx8mm_spdif2_sels, base + 0xa900);
+       hws[IMX8MM_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mm_enet_ref_sels, base + 0xa980);
+       hws[IMX8MM_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mm_enet_timer_sels, base + 0xaa00);
+       hws[IMX8MM_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mm_enet_phy_sels, base + 0xaa80);
+       hws[IMX8MM_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mm_nand_sels, base + 0xab00);
+       hws[IMX8MM_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mm_qspi_sels, base + 0xab80);
+       hws[IMX8MM_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mm_usdhc1_sels, base + 0xac00);
+       hws[IMX8MM_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mm_usdhc2_sels, base + 0xac80);
+       hws[IMX8MM_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mm_i2c1_sels, base + 0xad00);
+       hws[IMX8MM_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mm_i2c2_sels, base + 0xad80);
+       hws[IMX8MM_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mm_i2c3_sels, base + 0xae00);
+       hws[IMX8MM_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mm_i2c4_sels, base + 0xae80);
+       hws[IMX8MM_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mm_uart1_sels, base + 0xaf00);
+       hws[IMX8MM_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mm_uart2_sels, base + 0xaf80);
+       hws[IMX8MM_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mm_uart3_sels, base + 0xb000);
+       hws[IMX8MM_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mm_uart4_sels, base + 0xb080);
+       hws[IMX8MM_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mm_usb_core_sels, base + 0xb100);
+       hws[IMX8MM_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mm_usb_phy_sels, base + 0xb180);
+       hws[IMX8MM_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mm_gic_sels, base + 0xb200);
+       hws[IMX8MM_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mm_ecspi1_sels, base + 0xb280);
+       hws[IMX8MM_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mm_ecspi2_sels, base + 0xb300);
+       hws[IMX8MM_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mm_pwm1_sels, base + 0xb380);
+       hws[IMX8MM_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mm_pwm2_sels, base + 0xb400);
+       hws[IMX8MM_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mm_pwm3_sels, base + 0xb480);
+       hws[IMX8MM_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mm_pwm4_sels, base + 0xb500);
+       hws[IMX8MM_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mm_gpt1_sels, base + 0xb580);
+       hws[IMX8MM_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mm_wdog_sels, base + 0xb900);
+       hws[IMX8MM_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mm_wrclk_sels, base + 0xb980);
+       hws[IMX8MM_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mm_clko1_sels, base + 0xba00);
+       hws[IMX8MM_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mm_dsi_core_sels, base + 0xbb00);
+       hws[IMX8MM_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mm_dsi_phy_sels, base + 0xbb80);
+       hws[IMX8MM_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mm_dsi_dbi_sels, base + 0xbc00);
+       hws[IMX8MM_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mm_usdhc3_sels, base + 0xbc80);
+       hws[IMX8MM_CLK_CSI1_CORE] = imx8m_clk_hw_composite("csi1_core", imx8mm_csi1_core_sels, base + 0xbd00);
+       hws[IMX8MM_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mm_csi1_phy_sels, base + 0xbd80);
+       hws[IMX8MM_CLK_CSI1_ESC] = imx8m_clk_hw_composite("csi1_esc", imx8mm_csi1_esc_sels, base + 0xbe00);
+       hws[IMX8MM_CLK_CSI2_CORE] = imx8m_clk_hw_composite("csi2_core", imx8mm_csi2_core_sels, base + 0xbe80);
+       hws[IMX8MM_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mm_csi2_phy_sels, base + 0xbf00);
+       hws[IMX8MM_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mm_csi2_esc_sels, base + 0xbf80);
+       hws[IMX8MM_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mm_pcie2_ctrl_sels, base + 0xc000);
+       hws[IMX8MM_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mm_pcie2_phy_sels, base + 0xc080);
+       hws[IMX8MM_CLK_PCIE2_AUX] = imx8m_clk_hw_composite("pcie2_aux", imx8mm_pcie2_aux_sels, base + 0xc100);
+       hws[IMX8MM_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mm_ecspi3_sels, base + 0xc180);
+       hws[IMX8MM_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mm_pdm_sels, base + 0xc200);
+       hws[IMX8MM_CLK_VPU_H1] = imx8m_clk_hw_composite("vpu_h1", imx8mm_vpu_h1_sels, base + 0xc280);
 
        /* CCGR */
-       clks[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
-       clks[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
-       clks[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
-       clks[IMX8MM_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
-       clks[IMX8MM_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
-       clks[IMX8MM_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
-       clks[IMX8MM_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
-       clks[IMX8MM_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
-       clks[IMX8MM_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
-       clks[IMX8MM_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
-       clks[IMX8MM_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
-       clks[IMX8MM_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
-       clks[IMX8MM_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
-       clks[IMX8MM_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
-       clks[IMX8MM_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
-       clks[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
-       clks[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
-       clks[IMX8MM_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
-       clks[IMX8MM_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
-       clks[IMX8MM_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
-       clks[IMX8MM_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
-       clks[IMX8MM_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
-       clks[IMX8MM_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
-       clks[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
-       clks[IMX8MM_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
-       clks[IMX8MM_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
-       clks[IMX8MM_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
-       clks[IMX8MM_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
-       clks[IMX8MM_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
-       clks[IMX8MM_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
-       clks[IMX8MM_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
-       clks[IMX8MM_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
-       clks[IMX8MM_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
-       clks[IMX8MM_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
-       clks[IMX8MM_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
-       clks[IMX8MM_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
-       clks[IMX8MM_CLK_SNVS_ROOT] = imx_clk_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
-       clks[IMX8MM_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
-       clks[IMX8MM_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
-       clks[IMX8MM_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
-       clks[IMX8MM_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
-       clks[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
-       clks[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
-       clks[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
-       clks[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
-       clks[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
-       clks[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
-       clks[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
-       clks[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0);
-       clks[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
-       clks[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0);
-       clks[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
-       clks[IMX8MM_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
-       clks[IMX8MM_CLK_PDM_IPG]  = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
-       clks[IMX8MM_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_disp);
-       clks[IMX8MM_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
-       clks[IMX8MM_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
-       clks[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_disp);
-       clks[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
-       clks[IMX8MM_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
-       clks[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
-       clks[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
-       clks[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
-       clks[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
-       clks[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
-       clks[IMX8MM_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
-
-       clks[IMX8MM_CLK_GPT_3M] = imx_clk_fixed_factor("gpt_3m", "osc_24m", 1, 8);
-
-       clks[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
-       clks[IMX8MM_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
-
-       clks[IMX8MM_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
-                                          clks[IMX8MM_CLK_A53_DIV],
-                                          clks[IMX8MM_CLK_A53_SRC],
-                                          clks[IMX8MM_ARM_PLL_OUT],
-                                          clks[IMX8MM_SYS_PLL1_800M]);
-
-       imx_check_clocks(clks, ARRAY_SIZE(clks));
-
-       clk_data.clks = clks;
-       clk_data.clk_num = ARRAY_SIZE(clks);
-       ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       hws[IMX8MM_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
+       hws[IMX8MM_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
+       hws[IMX8MM_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
+       hws[IMX8MM_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
+       hws[IMX8MM_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
+       hws[IMX8MM_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
+       hws[IMX8MM_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
+       hws[IMX8MM_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
+       hws[IMX8MM_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
+       hws[IMX8MM_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
+       hws[IMX8MM_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
+       hws[IMX8MM_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
+       hws[IMX8MM_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
+       hws[IMX8MM_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
+       hws[IMX8MM_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
+       hws[IMX8MM_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
+       hws[IMX8MM_CLK_PCIE1_ROOT] = imx_clk_hw_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
+       hws[IMX8MM_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
+       hws[IMX8MM_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
+       hws[IMX8MM_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
+       hws[IMX8MM_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
+       hws[IMX8MM_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
+       hws[IMX8MM_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
+       hws[IMX8MM_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
+       hws[IMX8MM_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
+       hws[IMX8MM_CLK_SAI1_IPG] = imx_clk_hw_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
+       hws[IMX8MM_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
+       hws[IMX8MM_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
+       hws[IMX8MM_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
+       hws[IMX8MM_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
+       hws[IMX8MM_CLK_SAI4_ROOT] = imx_clk_hw_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
+       hws[IMX8MM_CLK_SAI4_IPG] = imx_clk_hw_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
+       hws[IMX8MM_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
+       hws[IMX8MM_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
+       hws[IMX8MM_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
+       hws[IMX8MM_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
+       hws[IMX8MM_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
+       hws[IMX8MM_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
+       hws[IMX8MM_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
+       hws[IMX8MM_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
+       hws[IMX8MM_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
+       hws[IMX8MM_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
+       hws[IMX8MM_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_div", base + 0x44f0, 0);
+       hws[IMX8MM_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
+       hws[IMX8MM_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
+       hws[IMX8MM_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
+       hws[IMX8MM_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
+       hws[IMX8MM_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
+       hws[IMX8MM_CLK_VPU_G1_ROOT] = imx_clk_hw_gate4("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0);
+       hws[IMX8MM_CLK_GPU_BUS_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
+       hws[IMX8MM_CLK_VPU_H1_ROOT] = imx_clk_hw_gate4("vpu_h1_root_clk", "vpu_h1", base + 0x4590, 0);
+       hws[IMX8MM_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0);
+       hws[IMX8MM_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
+       hws[IMX8MM_CLK_PDM_IPG]  = imx_clk_hw_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
+       hws[IMX8MM_CLK_DISP_ROOT] = imx_clk_hw_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_disp);
+       hws[IMX8MM_CLK_DISP_AXI_ROOT]  = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
+       hws[IMX8MM_CLK_DISP_APB_ROOT]  = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
+       hws[IMX8MM_CLK_DISP_RTRM_ROOT] = imx_clk_hw_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_disp);
+       hws[IMX8MM_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
+       hws[IMX8MM_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
+       hws[IMX8MM_CLK_VPU_DEC_ROOT] = imx_clk_hw_gate4("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0);
+       hws[IMX8MM_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
+       hws[IMX8MM_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
+       hws[IMX8MM_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
+       hws[IMX8MM_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", base + 0x4660, 0);
+       hws[IMX8MM_CLK_CSI1_ROOT] = imx_clk_hw_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
+
+       hws[IMX8MM_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc_24m", 1, 8);
+
+       hws[IMX8MM_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
+       hws[IMX8MM_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mm_dram_core_sels, ARRAY_SIZE(imx8mm_dram_core_sels), CLK_IS_CRITICAL);
+
+       hws[IMX8MM_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div",
+                                          hws[IMX8MM_CLK_A53_DIV]->clk,
+                                          hws[IMX8MM_CLK_A53_SRC]->clk,
+                                          hws[IMX8MM_ARM_PLL_OUT]->clk,
+                                          hws[IMX8MM_SYS_PLL1_800M]->clk);
+
+       imx_check_clk_hws(hws, IMX8MM_CLK_END);
+
+       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
        if (ret < 0) {
-               pr_err("failed to register clks for i.MX8MM\n");
-               goto unregister_clks;
+               dev_err(dev, "failed to register clks for i.MX8MM\n");
+               goto unregister_hws;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
+               int index = uart_clk_ids[i];
+
+               uart_hws[i] = &hws[index]->clk;
        }
 
-       imx_register_uart_clocks(uart_clks);
+       imx_register_uart_clocks(uart_hws);
 
        return 0;
 
-unregister_clks:
-       imx_unregister_clocks(clks, ARRAY_SIZE(clks));
+unregister_hws:
+       imx_unregister_hw_clocks(hws, IMX8MM_CLK_END);
 
        return ret;
 }
@@ -616,6 +634,11 @@ static struct platform_driver imx8mm_clk_driver = {
        .probe = imx8mm_clocks_probe,
        .driver = {
                .name = "imx8mm-ccm",
+               /*
+                * Disable bind attributes: clocks are not removed and
+                * reloading the driver will crash or break devices.
+                */
+               .suppress_bind_attrs = true,
                .of_match_table = of_match_ptr(imx8mm_clk_of_match),
        },
 };
index 9f5a5a5..c5e7316 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/types.h>
 
 #include "clk.h"
@@ -280,284 +281,302 @@ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sy
                                                 "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out",
                                                 "video_pll1_out", "osc_32k", };
 
-static struct clk *clks[IMX8MN_CLK_END];
-static struct clk_onecell_data clk_data;
+static struct clk_hw_onecell_data *clk_hw_data;
+static struct clk_hw **hws;
 
-static struct clk ** const uart_clks[] = {
-       &clks[IMX8MN_CLK_UART1_ROOT],
-       &clks[IMX8MN_CLK_UART2_ROOT],
-       &clks[IMX8MN_CLK_UART3_ROOT],
-       &clks[IMX8MN_CLK_UART4_ROOT],
-       NULL
+static const int uart_clk_ids[] = {
+       IMX8MN_CLK_UART1_ROOT,
+       IMX8MN_CLK_UART2_ROOT,
+       IMX8MN_CLK_UART3_ROOT,
+       IMX8MN_CLK_UART4_ROOT,
 };
+static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1];
 
 static int imx8mn_clocks_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
        void __iomem *base;
-       int ret;
+       int ret, i;
 
-       clks[IMX8MN_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
-       clks[IMX8MN_CLK_24M] = of_clk_get_by_name(np, "osc_24m");
-       clks[IMX8MN_CLK_32K] = of_clk_get_by_name(np, "osc_32k");
-       clks[IMX8MN_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
-       clks[IMX8MN_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
-       clks[IMX8MN_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
-       clks[IMX8MN_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
+       clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+                                         IMX8MN_CLK_END), GFP_KERNEL);
+       if (WARN_ON(!clk_hw_data))
+               return -ENOMEM;
+
+       clk_hw_data->num = IMX8MN_CLK_END;
+       hws = clk_hw_data->hws;
+
+       hws[IMX8MN_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
+       hws[IMX8MN_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m");
+       hws[IMX8MN_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k");
+       hws[IMX8MN_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
+       hws[IMX8MN_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2");
+       hws[IMX8MN_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3");
+       hws[IMX8MN_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
 
        np = of_find_compatible_node(NULL, NULL, "fsl,imx8mn-anatop");
        base = of_iomap(np, 0);
        if (WARN_ON(!base)) {
                ret = -ENOMEM;
-               goto unregister_clks;
+               goto unregister_hws;
        }
 
-       clks[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-
-       clks[IMX8MN_AUDIO_PLL1] = imx_clk_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
-       clks[IMX8MN_AUDIO_PLL2] = imx_clk_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
-       clks[IMX8MN_VIDEO_PLL1] = imx_clk_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
-       clks[IMX8MN_DRAM_PLL] = imx_clk_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_pll);
-       clks[IMX8MN_GPU_PLL] = imx_clk_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
-       clks[IMX8MN_VPU_PLL] = imx_clk_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
-       clks[IMX8MN_ARM_PLL] = imx_clk_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
-       clks[IMX8MN_SYS_PLL1] = imx_clk_fixed("sys_pll1", 800000000);
-       clks[IMX8MN_SYS_PLL2] = imx_clk_fixed("sys_pll2", 1000000000);
-       clks[IMX8MN_SYS_PLL3] = imx_clk_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
+       hws[IMX8MN_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MN_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MN_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MN_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MN_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MN_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MN_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MN_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+       hws[IMX8MN_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", base, &imx_1443x_pll);
+       hws[IMX8MN_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", base + 0x14, &imx_1443x_pll);
+       hws[IMX8MN_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", base + 0x28, &imx_1443x_pll);
+       hws[IMX8MN_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", base + 0x50, &imx_1443x_dram_pll);
+       hws[IMX8MN_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", base + 0x64, &imx_1416x_pll);
+       hws[IMX8MN_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", base + 0x74, &imx_1416x_pll);
+       hws[IMX8MN_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", base + 0x84, &imx_1416x_pll);
+       hws[IMX8MN_SYS_PLL1] = imx_clk_hw_fixed("sys_pll1", 800000000);
+       hws[IMX8MN_SYS_PLL2] = imx_clk_hw_fixed("sys_pll2", 1000000000);
+       hws[IMX8MN_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", base + 0x114, &imx_1416x_pll);
 
        /* PLL bypass out */
-       clks[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MN_GPU_PLL_BYPASS] = imx_clk_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MN_VPU_PLL_BYPASS] = imx_clk_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MN_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MN_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", base, 16, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MN_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", base + 0x14, 16, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MN_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", base + 0x28, 16, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MN_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", base + 0x50, 16, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MN_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", base + 0x64, 28, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MN_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", base + 0x74, 28, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MN_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x84, 28, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MN_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", base + 0x114, 28, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
 
        /* PLL out gate */
-       clks[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
-       clks[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
-       clks[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
-       clks[IMX8MN_DRAM_PLL_OUT] = imx_clk_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
-       clks[IMX8MN_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
-       clks[IMX8MN_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
-       clks[IMX8MN_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
-       clks[IMX8MN_SYS_PLL3_OUT] = imx_clk_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
+       hws[IMX8MN_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base, 13);
+       hws[IMX8MN_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x14, 13);
+       hws[IMX8MN_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x28, 13);
+       hws[IMX8MN_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", base + 0x50, 13);
+       hws[IMX8MN_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x64, 11);
+       hws[IMX8MN_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x74, 11);
+       hws[IMX8MN_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x84, 11);
+       hws[IMX8MN_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", base + 0x114, 11);
 
        /* SYS PLL1 fixed output */
-       clks[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27);
-       clks[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25);
-       clks[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23);
-       clks[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21);
-       clks[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19);
-       clks[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17);
-       clks[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15);
-       clks[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13);
-       clks[IMX8MN_SYS_PLL1_OUT] = imx_clk_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
-
-       clks[IMX8MN_SYS_PLL1_40M] = imx_clk_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
-       clks[IMX8MN_SYS_PLL1_80M] = imx_clk_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
-       clks[IMX8MN_SYS_PLL1_100M] = imx_clk_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
-       clks[IMX8MN_SYS_PLL1_133M] = imx_clk_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
-       clks[IMX8MN_SYS_PLL1_160M] = imx_clk_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
-       clks[IMX8MN_SYS_PLL1_200M] = imx_clk_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
-       clks[IMX8MN_SYS_PLL1_266M] = imx_clk_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
-       clks[IMX8MN_SYS_PLL1_400M] = imx_clk_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
-       clks[IMX8MN_SYS_PLL1_800M] = imx_clk_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+       hws[IMX8MN_SYS_PLL1_40M_CG] = imx_clk_hw_gate("sys_pll1_40m_cg", "sys_pll1", base + 0x94, 27);
+       hws[IMX8MN_SYS_PLL1_80M_CG] = imx_clk_hw_gate("sys_pll1_80m_cg", "sys_pll1", base + 0x94, 25);
+       hws[IMX8MN_SYS_PLL1_100M_CG] = imx_clk_hw_gate("sys_pll1_100m_cg", "sys_pll1", base + 0x94, 23);
+       hws[IMX8MN_SYS_PLL1_133M_CG] = imx_clk_hw_gate("sys_pll1_133m_cg", "sys_pll1", base + 0x94, 21);
+       hws[IMX8MN_SYS_PLL1_160M_CG] = imx_clk_hw_gate("sys_pll1_160m_cg", "sys_pll1", base + 0x94, 19);
+       hws[IMX8MN_SYS_PLL1_200M_CG] = imx_clk_hw_gate("sys_pll1_200m_cg", "sys_pll1", base + 0x94, 17);
+       hws[IMX8MN_SYS_PLL1_266M_CG] = imx_clk_hw_gate("sys_pll1_266m_cg", "sys_pll1", base + 0x94, 15);
+       hws[IMX8MN_SYS_PLL1_400M_CG] = imx_clk_hw_gate("sys_pll1_400m_cg", "sys_pll1", base + 0x94, 13);
+       hws[IMX8MN_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1", base + 0x94, 11);
+
+       hws[IMX8MN_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_40m_cg", 1, 20);
+       hws[IMX8MN_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_80m_cg", 1, 10);
+       hws[IMX8MN_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_100m_cg", 1, 8);
+       hws[IMX8MN_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_133m_cg", 1, 6);
+       hws[IMX8MN_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_160m_cg", 1, 5);
+       hws[IMX8MN_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_200m_cg", 1, 4);
+       hws[IMX8MN_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_266m_cg", 1, 3);
+       hws[IMX8MN_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_400m_cg", 1, 2);
+       hws[IMX8MN_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
 
        /* SYS PLL2 fixed output */
-       clks[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27);
-       clks[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25);
-       clks[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23);
-       clks[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21);
-       clks[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19);
-       clks[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17);
-       clks[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15);
-       clks[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13);
-       clks[IMX8MN_SYS_PLL2_OUT] = imx_clk_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
-
-       clks[IMX8MN_SYS_PLL2_50M] = imx_clk_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
-       clks[IMX8MN_SYS_PLL2_100M] = imx_clk_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
-       clks[IMX8MN_SYS_PLL2_125M] = imx_clk_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
-       clks[IMX8MN_SYS_PLL2_166M] = imx_clk_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
-       clks[IMX8MN_SYS_PLL2_200M] = imx_clk_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
-       clks[IMX8MN_SYS_PLL2_250M] = imx_clk_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
-       clks[IMX8MN_SYS_PLL2_333M] = imx_clk_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
-       clks[IMX8MN_SYS_PLL2_500M] = imx_clk_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
-       clks[IMX8MN_SYS_PLL2_1000M] = imx_clk_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+       hws[IMX8MN_SYS_PLL2_50M_CG] = imx_clk_hw_gate("sys_pll2_50m_cg", "sys_pll2", base + 0x104, 27);
+       hws[IMX8MN_SYS_PLL2_100M_CG] = imx_clk_hw_gate("sys_pll2_100m_cg", "sys_pll2", base + 0x104, 25);
+       hws[IMX8MN_SYS_PLL2_125M_CG] = imx_clk_hw_gate("sys_pll2_125m_cg", "sys_pll2", base + 0x104, 23);
+       hws[IMX8MN_SYS_PLL2_166M_CG] = imx_clk_hw_gate("sys_pll2_166m_cg", "sys_pll2", base + 0x104, 21);
+       hws[IMX8MN_SYS_PLL2_200M_CG] = imx_clk_hw_gate("sys_pll2_200m_cg", "sys_pll2", base + 0x104, 19);
+       hws[IMX8MN_SYS_PLL2_250M_CG] = imx_clk_hw_gate("sys_pll2_250m_cg", "sys_pll2", base + 0x104, 17);
+       hws[IMX8MN_SYS_PLL2_333M_CG] = imx_clk_hw_gate("sys_pll2_333m_cg", "sys_pll2", base + 0x104, 15);
+       hws[IMX8MN_SYS_PLL2_500M_CG] = imx_clk_hw_gate("sys_pll2_500m_cg", "sys_pll2", base + 0x104, 13);
+       hws[IMX8MN_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2", base + 0x104, 11);
+
+       hws[IMX8MN_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_50m_cg", 1, 20);
+       hws[IMX8MN_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_100m_cg", 1, 10);
+       hws[IMX8MN_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_125m_cg", 1, 8);
+       hws[IMX8MN_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_166m_cg", 1, 6);
+       hws[IMX8MN_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_200m_cg", 1, 5);
+       hws[IMX8MN_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_250m_cg", 1, 4);
+       hws[IMX8MN_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_333m_cg", 1, 3);
+       hws[IMX8MN_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2);
+       hws[IMX8MN_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
 
        np = dev->of_node;
        base = devm_platform_ioremap_resource(pdev, 0);
        if (WARN_ON(IS_ERR(base))) {
                ret = PTR_ERR(base);
-               goto unregister_clks;
+               goto unregister_hws;
        }
 
        /* CORE */
-       clks[IMX8MN_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
-       clks[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3,  imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels));
-       clks[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels,  ARRAY_SIZE(imx8mn_gpu_shader_sels));
-       clks[IMX8MN_CLK_A53_CG] = imx_clk_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
-       clks[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
-       clks[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
+       hws[IMX8MN_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mn_a53_sels, ARRAY_SIZE(imx8mn_a53_sels));
+       hws[IMX8MN_CLK_GPU_CORE_SRC] = imx_clk_hw_mux2("gpu_core_src", base + 0x8180, 24, 3,  imx8mn_gpu_core_sels, ARRAY_SIZE(imx8mn_gpu_core_sels));
+       hws[IMX8MN_CLK_GPU_SHADER_SRC] = imx_clk_hw_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mn_gpu_shader_sels,  ARRAY_SIZE(imx8mn_gpu_shader_sels));
+       hws[IMX8MN_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", base + 0x8000, 28);
+       hws[IMX8MN_CLK_GPU_CORE_CG] = imx_clk_hw_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
+       hws[IMX8MN_CLK_GPU_SHADER_CG] = imx_clk_hw_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
 
-       clks[IMX8MN_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
-       clks[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
-       clks[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
+       hws[IMX8MN_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+       hws[IMX8MN_CLK_GPU_CORE_DIV] = imx_clk_hw_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
+       hws[IMX8MN_CLK_GPU_SHADER_DIV] = imx_clk_hw_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
 
        /* BUS */
-       clks[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
-       clks[IMX8MN_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
-       clks[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
-       clks[IMX8MN_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
-       clks[IMX8MN_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
-       clks[IMX8MN_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
-       clks[IMX8MN_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
-       clks[IMX8MN_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
-       clks[IMX8MN_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
-
-       clks[IMX8MN_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
-       clks[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
-       clks[IMX8MN_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
-       clks[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
-       clks[IMX8MN_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
-       clks[IMX8MN_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000);
-       clks[IMX8MN_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mn_dram_apb_sels, base + 0xa080);
-       clks[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
-       clks[IMX8MN_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
-       clks[IMX8MN_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mn_sai3_sels, base + 0xa680);
-       clks[IMX8MN_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mn_sai5_sels, base + 0xa780);
-       clks[IMX8MN_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mn_sai6_sels, base + 0xa800);
-       clks[IMX8MN_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880);
-       clks[IMX8MN_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980);
-       clks[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00);
-       clks[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80);
-       clks[IMX8MN_CLK_NAND] = imx8m_clk_composite("nand", imx8mn_nand_sels, base + 0xab00);
-       clks[IMX8MN_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mn_qspi_sels, base + 0xab80);
-       clks[IMX8MN_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00);
-       clks[IMX8MN_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80);
-       clks[IMX8MN_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00);
-       clks[IMX8MN_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80);
-       clks[IMX8MN_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00);
-       clks[IMX8MN_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80);
-       clks[IMX8MN_CLK_UART1] = imx8m_clk_composite("uart1", imx8mn_uart1_sels, base + 0xaf00);
-       clks[IMX8MN_CLK_UART2] = imx8m_clk_composite("uart2", imx8mn_uart2_sels, base + 0xaf80);
-       clks[IMX8MN_CLK_UART3] = imx8m_clk_composite("uart3", imx8mn_uart3_sels, base + 0xb000);
-       clks[IMX8MN_CLK_UART4] = imx8m_clk_composite("uart4", imx8mn_uart4_sels, base + 0xb080);
-       clks[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100);
-       clks[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180);
-       clks[IMX8MN_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mn_gic_sels, base + 0xb200);
-       clks[IMX8MN_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280);
-       clks[IMX8MN_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300);
-       clks[IMX8MN_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380);
-       clks[IMX8MN_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
-       clks[IMX8MN_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
-       clks[IMX8MN_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
-       clks[IMX8MN_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
-       clks[IMX8MN_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
-       clks[IMX8MN_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
-       clks[IMX8MN_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mn_clko2_sels, base + 0xba80);
-       clks[IMX8MN_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00);
-       clks[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80);
-       clks[IMX8MN_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00);
-       clks[IMX8MN_CLK_USDHC3] = imx8m_clk_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80);
-       clks[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00);
-       clks[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80);
-       clks[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00);
-       clks[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80);
-       clks[IMX8MN_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180);
-       clks[IMX8MN_CLK_PDM] = imx8m_clk_composite("pdm", imx8mn_pdm_sels, base + 0xc200);
-       clks[IMX8MN_CLK_SAI7] = imx8m_clk_composite("sai7", imx8mn_sai7_sels, base + 0xc300);
-
-       clks[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
-       clks[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
-       clks[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
-       clks[IMX8MN_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
-       clks[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
-       clks[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
-       clks[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
-       clks[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
-       clks[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
-       clks[IMX8MN_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
-       clks[IMX8MN_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
-       clks[IMX8MN_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
-       clks[IMX8MN_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
-       clks[IMX8MN_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
-       clks[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
-       clks[IMX8MN_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
-       clks[IMX8MN_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
-       clks[IMX8MN_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
-       clks[IMX8MN_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
-       clks[IMX8MN_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
-       clks[IMX8MN_CLK_NAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
-       clks[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
-       clks[IMX8MN_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
-       clks[IMX8MN_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
-       clks[IMX8MN_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
-       clks[IMX8MN_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
-       clks[IMX8MN_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
-       clks[IMX8MN_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
-       clks[IMX8MN_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
-       clks[IMX8MN_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
-       clks[IMX8MN_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
-       clks[IMX8MN_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
-       clks[IMX8MN_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
-       clks[IMX8MN_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
-       clks[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_core_ref", base + 0x44d0, 0);
-       clks[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0);
-       clks[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
-       clks[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
-       clks[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
-       clks[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
-       clks[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
-       clks[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
-       clks[IMX8MN_CLK_ASRC_ROOT] = imx_clk_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0);
-       clks[IMX8MN_CLK_PDM_ROOT] = imx_clk_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
-       clks[IMX8MN_CLK_PDM_IPG]  = imx_clk_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
-       clks[IMX8MN_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
-       clks[IMX8MN_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
-       clks[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp);
-       clks[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp);
-       clks[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
-       clks[IMX8MN_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
-       clks[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
-       clks[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
-       clks[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
-       clks[IMX8MN_CLK_SAI7_ROOT] = imx_clk_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
-
-       clks[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
-
-       clks[IMX8MN_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
-                                          clks[IMX8MN_CLK_A53_DIV],
-                                          clks[IMX8MN_CLK_A53_SRC],
-                                          clks[IMX8MN_ARM_PLL_OUT],
-                                          clks[IMX8MN_SYS_PLL1_800M]);
-
-       imx_check_clocks(clks, ARRAY_SIZE(clks));
-
-       clk_data.clks = clks;
-       clk_data.clk_num = ARRAY_SIZE(clks);
-       ret = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       hws[IMX8MN_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mn_main_axi_sels, base + 0x8800);
+       hws[IMX8MN_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mn_enet_axi_sels, base + 0x8880);
+       hws[IMX8MN_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mn_nand_usdhc_sels, base + 0x8900);
+       hws[IMX8MN_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mn_disp_axi_sels, base + 0x8a00);
+       hws[IMX8MN_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mn_disp_apb_sels, base + 0x8a80);
+       hws[IMX8MN_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mn_usb_bus_sels, base + 0x8b80);
+       hws[IMX8MN_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mn_gpu_axi_sels, base + 0x8c00);
+       hws[IMX8MN_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mn_gpu_ahb_sels, base + 0x8c80);
+       hws[IMX8MN_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mn_noc_sels, base + 0x8d00);
+
+       hws[IMX8MN_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mn_ahb_sels, base + 0x9000);
+       hws[IMX8MN_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mn_audio_ahb_sels, base + 0x9100);
+       hws[IMX8MN_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
+       hws[IMX8MN_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+       hws[IMX8MN_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mn_dram_core_sels, ARRAY_SIZE(imx8mn_dram_core_sels), CLK_IS_CRITICAL);
+
+       /*
+        * DRAM clocks are manipulated from TF-A outside clock framework.
+        * Mark with GET_RATE_NOCACHE to always read div value from hardware
+        */
+       hws[IMX8MN_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mn_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
+       hws[IMX8MN_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mn_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+
+       hws[IMX8MN_CLK_DISP_PIXEL] = imx8m_clk_hw_composite("disp_pixel", imx8mn_disp_pixel_sels, base + 0xa500);
+       hws[IMX8MN_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mn_sai2_sels, base + 0xa600);
+       hws[IMX8MN_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mn_sai3_sels, base + 0xa680);
+       hws[IMX8MN_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mn_sai5_sels, base + 0xa780);
+       hws[IMX8MN_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mn_sai6_sels, base + 0xa800);
+       hws[IMX8MN_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mn_spdif1_sels, base + 0xa880);
+       hws[IMX8MN_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mn_enet_ref_sels, base + 0xa980);
+       hws[IMX8MN_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mn_enet_timer_sels, base + 0xaa00);
+       hws[IMX8MN_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mn_enet_phy_sels, base + 0xaa80);
+       hws[IMX8MN_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mn_nand_sels, base + 0xab00);
+       hws[IMX8MN_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mn_qspi_sels, base + 0xab80);
+       hws[IMX8MN_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mn_usdhc1_sels, base + 0xac00);
+       hws[IMX8MN_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mn_usdhc2_sels, base + 0xac80);
+       hws[IMX8MN_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mn_i2c1_sels, base + 0xad00);
+       hws[IMX8MN_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mn_i2c2_sels, base + 0xad80);
+       hws[IMX8MN_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mn_i2c3_sels, base + 0xae00);
+       hws[IMX8MN_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mn_i2c4_sels, base + 0xae80);
+       hws[IMX8MN_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mn_uart1_sels, base + 0xaf00);
+       hws[IMX8MN_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mn_uart2_sels, base + 0xaf80);
+       hws[IMX8MN_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mn_uart3_sels, base + 0xb000);
+       hws[IMX8MN_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mn_uart4_sels, base + 0xb080);
+       hws[IMX8MN_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mn_usb_core_sels, base + 0xb100);
+       hws[IMX8MN_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mn_usb_phy_sels, base + 0xb180);
+       hws[IMX8MN_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mn_gic_sels, base + 0xb200);
+       hws[IMX8MN_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mn_ecspi1_sels, base + 0xb280);
+       hws[IMX8MN_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mn_ecspi2_sels, base + 0xb300);
+       hws[IMX8MN_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mn_pwm1_sels, base + 0xb380);
+       hws[IMX8MN_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
+       hws[IMX8MN_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
+       hws[IMX8MN_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
+       hws[IMX8MN_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
+       hws[IMX8MN_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
+       hws[IMX8MN_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
+       hws[IMX8MN_CLK_CLKO2] = imx8m_clk_hw_composite("clko2", imx8mn_clko2_sels, base + 0xba80);
+       hws[IMX8MN_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mn_dsi_core_sels, base + 0xbb00);
+       hws[IMX8MN_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mn_dsi_phy_sels, base + 0xbb80);
+       hws[IMX8MN_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mn_dsi_dbi_sels, base + 0xbc00);
+       hws[IMX8MN_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mn_usdhc3_sels, base + 0xbc80);
+       hws[IMX8MN_CLK_CAMERA_PIXEL] = imx8m_clk_hw_composite("camera_pixel", imx8mn_camera_pixel_sels, base + 0xbd00);
+       hws[IMX8MN_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mn_csi1_phy_sels, base + 0xbd80);
+       hws[IMX8MN_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mn_csi2_phy_sels, base + 0xbf00);
+       hws[IMX8MN_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mn_csi2_esc_sels, base + 0xbf80);
+       hws[IMX8MN_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mn_ecspi3_sels, base + 0xc180);
+       hws[IMX8MN_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mn_pdm_sels, base + 0xc200);
+       hws[IMX8MN_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mn_sai7_sels, base + 0xc300);
+
+       hws[IMX8MN_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
+       hws[IMX8MN_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
+       hws[IMX8MN_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
+       hws[IMX8MN_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
+       hws[IMX8MN_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
+       hws[IMX8MN_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
+       hws[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
+       hws[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
+       hws[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
+       hws[IMX8MN_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
+       hws[IMX8MN_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
+       hws[IMX8MN_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
+       hws[IMX8MN_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
+       hws[IMX8MN_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
+       hws[IMX8MN_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
+       hws[IMX8MN_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
+       hws[IMX8MN_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
+       hws[IMX8MN_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
+       hws[IMX8MN_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
+       hws[IMX8MN_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
+       hws[IMX8MN_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
+       hws[IMX8MN_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
+       hws[IMX8MN_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
+       hws[IMX8MN_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_audio_root", base + 0x4340, 0, &share_count_sai2);
+       hws[IMX8MN_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
+       hws[IMX8MN_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_audio_root", base + 0x4350, 0, &share_count_sai3);
+       hws[IMX8MN_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
+       hws[IMX8MN_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
+       hws[IMX8MN_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
+       hws[IMX8MN_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
+       hws[IMX8MN_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
+       hws[IMX8MN_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
+       hws[IMX8MN_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
+       hws[IMX8MN_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
+       hws[IMX8MN_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
+       hws[IMX8MN_CLK_GPU_CORE_ROOT] = imx_clk_hw_gate4("gpu_core_root_clk", "gpu_core_div", base + 0x44f0, 0);
+       hws[IMX8MN_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
+       hws[IMX8MN_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
+       hws[IMX8MN_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
+       hws[IMX8MN_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
+       hws[IMX8MN_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
+       hws[IMX8MN_CLK_GPU_BUS_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", base + 0x4570, 0);
+       hws[IMX8MN_CLK_ASRC_ROOT] = imx_clk_hw_gate4("asrc_root_clk", "audio_ahb", base + 0x4580, 0);
+       hws[IMX8MN_CLK_PDM_ROOT] = imx_clk_hw_gate2_shared2("pdm_root_clk", "pdm", base + 0x45b0, 0, &share_count_pdm);
+       hws[IMX8MN_CLK_PDM_IPG]  = imx_clk_hw_gate2_shared2("pdm_ipg_clk", "ipg_audio_root", base + 0x45b0, 0, &share_count_pdm);
+       hws[IMX8MN_CLK_DISP_AXI_ROOT]  = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_disp);
+       hws[IMX8MN_CLK_DISP_APB_ROOT]  = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_disp);
+       hws[IMX8MN_CLK_CAMERA_PIXEL_ROOT] = imx_clk_hw_gate2_shared2("camera_pixel_clk", "camera_pixel", base + 0x45d0, 0, &share_count_disp);
+       hws[IMX8MN_CLK_DISP_PIXEL_ROOT] = imx_clk_hw_gate2_shared2("disp_pixel_clk", "disp_pixel", base + 0x45d0, 0, &share_count_disp);
+       hws[IMX8MN_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", base + 0x45e0, 0);
+       hws[IMX8MN_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
+       hws[IMX8MN_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
+       hws[IMX8MN_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
+       hws[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
+       hws[IMX8MN_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
+
+       hws[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
+
+       hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div",
+                                          hws[IMX8MN_CLK_A53_DIV]->clk,
+                                          hws[IMX8MN_CLK_A53_SRC]->clk,
+                                          hws[IMX8MN_ARM_PLL_OUT]->clk,
+                                          hws[IMX8MN_SYS_PLL1_800M]->clk);
+
+       imx_check_clk_hws(hws, IMX8MN_CLK_END);
+
+       ret = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
        if (ret < 0) {
-               dev_err(dev, "failed to register clks for i.MX8MN\n");
-               goto unregister_clks;
+               dev_err(dev, "failed to register hws for i.MX8MN\n");
+               goto unregister_hws;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
+               int index = uart_clk_ids[i];
+
+               uart_hws[i] = &hws[index]->clk;
        }
 
-       imx_register_uart_clocks(uart_clks);
+       imx_register_uart_clocks(uart_hws);
 
        return 0;
 
-unregister_clks:
-       imx_unregister_clocks(clks, ARRAY_SIZE(clks));
+unregister_hws:
+       imx_unregister_hw_clocks(hws, IMX8MN_CLK_END);
 
        return ret;
 }
@@ -572,6 +591,11 @@ static struct platform_driver imx8mn_clk_driver = {
        .probe = imx8mn_clocks_probe,
        .driver = {
                .name = "imx8mn-ccm",
+               /*
+                * Disable bind attributes: clocks are not removed and
+                * reloading the driver will crash or break devices.
+                */
+               .suppress_bind_attrs = true,
                .of_match_table = of_match_ptr(imx8mn_clk_of_match),
        },
 };
diff --git a/drivers/clk/imx/clk-imx8mp.c b/drivers/clk/imx/clk-imx8mp.c
new file mode 100644 (file)
index 0000000..f6c120c
--- /dev/null
@@ -0,0 +1,764 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2019 NXP.
+ */
+
+#include <dt-bindings/clock/imx8mp-clock.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+
+#include "clk.h"
+
+static u32 share_count_nand;
+static u32 share_count_media;
+
+static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", };
+static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", };
+static const char * const audio_pll2_bypass_sels[] = {"audio_pll2", "audio_pll2_ref_sel", };
+static const char * const video_pll1_bypass_sels[] = {"video_pll1", "video_pll1_ref_sel", };
+static const char * const dram_pll_bypass_sels[] = {"dram_pll", "dram_pll_ref_sel", };
+static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
+static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
+static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
+static const char * const sys_pll1_bypass_sels[] = {"sys_pll1", "sys_pll1_ref_sel", };
+static const char * const sys_pll2_bypass_sels[] = {"sys_pll2", "sys_pll2_ref_sel", };
+static const char * const sys_pll3_bypass_sels[] = {"sys_pll3", "sys_pll3_ref_sel", };
+
+static const char * const imx8mp_a53_sels[] = {"osc_24m", "arm_pll_out", "sys_pll2_500m",
+                                              "sys_pll2_1000m", "sys_pll1_800m", "sys_pll1_400m",
+                                              "audio_pll1_out", "sys_pll3_out", };
+
+static const char * const imx8mp_m7_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_250m",
+                                             "vpu_pll_out", "sys_pll1_800m", "audio_pll1_out",
+                                             "video_pll1_out", "sys_pll3_out", };
+
+static const char * const imx8mp_ml_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                             "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                             "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_gpu3d_core_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                                     "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                     "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_gpu3d_shader_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                                       "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                       "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_gpu2d_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                                "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_audio_axi_sels[] = {"osc_24m", "gpu_pll_out", "sys_pll1_800m",
+                                                    "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                    "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_hsio_axi_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
+                                                   "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                   "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mp_media_isp_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m",
+                                                    "sys_pll3_out", "sys_pll1_400m", "audio_pll2_out",
+                                                    "clk_ext1", "sys_pll2_500m", };
+
+static const char * const imx8mp_main_axi_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll1_800m",
+                                                   "sys_pll2_250m", "sys_pll2_1000m", "audio_pll1_out",
+                                                   "video_pll1_out", "sys_pll1_100m",};
+
+static const char * const imx8mp_enet_axi_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+                                                   "sys_pll2_250m", "sys_pll2_200m", "audio_pll1_out",
+                                                   "video_pll1_out", "sys_pll3_out", };
+
+static const char * const imx8mp_nand_usdhc_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll1_800m",
+                                                     "sys_pll2_200m", "sys_pll1_133m", "sys_pll3_out",
+                                                     "sys_pll2_250m", "audio_pll1_out", };
+
+static const char * const imx8mp_vpu_bus_sels[] = {"osc_24m", "sys_pll1_800m", "vpu_pll_out",
+                                                  "audio_pll2_out", "sys_pll3_out", "sys_pll2_1000m",
+                                                  "sys_pll2_200m", "sys_pll1_100m", };
+
+static const char * const imx8mp_media_axi_sels[] = {"osc_24m", "sys_pll2_1000m", "sys_pll1_800m",
+                                                    "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
+                                                    "clk_ext1", "sys_pll2_500m", };
+
+static const char * const imx8mp_media_apb_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll1_800m",
+                                                    "sys_pll3_out", "sys_pll1_40m", "audio_pll2_out",
+                                                    "clk_ext1", "sys_pll1_133m", };
+
+static const char * const imx8mp_gpu_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+                                                  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                  "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_gpu_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+                                                  "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                  "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_noc_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
+                                              "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
+                                              "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_noc_io_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_1000m", "sys_pll2_500m", "audio_pll1_out",
+                                                 "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_ml_axi_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+                                                 "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                 "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_ml_ahb_sels[] = {"osc_24m", "sys_pll1_800m", "gpu_pll_out",
+                                                 "sys_pll3_out", "sys_pll2_1000m", "audio_pll1_out",
+                                                 "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_ahb_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_800m",
+                                              "sys_pll1_400m", "sys_pll2_125m", "sys_pll3_out",
+                                              "audio_pll1_out", "video_pll1_out", };
+
+static const char * const imx8mp_audio_ahb_sels[] = {"osc_24m", "sys_pll2_500m", "sys_pll1_800m",
+                                                    "sys_pll2_1000m", "sys_pll2_166m", "sys_pll3_out",
+                                                    "audio_pll1_out", "video_pll1_out", };
+
+static const char * const imx8mp_mipi_dsi_esc_rx_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
+                                                          "sys_pll1_800m", "sys_pll2_1000m",
+                                                          "sys_pll3_out", "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mp_dram_alt_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_100m",
+                                                   "sys_pll2_500m", "sys_pll2_1000m", "sys_pll3_out",
+                                                   "audio_pll1_out", "sys_pll1_266m", };
+
+static const char * const imx8mp_dram_apb_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                   "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                   "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mp_vpu_g1_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m",
+                                                 "sys_pll2_1000m", "sys_pll1_100m", "sys_pll2_125m",
+                                                 "sys_pll3_out", "audio_pll1_out", };
+
+static const char * const imx8mp_vpu_g2_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m",
+                                                 "sys_pll2_1000m", "sys_pll1_100m", "sys_pll2_125m",
+                                                 "sys_pll3_out", "audio_pll1_out", };
+
+static const char * const imx8mp_can1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                               "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                               "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mp_can2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                               "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                               "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                                    "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                                    "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mp_pcie_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m",
+                                                   "clk_ext1", "clk_ext2", "clk_ext3",
+                                                   "clk_ext4", "sys_pll1_400m", };
+
+static const char * const imx8mp_pcie_aux_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m",
+                                                   "sys_pll3_out", "sys_pll2_100m", "sys_pll1_80m",
+                                                   "sys_pll1_160m", "sys_pll1_200m", };
+
+static const char * const imx8mp_i2c5_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mp_i2c6_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mp_sai1_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext1", "clk_ext2", };
+
+static const char * const imx8mp_sai2_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext2", "clk_ext3", };
+
+static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mp_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext1", "clk_ext2", };
+
+static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext2", "clk_ext3", };
+
+static const char * const imx8mp_sai6_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mp_enet_qos_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
+                                                   "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
+                                                   "video_pll1_out", "clk_ext4", };
+
+static const char * const imx8mp_enet_qos_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+                                                         "clk_ext1", "clk_ext2", "clk_ext3",
+                                                         "clk_ext4", "video_pll1_out", };
+
+static const char * const imx8mp_enet_ref_sels[] = {"osc_24m", "sys_pll2_125m", "sys_pll2_50m",
+                                                   "sys_pll2_100m", "sys_pll1_160m", "audio_pll1_out",
+                                                   "video_pll1_out", "clk_ext4", };
+
+static const char * const imx8mp_enet_timer_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+                                                     "clk_ext1", "clk_ext2", "clk_ext3",
+                                                     "clk_ext4", "video_pll1_out", };
+
+static const char * const imx8mp_enet_phy_ref_sels[] = {"osc_24m", "sys_pll2_50m", "sys_pll2_125m",
+                                                       "sys_pll2_200m", "sys_pll2_500m", "audio_pll1_out",
+                                                       "video_pll1_out", "audio_pll2_out", };
+
+static const char * const imx8mp_nand_sels[] = {"osc_24m", "sys_pll2_500m", "audio_pll1_out",
+                                               "sys_pll1_400m", "audio_pll2_out", "sys_pll3_out",
+                                               "sys_pll2_250m", "video_pll1_out", };
+
+static const char * const imx8mp_qspi_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll2_333m",
+                                               "sys_pll2_500m", "audio_pll2_out", "sys_pll1_266m",
+                                               "sys_pll3_out", "sys_pll1_100m", };
+
+static const char * const imx8mp_usdhc1_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_out", "sys_pll1_100m", };
+
+static const char * const imx8mp_usdhc2_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_out", "sys_pll1_100m", };
+
+static const char * const imx8mp_i2c1_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mp_i2c2_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mp_i2c3_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mp_i2c4_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                               "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                               "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mp_uart1_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mp_uart2_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mp_uart3_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext4", "audio_pll2_out", };
+
+static const char * const imx8mp_uart4_sels[] = {"osc_24m", "sys_pll1_80m", "sys_pll2_200m",
+                                                "sys_pll2_100m", "sys_pll3_out", "clk_ext2",
+                                                "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mp_usb_core_ref_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m",
+                                                       "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                       "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mp_usb_phy_ref_sels[] = {"osc_24m", "sys_pll1_100m", "sys_pll1_40m",
+                                                      "sys_pll2_100m", "sys_pll2_200m", "clk_ext2",
+                                                      "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mp_gic_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                              "sys_pll2_100m", "sys_pll1_800m",
+                                              "sys_pll2_500m", "clk_ext4", "audio_pll2_out" };
+
+static const char * const imx8mp_ecspi1_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mp_ecspi2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mp_pwm1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mp_pwm2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext1",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mp_pwm3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mp_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_160m",
+                                               "sys_pll1_40m", "sys_pll3_out", "clk_ext2",
+                                               "sys_pll1_80m", "video_pll1_out", };
+
+static const char * const imx8mp_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+                                               "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+                                               "audio_pll1_out", "clk_ext1" };
+
+static const char * const imx8mp_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+                                               "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+                                               "audio_pll1_out", "clk_ext2" };
+
+static const char * const imx8mp_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+                                               "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+                                               "audio_pll1_out", "clk_ext3" };
+
+static const char * const imx8mp_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+                                               "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+                                               "audio_pll1_out", "clk_ext1" };
+
+static const char * const imx8mp_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+                                               "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+                                               "audio_pll1_out", "clk_ext2" };
+
+static const char * const imx8mp_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
+                                               "sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
+                                               "audio_pll1_out", "clk_ext3" };
+
+static const char * const imx8mp_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
+                                               "vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
+                                               "sys_pll1_80m", "sys_pll2_166m" };
+
+static const char * const imx8mp_wrclk_sels[] = {"osc_24m", "sys_pll1_40m", "vpu_pll_out",
+                                                "sys_pll3_out", "sys_pll2_200m", "sys_pll1_266m",
+                                                "sys_pll2_500m", "sys_pll1_100m" };
+
+static const char * const imx8mp_ipp_do_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "sys_pll1_133m",
+                                                       "sys_pll1_200m", "audio_pll2_out", "sys_pll2_500m",
+                                                       "vpu_pll_out", "sys_pll1_80m" };
+
+static const char * const imx8mp_ipp_do_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m",
+                                                       "sys_pll1_166m", "sys_pll3_out", "audio_pll1_out",
+                                                       "video_pll1_out", "osc_32k" };
+
+static const char * const imx8mp_hdmi_fdcc_tst_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+                                                        "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                                        "audio_pll2_out", "video_pll1_out", };
+
+static const char * const imx8mp_hdmi_27m_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
+                                                   "sys_pll3_out", "audio_pll1_out", "video_pll1_out",
+                                                   "audio_pll2_out", "sys_pll1_133m", };
+
+static const char * const imx8mp_hdmi_ref_266m_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll3_out",
+                                                        "sys_pll2_333m", "sys_pll1_266m", "sys_pll2_200m",
+                                                        "audio_pll1_out", "video_pll1_out", };
+
+static const char * const imx8mp_usdhc3_sels[] = {"osc_24m", "sys_pll1_400m", "sys_pll1_800m",
+                                                 "sys_pll2_500m", "sys_pll3_out", "sys_pll1_266m",
+                                                 "audio_pll2_out", "sys_pll1_100m", };
+
+static const char * const imx8mp_media_cam1_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+                                                         "sys_pll1_800m", "sys_pll2_1000m",
+                                                         "sys_pll3_out", "audio_pll2_out",
+                                                         "video_pll1_out", };
+
+static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+                                                              "sys_pll1_800m", "sys_pll2_1000m",
+                                                              "clk_ext2", "audio_pll2_out",
+                                                              "video_pll1_out", };
+
+static const char * const imx8mp_media_disp1_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
+                                                          "audio_pll1_out", "sys_pll1_800m",
+                                                          "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
+
+static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_266m", "sys_pll2_250m",
+                                                         "sys_pll1_800m", "sys_pll2_1000m",
+                                                         "sys_pll3_out", "audio_pll2_out",
+                                                         "video_pll1_out", };
+
+static const char * const imx8mp_media_mipi_phy2_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
+                                                              "sys_pll1_800m", "sys_pll2_1000m",
+                                                              "clk_ext2", "audio_pll2_out",
+                                                              "video_pll1_out", };
+
+static const char * const imx8mp_media_mipi_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
+                                                              "sys_pll1_800m", "sys_pll2_1000m",
+                                                              "sys_pll3_out", "clk_ext3",
+                                                              "audio_pll2_out", };
+
+static const char * const imx8mp_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m",
+                                                     "sys_pll1_266m", "sys_pll1_800m", "sys_pll2_500m",
+                                                     "sys_pll2_333m", "sys_pll3_out", };
+
+static const char * const imx8mp_pcie2_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m",
+                                                    "clk_ext1", "clk_ext2", "clk_ext3",
+                                                    "clk_ext4", "sys_pll1_400m", };
+
+static const char * const imx8mp_media_mipi_test_byte_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll2_50m",
+                                                               "sys_pll3_out", "sys_pll2_100m",
+                                                               "sys_pll1_80m", "sys_pll1_160m",
+                                                               "sys_pll1_200m", };
+
+static const char * const imx8mp_ecspi3_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_40m",
+                                                 "sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
+                                                 "sys_pll2_250m", "audio_pll2_out", };
+
+static const char * const imx8mp_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audio_pll1_out",
+                                              "sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
+                                              "clk_ext3", "audio_pll2_out", };
+
+static const char * const imx8mp_vpu_vc8000e_sels[] = {"osc_24m", "vpu_pll_out", "sys_pll1_800m",
+                                                      "sys_pll2_1000m", "audio_pll2_out", "sys_pll2_125m",
+                                                      "sys_pll3_out", "audio_pll1_out", };
+
+static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out",
+                                               "video_pll1_out", "sys_pll1_133m", "osc_hdmi",
+                                               "clk_ext3", "clk_ext4", };
+
+static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
+
+static struct clk_hw **hws;
+static struct clk_hw_onecell_data *clk_hw_data;
+
+static const int uart_clk_ids[] = {
+       IMX8MP_CLK_UART1_ROOT,
+       IMX8MP_CLK_UART2_ROOT,
+       IMX8MP_CLK_UART3_ROOT,
+       IMX8MP_CLK_UART4_ROOT,
+};
+static struct clk **uart_clks[ARRAY_SIZE(uart_clk_ids) + 1];
+
+static int imx8mp_clocks_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       void __iomem *anatop_base, *ccm_base;
+       int i;
+
+       np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop");
+       anatop_base = of_iomap(np, 0);
+       if (WARN_ON(!anatop_base))
+               return -ENOMEM;
+
+       np = dev->of_node;
+       ccm_base = devm_platform_ioremap_resource(pdev, 0);
+       if (WARN_ON(IS_ERR(ccm_base))) {
+               iounmap(anatop_base);
+               return PTR_ERR(ccm_base);
+       }
+
+       clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL);
+       if (WARN_ON(!clk_hw_data)) {
+               iounmap(anatop_base);
+               return -ENOMEM;
+       }
+
+       clk_hw_data->num = IMX8MP_CLK_END;
+       hws = clk_hw_data->hws;
+
+       hws[IMX8MP_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
+       hws[IMX8MP_CLK_24M] = imx_obtain_fixed_clk_hw(np, "osc_24m");
+       hws[IMX8MP_CLK_32K] = imx_obtain_fixed_clk_hw(np, "osc_32k");
+       hws[IMX8MP_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
+       hws[IMX8MP_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2");
+       hws[IMX8MP_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3");
+       hws[IMX8MP_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
+
+       hws[IMX8MP_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", anatop_base + 0x0, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", anatop_base + 0x14, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", anatop_base + 0x28, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_DRAM_PLL_REF_SEL] = imx_clk_hw_mux("dram_pll_ref_sel", anatop_base + 0x50, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", anatop_base + 0x64, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", anatop_base + 0x74, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", anatop_base + 0x84, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_SYS_PLL1_REF_SEL] = imx_clk_hw_mux("sys_pll1_ref_sel", anatop_base + 0x94, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_SYS_PLL2_REF_SEL] = imx_clk_hw_mux("sys_pll2_ref_sel", anatop_base + 0x104, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MP_SYS_PLL3_REF_SEL] = imx_clk_hw_mux("sys_pll3_ref_sel", anatop_base + 0x114, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+       hws[IMX8MP_AUDIO_PLL1] = imx_clk_hw_pll14xx("audio_pll1", "audio_pll1_ref_sel", anatop_base, &imx_1443x_pll);
+       hws[IMX8MP_AUDIO_PLL2] = imx_clk_hw_pll14xx("audio_pll2", "audio_pll2_ref_sel", anatop_base + 0x14, &imx_1443x_pll);
+       hws[IMX8MP_VIDEO_PLL1] = imx_clk_hw_pll14xx("video_pll1", "video_pll1_ref_sel", anatop_base + 0x28, &imx_1443x_pll);
+       hws[IMX8MP_DRAM_PLL] = imx_clk_hw_pll14xx("dram_pll", "dram_pll_ref_sel", anatop_base + 0x50, &imx_1443x_dram_pll);
+       hws[IMX8MP_GPU_PLL] = imx_clk_hw_pll14xx("gpu_pll", "gpu_pll_ref_sel", anatop_base + 0x64, &imx_1416x_pll);
+       hws[IMX8MP_VPU_PLL] = imx_clk_hw_pll14xx("vpu_pll", "vpu_pll_ref_sel", anatop_base + 0x74, &imx_1416x_pll);
+       hws[IMX8MP_ARM_PLL] = imx_clk_hw_pll14xx("arm_pll", "arm_pll_ref_sel", anatop_base + 0x84, &imx_1416x_pll);
+       hws[IMX8MP_SYS_PLL1] = imx_clk_hw_pll14xx("sys_pll1", "sys_pll1_ref_sel", anatop_base + 0x94, &imx_1416x_pll);
+       hws[IMX8MP_SYS_PLL2] = imx_clk_hw_pll14xx("sys_pll2", "sys_pll2_ref_sel", anatop_base + 0x104, &imx_1416x_pll);
+       hws[IMX8MP_SYS_PLL3] = imx_clk_hw_pll14xx("sys_pll3", "sys_pll3_ref_sel", anatop_base + 0x114, &imx_1416x_pll);
+
+       hws[IMX8MP_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux_flags("audio_pll1_bypass", anatop_base, 4, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux_flags("audio_pll2_bypass", anatop_base + 0x14, 4, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux_flags("video_pll1_bypass", anatop_base + 0x28, 4, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_DRAM_PLL_BYPASS] = imx_clk_hw_mux_flags("dram_pll_bypass", anatop_base + 0x50, 4, 1, dram_pll_bypass_sels, ARRAY_SIZE(dram_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_GPU_PLL_BYPASS] = imx_clk_hw_mux_flags("gpu_pll_bypass", anatop_base + 0x64, 4, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_VPU_PLL_BYPASS] = imx_clk_hw_mux_flags("vpu_pll_bypass", anatop_base + 0x74, 4, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", anatop_base + 0x84, 4, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_SYS_PLL1_BYPASS] = imx_clk_hw_mux_flags("sys_pll1_bypass", anatop_base + 0x94, 4, 1, sys_pll1_bypass_sels, ARRAY_SIZE(sys_pll1_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_SYS_PLL2_BYPASS] = imx_clk_hw_mux_flags("sys_pll2_bypass", anatop_base + 0x104, 4, 1, sys_pll2_bypass_sels, ARRAY_SIZE(sys_pll2_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MP_SYS_PLL3_BYPASS] = imx_clk_hw_mux_flags("sys_pll3_bypass", anatop_base + 0x114, 4, 1, sys_pll3_bypass_sels, ARRAY_SIZE(sys_pll3_bypass_sels), CLK_SET_RATE_PARENT);
+
+       hws[IMX8MP_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", anatop_base, 13);
+       hws[IMX8MP_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", anatop_base + 0x14, 13);
+       hws[IMX8MP_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", anatop_base + 0x28, 13);
+       hws[IMX8MP_DRAM_PLL_OUT] = imx_clk_hw_gate("dram_pll_out", "dram_pll_bypass", anatop_base + 0x50, 13);
+       hws[IMX8MP_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", anatop_base + 0x64, 11);
+       hws[IMX8MP_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", anatop_base + 0x74, 11);
+       hws[IMX8MP_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", anatop_base + 0x84, 11);
+       hws[IMX8MP_SYS_PLL1_OUT] = imx_clk_hw_gate("sys_pll1_out", "sys_pll1_bypass", anatop_base + 0x94, 11);
+       hws[IMX8MP_SYS_PLL2_OUT] = imx_clk_hw_gate("sys_pll2_out", "sys_pll2_bypass", anatop_base + 0x104, 11);
+       hws[IMX8MP_SYS_PLL3_OUT] = imx_clk_hw_gate("sys_pll3_out", "sys_pll3_bypass", anatop_base + 0x114, 11);
+
+       hws[IMX8MP_SYS_PLL1_40M] = imx_clk_hw_fixed_factor("sys_pll1_40m", "sys_pll1_out", 1, 20);
+       hws[IMX8MP_SYS_PLL1_80M] = imx_clk_hw_fixed_factor("sys_pll1_80m", "sys_pll1_out", 1, 10);
+       hws[IMX8MP_SYS_PLL1_100M] = imx_clk_hw_fixed_factor("sys_pll1_100m", "sys_pll1_out", 1, 8);
+       hws[IMX8MP_SYS_PLL1_133M] = imx_clk_hw_fixed_factor("sys_pll1_133m", "sys_pll1_out", 1, 6);
+       hws[IMX8MP_SYS_PLL1_160M] = imx_clk_hw_fixed_factor("sys_pll1_160m", "sys_pll1_out", 1, 5);
+       hws[IMX8MP_SYS_PLL1_200M] = imx_clk_hw_fixed_factor("sys_pll1_200m", "sys_pll1_out", 1, 4);
+       hws[IMX8MP_SYS_PLL1_266M] = imx_clk_hw_fixed_factor("sys_pll1_266m", "sys_pll1_out", 1, 3);
+       hws[IMX8MP_SYS_PLL1_400M] = imx_clk_hw_fixed_factor("sys_pll1_400m", "sys_pll1_out", 1, 2);
+       hws[IMX8MP_SYS_PLL1_800M] = imx_clk_hw_fixed_factor("sys_pll1_800m", "sys_pll1_out", 1, 1);
+
+       hws[IMX8MP_SYS_PLL2_50M] = imx_clk_hw_fixed_factor("sys_pll2_50m", "sys_pll2_out", 1, 20);
+       hws[IMX8MP_SYS_PLL2_100M] = imx_clk_hw_fixed_factor("sys_pll2_100m", "sys_pll2_out", 1, 10);
+       hws[IMX8MP_SYS_PLL2_125M] = imx_clk_hw_fixed_factor("sys_pll2_125m", "sys_pll2_out", 1, 8);
+       hws[IMX8MP_SYS_PLL2_166M] = imx_clk_hw_fixed_factor("sys_pll2_166m", "sys_pll2_out", 1, 6);
+       hws[IMX8MP_SYS_PLL2_200M] = imx_clk_hw_fixed_factor("sys_pll2_200m", "sys_pll2_out", 1, 5);
+       hws[IMX8MP_SYS_PLL2_250M] = imx_clk_hw_fixed_factor("sys_pll2_250m", "sys_pll2_out", 1, 4);
+       hws[IMX8MP_SYS_PLL2_333M] = imx_clk_hw_fixed_factor("sys_pll2_333m", "sys_pll2_out", 1, 3);
+       hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
+       hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
+
+       hws[IMX8MP_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", ccm_base + 0x8000, 24, 3, imx8mp_a53_sels, ARRAY_SIZE(imx8mp_a53_sels));
+       hws[IMX8MP_CLK_M7_SRC] = imx_clk_hw_mux2("arm_m7_src", ccm_base + 0x8080, 24, 3, imx8mp_m7_sels, ARRAY_SIZE(imx8mp_m7_sels));
+       hws[IMX8MP_CLK_ML_SRC] = imx_clk_hw_mux2("ml_src", ccm_base + 0x8100, 24, 3, imx8mp_ml_sels, ARRAY_SIZE(imx8mp_ml_sels));
+       hws[IMX8MP_CLK_GPU3D_CORE_SRC] = imx_clk_hw_mux2("gpu3d_core_src", ccm_base + 0x8180, 24, 3,  imx8mp_gpu3d_core_sels, ARRAY_SIZE(imx8mp_gpu3d_core_sels));
+       hws[IMX8MP_CLK_GPU3D_SHADER_SRC] = imx_clk_hw_mux2("gpu3d_shader_src", ccm_base + 0x8200, 24, 3, imx8mp_gpu3d_shader_sels, ARRAY_SIZE(imx8mp_gpu3d_shader_sels));
+       hws[IMX8MP_CLK_GPU2D_SRC] = imx_clk_hw_mux2("gpu2d_src", ccm_base + 0x8280, 24, 3, imx8mp_gpu2d_sels, ARRAY_SIZE(imx8mp_gpu2d_sels));
+       hws[IMX8MP_CLK_AUDIO_AXI_SRC] = imx_clk_hw_mux2("audio_axi_src", ccm_base + 0x8300, 24, 3, imx8mp_audio_axi_sels, ARRAY_SIZE(imx8mp_audio_axi_sels));
+       hws[IMX8MP_CLK_HSIO_AXI_SRC] = imx_clk_hw_mux2("hsio_axi_src", ccm_base + 0x8380, 24, 3, imx8mp_hsio_axi_sels, ARRAY_SIZE(imx8mp_hsio_axi_sels));
+       hws[IMX8MP_CLK_MEDIA_ISP_SRC] = imx_clk_hw_mux2("media_isp_src", ccm_base + 0x8400, 24, 3, imx8mp_media_isp_sels, ARRAY_SIZE(imx8mp_media_isp_sels));
+       hws[IMX8MP_CLK_A53_CG] = imx_clk_hw_gate3("arm_a53_cg", "arm_a53_src", ccm_base + 0x8000, 28);
+       hws[IMX8MP_CLK_M4_CG] = imx_clk_hw_gate3("arm_m7_cg", "arm_m7_src", ccm_base + 0x8080, 28);
+       hws[IMX8MP_CLK_ML_CG] = imx_clk_hw_gate3("ml_cg", "ml_src", ccm_base + 0x8100, 28);
+       hws[IMX8MP_CLK_GPU3D_CORE_CG] = imx_clk_hw_gate3("gpu3d_core_cg", "gpu3d_core_src", ccm_base + 0x8180, 28);
+       hws[IMX8MP_CLK_GPU3D_SHADER_CG] = imx_clk_hw_gate3("gpu3d_shader_cg", "gpu3d_shader_src", ccm_base + 0x8200, 28);
+       hws[IMX8MP_CLK_GPU2D_CG] = imx_clk_hw_gate3("gpu2d_cg", "gpu2d_src", ccm_base + 0x8280, 28);
+       hws[IMX8MP_CLK_AUDIO_AXI_CG] = imx_clk_hw_gate3("audio_axi_cg", "audio_axi_src", ccm_base + 0x8300, 28);
+       hws[IMX8MP_CLK_HSIO_AXI_CG] = imx_clk_hw_gate3("hsio_axi_cg", "hsio_axi_src", ccm_base + 0x8380, 28);
+       hws[IMX8MP_CLK_MEDIA_ISP_CG] = imx_clk_hw_gate3("media_isp_cg", "media_isp_src", ccm_base + 0x8400, 28);
+       hws[IMX8MP_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", ccm_base + 0x8000, 0, 3);
+       hws[IMX8MP_CLK_M7_DIV] = imx_clk_hw_divider2("arm_m7_div", "arm_m7_cg", ccm_base + 0x8080, 0, 3);
+       hws[IMX8MP_CLK_ML_DIV] = imx_clk_hw_divider2("ml_div", "ml_cg", ccm_base + 0x8100, 0, 3);
+       hws[IMX8MP_CLK_GPU3D_CORE_DIV] = imx_clk_hw_divider2("gpu3d_core_div", "gpu3d_core_cg", ccm_base + 0x8180, 0, 3);
+       hws[IMX8MP_CLK_GPU3D_SHADER_DIV] = imx_clk_hw_divider2("gpu3d_shader_div", "gpu3d_shader_cg", ccm_base + 0x8200, 0, 3);
+       hws[IMX8MP_CLK_GPU2D_DIV] = imx_clk_hw_divider2("gpu2d_div", "gpu2d_cg", ccm_base + 0x8280, 0, 3);
+       hws[IMX8MP_CLK_AUDIO_AXI_DIV] = imx_clk_hw_divider2("audio_axi_div", "audio_axi_cg", ccm_base + 0x8300, 0, 3);
+       hws[IMX8MP_CLK_HSIO_AXI_DIV] = imx_clk_hw_divider2("hsio_axi_div", "hsio_axi_cg", ccm_base + 0x8380, 0, 3);
+       hws[IMX8MP_CLK_MEDIA_ISP_DIV] = imx_clk_hw_divider2("media_isp_div", "media_isp_cg", ccm_base + 0x8400, 0, 3);
+
+       hws[IMX8MP_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mp_main_axi_sels, ccm_base + 0x8800);
+       hws[IMX8MP_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mp_enet_axi_sels, ccm_base + 0x8880);
+       hws[IMX8MP_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite_critical("nand_usdhc_bus", imx8mp_nand_usdhc_sels, ccm_base + 0x8900);
+       hws[IMX8MP_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mp_vpu_bus_sels, ccm_base + 0x8980);
+       hws[IMX8MP_CLK_MEDIA_AXI] = imx8m_clk_hw_composite("media_axi", imx8mp_media_axi_sels, ccm_base + 0x8a00);
+       hws[IMX8MP_CLK_MEDIA_APB] = imx8m_clk_hw_composite("media_apb", imx8mp_media_apb_sels, ccm_base + 0x8a80);
+       hws[IMX8MP_CLK_HDMI_APB] = imx8m_clk_hw_composite("hdmi_apb", imx8mp_media_apb_sels, ccm_base + 0x8b00);
+       hws[IMX8MP_CLK_HDMI_AXI] = imx8m_clk_hw_composite("hdmi_axi", imx8mp_media_apb_sels, ccm_base + 0x8b80);
+       hws[IMX8MP_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mp_gpu_axi_sels, ccm_base + 0x8c00);
+       hws[IMX8MP_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mp_gpu_ahb_sels, ccm_base + 0x8c80);
+       hws[IMX8MP_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mp_noc_sels, ccm_base + 0x8d00);
+       hws[IMX8MP_CLK_NOC_IO] = imx8m_clk_hw_composite_critical("noc_io", imx8mp_noc_io_sels, ccm_base + 0x8d80);
+       hws[IMX8MP_CLK_ML_AXI] = imx8m_clk_hw_composite("ml_axi", imx8mp_ml_axi_sels, ccm_base + 0x8e00);
+       hws[IMX8MP_CLK_ML_AHB] = imx8m_clk_hw_composite("ml_ahb", imx8mp_ml_ahb_sels, ccm_base + 0x8e80);
+
+       hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
+       hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
+       hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
+
+       hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
+       hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1);
+
+       hws[IMX8MP_CLK_DRAM_ALT] = imx8m_clk_hw_composite("dram_alt", imx8mp_dram_alt_sels, ccm_base + 0xa000);
+       hws[IMX8MP_CLK_DRAM_APB] = imx8m_clk_hw_composite_critical("dram_apb", imx8mp_dram_apb_sels, ccm_base + 0xa080);
+       hws[IMX8MP_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mp_vpu_g1_sels, ccm_base + 0xa100);
+       hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
+       hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
+       hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, ccm_base + 0xa280);
+       hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite("memrepair", imx8mp_memrepair_sels, ccm_base + 0xa300);
+       hws[IMX8MP_CLK_PCIE_PHY] = imx8m_clk_hw_composite("pcie_phy", imx8mp_pcie_phy_sels, ccm_base + 0xa380);
+       hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", imx8mp_pcie_aux_sels, ccm_base + 0xa400);
+       hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, ccm_base + 0xa480);
+       hws[IMX8MP_CLK_I2C6] = imx8m_clk_hw_composite("i2c6", imx8mp_i2c6_sels, ccm_base + 0xa500);
+       hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580);
+       hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600);
+       hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680);
+       hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700);
+       hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780);
+       hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800);
+       hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880);
+       hws[IMX8MP_CLK_ENET_QOS_TIMER] = imx8m_clk_hw_composite("enet_qos_timer", imx8mp_enet_qos_timer_sels, ccm_base + 0xa900);
+       hws[IMX8MP_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mp_enet_ref_sels, ccm_base + 0xa980);
+       hws[IMX8MP_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mp_enet_timer_sels, ccm_base + 0xaa00);
+       hws[IMX8MP_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy_ref", imx8mp_enet_phy_ref_sels, ccm_base + 0xaa80);
+       hws[IMX8MP_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mp_nand_sels, ccm_base + 0xab00);
+       hws[IMX8MP_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mp_qspi_sels, ccm_base + 0xab80);
+       hws[IMX8MP_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mp_usdhc1_sels, ccm_base + 0xac00);
+       hws[IMX8MP_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mp_usdhc2_sels, ccm_base + 0xac80);
+       hws[IMX8MP_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mp_i2c1_sels, ccm_base + 0xad00);
+       hws[IMX8MP_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mp_i2c2_sels, ccm_base + 0xad80);
+       hws[IMX8MP_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mp_i2c3_sels, ccm_base + 0xae00);
+       hws[IMX8MP_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mp_i2c4_sels, ccm_base + 0xae80);
+
+       hws[IMX8MP_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mp_uart1_sels, ccm_base + 0xaf00);
+       hws[IMX8MP_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mp_uart2_sels, ccm_base + 0xaf80);
+       hws[IMX8MP_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mp_uart3_sels, ccm_base + 0xb000);
+       hws[IMX8MP_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mp_uart4_sels, ccm_base + 0xb080);
+       hws[IMX8MP_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mp_usb_core_ref_sels, ccm_base + 0xb100);
+       hws[IMX8MP_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mp_usb_phy_ref_sels, ccm_base + 0xb180);
+       hws[IMX8MP_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mp_gic_sels, ccm_base + 0xb200);
+       hws[IMX8MP_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mp_ecspi1_sels, ccm_base + 0xb280);
+       hws[IMX8MP_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mp_ecspi2_sels, ccm_base + 0xb300);
+       hws[IMX8MP_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mp_pwm1_sels, ccm_base + 0xb380);
+       hws[IMX8MP_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mp_pwm2_sels, ccm_base + 0xb400);
+       hws[IMX8MP_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mp_pwm3_sels, ccm_base + 0xb480);
+       hws[IMX8MP_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mp_pwm4_sels, ccm_base + 0xb500);
+
+       hws[IMX8MP_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mp_gpt1_sels, ccm_base + 0xb580);
+       hws[IMX8MP_CLK_GPT2] = imx8m_clk_hw_composite("gpt2", imx8mp_gpt2_sels, ccm_base + 0xb600);
+       hws[IMX8MP_CLK_GPT3] = imx8m_clk_hw_composite("gpt3", imx8mp_gpt3_sels, ccm_base + 0xb680);
+       hws[IMX8MP_CLK_GPT4] = imx8m_clk_hw_composite("gpt4", imx8mp_gpt4_sels, ccm_base + 0xb700);
+       hws[IMX8MP_CLK_GPT5] = imx8m_clk_hw_composite("gpt5", imx8mp_gpt5_sels, ccm_base + 0xb780);
+       hws[IMX8MP_CLK_GPT6] = imx8m_clk_hw_composite("gpt6", imx8mp_gpt6_sels, ccm_base + 0xb800);
+       hws[IMX8MP_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mp_wdog_sels, ccm_base + 0xb900);
+       hws[IMX8MP_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mp_wrclk_sels, ccm_base + 0xb980);
+       hws[IMX8MP_CLK_IPP_DO_CLKO1] = imx8m_clk_hw_composite("ipp_do_clko1", imx8mp_ipp_do_clko1_sels, ccm_base + 0xba00);
+       hws[IMX8MP_CLK_IPP_DO_CLKO2] = imx8m_clk_hw_composite("ipp_do_clko2", imx8mp_ipp_do_clko2_sels, ccm_base + 0xba80);
+       hws[IMX8MP_CLK_HDMI_FDCC_TST] = imx8m_clk_hw_composite("hdmi_fdcc_tst", imx8mp_hdmi_fdcc_tst_sels, ccm_base + 0xbb00);
+       hws[IMX8MP_CLK_HDMI_27M] = imx8m_clk_hw_composite("hdmi_27m", imx8mp_hdmi_27m_sels, ccm_base + 0xbb80);
+       hws[IMX8MP_CLK_HDMI_REF_266M] = imx8m_clk_hw_composite("hdmi_ref_266m", imx8mp_hdmi_ref_266m_sels, ccm_base + 0xbc00);
+       hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80);
+       hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00);
+       hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
+       hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00);
+       hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
+       hws[IMX8MP_CLK_MEDIA_MIPI_PHY2_REF] = imx8m_clk_hw_composite("media_mipi_phy2_ref", imx8mp_media_mipi_phy2_ref_sels, ccm_base + 0xbf00);
+       hws[IMX8MP_CLK_MEDIA_MIPI_CSI2_ESC] = imx8m_clk_hw_composite("media_mipi_csi2_esc", imx8mp_media_mipi_csi2_esc_sels, ccm_base + 0xbf80);
+       hws[IMX8MP_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mp_pcie2_ctrl_sels, ccm_base + 0xc000);
+       hws[IMX8MP_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mp_pcie2_phy_sels, ccm_base + 0xc080);
+       hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = imx8m_clk_hw_composite("media_mipi_test_byte", imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100);
+       hws[IMX8MP_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mp_ecspi3_sels, ccm_base + 0xc180);
+       hws[IMX8MP_CLK_PDM] = imx8m_clk_hw_composite("pdm", imx8mp_pdm_sels, ccm_base + 0xc200);
+       hws[IMX8MP_CLK_VPU_VC8000E] = imx8m_clk_hw_composite("vpu_vc8000e", imx8mp_vpu_vc8000e_sels, ccm_base + 0xc280);
+       hws[IMX8MP_CLK_SAI7] = imx8m_clk_hw_composite("sai7", imx8mp_sai7_sels, ccm_base + 0xc300);
+
+       hws[IMX8MP_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
+       hws[IMX8MP_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", ccm_base + 0x9800, 24, 1, imx8mp_dram_core_sels, ARRAY_SIZE(imx8mp_dram_core_sels), CLK_IS_CRITICAL);
+
+       hws[IMX8MP_CLK_DRAM1_ROOT] = imx_clk_hw_gate4_flags("dram1_root_clk", "dram_core_clk", ccm_base + 0x4050, 0, CLK_IS_CRITICAL);
+       hws[IMX8MP_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", ccm_base + 0x4070, 0);
+       hws[IMX8MP_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", ccm_base + 0x4080, 0);
+       hws[IMX8MP_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", ccm_base + 0x4090, 0);
+       hws[IMX8MP_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", ccm_base + 0x40a0, 0);
+       hws[IMX8MP_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", ccm_base + 0x40b0, 0);
+       hws[IMX8MP_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", ccm_base + 0x40c0, 0);
+       hws[IMX8MP_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", ccm_base + 0x40d0, 0);
+       hws[IMX8MP_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", ccm_base + 0x40e0, 0);
+       hws[IMX8MP_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", ccm_base + 0x40f0, 0);
+       hws[IMX8MP_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", ccm_base + 0x4100, 0);
+       hws[IMX8MP_CLK_GPT2_ROOT] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2", ccm_base + 0x4110, 0);
+       hws[IMX8MP_CLK_GPT3_ROOT] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3", ccm_base + 0x4120, 0);
+       hws[IMX8MP_CLK_GPT4_ROOT] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4", ccm_base + 0x4130, 0);
+       hws[IMX8MP_CLK_GPT5_ROOT] = imx_clk_hw_gate4("gpt5_root_clk", "gpt5", ccm_base + 0x4140, 0);
+       hws[IMX8MP_CLK_GPT6_ROOT] = imx_clk_hw_gate4("gpt6_root_clk", "gpt6", ccm_base + 0x4150, 0);
+       hws[IMX8MP_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", ccm_base + 0x4170, 0);
+       hws[IMX8MP_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", ccm_base + 0x4180, 0);
+       hws[IMX8MP_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", ccm_base + 0x4190, 0);
+       hws[IMX8MP_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", ccm_base + 0x41a0, 0);
+       hws[IMX8MP_CLK_PCIE_ROOT] = imx_clk_hw_gate4("pcie_root_clk", "pcie_aux", ccm_base + 0x4250, 0);
+       hws[IMX8MP_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", ccm_base + 0x4280, 0);
+       hws[IMX8MP_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", ccm_base + 0x4290, 0);
+       hws[IMX8MP_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", ccm_base + 0x42a0, 0);
+       hws[IMX8MP_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", ccm_base + 0x42b0, 0);
+       hws[IMX8MP_CLK_QOS_ROOT] = imx_clk_hw_gate4("qos_root_clk", "ipg_root", ccm_base + 0x42c0, 0);
+       hws[IMX8MP_CLK_QOS_ENET_ROOT] = imx_clk_hw_gate4("qos_enet_root_clk", "ipg_root", ccm_base + 0x42e0, 0);
+       hws[IMX8MP_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", ccm_base + 0x42f0, 0);
+       hws[IMX8MP_CLK_NAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", ccm_base + 0x4300, 0, &share_count_nand);
+       hws[IMX8MP_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", ccm_base + 0x4300, 0, &share_count_nand);
+       hws[IMX8MP_CLK_I2C5_ROOT] = imx_clk_hw_gate2("i2c5_root_clk", "i2c5", ccm_base + 0x4330, 0);
+       hws[IMX8MP_CLK_I2C6_ROOT] = imx_clk_hw_gate2("i2c6_root_clk", "i2c6", ccm_base + 0x4340, 0);
+       hws[IMX8MP_CLK_CAN1_ROOT] = imx_clk_hw_gate2("can1_root_clk", "can1", ccm_base + 0x4350, 0);
+       hws[IMX8MP_CLK_CAN2_ROOT] = imx_clk_hw_gate2("can2_root_clk", "can2", ccm_base + 0x4360, 0);
+       hws[IMX8MP_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_root_clk", "ipg_root", ccm_base + 0x43a0, 0);
+       hws[IMX8MP_CLK_ENET_QOS_ROOT] = imx_clk_hw_gate4("enet_qos_root_clk", "enet_axi", ccm_base + 0x43b0, 0);
+       hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
+       hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_div", ccm_base + 0x4450, 0);
+       hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core_div", ccm_base + 0x4460, 0);
+       hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0);
+       hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
+       hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
+       hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
+       hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
+       hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "osc_32k", ccm_base + 0x44d0, 0);
+       hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
+       hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
+       hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
+       hws[IMX8MP_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", ccm_base + 0x4530, 0);
+       hws[IMX8MP_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", ccm_base + 0x4540, 0);
+       hws[IMX8MP_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", ccm_base + 0x4550, 0);
+       hws[IMX8MP_CLK_VPU_G1_ROOT] = imx_clk_hw_gate4("vpu_g1_root_clk", "vpu_g1", ccm_base + 0x4560, 0);
+       hws[IMX8MP_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_axi", ccm_base + 0x4570, 0);
+       hws[IMX8MP_CLK_VPU_VC8KE_ROOT] = imx_clk_hw_gate4("vpu_vc8ke_root_clk", "vpu_vc8000e", ccm_base + 0x4590, 0);
+       hws[IMX8MP_CLK_VPU_G2_ROOT] = imx_clk_hw_gate4("vpu_g2_root_clk", "vpu_g2", ccm_base + 0x45a0, 0);
+       hws[IMX8MP_CLK_NPU_ROOT] = imx_clk_hw_gate4("npu_root_clk", "ml_div", ccm_base + 0x45b0, 0);
+       hws[IMX8MP_CLK_HSIO_ROOT] = imx_clk_hw_gate4("hsio_root_clk", "ipg_root", ccm_base + 0x45c0, 0);
+       hws[IMX8MP_CLK_MEDIA_APB_ROOT] = imx_clk_hw_gate2_shared2("media_apb_root_clk", "media_apb", ccm_base + 0x45d0, 0, &share_count_media);
+       hws[IMX8MP_CLK_MEDIA_AXI_ROOT] = imx_clk_hw_gate2_shared2("media_axi_root_clk", "media_axi", ccm_base + 0x45d0, 0, &share_count_media);
+       hws[IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam1_pix_root_clk", "media_cam1_pix", ccm_base + 0x45d0, 0, &share_count_media);
+       hws[IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_cam2_pix_root_clk", "media_cam2_pix", ccm_base + 0x45d0, 0, &share_count_media);
+       hws[IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp1_pix_root_clk", "media_disp1_pix", ccm_base + 0x45d0, 0, &share_count_media);
+       hws[IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT] = imx_clk_hw_gate2_shared2("media_disp2_pix_root_clk", "media_disp2_pix", ccm_base + 0x45d0, 0, &share_count_media);
+       hws[IMX8MP_CLK_MEDIA_ISP_ROOT] = imx_clk_hw_gate2_shared2("media_isp_root_clk", "media_isp_div", ccm_base + 0x45d0, 0, &share_count_media);
+
+       hws[IMX8MP_CLK_USDHC3_ROOT] = imx_clk_hw_gate4("usdhc3_root_clk", "usdhc3", ccm_base + 0x45e0, 0);
+       hws[IMX8MP_CLK_HDMI_ROOT] = imx_clk_hw_gate4("hdmi_root_clk", "hdmi_axi", ccm_base + 0x45f0, 0);
+       hws[IMX8MP_CLK_TSENSOR_ROOT] = imx_clk_hw_gate4("tsensor_root_clk", "ipg_root", ccm_base + 0x4620, 0);
+       hws[IMX8MP_CLK_VPU_ROOT] = imx_clk_hw_gate4("vpu_root_clk", "vpu_bus", ccm_base + 0x4630, 0);
+       hws[IMX8MP_CLK_AUDIO_ROOT] = imx_clk_hw_gate4("audio_root_clk", "ipg_root", ccm_base + 0x4650, 0);
+
+       hws[IMX8MP_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div",
+                                            hws[IMX8MP_CLK_A53_DIV]->clk,
+                                            hws[IMX8MP_CLK_A53_SRC]->clk,
+                                            hws[IMX8MP_ARM_PLL_OUT]->clk,
+                                            hws[IMX8MP_SYS_PLL1_800M]->clk);
+
+       imx_check_clk_hws(hws, IMX8MP_CLK_END);
+
+       of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
+
+       for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
+               int index = uart_clk_ids[i];
+
+               uart_clks[i] = &hws[index]->clk;
+       }
+
+       imx_register_uart_clocks(uart_clks);
+
+       return 0;
+}
+
+static const struct of_device_id imx8mp_clk_of_match[] = {
+       { .compatible = "fsl,imx8mp-ccm" },
+       { /* Sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, imx8mp_clk_of_match);
+
+static struct platform_driver imx8mp_clk_driver = {
+       .probe = imx8mp_clocks_probe,
+       .driver = {
+               .name = "imx8mp-ccm",
+               /*
+                * Disable bind attributes: clocks are not removed and
+                * reloading the driver will crash or break devices.
+                */
+               .suppress_bind_attrs = true,
+               .of_match_table = of_match_ptr(imx8mp_clk_of_match),
+       },
+};
+module_platform_driver(imx8mp_clk_driver);
index 5f10a60..4c0edca 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/module.h>
 #include <linux/of_address.h>
 #include <linux/types.h>
+#include <linux/slab.h>
 #include <linux/platform_device.h>
 
 #include "clk.h"
@@ -24,8 +25,6 @@ static u32 share_count_sai6;
 static u32 share_count_dcss;
 static u32 share_count_nand;
 
-static struct clk *clks[IMX8MQ_CLK_END];
-
 static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", };
 static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
 static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
@@ -269,124 +268,133 @@ static const char * const imx8mq_clko1_sels[] = {"osc_25m", "sys1_pll_800m", "os
 static const char * const imx8mq_clko2_sels[] = {"osc_25m", "sys2_pll_200m", "sys1_pll_400m", "sys2_pll_166m",
                                          "sys3_pll_out", "audio_pll1_out", "video_pll1_out", "ckil", };
 
-static struct clk_onecell_data clk_data;
+static struct clk_hw_onecell_data *clk_hw_data;
+static struct clk_hw **hws;
 
-static struct clk ** const uart_clks[] = {
-       &clks[IMX8MQ_CLK_UART1_ROOT],
-       &clks[IMX8MQ_CLK_UART2_ROOT],
-       &clks[IMX8MQ_CLK_UART3_ROOT],
-       &clks[IMX8MQ_CLK_UART4_ROOT],
-       NULL
+static const int uart_clk_ids[] = {
+       IMX8MQ_CLK_UART1_ROOT,
+       IMX8MQ_CLK_UART2_ROOT,
+       IMX8MQ_CLK_UART3_ROOT,
+       IMX8MQ_CLK_UART4_ROOT,
 };
+static struct clk **uart_hws[ARRAY_SIZE(uart_clk_ids) + 1];
 
 static int imx8mq_clocks_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct device_node *np = dev->of_node;
        void __iomem *base;
-       int err;
+       int err, i;
+
+       clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
+                                         IMX8MQ_CLK_END), GFP_KERNEL);
+       if (WARN_ON(!clk_hw_data))
+               return -ENOMEM;
+
+       clk_hw_data->num = IMX8MQ_CLK_END;
+       hws = clk_hw_data->hws;
 
-       clks[IMX8MQ_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
-       clks[IMX8MQ_CLK_32K] = of_clk_get_by_name(np, "ckil");
-       clks[IMX8MQ_CLK_25M] = of_clk_get_by_name(np, "osc_25m");
-       clks[IMX8MQ_CLK_27M] = of_clk_get_by_name(np, "osc_27m");
-       clks[IMX8MQ_CLK_EXT1] = of_clk_get_by_name(np, "clk_ext1");
-       clks[IMX8MQ_CLK_EXT2] = of_clk_get_by_name(np, "clk_ext2");
-       clks[IMX8MQ_CLK_EXT3] = of_clk_get_by_name(np, "clk_ext3");
-       clks[IMX8MQ_CLK_EXT4] = of_clk_get_by_name(np, "clk_ext4");
+       hws[IMX8MQ_CLK_DUMMY] = imx_clk_hw_fixed("dummy", 0);
+       hws[IMX8MQ_CLK_32K] = imx_obtain_fixed_clk_hw(np, "ckil");
+       hws[IMX8MQ_CLK_25M] = imx_obtain_fixed_clk_hw(np, "osc_25m");
+       hws[IMX8MQ_CLK_27M] = imx_obtain_fixed_clk_hw(np, "osc_27m");
+       hws[IMX8MQ_CLK_EXT1] = imx_obtain_fixed_clk_hw(np, "clk_ext1");
+       hws[IMX8MQ_CLK_EXT2] = imx_obtain_fixed_clk_hw(np, "clk_ext2");
+       hws[IMX8MQ_CLK_EXT3] = imx_obtain_fixed_clk_hw(np, "clk_ext3");
+       hws[IMX8MQ_CLK_EXT4] = imx_obtain_fixed_clk_hw(np, "clk_ext4");
 
        np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop");
        base = of_iomap(np, 0);
        if (WARN_ON(!base))
                return -ENOMEM;
 
-       clks[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MQ_VPU_PLL_REF_SEL] = imx_clk_mux("vpu_pll_ref_sel", base + 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MQ_SYS3_PLL1_REF_SEL]  = imx_clk_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MQ_DRAM_PLL1_REF_SEL]  = imx_clk_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-       clks[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
-
-       clks[IMX8MQ_ARM_PLL_REF_DIV]    = imx_clk_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6);
-       clks[IMX8MQ_GPU_PLL_REF_DIV]    = imx_clk_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6);
-       clks[IMX8MQ_VPU_PLL_REF_DIV]    = imx_clk_divider("vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6);
-       clks[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6);
-       clks[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6);
-       clks[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6);
-
-       clks[IMX8MQ_ARM_PLL] = imx_clk_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28);
-       clks[IMX8MQ_GPU_PLL] = imx_clk_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18);
-       clks[IMX8MQ_VPU_PLL] = imx_clk_frac_pll("vpu_pll", "vpu_pll_ref_div", base + 0x20);
-       clks[IMX8MQ_AUDIO_PLL1] = imx_clk_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0);
-       clks[IMX8MQ_AUDIO_PLL2] = imx_clk_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8);
-       clks[IMX8MQ_VIDEO_PLL1] = imx_clk_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10);
+       hws[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_VPU_PLL_REF_SEL] = imx_clk_hw_mux("vpu_pll_ref_sel", base + 0x20, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_AUDIO_PLL1_REF_SEL] = imx_clk_hw_mux("audio_pll1_ref_sel", base + 0x0, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_AUDIO_PLL2_REF_SEL] = imx_clk_hw_mux("audio_pll2_ref_sel", base + 0x8, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_VIDEO_PLL1_REF_SEL] = imx_clk_hw_mux("video_pll1_ref_sel", base + 0x10, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_SYS3_PLL1_REF_SEL]   = imx_clk_hw_mux("sys3_pll1_ref_sel", base + 0x48, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_DRAM_PLL1_REF_SEL]   = imx_clk_hw_mux("dram_pll1_ref_sel", base + 0x60, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+       hws[IMX8MQ_VIDEO2_PLL1_REF_SEL] = imx_clk_hw_mux("video2_pll1_ref_sel", base + 0x54, 0, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
+
+       hws[IMX8MQ_ARM_PLL_REF_DIV]     = imx_clk_hw_divider("arm_pll_ref_div", "arm_pll_ref_sel", base + 0x28, 5, 6);
+       hws[IMX8MQ_GPU_PLL_REF_DIV]     = imx_clk_hw_divider("gpu_pll_ref_div", "gpu_pll_ref_sel", base + 0x18, 5, 6);
+       hws[IMX8MQ_VPU_PLL_REF_DIV]     = imx_clk_hw_divider("vpu_pll_ref_div", "vpu_pll_ref_sel", base + 0x20, 5, 6);
+       hws[IMX8MQ_AUDIO_PLL1_REF_DIV] = imx_clk_hw_divider("audio_pll1_ref_div", "audio_pll1_ref_sel", base + 0x0, 5, 6);
+       hws[IMX8MQ_AUDIO_PLL2_REF_DIV] = imx_clk_hw_divider("audio_pll2_ref_div", "audio_pll2_ref_sel", base + 0x8, 5, 6);
+       hws[IMX8MQ_VIDEO_PLL1_REF_DIV] = imx_clk_hw_divider("video_pll1_ref_div", "video_pll1_ref_sel", base + 0x10, 5, 6);
+
+       hws[IMX8MQ_ARM_PLL] = imx_clk_hw_frac_pll("arm_pll", "arm_pll_ref_div", base + 0x28);
+       hws[IMX8MQ_GPU_PLL] = imx_clk_hw_frac_pll("gpu_pll", "gpu_pll_ref_div", base + 0x18);
+       hws[IMX8MQ_VPU_PLL] = imx_clk_hw_frac_pll("vpu_pll", "vpu_pll_ref_div", base + 0x20);
+       hws[IMX8MQ_AUDIO_PLL1] = imx_clk_hw_frac_pll("audio_pll1", "audio_pll1_ref_div", base + 0x0);
+       hws[IMX8MQ_AUDIO_PLL2] = imx_clk_hw_frac_pll("audio_pll2", "audio_pll2_ref_div", base + 0x8);
+       hws[IMX8MQ_VIDEO_PLL1] = imx_clk_hw_frac_pll("video_pll1", "video_pll1_ref_div", base + 0x10);
 
        /* PLL bypass out */
-       clks[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
-       clks[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
-       clks[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
-       clks[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
-       clks[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels));
-       clks[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels));
+       hws[IMX8MQ_ARM_PLL_BYPASS] = imx_clk_hw_mux_flags("arm_pll_bypass", base + 0x28, 14, 1, arm_pll_bypass_sels, ARRAY_SIZE(arm_pll_bypass_sels), CLK_SET_RATE_PARENT);
+       hws[IMX8MQ_GPU_PLL_BYPASS] = imx_clk_hw_mux("gpu_pll_bypass", base + 0x18, 14, 1, gpu_pll_bypass_sels, ARRAY_SIZE(gpu_pll_bypass_sels));
+       hws[IMX8MQ_VPU_PLL_BYPASS] = imx_clk_hw_mux("vpu_pll_bypass", base + 0x20, 14, 1, vpu_pll_bypass_sels, ARRAY_SIZE(vpu_pll_bypass_sels));
+       hws[IMX8MQ_AUDIO_PLL1_BYPASS] = imx_clk_hw_mux("audio_pll1_bypass", base + 0x0, 14, 1, audio_pll1_bypass_sels, ARRAY_SIZE(audio_pll1_bypass_sels));
+       hws[IMX8MQ_AUDIO_PLL2_BYPASS] = imx_clk_hw_mux("audio_pll2_bypass", base + 0x8, 14, 1, audio_pll2_bypass_sels, ARRAY_SIZE(audio_pll2_bypass_sels));
+       hws[IMX8MQ_VIDEO_PLL1_BYPASS] = imx_clk_hw_mux("video_pll1_bypass", base + 0x10, 14, 1, video_pll1_bypass_sels, ARRAY_SIZE(video_pll1_bypass_sels));
 
        /* PLL OUT GATE */
-       clks[IMX8MQ_ARM_PLL_OUT] = imx_clk_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21);
-       clks[IMX8MQ_GPU_PLL_OUT] = imx_clk_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21);
-       clks[IMX8MQ_VPU_PLL_OUT] = imx_clk_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x20, 21);
-       clks[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21);
-       clks[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21);
-       clks[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21);
-
-       clks[IMX8MQ_SYS1_PLL_OUT] = imx_clk_fixed("sys1_pll_out", 800000000);
-       clks[IMX8MQ_SYS2_PLL_OUT] = imx_clk_fixed("sys2_pll_out", 1000000000);
-       clks[IMX8MQ_SYS3_PLL_OUT] = imx_clk_sccg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, base + 0x48, CLK_IS_CRITICAL);
-       clks[IMX8MQ_DRAM_PLL_OUT] = imx_clk_sccg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL);
-       clks[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_sccg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0);
+       hws[IMX8MQ_ARM_PLL_OUT] = imx_clk_hw_gate("arm_pll_out", "arm_pll_bypass", base + 0x28, 21);
+       hws[IMX8MQ_GPU_PLL_OUT] = imx_clk_hw_gate("gpu_pll_out", "gpu_pll_bypass", base + 0x18, 21);
+       hws[IMX8MQ_VPU_PLL_OUT] = imx_clk_hw_gate("vpu_pll_out", "vpu_pll_bypass", base + 0x20, 21);
+       hws[IMX8MQ_AUDIO_PLL1_OUT] = imx_clk_hw_gate("audio_pll1_out", "audio_pll1_bypass", base + 0x0, 21);
+       hws[IMX8MQ_AUDIO_PLL2_OUT] = imx_clk_hw_gate("audio_pll2_out", "audio_pll2_bypass", base + 0x8, 21);
+       hws[IMX8MQ_VIDEO_PLL1_OUT] = imx_clk_hw_gate("video_pll1_out", "video_pll1_bypass", base + 0x10, 21);
+
+       hws[IMX8MQ_SYS1_PLL_OUT] = imx_clk_hw_fixed("sys1_pll_out", 800000000);
+       hws[IMX8MQ_SYS2_PLL_OUT] = imx_clk_hw_fixed("sys2_pll_out", 1000000000);
+       hws[IMX8MQ_SYS3_PLL_OUT] = imx_clk_hw_sscg_pll("sys3_pll_out", sys3_pll_out_sels, ARRAY_SIZE(sys3_pll_out_sels), 0, 0, 0, base + 0x48, CLK_IS_CRITICAL);
+       hws[IMX8MQ_DRAM_PLL_OUT] = imx_clk_hw_sscg_pll("dram_pll_out", dram_pll_out_sels, ARRAY_SIZE(dram_pll_out_sels), 0, 0, 0, base + 0x60, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
+       hws[IMX8MQ_VIDEO2_PLL_OUT] = imx_clk_hw_sscg_pll("video2_pll_out", video2_pll_out_sels, ARRAY_SIZE(video2_pll_out_sels), 0, 0, 0, base + 0x54, 0);
 
        /* SYS PLL1 fixed output */
-       clks[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9);
-       clks[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11);
-       clks[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13);
-       clks[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15);
-       clks[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17);
-       clks[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19);
-       clks[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21);
-       clks[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23);
-       clks[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25);
-
-       clks[IMX8MQ_SYS1_PLL_40M] = imx_clk_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20);
-       clks[IMX8MQ_SYS1_PLL_80M] = imx_clk_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10);
-       clks[IMX8MQ_SYS1_PLL_100M] = imx_clk_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8);
-       clks[IMX8MQ_SYS1_PLL_133M] = imx_clk_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6);
-       clks[IMX8MQ_SYS1_PLL_160M] = imx_clk_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5);
-       clks[IMX8MQ_SYS1_PLL_200M] = imx_clk_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4);
-       clks[IMX8MQ_SYS1_PLL_266M] = imx_clk_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3);
-       clks[IMX8MQ_SYS1_PLL_400M] = imx_clk_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2);
-       clks[IMX8MQ_SYS1_PLL_800M] = imx_clk_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1);
+       hws[IMX8MQ_SYS1_PLL_40M_CG] = imx_clk_hw_gate("sys1_pll_40m_cg", "sys1_pll_out", base + 0x30, 9);
+       hws[IMX8MQ_SYS1_PLL_80M_CG] = imx_clk_hw_gate("sys1_pll_80m_cg", "sys1_pll_out", base + 0x30, 11);
+       hws[IMX8MQ_SYS1_PLL_100M_CG] = imx_clk_hw_gate("sys1_pll_100m_cg", "sys1_pll_out", base + 0x30, 13);
+       hws[IMX8MQ_SYS1_PLL_133M_CG] = imx_clk_hw_gate("sys1_pll_133m_cg", "sys1_pll_out", base + 0x30, 15);
+       hws[IMX8MQ_SYS1_PLL_160M_CG] = imx_clk_hw_gate("sys1_pll_160m_cg", "sys1_pll_out", base + 0x30, 17);
+       hws[IMX8MQ_SYS1_PLL_200M_CG] = imx_clk_hw_gate("sys1_pll_200m_cg", "sys1_pll_out", base + 0x30, 19);
+       hws[IMX8MQ_SYS1_PLL_266M_CG] = imx_clk_hw_gate("sys1_pll_266m_cg", "sys1_pll_out", base + 0x30, 21);
+       hws[IMX8MQ_SYS1_PLL_400M_CG] = imx_clk_hw_gate("sys1_pll_400m_cg", "sys1_pll_out", base + 0x30, 23);
+       hws[IMX8MQ_SYS1_PLL_800M_CG] = imx_clk_hw_gate("sys1_pll_800m_cg", "sys1_pll_out", base + 0x30, 25);
+
+       hws[IMX8MQ_SYS1_PLL_40M] = imx_clk_hw_fixed_factor("sys1_pll_40m", "sys1_pll_40m_cg", 1, 20);
+       hws[IMX8MQ_SYS1_PLL_80M] = imx_clk_hw_fixed_factor("sys1_pll_80m", "sys1_pll_80m_cg", 1, 10);
+       hws[IMX8MQ_SYS1_PLL_100M] = imx_clk_hw_fixed_factor("sys1_pll_100m", "sys1_pll_100m_cg", 1, 8);
+       hws[IMX8MQ_SYS1_PLL_133M] = imx_clk_hw_fixed_factor("sys1_pll_133m", "sys1_pll_133m_cg", 1, 6);
+       hws[IMX8MQ_SYS1_PLL_160M] = imx_clk_hw_fixed_factor("sys1_pll_160m", "sys1_pll_160m_cg", 1, 5);
+       hws[IMX8MQ_SYS1_PLL_200M] = imx_clk_hw_fixed_factor("sys1_pll_200m", "sys1_pll_200m_cg", 1, 4);
+       hws[IMX8MQ_SYS1_PLL_266M] = imx_clk_hw_fixed_factor("sys1_pll_266m", "sys1_pll_266m_cg", 1, 3);
+       hws[IMX8MQ_SYS1_PLL_400M] = imx_clk_hw_fixed_factor("sys1_pll_400m", "sys1_pll_400m_cg", 1, 2);
+       hws[IMX8MQ_SYS1_PLL_800M] = imx_clk_hw_fixed_factor("sys1_pll_800m", "sys1_pll_800m_cg", 1, 1);
 
        /* SYS PLL2 fixed output */
-       clks[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9);
-       clks[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11);
-       clks[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13);
-       clks[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15);
-       clks[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17);
-       clks[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19);
-       clks[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21);
-       clks[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23);
-       clks[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25);
-
-       clks[IMX8MQ_SYS2_PLL_50M] = imx_clk_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20);
-       clks[IMX8MQ_SYS2_PLL_100M] = imx_clk_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10);
-       clks[IMX8MQ_SYS2_PLL_125M] = imx_clk_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8);
-       clks[IMX8MQ_SYS2_PLL_166M] = imx_clk_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6);
-       clks[IMX8MQ_SYS2_PLL_200M] = imx_clk_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5);
-       clks[IMX8MQ_SYS2_PLL_250M] = imx_clk_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4);
-       clks[IMX8MQ_SYS2_PLL_333M] = imx_clk_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3);
-       clks[IMX8MQ_SYS2_PLL_500M] = imx_clk_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2);
-       clks[IMX8MQ_SYS2_PLL_1000M] = imx_clk_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1);
+       hws[IMX8MQ_SYS2_PLL_50M_CG] = imx_clk_hw_gate("sys2_pll_50m_cg", "sys2_pll_out", base + 0x3c, 9);
+       hws[IMX8MQ_SYS2_PLL_100M_CG] = imx_clk_hw_gate("sys2_pll_100m_cg", "sys2_pll_out", base + 0x3c, 11);
+       hws[IMX8MQ_SYS2_PLL_125M_CG] = imx_clk_hw_gate("sys2_pll_125m_cg", "sys2_pll_out", base + 0x3c, 13);
+       hws[IMX8MQ_SYS2_PLL_166M_CG] = imx_clk_hw_gate("sys2_pll_166m_cg", "sys2_pll_out", base + 0x3c, 15);
+       hws[IMX8MQ_SYS2_PLL_200M_CG] = imx_clk_hw_gate("sys2_pll_200m_cg", "sys2_pll_out", base + 0x3c, 17);
+       hws[IMX8MQ_SYS2_PLL_250M_CG] = imx_clk_hw_gate("sys2_pll_250m_cg", "sys2_pll_out", base + 0x3c, 19);
+       hws[IMX8MQ_SYS2_PLL_333M_CG] = imx_clk_hw_gate("sys2_pll_333m_cg", "sys2_pll_out", base + 0x3c, 21);
+       hws[IMX8MQ_SYS2_PLL_500M_CG] = imx_clk_hw_gate("sys2_pll_500m_cg", "sys2_pll_out", base + 0x3c, 23);
+       hws[IMX8MQ_SYS2_PLL_1000M_CG] = imx_clk_hw_gate("sys2_pll_1000m_cg", "sys2_pll_out", base + 0x3c, 25);
+
+       hws[IMX8MQ_SYS2_PLL_50M] = imx_clk_hw_fixed_factor("sys2_pll_50m", "sys2_pll_50m_cg", 1, 20);
+       hws[IMX8MQ_SYS2_PLL_100M] = imx_clk_hw_fixed_factor("sys2_pll_100m", "sys2_pll_100m_cg", 1, 10);
+       hws[IMX8MQ_SYS2_PLL_125M] = imx_clk_hw_fixed_factor("sys2_pll_125m", "sys2_pll_125m_cg", 1, 8);
+       hws[IMX8MQ_SYS2_PLL_166M] = imx_clk_hw_fixed_factor("sys2_pll_166m", "sys2_pll_166m_cg", 1, 6);
+       hws[IMX8MQ_SYS2_PLL_200M] = imx_clk_hw_fixed_factor("sys2_pll_200m", "sys2_pll_200m_cg", 1, 5);
+       hws[IMX8MQ_SYS2_PLL_250M] = imx_clk_hw_fixed_factor("sys2_pll_250m", "sys2_pll_250m_cg", 1, 4);
+       hws[IMX8MQ_SYS2_PLL_333M] = imx_clk_hw_fixed_factor("sys2_pll_333m", "sys2_pll_333m_cg", 1, 3);
+       hws[IMX8MQ_SYS2_PLL_500M] = imx_clk_hw_fixed_factor("sys2_pll_500m", "sys2_pll_500m_cg", 1, 2);
+       hws[IMX8MQ_SYS2_PLL_1000M] = imx_clk_hw_fixed_factor("sys2_pll_1000m", "sys2_pll_1000m_cg", 1, 1);
 
        np = dev->of_node;
        base = devm_platform_ioremap_resource(pdev, 0);
@@ -394,206 +402,213 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
                return PTR_ERR(base);
 
        /* CORE */
-       clks[IMX8MQ_CLK_A53_SRC] = imx_clk_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
-       clks[IMX8MQ_CLK_M4_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels));
-       clks[IMX8MQ_CLK_VPU_SRC] = imx_clk_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels));
-       clks[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_mux2("gpu_core_src", base + 0x8180, 24, 3,  imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels));
-       clks[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels,  ARRAY_SIZE(imx8mq_gpu_shader_sels));
-
-       clks[IMX8MQ_CLK_A53_CG] = imx_clk_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
-       clks[IMX8MQ_CLK_M4_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
-       clks[IMX8MQ_CLK_VPU_CG] = imx_clk_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
-       clks[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
-       clks[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
-
-       clks[IMX8MQ_CLK_A53_DIV] = imx_clk_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
-       clks[IMX8MQ_CLK_M4_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
-       clks[IMX8MQ_CLK_VPU_DIV] = imx_clk_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
-       clks[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
-       clks[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
+       hws[IMX8MQ_CLK_A53_SRC] = imx_clk_hw_mux2("arm_a53_src", base + 0x8000, 24, 3, imx8mq_a53_sels, ARRAY_SIZE(imx8mq_a53_sels));
+       hws[IMX8MQ_CLK_M4_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, imx8mq_arm_m4_sels, ARRAY_SIZE(imx8mq_arm_m4_sels));
+       hws[IMX8MQ_CLK_VPU_SRC] = imx_clk_hw_mux2("vpu_src", base + 0x8100, 24, 3, imx8mq_vpu_sels, ARRAY_SIZE(imx8mq_vpu_sels));
+       hws[IMX8MQ_CLK_GPU_CORE_SRC] = imx_clk_hw_mux2("gpu_core_src", base + 0x8180, 24, 3,  imx8mq_gpu_core_sels, ARRAY_SIZE(imx8mq_gpu_core_sels));
+       hws[IMX8MQ_CLK_GPU_SHADER_SRC] = imx_clk_hw_mux2("gpu_shader_src", base + 0x8200, 24, 3, imx8mq_gpu_shader_sels,  ARRAY_SIZE(imx8mq_gpu_shader_sels));
+
+       hws[IMX8MQ_CLK_A53_CG] = imx_clk_hw_gate3_flags("arm_a53_cg", "arm_a53_src", base + 0x8000, 28, CLK_IS_CRITICAL);
+       hws[IMX8MQ_CLK_M4_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
+       hws[IMX8MQ_CLK_VPU_CG] = imx_clk_hw_gate3("vpu_cg", "vpu_src", base + 0x8100, 28);
+       hws[IMX8MQ_CLK_GPU_CORE_CG] = imx_clk_hw_gate3("gpu_core_cg", "gpu_core_src", base + 0x8180, 28);
+       hws[IMX8MQ_CLK_GPU_SHADER_CG] = imx_clk_hw_gate3("gpu_shader_cg", "gpu_shader_src", base + 0x8200, 28);
+
+       hws[IMX8MQ_CLK_A53_DIV] = imx_clk_hw_divider2("arm_a53_div", "arm_a53_cg", base + 0x8000, 0, 3);
+       hws[IMX8MQ_CLK_M4_DIV] = imx_clk_hw_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
+       hws[IMX8MQ_CLK_VPU_DIV] = imx_clk_hw_divider2("vpu_div", "vpu_cg", base + 0x8100, 0, 3);
+       hws[IMX8MQ_CLK_GPU_CORE_DIV] = imx_clk_hw_divider2("gpu_core_div", "gpu_core_cg", base + 0x8180, 0, 3);
+       hws[IMX8MQ_CLK_GPU_SHADER_DIV] = imx_clk_hw_divider2("gpu_shader_div", "gpu_shader_cg", base + 0x8200, 0, 3);
 
        /* BUS */
-       clks[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
-       clks[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
-       clks[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
-       clks[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
-       clks[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
-       clks[IMX8MQ_CLK_DISP_APB] = imx8m_clk_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
-       clks[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
-       clks[IMX8MQ_CLK_USB_BUS] = imx8m_clk_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
-       clks[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
-       clks[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
-       clks[IMX8MQ_CLK_NOC] = imx8m_clk_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
-       clks[IMX8MQ_CLK_NOC_APB] = imx8m_clk_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
+       hws[IMX8MQ_CLK_MAIN_AXI] = imx8m_clk_hw_composite_critical("main_axi", imx8mq_main_axi_sels, base + 0x8800);
+       hws[IMX8MQ_CLK_ENET_AXI] = imx8m_clk_hw_composite("enet_axi", imx8mq_enet_axi_sels, base + 0x8880);
+       hws[IMX8MQ_CLK_NAND_USDHC_BUS] = imx8m_clk_hw_composite("nand_usdhc_bus", imx8mq_nand_usdhc_sels, base + 0x8900);
+       hws[IMX8MQ_CLK_VPU_BUS] = imx8m_clk_hw_composite("vpu_bus", imx8mq_vpu_bus_sels, base + 0x8980);
+       hws[IMX8MQ_CLK_DISP_AXI] = imx8m_clk_hw_composite("disp_axi", imx8mq_disp_axi_sels, base + 0x8a00);
+       hws[IMX8MQ_CLK_DISP_APB] = imx8m_clk_hw_composite("disp_apb", imx8mq_disp_apb_sels, base + 0x8a80);
+       hws[IMX8MQ_CLK_DISP_RTRM] = imx8m_clk_hw_composite("disp_rtrm", imx8mq_disp_rtrm_sels, base + 0x8b00);
+       hws[IMX8MQ_CLK_USB_BUS] = imx8m_clk_hw_composite("usb_bus", imx8mq_usb_bus_sels, base + 0x8b80);
+       hws[IMX8MQ_CLK_GPU_AXI] = imx8m_clk_hw_composite("gpu_axi", imx8mq_gpu_axi_sels, base + 0x8c00);
+       hws[IMX8MQ_CLK_GPU_AHB] = imx8m_clk_hw_composite("gpu_ahb", imx8mq_gpu_ahb_sels, base + 0x8c80);
+       hws[IMX8MQ_CLK_NOC] = imx8m_clk_hw_composite_critical("noc", imx8mq_noc_sels, base + 0x8d00);
+       hws[IMX8MQ_CLK_NOC_APB] = imx8m_clk_hw_composite_critical("noc_apb", imx8mq_noc_apb_sels, base + 0x8d80);
 
        /* AHB */
        /* AHB clock is used by the AHB bus therefore marked as critical */
-       clks[IMX8MQ_CLK_AHB] = imx8m_clk_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000);
-       clks[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
+       hws[IMX8MQ_CLK_AHB] = imx8m_clk_hw_composite_critical("ahb", imx8mq_ahb_sels, base + 0x9000);
+       hws[IMX8MQ_CLK_AUDIO_AHB] = imx8m_clk_hw_composite("audio_ahb", imx8mq_audio_ahb_sels, base + 0x9100);
 
        /* IPG */
-       clks[IMX8MQ_CLK_IPG_ROOT] = imx_clk_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
-       clks[IMX8MQ_CLK_IPG_AUDIO_ROOT] = imx_clk_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+       hws[IMX8MQ_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb", base + 0x9080, 0, 1);
+       hws[IMX8MQ_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", base + 0x9180, 0, 1);
+
+       /*
+        * DRAM clocks are manipulated from TF-A outside clock framework.
+        * Mark with GET_RATE_NOCACHE to always read div value from hardware
+        */
+       hws[IMX8MQ_CLK_DRAM_CORE] = imx_clk_hw_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
+       hws[IMX8MQ_CLK_DRAM_ALT] = __imx8m_clk_hw_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000, CLK_GET_RATE_NOCACHE);
+       hws[IMX8MQ_CLK_DRAM_APB] = __imx8m_clk_hw_composite("dram_apb", imx8mq_dram_apb_sels, base + 0xa080, CLK_IS_CRITICAL | CLK_GET_RATE_NOCACHE);
 
        /* IP */
-       clks[IMX8MQ_CLK_DRAM_CORE] = imx_clk_mux2_flags("dram_core_clk", base + 0x9800, 24, 1, imx8mq_dram_core_sels, ARRAY_SIZE(imx8mq_dram_core_sels), CLK_IS_CRITICAL);
-
-       clks[IMX8MQ_CLK_DRAM_ALT] = imx8m_clk_composite("dram_alt", imx8mq_dram_alt_sels, base + 0xa000);
-       clks[IMX8MQ_CLK_DRAM_APB] = imx8m_clk_composite_critical("dram_apb", imx8mq_dram_apb_sels, base + 0xa080);
-       clks[IMX8MQ_CLK_VPU_G1] = imx8m_clk_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
-       clks[IMX8MQ_CLK_VPU_G2] = imx8m_clk_composite("vpu_g2", imx8mq_vpu_g2_sels, base + 0xa180);
-       clks[IMX8MQ_CLK_DISP_DTRC] = imx8m_clk_composite("disp_dtrc", imx8mq_disp_dtrc_sels, base + 0xa200);
-       clks[IMX8MQ_CLK_DISP_DC8000] = imx8m_clk_composite("disp_dc8000", imx8mq_disp_dc8000_sels, base + 0xa280);
-       clks[IMX8MQ_CLK_PCIE1_CTRL] = imx8m_clk_composite("pcie1_ctrl", imx8mq_pcie1_ctrl_sels, base + 0xa300);
-       clks[IMX8MQ_CLK_PCIE1_PHY] = imx8m_clk_composite("pcie1_phy", imx8mq_pcie1_phy_sels, base + 0xa380);
-       clks[IMX8MQ_CLK_PCIE1_AUX] = imx8m_clk_composite("pcie1_aux", imx8mq_pcie1_aux_sels, base + 0xa400);
-       clks[IMX8MQ_CLK_DC_PIXEL] = imx8m_clk_composite("dc_pixel", imx8mq_dc_pixel_sels, base + 0xa480);
-       clks[IMX8MQ_CLK_LCDIF_PIXEL] = imx8m_clk_composite("lcdif_pixel", imx8mq_lcdif_pixel_sels, base + 0xa500);
-       clks[IMX8MQ_CLK_SAI1] = imx8m_clk_composite("sai1", imx8mq_sai1_sels, base + 0xa580);
-       clks[IMX8MQ_CLK_SAI2] = imx8m_clk_composite("sai2", imx8mq_sai2_sels, base + 0xa600);
-       clks[IMX8MQ_CLK_SAI3] = imx8m_clk_composite("sai3", imx8mq_sai3_sels, base + 0xa680);
-       clks[IMX8MQ_CLK_SAI4] = imx8m_clk_composite("sai4", imx8mq_sai4_sels, base + 0xa700);
-       clks[IMX8MQ_CLK_SAI5] = imx8m_clk_composite("sai5", imx8mq_sai5_sels, base + 0xa780);
-       clks[IMX8MQ_CLK_SAI6] = imx8m_clk_composite("sai6", imx8mq_sai6_sels, base + 0xa800);
-       clks[IMX8MQ_CLK_SPDIF1] = imx8m_clk_composite("spdif1", imx8mq_spdif1_sels, base + 0xa880);
-       clks[IMX8MQ_CLK_SPDIF2] = imx8m_clk_composite("spdif2", imx8mq_spdif2_sels, base + 0xa900);
-       clks[IMX8MQ_CLK_ENET_REF] = imx8m_clk_composite("enet_ref", imx8mq_enet_ref_sels, base + 0xa980);
-       clks[IMX8MQ_CLK_ENET_TIMER] = imx8m_clk_composite("enet_timer", imx8mq_enet_timer_sels, base + 0xaa00);
-       clks[IMX8MQ_CLK_ENET_PHY_REF] = imx8m_clk_composite("enet_phy", imx8mq_enet_phy_sels, base + 0xaa80);
-       clks[IMX8MQ_CLK_NAND] = imx8m_clk_composite("nand", imx8mq_nand_sels, base + 0xab00);
-       clks[IMX8MQ_CLK_QSPI] = imx8m_clk_composite("qspi", imx8mq_qspi_sels, base + 0xab80);
-       clks[IMX8MQ_CLK_USDHC1] = imx8m_clk_composite("usdhc1", imx8mq_usdhc1_sels, base + 0xac00);
-       clks[IMX8MQ_CLK_USDHC2] = imx8m_clk_composite("usdhc2", imx8mq_usdhc2_sels, base + 0xac80);
-       clks[IMX8MQ_CLK_I2C1] = imx8m_clk_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00);
-       clks[IMX8MQ_CLK_I2C2] = imx8m_clk_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80);
-       clks[IMX8MQ_CLK_I2C3] = imx8m_clk_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00);
-       clks[IMX8MQ_CLK_I2C4] = imx8m_clk_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80);
-       clks[IMX8MQ_CLK_UART1] = imx8m_clk_composite("uart1", imx8mq_uart1_sels, base + 0xaf00);
-       clks[IMX8MQ_CLK_UART2] = imx8m_clk_composite("uart2", imx8mq_uart2_sels, base + 0xaf80);
-       clks[IMX8MQ_CLK_UART3] = imx8m_clk_composite("uart3", imx8mq_uart3_sels, base + 0xb000);
-       clks[IMX8MQ_CLK_UART4] = imx8m_clk_composite("uart4", imx8mq_uart4_sels, base + 0xb080);
-       clks[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100);
-       clks[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180);
-       clks[IMX8MQ_CLK_GIC] = imx8m_clk_composite_critical("gic", imx8mq_gic_sels, base + 0xb200);
-       clks[IMX8MQ_CLK_ECSPI1] = imx8m_clk_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280);
-       clks[IMX8MQ_CLK_ECSPI2] = imx8m_clk_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300);
-       clks[IMX8MQ_CLK_PWM1] = imx8m_clk_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380);
-       clks[IMX8MQ_CLK_PWM2] = imx8m_clk_composite("pwm2", imx8mq_pwm2_sels, base + 0xb400);
-       clks[IMX8MQ_CLK_PWM3] = imx8m_clk_composite("pwm3", imx8mq_pwm3_sels, base + 0xb480);
-       clks[IMX8MQ_CLK_PWM4] = imx8m_clk_composite("pwm4", imx8mq_pwm4_sels, base + 0xb500);
-       clks[IMX8MQ_CLK_GPT1] = imx8m_clk_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580);
-       clks[IMX8MQ_CLK_WDOG] = imx8m_clk_composite("wdog", imx8mq_wdog_sels, base + 0xb900);
-       clks[IMX8MQ_CLK_WRCLK] = imx8m_clk_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980);
-       clks[IMX8MQ_CLK_CLKO1] = imx8m_clk_composite("clko1", imx8mq_clko1_sels, base + 0xba00);
-       clks[IMX8MQ_CLK_CLKO2] = imx8m_clk_composite("clko2", imx8mq_clko2_sels, base + 0xba80);
-       clks[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00);
-       clks[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80);
-       clks[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00);
-       clks[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80);
-       clks[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200);
-       clks[IMX8MQ_CLK_DSI_IPG_DIV] = imx_clk_divider2("dsi_ipg_div", "dsi_ahb", base + 0x9280, 0, 6);
-       clks[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00);
-       clks[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80);
-       clks[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00);
-       clks[IMX8MQ_CLK_CSI2_CORE] = imx8m_clk_composite("csi2_core", imx8mq_csi2_core_sels, base + 0xbe80);
-       clks[IMX8MQ_CLK_CSI2_PHY_REF] = imx8m_clk_composite("csi2_phy_ref", imx8mq_csi2_phy_sels, base + 0xbf00);
-       clks[IMX8MQ_CLK_CSI2_ESC] = imx8m_clk_composite("csi2_esc", imx8mq_csi2_esc_sels, base + 0xbf80);
-       clks[IMX8MQ_CLK_PCIE2_CTRL] = imx8m_clk_composite("pcie2_ctrl", imx8mq_pcie2_ctrl_sels, base + 0xc000);
-       clks[IMX8MQ_CLK_PCIE2_PHY] = imx8m_clk_composite("pcie2_phy", imx8mq_pcie2_phy_sels, base + 0xc080);
-       clks[IMX8MQ_CLK_PCIE2_AUX] = imx8m_clk_composite("pcie2_aux", imx8mq_pcie2_aux_sels, base + 0xc100);
-       clks[IMX8MQ_CLK_ECSPI3] = imx8m_clk_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180);
-
-       clks[IMX8MQ_CLK_ECSPI1_ROOT] = imx_clk_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
-       clks[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
-       clks[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
-       clks[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
-       clks[IMX8MQ_CLK_GPIO1_ROOT] = imx_clk_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
-       clks[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
-       clks[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
-       clks[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
-       clks[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
-       clks[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
-       clks[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
-       clks[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
-       clks[IMX8MQ_CLK_I2C3_ROOT] = imx_clk_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
-       clks[IMX8MQ_CLK_I2C4_ROOT] = imx_clk_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
-       clks[IMX8MQ_CLK_MU_ROOT] = imx_clk_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
-       clks[IMX8MQ_CLK_OCOTP_ROOT] = imx_clk_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
-       clks[IMX8MQ_CLK_PCIE1_ROOT] = imx_clk_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
-       clks[IMX8MQ_CLK_PCIE2_ROOT] = imx_clk_gate4("pcie2_root_clk", "pcie2_ctrl", base + 0x4640, 0);
-       clks[IMX8MQ_CLK_PWM1_ROOT] = imx_clk_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
-       clks[IMX8MQ_CLK_PWM2_ROOT] = imx_clk_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
-       clks[IMX8MQ_CLK_PWM3_ROOT] = imx_clk_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
-       clks[IMX8MQ_CLK_PWM4_ROOT] = imx_clk_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
-       clks[IMX8MQ_CLK_QSPI_ROOT] = imx_clk_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
-       clks[IMX8MQ_CLK_RAWNAND_ROOT] = imx_clk_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
-       clks[IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
-       clks[IMX8MQ_CLK_SAI1_ROOT] = imx_clk_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
-       clks[IMX8MQ_CLK_SAI1_IPG] = imx_clk_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
-       clks[IMX8MQ_CLK_SAI2_ROOT] = imx_clk_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
-       clks[IMX8MQ_CLK_SAI2_IPG] = imx_clk_gate2_shared2("sai2_ipg_clk", "ipg_root", base + 0x4340, 0, &share_count_sai2);
-       clks[IMX8MQ_CLK_SAI3_ROOT] = imx_clk_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
-       clks[IMX8MQ_CLK_SAI3_IPG] = imx_clk_gate2_shared2("sai3_ipg_clk", "ipg_root", base + 0x4350, 0, &share_count_sai3);
-       clks[IMX8MQ_CLK_SAI4_ROOT] = imx_clk_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
-       clks[IMX8MQ_CLK_SAI4_IPG] = imx_clk_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
-       clks[IMX8MQ_CLK_SAI5_ROOT] = imx_clk_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
-       clks[IMX8MQ_CLK_SAI5_IPG] = imx_clk_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
-       clks[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
-       clks[IMX8MQ_CLK_SAI6_IPG] = imx_clk_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
-       clks[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
-       clks[IMX8MQ_CLK_UART1_ROOT] = imx_clk_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
-       clks[IMX8MQ_CLK_UART2_ROOT] = imx_clk_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
-       clks[IMX8MQ_CLK_UART3_ROOT] = imx_clk_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
-       clks[IMX8MQ_CLK_UART4_ROOT] = imx_clk_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
-       clks[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
-       clks[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0);
-       clks[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0);
-       clks[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0);
-       clks[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
-       clks[IMX8MQ_CLK_USDHC2_ROOT] = imx_clk_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
-       clks[IMX8MQ_CLK_WDOG1_ROOT] = imx_clk_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
-       clks[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
-       clks[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
-       clks[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
-       clks[IMX8MQ_CLK_GPU_ROOT] = imx_clk_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0);
-       clks[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
-       clks[IMX8MQ_CLK_DISP_ROOT] = imx_clk_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
-       clks[IMX8MQ_CLK_DISP_AXI_ROOT]  = imx_clk_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
-       clks[IMX8MQ_CLK_DISP_APB_ROOT]  = imx_clk_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
-       clks[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
-       clks[IMX8MQ_CLK_TMU_ROOT] = imx_clk_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
-       clks[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
-       clks[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
-       clks[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
-       clks[IMX8MQ_CLK_SDMA1_ROOT] = imx_clk_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
-       clks[IMX8MQ_CLK_SDMA2_ROOT] = imx_clk_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
-
-       clks[IMX8MQ_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc_25m", 1, 8);
-       clks[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
-
-       clks[IMX8MQ_CLK_ARM] = imx_clk_cpu("arm", "arm_a53_div",
-                                          clks[IMX8MQ_CLK_A53_DIV],
-                                          clks[IMX8MQ_CLK_A53_SRC],
-                                          clks[IMX8MQ_ARM_PLL_OUT],
-                                          clks[IMX8MQ_SYS1_PLL_800M]);
-
-       imx_check_clocks(clks, ARRAY_SIZE(clks));
-
-       clk_data.clks = clks;
-       clk_data.clk_num = ARRAY_SIZE(clks);
-
-       err = of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
+       hws[IMX8MQ_CLK_VPU_G1] = imx8m_clk_hw_composite("vpu_g1", imx8mq_vpu_g1_sels, base + 0xa100);
+       hws[IMX8MQ_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mq_vpu_g2_sels, base + 0xa180);
+       hws[IMX8MQ_CLK_DISP_DTRC] = imx8m_clk_hw_composite("disp_dtrc", imx8mq_disp_dtrc_sels, base + 0xa200);
+       hws[IMX8MQ_CLK_DISP_DC8000] = imx8m_clk_hw_composite("disp_dc8000", imx8mq_disp_dc8000_sels, base + 0xa280);
+       hws[IMX8MQ_CLK_PCIE1_CTRL] = imx8m_clk_hw_composite("pcie1_ctrl", imx8mq_pcie1_ctrl_sels, base + 0xa300);
+       hws[IMX8MQ_CLK_PCIE1_PHY] = imx8m_clk_hw_composite("pcie1_phy", imx8mq_pcie1_phy_sels, base + 0xa380);
+       hws[IMX8MQ_CLK_PCIE1_AUX] = imx8m_clk_hw_composite("pcie1_aux", imx8mq_pcie1_aux_sels, base + 0xa400);
+       hws[IMX8MQ_CLK_DC_PIXEL] = imx8m_clk_hw_composite("dc_pixel", imx8mq_dc_pixel_sels, base + 0xa480);
+       hws[IMX8MQ_CLK_LCDIF_PIXEL] = imx8m_clk_hw_composite("lcdif_pixel", imx8mq_lcdif_pixel_sels, base + 0xa500);
+       hws[IMX8MQ_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mq_sai1_sels, base + 0xa580);
+       hws[IMX8MQ_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mq_sai2_sels, base + 0xa600);
+       hws[IMX8MQ_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mq_sai3_sels, base + 0xa680);
+       hws[IMX8MQ_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mq_sai4_sels, base + 0xa700);
+       hws[IMX8MQ_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mq_sai5_sels, base + 0xa780);
+       hws[IMX8MQ_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mq_sai6_sels, base + 0xa800);
+       hws[IMX8MQ_CLK_SPDIF1] = imx8m_clk_hw_composite("spdif1", imx8mq_spdif1_sels, base + 0xa880);
+       hws[IMX8MQ_CLK_SPDIF2] = imx8m_clk_hw_composite("spdif2", imx8mq_spdif2_sels, base + 0xa900);
+       hws[IMX8MQ_CLK_ENET_REF] = imx8m_clk_hw_composite("enet_ref", imx8mq_enet_ref_sels, base + 0xa980);
+       hws[IMX8MQ_CLK_ENET_TIMER] = imx8m_clk_hw_composite("enet_timer", imx8mq_enet_timer_sels, base + 0xaa00);
+       hws[IMX8MQ_CLK_ENET_PHY_REF] = imx8m_clk_hw_composite("enet_phy", imx8mq_enet_phy_sels, base + 0xaa80);
+       hws[IMX8MQ_CLK_NAND] = imx8m_clk_hw_composite("nand", imx8mq_nand_sels, base + 0xab00);
+       hws[IMX8MQ_CLK_QSPI] = imx8m_clk_hw_composite("qspi", imx8mq_qspi_sels, base + 0xab80);
+       hws[IMX8MQ_CLK_USDHC1] = imx8m_clk_hw_composite("usdhc1", imx8mq_usdhc1_sels, base + 0xac00);
+       hws[IMX8MQ_CLK_USDHC2] = imx8m_clk_hw_composite("usdhc2", imx8mq_usdhc2_sels, base + 0xac80);
+       hws[IMX8MQ_CLK_I2C1] = imx8m_clk_hw_composite("i2c1", imx8mq_i2c1_sels, base + 0xad00);
+       hws[IMX8MQ_CLK_I2C2] = imx8m_clk_hw_composite("i2c2", imx8mq_i2c2_sels, base + 0xad80);
+       hws[IMX8MQ_CLK_I2C3] = imx8m_clk_hw_composite("i2c3", imx8mq_i2c3_sels, base + 0xae00);
+       hws[IMX8MQ_CLK_I2C4] = imx8m_clk_hw_composite("i2c4", imx8mq_i2c4_sels, base + 0xae80);
+       hws[IMX8MQ_CLK_UART1] = imx8m_clk_hw_composite("uart1", imx8mq_uart1_sels, base + 0xaf00);
+       hws[IMX8MQ_CLK_UART2] = imx8m_clk_hw_composite("uart2", imx8mq_uart2_sels, base + 0xaf80);
+       hws[IMX8MQ_CLK_UART3] = imx8m_clk_hw_composite("uart3", imx8mq_uart3_sels, base + 0xb000);
+       hws[IMX8MQ_CLK_UART4] = imx8m_clk_hw_composite("uart4", imx8mq_uart4_sels, base + 0xb080);
+       hws[IMX8MQ_CLK_USB_CORE_REF] = imx8m_clk_hw_composite("usb_core_ref", imx8mq_usb_core_sels, base + 0xb100);
+       hws[IMX8MQ_CLK_USB_PHY_REF] = imx8m_clk_hw_composite("usb_phy_ref", imx8mq_usb_phy_sels, base + 0xb180);
+       hws[IMX8MQ_CLK_GIC] = imx8m_clk_hw_composite_critical("gic", imx8mq_gic_sels, base + 0xb200);
+       hws[IMX8MQ_CLK_ECSPI1] = imx8m_clk_hw_composite("ecspi1", imx8mq_ecspi1_sels, base + 0xb280);
+       hws[IMX8MQ_CLK_ECSPI2] = imx8m_clk_hw_composite("ecspi2", imx8mq_ecspi2_sels, base + 0xb300);
+       hws[IMX8MQ_CLK_PWM1] = imx8m_clk_hw_composite("pwm1", imx8mq_pwm1_sels, base + 0xb380);
+       hws[IMX8MQ_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mq_pwm2_sels, base + 0xb400);
+       hws[IMX8MQ_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mq_pwm3_sels, base + 0xb480);
+       hws[IMX8MQ_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mq_pwm4_sels, base + 0xb500);
+       hws[IMX8MQ_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mq_gpt1_sels, base + 0xb580);
+       hws[IMX8MQ_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mq_wdog_sels, base + 0xb900);
+       hws[IMX8MQ_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mq_wrclk_sels, base + 0xb980);
+       hws[IMX8MQ_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mq_clko1_sels, base + 0xba00);
+       hws[IMX8MQ_CLK_CLKO2] = imx8m_clk_hw_composite("clko2", imx8mq_clko2_sels, base + 0xba80);
+       hws[IMX8MQ_CLK_DSI_CORE] = imx8m_clk_hw_composite("dsi_core", imx8mq_dsi_core_sels, base + 0xbb00);
+       hws[IMX8MQ_CLK_DSI_PHY_REF] = imx8m_clk_hw_composite("dsi_phy_ref", imx8mq_dsi_phy_sels, base + 0xbb80);
+       hws[IMX8MQ_CLK_DSI_DBI] = imx8m_clk_hw_composite("dsi_dbi", imx8mq_dsi_dbi_sels, base + 0xbc00);
+       hws[IMX8MQ_CLK_DSI_ESC] = imx8m_clk_hw_composite("dsi_esc", imx8mq_dsi_esc_sels, base + 0xbc80);
+       hws[IMX8MQ_CLK_DSI_AHB] = imx8m_clk_hw_composite("dsi_ahb", imx8mq_dsi_ahb_sels, base + 0x9200);
+       hws[IMX8MQ_CLK_DSI_IPG_DIV] = imx_clk_hw_divider2("dsi_ipg_div", "dsi_ahb", base + 0x9280, 0, 6);
+       hws[IMX8MQ_CLK_CSI1_CORE] = imx8m_clk_hw_composite("csi1_core", imx8mq_csi1_core_sels, base + 0xbd00);
+       hws[IMX8MQ_CLK_CSI1_PHY_REF] = imx8m_clk_hw_composite("csi1_phy_ref", imx8mq_csi1_phy_sels, base + 0xbd80);
+       hws[IMX8MQ_CLK_CSI1_ESC] = imx8m_clk_hw_composite("csi1_esc", imx8mq_csi1_esc_sels, base + 0xbe00);
+       hws[IMX8MQ_CLK_CSI2_CORE] = imx8m_clk_hw_composite("csi2_core", imx8mq_csi2_core_sels, base + 0xbe80);
+       hws[IMX8MQ_CLK_CSI2_PHY_REF] = imx8m_clk_hw_composite("csi2_phy_ref", imx8mq_csi2_phy_sels, base + 0xbf00);
+       hws[IMX8MQ_CLK_CSI2_ESC] = imx8m_clk_hw_composite("csi2_esc", imx8mq_csi2_esc_sels, base + 0xbf80);
+       hws[IMX8MQ_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mq_pcie2_ctrl_sels, base + 0xc000);
+       hws[IMX8MQ_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mq_pcie2_phy_sels, base + 0xc080);
+       hws[IMX8MQ_CLK_PCIE2_AUX] = imx8m_clk_hw_composite("pcie2_aux", imx8mq_pcie2_aux_sels, base + 0xc100);
+       hws[IMX8MQ_CLK_ECSPI3] = imx8m_clk_hw_composite("ecspi3", imx8mq_ecspi3_sels, base + 0xc180);
+
+       hws[IMX8MQ_CLK_ECSPI1_ROOT] = imx_clk_hw_gate4("ecspi1_root_clk", "ecspi1", base + 0x4070, 0);
+       hws[IMX8MQ_CLK_ECSPI2_ROOT] = imx_clk_hw_gate4("ecspi2_root_clk", "ecspi2", base + 0x4080, 0);
+       hws[IMX8MQ_CLK_ECSPI3_ROOT] = imx_clk_hw_gate4("ecspi3_root_clk", "ecspi3", base + 0x4090, 0);
+       hws[IMX8MQ_CLK_ENET1_ROOT] = imx_clk_hw_gate4("enet1_root_clk", "enet_axi", base + 0x40a0, 0);
+       hws[IMX8MQ_CLK_GPIO1_ROOT] = imx_clk_hw_gate4("gpio1_root_clk", "ipg_root", base + 0x40b0, 0);
+       hws[IMX8MQ_CLK_GPIO2_ROOT] = imx_clk_hw_gate4("gpio2_root_clk", "ipg_root", base + 0x40c0, 0);
+       hws[IMX8MQ_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
+       hws[IMX8MQ_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
+       hws[IMX8MQ_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
+       hws[IMX8MQ_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
+       hws[IMX8MQ_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
+       hws[IMX8MQ_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
+       hws[IMX8MQ_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
+       hws[IMX8MQ_CLK_I2C4_ROOT] = imx_clk_hw_gate4("i2c4_root_clk", "i2c4", base + 0x41a0, 0);
+       hws[IMX8MQ_CLK_MU_ROOT] = imx_clk_hw_gate4("mu_root_clk", "ipg_root", base + 0x4210, 0);
+       hws[IMX8MQ_CLK_OCOTP_ROOT] = imx_clk_hw_gate4("ocotp_root_clk", "ipg_root", base + 0x4220, 0);
+       hws[IMX8MQ_CLK_PCIE1_ROOT] = imx_clk_hw_gate4("pcie1_root_clk", "pcie1_ctrl", base + 0x4250, 0);
+       hws[IMX8MQ_CLK_PCIE2_ROOT] = imx_clk_hw_gate4("pcie2_root_clk", "pcie2_ctrl", base + 0x4640, 0);
+       hws[IMX8MQ_CLK_PWM1_ROOT] = imx_clk_hw_gate4("pwm1_root_clk", "pwm1", base + 0x4280, 0);
+       hws[IMX8MQ_CLK_PWM2_ROOT] = imx_clk_hw_gate4("pwm2_root_clk", "pwm2", base + 0x4290, 0);
+       hws[IMX8MQ_CLK_PWM3_ROOT] = imx_clk_hw_gate4("pwm3_root_clk", "pwm3", base + 0x42a0, 0);
+       hws[IMX8MQ_CLK_PWM4_ROOT] = imx_clk_hw_gate4("pwm4_root_clk", "pwm4", base + 0x42b0, 0);
+       hws[IMX8MQ_CLK_QSPI_ROOT] = imx_clk_hw_gate4("qspi_root_clk", "qspi", base + 0x42f0, 0);
+       hws[IMX8MQ_CLK_RAWNAND_ROOT] = imx_clk_hw_gate2_shared2("nand_root_clk", "nand", base + 0x4300, 0, &share_count_nand);
+       hws[IMX8MQ_CLK_NAND_USDHC_BUS_RAWNAND_CLK] = imx_clk_hw_gate2_shared2("nand_usdhc_rawnand_clk", "nand_usdhc_bus", base + 0x4300, 0, &share_count_nand);
+       hws[IMX8MQ_CLK_SAI1_ROOT] = imx_clk_hw_gate2_shared2("sai1_root_clk", "sai1", base + 0x4330, 0, &share_count_sai1);
+       hws[IMX8MQ_CLK_SAI1_IPG] = imx_clk_hw_gate2_shared2("sai1_ipg_clk", "ipg_audio_root", base + 0x4330, 0, &share_count_sai1);
+       hws[IMX8MQ_CLK_SAI2_ROOT] = imx_clk_hw_gate2_shared2("sai2_root_clk", "sai2", base + 0x4340, 0, &share_count_sai2);
+       hws[IMX8MQ_CLK_SAI2_IPG] = imx_clk_hw_gate2_shared2("sai2_ipg_clk", "ipg_root", base + 0x4340, 0, &share_count_sai2);
+       hws[IMX8MQ_CLK_SAI3_ROOT] = imx_clk_hw_gate2_shared2("sai3_root_clk", "sai3", base + 0x4350, 0, &share_count_sai3);
+       hws[IMX8MQ_CLK_SAI3_IPG] = imx_clk_hw_gate2_shared2("sai3_ipg_clk", "ipg_root", base + 0x4350, 0, &share_count_sai3);
+       hws[IMX8MQ_CLK_SAI4_ROOT] = imx_clk_hw_gate2_shared2("sai4_root_clk", "sai4", base + 0x4360, 0, &share_count_sai4);
+       hws[IMX8MQ_CLK_SAI4_IPG] = imx_clk_hw_gate2_shared2("sai4_ipg_clk", "ipg_audio_root", base + 0x4360, 0, &share_count_sai4);
+       hws[IMX8MQ_CLK_SAI5_ROOT] = imx_clk_hw_gate2_shared2("sai5_root_clk", "sai5", base + 0x4370, 0, &share_count_sai5);
+       hws[IMX8MQ_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
+       hws[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
+       hws[IMX8MQ_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
+       hws[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
+       hws[IMX8MQ_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
+       hws[IMX8MQ_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
+       hws[IMX8MQ_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
+       hws[IMX8MQ_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", base + 0x44c0, 0);
+       hws[IMX8MQ_CLK_USB1_CTRL_ROOT] = imx_clk_hw_gate4("usb1_ctrl_root_clk", "usb_bus", base + 0x44d0, 0);
+       hws[IMX8MQ_CLK_USB2_CTRL_ROOT] = imx_clk_hw_gate4("usb2_ctrl_root_clk", "usb_bus", base + 0x44e0, 0);
+       hws[IMX8MQ_CLK_USB1_PHY_ROOT] = imx_clk_hw_gate4("usb1_phy_root_clk", "usb_phy_ref", base + 0x44f0, 0);
+       hws[IMX8MQ_CLK_USB2_PHY_ROOT] = imx_clk_hw_gate4("usb2_phy_root_clk", "usb_phy_ref", base + 0x4500, 0);
+       hws[IMX8MQ_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", base + 0x4510, 0);
+       hws[IMX8MQ_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", base + 0x4520, 0);
+       hws[IMX8MQ_CLK_WDOG1_ROOT] = imx_clk_hw_gate4("wdog1_root_clk", "wdog", base + 0x4530, 0);
+       hws[IMX8MQ_CLK_WDOG2_ROOT] = imx_clk_hw_gate4("wdog2_root_clk", "wdog", base + 0x4540, 0);
+       hws[IMX8MQ_CLK_WDOG3_ROOT] = imx_clk_hw_gate4("wdog3_root_clk", "wdog", base + 0x4550, 0);
+       hws[IMX8MQ_CLK_VPU_G1_ROOT] = imx_clk_hw_gate2_flags("vpu_g1_root_clk", "vpu_g1", base + 0x4560, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
+       hws[IMX8MQ_CLK_GPU_ROOT] = imx_clk_hw_gate4("gpu_root_clk", "gpu_core_div", base + 0x4570, 0);
+       hws[IMX8MQ_CLK_VPU_G2_ROOT] = imx_clk_hw_gate2_flags("vpu_g2_root_clk", "vpu_g2", base + 0x45a0, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
+       hws[IMX8MQ_CLK_DISP_ROOT] = imx_clk_hw_gate2_shared2("disp_root_clk", "disp_dc8000", base + 0x45d0, 0, &share_count_dcss);
+       hws[IMX8MQ_CLK_DISP_AXI_ROOT]  = imx_clk_hw_gate2_shared2("disp_axi_root_clk", "disp_axi", base + 0x45d0, 0, &share_count_dcss);
+       hws[IMX8MQ_CLK_DISP_APB_ROOT]  = imx_clk_hw_gate2_shared2("disp_apb_root_clk", "disp_apb", base + 0x45d0, 0, &share_count_dcss);
+       hws[IMX8MQ_CLK_DISP_RTRM_ROOT] = imx_clk_hw_gate2_shared2("disp_rtrm_root_clk", "disp_rtrm", base + 0x45d0, 0, &share_count_dcss);
+       hws[IMX8MQ_CLK_TMU_ROOT] = imx_clk_hw_gate4("tmu_root_clk", "ipg_root", base + 0x4620, 0);
+       hws[IMX8MQ_CLK_VPU_DEC_ROOT] = imx_clk_hw_gate2_flags("vpu_dec_root_clk", "vpu_bus", base + 0x4630, 0, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE);
+       hws[IMX8MQ_CLK_CSI1_ROOT] = imx_clk_hw_gate4("csi1_root_clk", "csi1_core", base + 0x4650, 0);
+       hws[IMX8MQ_CLK_CSI2_ROOT] = imx_clk_hw_gate4("csi2_root_clk", "csi2_core", base + 0x4660, 0);
+       hws[IMX8MQ_CLK_SDMA1_ROOT] = imx_clk_hw_gate4("sdma1_clk", "ipg_root", base + 0x43a0, 0);
+       hws[IMX8MQ_CLK_SDMA2_ROOT] = imx_clk_hw_gate4("sdma2_clk", "ipg_audio_root", base + 0x43b0, 0);
+
+       hws[IMX8MQ_GPT_3M_CLK] = imx_clk_hw_fixed_factor("gpt_3m", "osc_25m", 1, 8);
+       hws[IMX8MQ_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
+
+       hws[IMX8MQ_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_div",
+                                          hws[IMX8MQ_CLK_A53_DIV]->clk,
+                                          hws[IMX8MQ_CLK_A53_SRC]->clk,
+                                          hws[IMX8MQ_ARM_PLL_OUT]->clk,
+                                          hws[IMX8MQ_SYS1_PLL_800M]->clk);
+
+       imx_check_clk_hws(hws, IMX8MQ_CLK_END);
+
+       err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
        if (err < 0) {
-               dev_err(dev, "failed to register clks for i.MX8MQ\n");
-               goto unregister_clks;
+               dev_err(dev, "failed to register hws for i.MX8MQ\n");
+               goto unregister_hws;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(uart_clk_ids); i++) {
+               int index = uart_clk_ids[i];
+
+               uart_hws[i] = &hws[index]->clk;
        }
 
-       imx_register_uart_clocks(uart_clks);
+       imx_register_uart_clocks(uart_hws);
 
        return 0;
 
-unregister_clks:
-       imx_unregister_clocks(clks, ARRAY_SIZE(clks));
+unregister_hws:
+       imx_unregister_hw_clocks(hws, IMX8MQ_CLK_END);
 
        return err;
 }
@@ -609,6 +624,11 @@ static struct platform_driver imx8mq_clk_driver = {
        .probe = imx8mq_clocks_probe,
        .driver = {
                .name = "imx8mq-ccm",
+               /*
+                * Disable bind attributes: clocks are not removed and
+                * reloading the driver will crash or break devices.
+                */
+               .suppress_bind_attrs = true,
                .of_match_table = of_match_ptr(imx8mq_clk_of_match),
        },
 };
index c0aff7c..04c8ee3 100644 (file)
@@ -173,6 +173,17 @@ static int imx8qxp_lpcg_clk_probe(struct platform_device *pdev)
        if (!ss_lpcg)
                return -ENODEV;
 
+       /*
+        * Please don't replace this with devm_platform_ioremap_resource.
+        *
+        * devm_platform_ioremap_resource calls devm_ioremap_resource which
+        * differs from devm_ioremap by also calling devm_request_mem_region
+        * and preventing other mappings in the same area.
+        *
+        * On imx8 the LPCG nodes map entire subsystems and overlap
+        * peripherals, this means that using devm_platform_ioremap_resource
+        * will cause many devices to fail to probe including serial ports.
+        */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!res)
                return -EINVAL;
index a03bbed..de93ce7 100644 (file)
@@ -166,7 +166,7 @@ static const struct clk_ops clk_pfdv2_ops = {
        .is_enabled     = clk_pfdv2_is_enabled,
 };
 
-struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
+struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,
                             void __iomem *reg, u8 idx)
 {
        struct clk_init_data init;
index 3636c80..5b0519a 100644 (file)
@@ -67,6 +67,13 @@ struct imx_pll14xx_clk imx_1443x_pll = {
        .rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
 };
 
+struct imx_pll14xx_clk imx_1443x_dram_pll = {
+       .type = PLL_1443X,
+       .rate_table = imx_pll1443x_tbl,
+       .rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
+       .flags = CLK_GET_RATE_NOCACHE,
+};
+
 struct imx_pll14xx_clk imx_1416x_pll = {
        .type = PLL_1416X,
        .rate_table = imx_pll1416x_tbl,
@@ -369,13 +376,14 @@ static const struct clk_ops clk_pll1443x_ops = {
        .set_rate       = clk_pll1443x_set_rate,
 };
 
-struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
-                           void __iomem *base,
-                           const struct imx_pll14xx_clk *pll_clk)
+struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
+                                 void __iomem *base,
+                                 const struct imx_pll14xx_clk *pll_clk)
 {
        struct clk_pll14xx *pll;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
        u32 val;
 
        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
@@ -412,12 +420,15 @@ struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
        val &= ~BYPASS_MASK;
        writel_relaxed(val, pll->base + GNRL_CTL);
 
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk)) {
-               pr_err("%s: failed to register pll %s %lu\n",
-                       __func__, name, PTR_ERR(clk));
+       hw = &pll->hw;
+
+       ret = clk_hw_register(NULL, hw);
+       if (ret) {
+               pr_err("%s: failed to register pll %s %d\n",
+                       __func__, name, ret);
                kfree(pll);
+               return ERR_PTR(ret);
        }
 
-       return clk;
+       return hw;
 }
index 4ba9973..de4f8a4 100644 (file)
@@ -111,12 +111,13 @@ static const struct clk_ops clk_pllv1_ops = {
        .recalc_rate = clk_pllv1_recalc_rate,
 };
 
-struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
+struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
                const char *parent, void __iomem *base)
 {
        struct clk_pllv1 *pll;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        pll = kmalloc(sizeof(*pll), GFP_KERNEL);
        if (!pll)
@@ -132,10 +133,13 @@ struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
        init.num_parents = 1;
 
        pll->hw.init = &init;
+       hw = &pll->hw;
 
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk))
+       ret = clk_hw_register(NULL, hw);
+       if (ret) {
                kfree(pll);
+               return ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
index eeba3cb..ff17f06 100644 (file)
@@ -239,12 +239,13 @@ static const struct clk_ops clk_pllv2_ops = {
        .set_rate = clk_pllv2_set_rate,
 };
 
-struct clk *imx_clk_pllv2(const char *name, const char *parent,
+struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent,
                void __iomem *base)
 {
        struct clk_pllv2 *pll;
-       struct clk *clk;
+       struct clk_hw *hw;
        struct clk_init_data init;
+       int ret;
 
        pll = kzalloc(sizeof(*pll), GFP_KERNEL);
        if (!pll)
@@ -259,10 +260,13 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent,
        init.num_parents = 1;
 
        pll->hw.init = &init;
+       hw = &pll->hw;
 
-       clk = clk_register(NULL, &pll->hw);
-       if (IS_ERR(clk))
+       ret = clk_hw_register(NULL, hw);
+       if (ret) {
                kfree(pll);
+               return ERR_PTR(ret);
+       }
 
-       return clk;
+       return hw;
 }
index 8155b12..f51a800 100644 (file)
@@ -206,7 +206,7 @@ static const struct clk_ops clk_pllv4_ops = {
        .is_enabled     = clk_pllv4_is_enabled,
 };
 
-struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
+struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
                          void __iomem *base)
 {
        struct clk_pllv4 *pll;
similarity index 70%
rename from drivers/clk/imx/clk-sccg-pll.c
rename to drivers/clk/imx/clk-sscg-pll.c
index 5d65f65..acd1b90 100644 (file)
@@ -67,7 +67,7 @@
 
 #define PLL_SCCG_LOCK_TIMEOUT          70
 
-struct clk_sccg_pll_setup {
+struct clk_sscg_pll_setup {
        int divr1, divf1;
        int divr2, divf2;
        int divq;
@@ -83,22 +83,22 @@ struct clk_sccg_pll_setup {
        int fout_error;
 };
 
-struct clk_sccg_pll {
+struct clk_sscg_pll {
        struct clk_hw   hw;
        const struct clk_ops  ops;
 
        void __iomem *base;
 
-       struct clk_sccg_pll_setup setup;
+       struct clk_sscg_pll_setup setup;
 
        u8 parent;
        u8 bypass1;
        u8 bypass2;
 };
 
-#define to_clk_sccg_pll(_hw) container_of(_hw, struct clk_sccg_pll, hw)
+#define to_clk_sscg_pll(_hw) container_of(_hw, struct clk_sscg_pll, hw)
 
-static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll)
+static int clk_sscg_pll_wait_lock(struct clk_sscg_pll *pll)
 {
        u32 val;
 
@@ -112,15 +112,15 @@ static int clk_sccg_pll_wait_lock(struct clk_sccg_pll *pll)
        return 0;
 }
 
-static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
-                                       struct clk_sccg_pll_setup *temp_setup)
+static int clk_sscg_pll2_check_match(struct clk_sscg_pll_setup *setup,
+                                       struct clk_sscg_pll_setup *temp_setup)
 {
        int new_diff = temp_setup->fout - temp_setup->fout_request;
        int diff = temp_setup->fout_error;
 
        if (abs(diff) > abs(new_diff)) {
                temp_setup->fout_error = new_diff;
-               memcpy(setup, temp_setup, sizeof(struct clk_sccg_pll_setup));
+               memcpy(setup, temp_setup, sizeof(struct clk_sscg_pll_setup));
 
                if (temp_setup->fout_request == temp_setup->fout)
                        return 0;
@@ -128,8 +128,8 @@ static int clk_sccg_pll2_check_match(struct clk_sccg_pll_setup *setup,
        return -1;
 }
 
-static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
-                               struct clk_sccg_pll_setup *temp_setup)
+static int clk_sscg_divq_lookup(struct clk_sscg_pll_setup *setup,
+                               struct clk_sscg_pll_setup *temp_setup)
 {
        int ret = -EINVAL;
 
@@ -144,7 +144,7 @@ static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
                        temp_setup->fout = temp_setup->vco2;
                        do_div(temp_setup->fout, 2 * (temp_setup->divq + 1));
 
-                       ret = clk_sccg_pll2_check_match(setup, temp_setup);
+                       ret = clk_sscg_pll2_check_match(setup, temp_setup);
                        if (!ret) {
                                temp_setup->bypass = PLL_BYPASS1;
                                return ret;
@@ -155,14 +155,14 @@ static int clk_sccg_divq_lookup(struct clk_sccg_pll_setup *setup,
        return ret;
 }
 
-static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
-                                       struct clk_sccg_pll_setup *temp_setup)
+static int clk_sscg_divf2_lookup(struct clk_sscg_pll_setup *setup,
+                                       struct clk_sscg_pll_setup *temp_setup)
 {
        int ret = -EINVAL;
 
        for (temp_setup->divf2 = 0; temp_setup->divf2 <= PLL_DIVF2_MAX;
             temp_setup->divf2++) {
-               ret = clk_sccg_divq_lookup(setup, temp_setup);
+               ret = clk_sscg_divq_lookup(setup, temp_setup);
                if (!ret)
                        return ret;
        }
@@ -170,8 +170,8 @@ static int clk_sccg_divf2_lookup(struct clk_sccg_pll_setup *setup,
        return ret;
 }
 
-static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
-                               struct clk_sccg_pll_setup *temp_setup)
+static int clk_sscg_divr2_lookup(struct clk_sscg_pll_setup *setup,
+                               struct clk_sscg_pll_setup *temp_setup)
 {
        int ret = -EINVAL;
 
@@ -181,7 +181,7 @@ static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
                do_div(temp_setup->ref_div2, temp_setup->divr2 + 1);
                if (temp_setup->ref_div2 >= PLL_STAGE2_REF_MIN_FREQ &&
                    temp_setup->ref_div2 <= PLL_STAGE2_REF_MAX_FREQ) {
-                       ret = clk_sccg_divf2_lookup(setup, temp_setup);
+                       ret = clk_sscg_divf2_lookup(setup, temp_setup);
                        if (!ret)
                                return ret;
                }
@@ -190,8 +190,8 @@ static int clk_sccg_divr2_lookup(struct clk_sccg_pll_setup *setup,
        return ret;
 }
 
-static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
-                                       struct clk_sccg_pll_setup *temp_setup,
+static int clk_sscg_pll2_find_setup(struct clk_sscg_pll_setup *setup,
+                                       struct clk_sscg_pll_setup *temp_setup,
                                        uint64_t ref)
 {
 
@@ -202,12 +202,12 @@ static int clk_sccg_pll2_find_setup(struct clk_sccg_pll_setup *setup,
 
        temp_setup->vco1 = ref;
 
-       ret = clk_sccg_divr2_lookup(setup, temp_setup);
+       ret = clk_sscg_divr2_lookup(setup, temp_setup);
        return ret;
 }
 
-static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
-                               struct clk_sccg_pll_setup *temp_setup)
+static int clk_sscg_divf1_lookup(struct clk_sscg_pll_setup *setup,
+                               struct clk_sscg_pll_setup *temp_setup)
 {
        int ret = -EINVAL;
 
@@ -219,7 +219,7 @@ static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
                vco1 *= 2;
                vco1 *= temp_setup->divf1 + 1;
 
-               ret = clk_sccg_pll2_find_setup(setup, temp_setup, vco1);
+               ret = clk_sscg_pll2_find_setup(setup, temp_setup, vco1);
                if (!ret) {
                        temp_setup->bypass = PLL_BYPASS_NONE;
                        return ret;
@@ -229,8 +229,8 @@ static int clk_sccg_divf1_lookup(struct clk_sccg_pll_setup *setup,
        return ret;
 }
 
-static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
-                               struct clk_sccg_pll_setup *temp_setup)
+static int clk_sscg_divr1_lookup(struct clk_sscg_pll_setup *setup,
+                               struct clk_sscg_pll_setup *temp_setup)
 {
        int ret = -EINVAL;
 
@@ -240,7 +240,7 @@ static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
                do_div(temp_setup->ref_div1, temp_setup->divr1 + 1);
                if (temp_setup->ref_div1 >= PLL_STAGE1_REF_MIN_FREQ &&
                    temp_setup->ref_div1 <= PLL_STAGE1_REF_MAX_FREQ) {
-                       ret = clk_sccg_divf1_lookup(setup, temp_setup);
+                       ret = clk_sscg_divf1_lookup(setup, temp_setup);
                        if (!ret)
                                return ret;
                }
@@ -249,8 +249,8 @@ static int clk_sccg_divr1_lookup(struct clk_sccg_pll_setup *setup,
        return ret;
 }
 
-static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
-                                       struct clk_sccg_pll_setup *temp_setup,
+static int clk_sscg_pll1_find_setup(struct clk_sscg_pll_setup *setup,
+                                       struct clk_sscg_pll_setup *temp_setup,
                                        uint64_t ref)
 {
 
@@ -261,20 +261,20 @@ static int clk_sccg_pll1_find_setup(struct clk_sccg_pll_setup *setup,
 
        temp_setup->ref = ref;
 
-       ret = clk_sccg_divr1_lookup(setup, temp_setup);
+       ret = clk_sscg_divr1_lookup(setup, temp_setup);
 
        return ret;
 }
 
-static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
+static int clk_sscg_pll_find_setup(struct clk_sscg_pll_setup *setup,
                                        uint64_t prate,
                                        uint64_t rate, int try_bypass)
 {
-       struct clk_sccg_pll_setup temp_setup;
+       struct clk_sscg_pll_setup temp_setup;
        int ret = -EINVAL;
 
-       memset(&temp_setup, 0, sizeof(struct clk_sccg_pll_setup));
-       memset(setup, 0, sizeof(struct clk_sccg_pll_setup));
+       memset(&temp_setup, 0, sizeof(struct clk_sscg_pll_setup));
+       memset(setup, 0, sizeof(struct clk_sscg_pll_setup));
 
        temp_setup.fout_error = PLL_OUT_MAX_FREQ;
        temp_setup.fout_request = rate;
@@ -290,11 +290,11 @@ static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
                break;
 
        case PLL_BYPASS1:
-               ret = clk_sccg_pll2_find_setup(setup, &temp_setup, prate);
+               ret = clk_sscg_pll2_find_setup(setup, &temp_setup, prate);
                break;
 
        case PLL_BYPASS_NONE:
-               ret = clk_sccg_pll1_find_setup(setup, &temp_setup, prate);
+               ret = clk_sscg_pll1_find_setup(setup, &temp_setup, prate);
                break;
        }
 
@@ -302,30 +302,30 @@ static int clk_sccg_pll_find_setup(struct clk_sccg_pll_setup *setup,
 }
 
 
-static int clk_sccg_pll_is_prepared(struct clk_hw *hw)
+static int clk_sscg_pll_is_prepared(struct clk_hw *hw)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
 
        u32 val = readl_relaxed(pll->base + PLL_CFG0);
 
        return (val & PLL_PD_MASK) ? 0 : 1;
 }
 
-static int clk_sccg_pll_prepare(struct clk_hw *hw)
+static int clk_sscg_pll_prepare(struct clk_hw *hw)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
        u32 val;
 
        val = readl_relaxed(pll->base + PLL_CFG0);
        val &= ~PLL_PD_MASK;
        writel_relaxed(val, pll->base + PLL_CFG0);
 
-       return clk_sccg_pll_wait_lock(pll);
+       return clk_sscg_pll_wait_lock(pll);
 }
 
-static void clk_sccg_pll_unprepare(struct clk_hw *hw)
+static void clk_sscg_pll_unprepare(struct clk_hw *hw)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
        u32 val;
 
        val = readl_relaxed(pll->base + PLL_CFG0);
@@ -333,10 +333,10 @@ static void clk_sccg_pll_unprepare(struct clk_hw *hw)
        writel_relaxed(val, pll->base + PLL_CFG0);
 }
 
-static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
+static unsigned long clk_sscg_pll_recalc_rate(struct clk_hw *hw,
                                         unsigned long parent_rate)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
        u32 val, divr1, divf1, divr2, divf2, divq;
        u64 temp64;
 
@@ -364,11 +364,11 @@ static unsigned long clk_sccg_pll_recalc_rate(struct clk_hw *hw,
        return temp64;
 }
 
-static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
+static int clk_sscg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
                            unsigned long parent_rate)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
-       struct clk_sccg_pll_setup *setup = &pll->setup;
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
+       struct clk_sscg_pll_setup *setup = &pll->setup;
        u32 val;
 
        /* set bypass here too since the parent might be the same */
@@ -387,12 +387,12 @@ static int clk_sccg_pll_set_rate(struct clk_hw *hw, unsigned long rate,
        val |= FIELD_PREP(PLL_DIVQ_MASK, setup->divq);
        writel_relaxed(val, pll->base + PLL_CFG2);
 
-       return clk_sccg_pll_wait_lock(pll);
+       return clk_sscg_pll_wait_lock(pll);
 }
 
-static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
+static u8 clk_sscg_pll_get_parent(struct clk_hw *hw)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
        u32 val;
        u8 ret = pll->parent;
 
@@ -404,9 +404,9 @@ static u8 clk_sccg_pll_get_parent(struct clk_hw *hw)
        return ret;
 }
 
-static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
+static int clk_sscg_pll_set_parent(struct clk_hw *hw, u8 index)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
        u32 val;
 
        val = readl(pll->base + PLL_CFG0);
@@ -414,18 +414,18 @@ static int clk_sccg_pll_set_parent(struct clk_hw *hw, u8 index)
        val |= FIELD_PREP(SSCG_PLL_BYPASS_MASK, pll->setup.bypass);
        writel(val, pll->base + PLL_CFG0);
 
-       return clk_sccg_pll_wait_lock(pll);
+       return clk_sscg_pll_wait_lock(pll);
 }
 
-static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
+static int __clk_sscg_pll_determine_rate(struct clk_hw *hw,
                                        struct clk_rate_request *req,
                                        uint64_t min,
                                        uint64_t max,
                                        uint64_t rate,
                                        int bypass)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
-       struct clk_sccg_pll_setup *setup = &pll->setup;
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
+       struct clk_sscg_pll_setup *setup = &pll->setup;
        struct clk_hw *parent_hw = NULL;
        int bypass_parent_index;
        int ret = -EINVAL;
@@ -448,7 +448,7 @@ static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
        parent_hw = clk_hw_get_parent_by_index(hw, bypass_parent_index);
        ret = __clk_determine_rate(parent_hw, req);
        if (!ret) {
-               ret = clk_sccg_pll_find_setup(setup, req->rate,
+               ret = clk_sscg_pll_find_setup(setup, req->rate,
                                                rate, bypass);
        }
 
@@ -459,11 +459,11 @@ static int __clk_sccg_pll_determine_rate(struct clk_hw *hw,
        return ret;
 }
 
-static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
+static int clk_sscg_pll_determine_rate(struct clk_hw *hw,
                                       struct clk_rate_request *req)
 {
-       struct clk_sccg_pll *pll = to_clk_sccg_pll(hw);
-       struct clk_sccg_pll_setup *setup = &pll->setup;
+       struct clk_sscg_pll *pll = to_clk_sscg_pll(hw);
+       struct clk_sscg_pll_setup *setup = &pll->setup;
        uint64_t rate = req->rate;
        uint64_t min = req->min_rate;
        uint64_t max = req->max_rate;
@@ -472,18 +472,18 @@ static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
        if (rate < PLL_OUT_MIN_FREQ || rate > PLL_OUT_MAX_FREQ)
                return ret;
 
-       ret = __clk_sccg_pll_determine_rate(hw, req, req->rate, req->rate,
+       ret = __clk_sscg_pll_determine_rate(hw, req, req->rate, req->rate,
                                                rate, PLL_BYPASS2);
        if (!ret)
                return ret;
 
-       ret = __clk_sccg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
+       ret = __clk_sscg_pll_determine_rate(hw, req, PLL_STAGE1_REF_MIN_FREQ,
                                                PLL_STAGE1_REF_MAX_FREQ, rate,
                                                PLL_BYPASS1);
        if (!ret)
                return ret;
 
-       ret = __clk_sccg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
+       ret = __clk_sscg_pll_determine_rate(hw, req, PLL_REF_MIN_FREQ,
                                                PLL_REF_MAX_FREQ, rate,
                                                PLL_BYPASS_NONE);
        if (!ret)
@@ -495,25 +495,25 @@ static int clk_sccg_pll_determine_rate(struct clk_hw *hw,
        return ret;
 }
 
-static const struct clk_ops clk_sccg_pll_ops = {
-       .prepare        = clk_sccg_pll_prepare,
-       .unprepare      = clk_sccg_pll_unprepare,
-       .is_prepared    = clk_sccg_pll_is_prepared,
-       .recalc_rate    = clk_sccg_pll_recalc_rate,
-       .set_rate       = clk_sccg_pll_set_rate,
-       .set_parent     = clk_sccg_pll_set_parent,
-       .get_parent     = clk_sccg_pll_get_parent,
-       .determine_rate = clk_sccg_pll_determine_rate,
+static const struct clk_ops clk_sscg_pll_ops = {
+       .prepare        = clk_sscg_pll_prepare,
+       .unprepare      = clk_sscg_pll_unprepare,
+       .is_prepared    = clk_sscg_pll_is_prepared,
+       .recalc_rate    = clk_sscg_pll_recalc_rate,
+       .set_rate       = clk_sscg_pll_set_rate,
+       .set_parent     = clk_sscg_pll_set_parent,
+       .get_parent     = clk_sscg_pll_get_parent,
+       .determine_rate = clk_sscg_pll_determine_rate,
 };
 
-struct clk *imx_clk_sccg_pll(const char *name,
+struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
                                const char * const *parent_names,
                                u8 num_parents,
                                u8 parent, u8 bypass1, u8 bypass2,
                                void __iomem *base,
                                unsigned long flags)
 {
-       struct clk_sccg_pll *pll;
+       struct clk_sscg_pll *pll;
        struct clk_init_data init;
        struct clk_hw *hw;
        int ret;
@@ -528,7 +528,7 @@ struct clk *imx_clk_sccg_pll(const char *name,
 
        pll->base = base;
        init.name = name;
-       init.ops = &clk_sccg_pll_ops;
+       init.ops = &clk_sscg_pll_ops;
 
        init.flags = flags;
        init.parent_names = parent_names;
@@ -545,5 +545,5 @@ struct clk *imx_clk_sccg_pll(const char *name,
                return ERR_PTR(ret);
        }
 
-       return hw->clk;
+       return hw;
 }
index cfc05e4..87ab8db 100644 (file)
@@ -22,6 +22,14 @@ void imx_unregister_clocks(struct clk *clks[], unsigned int count)
                clk_unregister(clks[i]);
 }
 
+void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count)
+{
+       unsigned int i;
+
+       for (i = 0; i < count; i++)
+               clk_hw_unregister(hws[i]);
+}
+
 void __init imx_mmdc_mask_handshake(void __iomem *ccm_base,
                                    unsigned int chn)
 {
@@ -94,8 +102,8 @@ struct clk_hw * __init imx_obtain_fixed_clock_hw(
        return __clk_get_hw(clk);
 }
 
-struct clk_hw * __init imx_obtain_fixed_clk_hw(struct device_node *np,
-                                              const char *name)
+struct clk_hw * imx_obtain_fixed_clk_hw(struct device_node *np,
+                                       const char *name)
 {
        struct clk *clk;
 
index bc5bb6a..b05213b 100644 (file)
@@ -12,6 +12,7 @@ void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
 void imx_register_uart_clocks(struct clk ** const clks[]);
 void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
 void imx_unregister_clocks(struct clk *clks[], unsigned int count);
+void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count);
 
 extern void imx_cscmr1_fixup(u32 *val);
 
@@ -24,7 +25,7 @@ enum imx_pllv1_type {
        IMX_PLLV1_IMX35,
 };
 
-enum imx_sccg_pll_type {
+enum imx_sscg_pll_type {
        SCCG_PLL1,
        SCCG_PLL2,
 };
@@ -52,64 +53,98 @@ struct imx_pll14xx_clk {
 
 extern struct imx_pll14xx_clk imx_1416x_pll;
 extern struct imx_pll14xx_clk imx_1443x_pll;
+extern struct imx_pll14xx_clk imx_1443x_dram_pll;
 
 #define imx_clk_cpu(name, parent_name, div, mux, pll, step) \
-       imx_clk_hw_cpu(name, parent_name, div, mux, pll, step)->clk
+       to_clk(imx_clk_hw_cpu(name, parent_name, div, mux, pll, step))
 
 #define clk_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
                                cgr_val, clk_gate_flags, lock, share_count) \
-       clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
-                               cgr_val, clk_gate_flags, lock, share_count)->clk
+       to_clk(clk_hw_register_gate2(dev, name, parent_name, flags, reg, bit_idx, \
+                               cgr_val, clk_gate_flags, lock, share_count))
 
 #define imx_clk_pllv3(type, name, parent_name, base, div_mask) \
-       imx_clk_hw_pllv3(type, name, parent_name, base, div_mask)->clk
+       to_clk(imx_clk_hw_pllv3(type, name, parent_name, base, div_mask))
 
 #define imx_clk_pfd(name, parent_name, reg, idx) \
-       imx_clk_hw_pfd(name, parent_name, reg, idx)->clk
+       to_clk(imx_clk_hw_pfd(name, parent_name, reg, idx))
 
 #define imx_clk_gate_exclusive(name, parent, reg, shift, exclusive_mask) \
-       imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask)->clk
+       to_clk(imx_clk_hw_gate_exclusive(name, parent, reg, shift, exclusive_mask))
+
+#define imx_clk_fixed(name, rate) \
+       to_clk(imx_clk_hw_fixed(name, rate))
 
 #define imx_clk_fixed_factor(name, parent, mult, div) \
-       imx_clk_hw_fixed_factor(name, parent, mult, div)->clk
+       to_clk(imx_clk_hw_fixed_factor(name, parent, mult, div))
+
+#define imx_clk_divider(name, parent, reg, shift, width) \
+       to_clk(imx_clk_hw_divider(name, parent, reg, shift, width))
 
 #define imx_clk_divider2(name, parent, reg, shift, width) \
-       imx_clk_hw_divider2(name, parent, reg, shift, width)->clk
+       to_clk(imx_clk_hw_divider2(name, parent, reg, shift, width))
+
+#define imx_clk_divider_flags(name, parent, reg, shift, width, flags) \
+       to_clk(imx_clk_hw_divider_flags(name, parent, reg, shift, width, flags))
+
+#define imx_clk_gate(name, parent, reg, shift) \
+       to_clk(imx_clk_hw_gate(name, parent, reg, shift))
 
 #define imx_clk_gate_dis(name, parent, reg, shift) \
-       imx_clk_hw_gate_dis(name, parent, reg, shift)->clk
+       to_clk(imx_clk_hw_gate_dis(name, parent, reg, shift))
 
 #define imx_clk_gate2(name, parent, reg, shift) \
-       imx_clk_hw_gate2(name, parent, reg, shift)->clk
+       to_clk(imx_clk_hw_gate2(name, parent, reg, shift))
 
 #define imx_clk_gate2_flags(name, parent, reg, shift, flags) \
-       imx_clk_hw_gate2_flags(name, parent, reg, shift, flags)->clk
+       to_clk(imx_clk_hw_gate2_flags(name, parent, reg, shift, flags))
 
 #define imx_clk_gate2_shared2(name, parent, reg, shift, share_count) \
-       imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count)->clk
+       to_clk(imx_clk_hw_gate2_shared2(name, parent, reg, shift, share_count))
 
 #define imx_clk_gate3(name, parent, reg, shift) \
-       imx_clk_hw_gate3(name, parent, reg, shift)->clk
+       to_clk(imx_clk_hw_gate3(name, parent, reg, shift))
 
 #define imx_clk_gate4(name, parent, reg, shift) \
-       imx_clk_hw_gate4(name, parent, reg, shift)->clk
+       to_clk(imx_clk_hw_gate4(name, parent, reg, shift))
 
 #define imx_clk_mux(name, reg, shift, width, parents, num_parents) \
-       imx_clk_hw_mux(name, reg, shift, width, parents, num_parents)->clk
+       to_clk(imx_clk_hw_mux(name, reg, shift, width, parents, num_parents))
+
+#define imx_clk_pllv1(type, name, parent, base) \
+       to_clk(imx_clk_hw_pllv1(type, name, parent, base))
+
+#define imx_clk_pllv2(name, parent, base) \
+       to_clk(imx_clk_hw_pllv2(name, parent, base))
+
+#define imx_clk_frac_pll(name, parent_name, base) \
+       to_clk(imx_clk_hw_frac_pll(name, parent_name, base))
+
+#define imx_clk_sscg_pll(name, parent_names, num_parents, parent,\
+                               bypass1, bypass2, base, flags) \
+       to_clk(imx_clk_hw_sscg_pll(name, parent_names, num_parents, parent,\
+                               bypass1, bypass2, base, flags))
 
 struct clk *imx_clk_pll14xx(const char *name, const char *parent_name,
                 void __iomem *base, const struct imx_pll14xx_clk *pll_clk);
 
-struct clk *imx_clk_pllv1(enum imx_pllv1_type type, const char *name,
+#define imx_clk_pll14xx(name, parent_name, base, pll_clk) \
+       to_clk(imx_clk_hw_pll14xx(name, parent_name, base, pll_clk))
+
+struct clk_hw *imx_clk_hw_pll14xx(const char *name, const char *parent_name,
+                                 void __iomem *base,
+                                 const struct imx_pll14xx_clk *pll_clk);
+
+struct clk_hw *imx_clk_hw_pllv1(enum imx_pllv1_type type, const char *name,
                const char *parent, void __iomem *base);
 
-struct clk *imx_clk_pllv2(const char *name, const char *parent,
+struct clk_hw *imx_clk_hw_pllv2(const char *name, const char *parent,
                void __iomem *base);
 
-struct clk *imx_clk_frac_pll(const char *name, const char *parent_name,
+struct clk_hw *imx_clk_hw_frac_pll(const char *name, const char *parent_name,
                             void __iomem *base);
 
-struct clk *imx_clk_sccg_pll(const char *name,
+struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
                                const char * const *parent_names,
                                u8 num_parents,
                                u8 parent, u8 bypass1, u8 bypass2,
@@ -149,7 +184,7 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
                .kdiv   =       (_k),                   \
        }
 
-struct clk_hw *imx_clk_pllv4(const char *name, const char *parent_name,
+struct clk_hw *imx_clk_hw_pllv4(const char *name, const char *parent_name,
                             void __iomem *base);
 
 struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
@@ -173,7 +208,7 @@ struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
 struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name,
                void __iomem *reg, u8 idx);
 
-struct clk_hw *imx_clk_pfdv2(const char *name, const char *parent_name,
+struct clk_hw *imx_clk_hw_pfdv2(const char *name, const char *parent_name,
                             void __iomem *reg, u8 idx);
 
 struct clk_hw *imx_clk_hw_busy_divider(const char *name, const char *parent_name,
@@ -184,7 +219,7 @@ struct clk_hw *imx_clk_hw_busy_mux(const char *name, void __iomem *reg, u8 shift
                             u8 width, void __iomem *busy_reg, u8 busy_shift,
                             const char * const *parent_names, int num_parents);
 
-struct clk_hw *imx7ulp_clk_composite(const char *name,
+struct clk_hw *imx7ulp_clk_hw_composite(const char *name,
                                     const char * const *parent_names,
                                     int num_parents, bool mux_present,
                                     bool rate_present, bool gate_present,
@@ -198,9 +233,11 @@ struct clk_hw *imx_clk_hw_fixup_mux(const char *name, void __iomem *reg,
                              u8 shift, u8 width, const char * const *parents,
                              int num_parents, void (*fixup)(u32 *val));
 
-static inline struct clk *imx_clk_fixed(const char *name, int rate)
+static inline struct clk *to_clk(struct clk_hw *hw)
 {
-       return clk_register_fixed_rate(NULL, name, NULL, 0, rate);
+       if (IS_ERR_OR_NULL(hw))
+               return ERR_CAST(hw);
+       return hw->clk;
 }
 
 static inline struct clk_hw *imx_clk_hw_fixed(const char *name, int rate)
@@ -224,13 +261,6 @@ static inline struct clk_hw *imx_clk_hw_fixed_factor(const char *name,
                        CLK_SET_RATE_PARENT, mult, div);
 }
 
-static inline struct clk *imx_clk_divider(const char *name, const char *parent,
-               void __iomem *reg, u8 shift, u8 width)
-{
-       return clk_register_divider(NULL, name, parent, CLK_SET_RATE_PARENT,
-                       reg, shift, width, 0, &imx_ccm_lock);
-}
-
 static inline struct clk_hw *imx_clk_hw_divider(const char *name,
                                                const char *parent,
                                                void __iomem *reg, u8 shift,
@@ -240,14 +270,6 @@ static inline struct clk_hw *imx_clk_hw_divider(const char *name,
                                       reg, shift, width, 0, &imx_ccm_lock);
 }
 
-static inline struct clk *imx_clk_divider_flags(const char *name,
-               const char *parent, void __iomem *reg, u8 shift, u8 width,
-               unsigned long flags)
-{
-       return clk_register_divider(NULL, name, parent, flags,
-                       reg, shift, width, 0, &imx_ccm_lock);
-}
-
 static inline struct clk_hw *imx_clk_hw_divider_flags(const char *name,
                                                   const char *parent,
                                                   void __iomem *reg, u8 shift,
@@ -274,13 +296,6 @@ static inline struct clk *imx_clk_divider2_flags(const char *name,
                        reg, shift, width, 0, &imx_ccm_lock);
 }
 
-static inline struct clk *imx_clk_gate(const char *name, const char *parent,
-               void __iomem *reg, u8 shift)
-{
-       return clk_register_gate(NULL, name, parent, CLK_SET_RATE_PARENT, reg,
-                       shift, 0, &imx_ccm_lock);
-}
-
 static inline struct clk_hw *imx_clk_hw_gate_flags(const char *name, const char *parent,
                void __iomem *reg, u8 shift, unsigned long flags)
 {
@@ -355,15 +370,18 @@ static inline struct clk_hw *imx_clk_hw_gate3(const char *name, const char *pare
                        reg, shift, 0, &imx_ccm_lock);
 }
 
-static inline struct clk *imx_clk_gate3_flags(const char *name,
+static inline struct clk_hw *imx_clk_hw_gate3_flags(const char *name,
                const char *parent, void __iomem *reg, u8 shift,
                unsigned long flags)
 {
-       return clk_register_gate(NULL, name, parent,
+       return clk_hw_register_gate(NULL, name, parent,
                        flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
                        reg, shift, 0, &imx_ccm_lock);
 }
 
+#define imx_clk_gate3_flags(name, parent, reg, shift, flags) \
+       to_clk(imx_clk_hw_gate3_flags(name, parent, reg, shift, flags))
+
 static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *parent,
                void __iomem *reg, u8 shift)
 {
@@ -372,15 +390,18 @@ static inline struct clk_hw *imx_clk_hw_gate4(const char *name, const char *pare
                        reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
 }
 
-static inline struct clk *imx_clk_gate4_flags(const char *name,
+static inline struct clk_hw *imx_clk_hw_gate4_flags(const char *name,
                const char *parent, void __iomem *reg, u8 shift,
                unsigned long flags)
 {
-       return clk_register_gate2(NULL, name, parent,
+       return clk_hw_register_gate2(NULL, name, parent,
                        flags | CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
                        reg, shift, 0x3, 0, &imx_ccm_lock, NULL);
 }
 
+#define imx_clk_gate4_flags(name, parent, reg, shift, flags) \
+       to_clk(imx_clk_hw_gate4_flags(name, parent, reg, shift, flags))
+
 static inline struct clk_hw *imx_clk_hw_mux(const char *name, void __iomem *reg,
                        u8 shift, u8 width, const char * const *parents,
                        int num_parents)
@@ -420,6 +441,16 @@ static inline struct clk *imx_clk_mux_flags(const char *name,
                        &imx_ccm_lock);
 }
 
+static inline struct clk_hw *imx_clk_hw_mux2_flags(const char *name,
+               void __iomem *reg, u8 shift, u8 width,
+               const char * const *parents,
+               int num_parents, unsigned long flags)
+{
+       return clk_hw_register_mux(NULL, name, parents, num_parents,
+                       flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE,
+                       reg, shift, width, 0, &imx_ccm_lock);
+}
+
 static inline struct clk *imx_clk_mux2_flags(const char *name,
                void __iomem *reg, u8 shift, u8 width,
                const char * const *parents,
@@ -446,23 +477,38 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
                struct clk *div, struct clk *mux, struct clk *pll,
                struct clk *step);
 
-struct clk *imx8m_clk_composite_flags(const char *name,
-                                       const char * const *parent_names,
-                                       int num_parents, void __iomem *reg,
-                                       unsigned long flags);
+struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
+                                           const char * const *parent_names,
+                                           int num_parents,
+                                           void __iomem *reg,
+                                           unsigned long flags);
 
-#define __imx8m_clk_composite(name, parent_names, reg, flags) \
-       imx8m_clk_composite_flags(name, parent_names, \
+#define imx8m_clk_composite_flags(name, parent_names, num_parents, reg, \
+                                 flags) \
+       to_clk(imx8m_clk_hw_composite_flags(name, parent_names, \
+                               num_parents, reg, flags))
+
+#define __imx8m_clk_hw_composite(name, parent_names, reg, flags) \
+       imx8m_clk_hw_composite_flags(name, parent_names, \
                ARRAY_SIZE(parent_names), reg, \
                flags | CLK_SET_RATE_NO_REPARENT | CLK_OPS_PARENT_ENABLE)
 
+#define __imx8m_clk_composite(name, parent_names, reg, flags) \
+       to_clk(__imx8m_clk_hw_composite(name, parent_names, reg, flags))
+
+#define imx8m_clk_hw_composite(name, parent_names, reg) \
+       __imx8m_clk_hw_composite(name, parent_names, reg, 0)
+
 #define imx8m_clk_composite(name, parent_names, reg) \
        __imx8m_clk_composite(name, parent_names, reg, 0)
 
+#define imx8m_clk_hw_composite_critical(name, parent_names, reg) \
+       __imx8m_clk_hw_composite(name, parent_names, reg, CLK_IS_CRITICAL)
+
 #define imx8m_clk_composite_critical(name, parent_names, reg) \
        __imx8m_clk_composite(name, parent_names, reg, CLK_IS_CRITICAL)
 
-struct clk_hw *imx_clk_divider_gate(const char *name, const char *parent_name,
+struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name,
                unsigned long flags, void __iomem *reg, u8 shift, u8 width,
                u8 clk_divider_flags, const struct clk_div_table *table,
                spinlock_t *lock);
index 7efc361..ea3c70d 100644 (file)
@@ -174,36 +174,36 @@ config COMMON_CLK_MT6779_AUDSYS
          This driver supports Mediatek MT6779 audsys clocks.
 
 config COMMON_CLK_MT6797
-       bool "Clock driver for MediaTek MT6797"
-       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
-       select COMMON_CLK_MEDIATEK
-       default ARCH_MEDIATEK && ARM64
-       ---help---
-         This driver supports MediaTek MT6797 basic clocks.
+       bool "Clock driver for MediaTek MT6797"
+       depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
+       select COMMON_CLK_MEDIATEK
+       default ARCH_MEDIATEK && ARM64
+       ---help---
+         This driver supports MediaTek MT6797 basic clocks.
 
 config COMMON_CLK_MT6797_MMSYS
-       bool "Clock driver for MediaTek MT6797 mmsys"
-       depends on COMMON_CLK_MT6797
-       ---help---
-         This driver supports MediaTek MT6797 mmsys clocks.
+       bool "Clock driver for MediaTek MT6797 mmsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports MediaTek MT6797 mmsys clocks.
 
 config COMMON_CLK_MT6797_IMGSYS
-       bool "Clock driver for MediaTek MT6797 imgsys"
-       depends on COMMON_CLK_MT6797
-       ---help---
-         This driver supports MediaTek MT6797 imgsys clocks.
+       bool "Clock driver for MediaTek MT6797 imgsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports MediaTek MT6797 imgsys clocks.
 
 config COMMON_CLK_MT6797_VDECSYS
-       bool "Clock driver for MediaTek MT6797 vdecsys"
-       depends on COMMON_CLK_MT6797
-       ---help---
-         This driver supports MediaTek MT6797 vdecsys clocks.
+       bool "Clock driver for MediaTek MT6797 vdecsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports MediaTek MT6797 vdecsys clocks.
 
 config COMMON_CLK_MT6797_VENCSYS
-       bool "Clock driver for MediaTek MT6797 vencsys"
-       depends on COMMON_CLK_MT6797
-       ---help---
-         This driver supports MediaTek MT6797 vencsys clocks.
+       bool "Clock driver for MediaTek MT6797 vencsys"
+       depends on COMMON_CLK_MT6797
+       ---help---
+         This driver supports MediaTek MT6797 vencsys clocks.
 
 config COMMON_CLK_MT7622
        bool "Clock driver for MediaTek MT7622"
index 3939f21..6eca2a4 100644 (file)
@@ -18,4 +18,4 @@ obj-$(CONFIG_COMMON_CLK_AXG) += axg.o axg-aoclk.o
 obj-$(CONFIG_COMMON_CLK_AXG_AUDIO) += axg-audio.o
 obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
 obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
-obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o
+obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
index 2d39a8b..fc9df48 100644 (file)
@@ -129,7 +129,7 @@ static int mpll_set_rate(struct clk_hw *hw,
        return 0;
 }
 
-static void mpll_init(struct clk_hw *hw)
+static int mpll_init(struct clk_hw *hw)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
@@ -151,6 +151,8 @@ static void mpll_init(struct clk_hw *hw)
        /* Set the magic misc bit if required */
        if (MESON_PARM_APPLICABLE(&mpll->misc))
                meson_parm_write(clk->map, &mpll->misc, 1);
+
+       return 0;
 }
 
 const struct clk_ops meson_clk_mpll_ro_ops = {
index 80c3ada..fe22e17 100644 (file)
@@ -78,7 +78,7 @@ meson_clk_triphase_data(struct clk_regmap *clk)
        return (struct meson_clk_triphase_data *)clk->data;
 }
 
-static void meson_clk_triphase_sync(struct clk_hw *hw)
+static int meson_clk_triphase_sync(struct clk_hw *hw)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_triphase_data *tph = meson_clk_triphase_data(clk);
@@ -88,6 +88,8 @@ static void meson_clk_triphase_sync(struct clk_hw *hw)
        val = meson_parm_read(clk->map, &tph->ph0);
        meson_parm_write(clk->map, &tph->ph1, val);
        meson_parm_write(clk->map, &tph->ph2, val);
+
+       return 0;
 }
 
 static int meson_clk_triphase_get_phase(struct clk_hw *hw)
index ddb1e56..b17a13e 100644 (file)
@@ -77,6 +77,15 @@ static unsigned long meson_clk_pll_recalc_rate(struct clk_hw *hw,
        unsigned int m, n, frac;
 
        n = meson_parm_read(clk->map, &pll->n);
+
+       /*
+        * On some HW, N is set to zero on init. This value is invalid as
+        * it would result in a division by zero. The rate can't be
+        * calculated in this case
+        */
+       if (n == 0)
+               return 0;
+
        m = meson_parm_read(clk->map, &pll->m);
 
        frac = MESON_PARM_APPLICABLE(&pll->frac) ?
@@ -277,7 +286,7 @@ static int meson_clk_pll_wait_lock(struct clk_hw *hw)
        return -ETIMEDOUT;
 }
 
-static void meson_clk_pll_init(struct clk_hw *hw)
+static int meson_clk_pll_init(struct clk_hw *hw)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_clk_pll_data *pll = meson_clk_pll_data(clk);
@@ -288,6 +297,8 @@ static void meson_clk_pll_init(struct clk_hw *hw)
                                       pll->init_count);
                meson_parm_write(clk->map, &pll->rst, 0);
        }
+
+       return 0;
 }
 
 static int meson_clk_pll_is_enabled(struct clk_hw *hw)
index b3af61c..d2760a0 100644 (file)
@@ -4692,6 +4692,7 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
        &g12a_bt656,
        &g12a_usb1_to_ddr,
        &g12a_mmc_pclk,
+       &g12a_uart2,
        &g12a_vpu_intr,
        &g12a_gic,
        &g12a_sd_emmc_a_clk0,
diff --git a/drivers/clk/meson/meson8-ddr.c b/drivers/clk/meson/meson8-ddr.c
new file mode 100644 (file)
index 0000000..4b73ea2
--- /dev/null
@@ -0,0 +1,149 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Amlogic Meson8 DDR clock controller
+ *
+ * Copyright (C) 2019 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
+ */
+
+#include <dt-bindings/clock/meson8-ddr-clkc.h>
+
+#include <linux/clk-provider.h>
+#include <linux/platform_device.h>
+
+#include "clk-regmap.h"
+#include "clk-pll.h"
+
+#define AM_DDR_PLL_CNTL                        0x00
+#define AM_DDR_PLL_CNTL1               0x04
+#define AM_DDR_PLL_CNTL2               0x08
+#define AM_DDR_PLL_CNTL3               0x0c
+#define AM_DDR_PLL_CNTL4               0x10
+#define AM_DDR_PLL_STS                 0x14
+#define DDR_CLK_CNTL                   0x18
+#define DDR_CLK_STS                    0x1c
+
+static struct clk_regmap meson8_ddr_pll_dco = {
+       .data = &(struct meson_clk_pll_data){
+               .en = {
+                       .reg_off = AM_DDR_PLL_CNTL,
+                       .shift   = 30,
+                       .width   = 1,
+               },
+               .m = {
+                       .reg_off = AM_DDR_PLL_CNTL,
+                       .shift   = 0,
+                       .width   = 9,
+               },
+               .n = {
+                       .reg_off = AM_DDR_PLL_CNTL,
+                       .shift   = 9,
+                       .width   = 5,
+               },
+               .l = {
+                       .reg_off = AM_DDR_PLL_CNTL,
+                       .shift   = 31,
+                       .width   = 1,
+               },
+               .rst = {
+                       .reg_off = AM_DDR_PLL_CNTL,
+                       .shift   = 29,
+                       .width   = 1,
+               },
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "ddr_pll_dco",
+               .ops = &meson_clk_pll_ro_ops,
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+               },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_regmap meson8_ddr_pll = {
+       .data = &(struct clk_regmap_div_data){
+               .offset = AM_DDR_PLL_CNTL,
+               .shift = 16,
+               .width = 2,
+               .flags = CLK_DIVIDER_POWER_OF_TWO,
+       },
+       .hw.init = &(struct clk_init_data){
+               .name = "ddr_pll",
+               .ops = &clk_regmap_divider_ro_ops,
+               .parent_hws = (const struct clk_hw *[]) {
+                       &meson8_ddr_pll_dco.hw
+               },
+               .num_parents = 1,
+       },
+};
+
+static struct clk_hw_onecell_data meson8_ddr_clk_hw_onecell_data = {
+       .hws = {
+               [DDR_CLKID_DDR_PLL_DCO]         = &meson8_ddr_pll_dco.hw,
+               [DDR_CLKID_DDR_PLL]             = &meson8_ddr_pll.hw,
+       },
+       .num = 2,
+};
+
+static struct clk_regmap *const meson8_ddr_clk_regmaps[] = {
+       &meson8_ddr_pll_dco,
+       &meson8_ddr_pll,
+};
+
+static const struct regmap_config meson8_ddr_clkc_regmap_config = {
+       .reg_bits = 8,
+       .val_bits = 32,
+       .reg_stride = 4,
+       .max_register = DDR_CLK_STS,
+};
+
+static int meson8_ddr_clkc_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       void __iomem *base;
+       struct clk_hw *hw;
+       int ret, i;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       regmap = devm_regmap_init_mmio(&pdev->dev, base,
+                                      &meson8_ddr_clkc_regmap_config);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /* Populate regmap */
+       for (i = 0; i < ARRAY_SIZE(meson8_ddr_clk_regmaps); i++)
+               meson8_ddr_clk_regmaps[i]->map = regmap;
+
+       /* Register all clks */
+       for (i = 0; i < meson8_ddr_clk_hw_onecell_data.num; i++) {
+               hw = meson8_ddr_clk_hw_onecell_data.hws[i];
+
+               ret = devm_clk_hw_register(&pdev->dev, hw);
+               if (ret) {
+                       dev_err(&pdev->dev, "Clock registration failed\n");
+                       return ret;
+               }
+       }
+
+       return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get,
+                                          &meson8_ddr_clk_hw_onecell_data);
+}
+
+static const struct of_device_id meson8_ddr_clkc_match_table[] = {
+       { .compatible = "amlogic,meson8-ddr-clkc" },
+       { .compatible = "amlogic,meson8b-ddr-clkc" },
+       { /* sentinel */ }
+};
+
+static struct platform_driver meson8_ddr_clkc_driver = {
+       .probe          = meson8_ddr_clkc_probe,
+       .driver         = {
+               .name   = "meson8-ddr-clkc",
+               .of_match_table = meson8_ddr_clkc_match_table,
+       },
+};
+
+builtin_platform_driver(meson8_ddr_clkc_driver);
index 67e6691..9fd31f2 100644 (file)
@@ -97,8 +97,10 @@ static struct clk_regmap meson8b_fixed_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "fixed_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_xtal.hw
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+                       .name = "xtal",
+                       .index = -1,
                },
                .num_parents = 1,
        },
@@ -162,8 +164,10 @@ static struct clk_regmap meson8b_hdmi_pll_dco = {
                /* sometimes also called "HPLL" or "HPLL PLL" */
                .name = "hdmi_pll_dco",
                .ops = &meson_clk_pll_ro_ops,
-               .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_xtal.hw
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+                       .name = "xtal",
+                       .index = -1,
                },
                .num_parents = 1,
        },
@@ -237,8 +241,10 @@ static struct clk_regmap meson8b_sys_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "sys_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_xtal.hw
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+                       .name = "xtal",
+                       .index = -1,
                },
                .num_parents = 1,
        },
@@ -631,9 +637,9 @@ static struct clk_regmap meson8b_cpu_in_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_in_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_xtal.hw,
-                       &meson8b_sys_pll.hw,
+               .parent_data = (const struct clk_parent_data[]) {
+                       { .fw_name = "xtal", .name = "xtal", .index = -1, },
+                       { .hw = &meson8b_sys_pll.hw, },
                },
                .num_parents = 2,
                .flags = (CLK_SET_RATE_PARENT |
@@ -736,9 +742,9 @@ static struct clk_regmap meson8b_cpu_clk = {
        .hw.init = &(struct clk_init_data){
                .name = "cpu_clk",
                .ops = &clk_regmap_mux_ops,
-               .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_xtal.hw,
-                       &meson8b_cpu_scale_out_sel.hw,
+               .parent_data = (const struct clk_parent_data[]) {
+                       { .fw_name = "xtal", .name = "xtal", .index = -1, },
+                       { .hw = &meson8b_cpu_scale_out_sel.hw, },
                },
                .num_parents = 2,
                .flags = (CLK_SET_RATE_PARENT |
@@ -758,12 +764,12 @@ static struct clk_regmap meson8b_nand_clk_sel = {
                .name = "nand_clk_sel",
                .ops = &clk_regmap_mux_ops,
                /* FIXME all other parents are unknown: */
-               .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_fclk_div4.hw,
-                       &meson8b_fclk_div3.hw,
-                       &meson8b_fclk_div5.hw,
-                       &meson8b_fclk_div7.hw,
-                       &meson8b_xtal.hw,
+               .parent_data = (const struct clk_parent_data[]) {
+                       { .hw = &meson8b_fclk_div4.hw, },
+                       { .hw = &meson8b_fclk_div3.hw, },
+                       { .hw = &meson8b_fclk_div5.hw, },
+                       { .hw = &meson8b_fclk_div7.hw, },
+                       { .fw_name = "xtal", .name = "xtal", .index = -1, },
                },
                .num_parents = 5,
                .flags = CLK_SET_RATE_PARENT,
@@ -1721,8 +1727,10 @@ static struct clk_regmap meson8b_hdmi_sys_sel = {
                .name = "hdmi_sys_sel",
                .ops = &clk_regmap_mux_ro_ops,
                /* FIXME: all other parents are unknown */
-               .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_xtal.hw
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+                       .name = "xtal",
+                       .index = -1,
                },
                .num_parents = 1,
                .flags = CLK_SET_RATE_NO_REPARENT,
@@ -1764,17 +1772,20 @@ static struct clk_regmap meson8b_hdmi_sys = {
 
 /*
  * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
- * muxed by a glitch-free switch on Meson8b and Meson8m2. Meson8 only
- * has mali_0 and no glitch-free mux.
+ * muxed by a glitch-free switch on Meson8b and Meson8m2. The CCF can
+ * actually manage this glitch-free mux because it does top-to-bottom
+ * updates the each clock tree and switches to the "inactive" one when
+ * CLK_SET_RATE_GATE is set.
+ * Meson8 only has mali_0 and no glitch-free mux.
  */
-static const struct clk_hw *meson8b_mali_0_1_parent_hws[] = {
-       &meson8b_xtal.hw,
-       &meson8b_mpll2.hw,
-       &meson8b_mpll1.hw,
-       &meson8b_fclk_div7.hw,
-       &meson8b_fclk_div4.hw,
-       &meson8b_fclk_div3.hw,
-       &meson8b_fclk_div5.hw,
+static const struct clk_parent_data meson8b_mali_0_1_parent_data[] = {
+       { .fw_name = "xtal", .name = "xtal", .index = -1, },
+       { .hw = &meson8b_mpll2.hw, },
+       { .hw = &meson8b_mpll1.hw, },
+       { .hw = &meson8b_fclk_div7.hw, },
+       { .hw = &meson8b_fclk_div4.hw, },
+       { .hw = &meson8b_fclk_div3.hw, },
+       { .hw = &meson8b_fclk_div5.hw, },
 };
 
 static u32 meson8b_mali_0_1_mux_table[] = { 0, 2, 3, 4, 5, 6, 7 };
@@ -1789,8 +1800,8 @@ static struct clk_regmap meson8b_mali_0_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_0_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_hws = meson8b_mali_0_1_parent_hws,
-               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws),
+               .parent_data = meson8b_mali_0_1_parent_data,
+               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_data),
                /*
                 * Don't propagate rate changes up because the only changeable
                 * parents are mpll1 and mpll2 but we need those for audio and
@@ -1830,7 +1841,7 @@ static struct clk_regmap meson8b_mali_0 = {
                        &meson8b_mali_0_div.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
+               .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
        },
 };
 
@@ -1844,8 +1855,8 @@ static struct clk_regmap meson8b_mali_1_sel = {
        .hw.init = &(struct clk_init_data){
                .name = "mali_1_sel",
                .ops = &clk_regmap_mux_ops,
-               .parent_hws = meson8b_mali_0_1_parent_hws,
-               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_hws),
+               .parent_data = meson8b_mali_0_1_parent_data,
+               .num_parents = ARRAY_SIZE(meson8b_mali_0_1_parent_data),
                /*
                 * Don't propagate rate changes up because the only changeable
                 * parents are mpll1 and mpll2 but we need those for audio and
@@ -1885,7 +1896,7 @@ static struct clk_regmap meson8b_mali_1 = {
                        &meson8b_mali_1_div.hw
                },
                .num_parents = 1,
-               .flags = CLK_SET_RATE_PARENT,
+               .flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
        },
 };
 
@@ -1944,8 +1955,10 @@ static struct clk_regmap meson8m2_gp_pll_dco = {
        .hw.init = &(struct clk_init_data){
                .name = "gp_pll_dco",
                .ops = &meson_clk_pll_ops,
-               .parent_hws = (const struct clk_hw *[]) {
-                       &meson8b_xtal.hw
+               .parent_data = &(const struct clk_parent_data) {
+                       .fw_name = "xtal",
+                       .name = "xtal",
+                       .index = -1,
                },
                .num_parents = 1,
        },
@@ -3585,7 +3598,7 @@ static const struct reset_control_ops meson8b_clk_reset_ops = {
 
 struct meson8b_nb_data {
        struct notifier_block nb;
-       struct clk_hw_onecell_data *onecell_data;
+       struct clk_hw *cpu_clk;
 };
 
 static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb,
@@ -3593,30 +3606,25 @@ static int meson8b_cpu_clk_notifier_cb(struct notifier_block *nb,
 {
        struct meson8b_nb_data *nb_data =
                container_of(nb, struct meson8b_nb_data, nb);
-       struct clk_hw **hws = nb_data->onecell_data->hws;
-       struct clk_hw *cpu_clk_hw, *parent_clk_hw;
-       struct clk *cpu_clk, *parent_clk;
+       struct clk_hw *parent_clk;
        int ret;
 
        switch (event) {
        case PRE_RATE_CHANGE:
-               parent_clk_hw = hws[CLKID_XTAL];
+               /* xtal */
+               parent_clk = clk_hw_get_parent_by_index(nb_data->cpu_clk, 0);
                break;
 
        case POST_RATE_CHANGE:
-               parent_clk_hw = hws[CLKID_CPU_SCALE_OUT_SEL];
+               /* cpu_scale_out_sel */
+               parent_clk = clk_hw_get_parent_by_index(nb_data->cpu_clk, 1);
                break;
 
        default:
                return NOTIFY_DONE;
        }
 
-       cpu_clk_hw = hws[CLKID_CPUCLK];
-       cpu_clk = __clk_lookup(clk_hw_get_name(cpu_clk_hw));
-
-       parent_clk = __clk_lookup(clk_hw_get_name(parent_clk_hw));
-
-       ret = clk_set_parent(cpu_clk, parent_clk);
+       ret = clk_hw_set_parent(nb_data->cpu_clk, parent_clk);
        if (ret)
                return notifier_from_errno(ret);
 
@@ -3682,20 +3690,26 @@ static void __init meson8b_clkc_init_common(struct device_node *np,
                meson8b_clk_regmaps[i]->map = map;
 
        /*
-        * register all clks
-        * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
+        * always skip CLKID_UNUSED and also skip XTAL if the .dtb provides the
+        * XTAL clock as input.
         */
-       for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
+       if (!IS_ERR(of_clk_get_by_name(np, "xtal")))
+               i = CLKID_PLL_FIXED;
+       else
+               i = CLKID_XTAL;
+
+       /* register all clks */
+       for (; i < CLK_NR_CLKS; i++) {
                /* array might be sparse */
                if (!clk_hw_onecell_data->hws[i])
                        continue;
 
-               ret = clk_hw_register(NULL, clk_hw_onecell_data->hws[i]);
+               ret = of_clk_hw_register(np, clk_hw_onecell_data->hws[i]);
                if (ret)
                        return;
        }
 
-       meson8b_cpu_nb_data.onecell_data = clk_hw_onecell_data;
+       meson8b_cpu_nb_data.cpu_clk = clk_hw_onecell_data->hws[CLKID_CPUCLK];
 
        /*
         * FIXME we shouldn't program the muxes in notifier handlers. The
index 3acf037..76d31c0 100644 (file)
@@ -216,7 +216,7 @@ static int sclk_div_is_enabled(struct clk_hw *hw)
        return 0;
 }
 
-static void sclk_div_init(struct clk_hw *hw)
+static int sclk_div_init(struct clk_hw *hw)
 {
        struct clk_regmap *clk = to_clk_regmap(hw);
        struct meson_sclk_div_data *sclk = meson_sclk_div_data(clk);
@@ -231,6 +231,8 @@ static void sclk_div_init(struct clk_hw *hw)
                sclk->cached_div = val + 1;
 
        sclk_div_get_duty_cycle(hw, &sclk->cached_duty);
+
+       return 0;
 }
 
 const struct clk_ops meson_sclk_div_ops = {
index 567755d..1b4f023 100644 (file)
@@ -266,10 +266,12 @@ static void roclk_disable(struct clk_hw *hw)
        writel(REFO_ON | REFO_OE, PIC32_CLR(refo->ctrl_reg));
 }
 
-static void roclk_init(struct clk_hw *hw)
+static int roclk_init(struct clk_hw *hw)
 {
        /* initialize clock in disabled state */
        roclk_disable(hw);
+
+       return 0;
 }
 
 static u8 roclk_get_parent(struct clk_hw *hw)
@@ -880,7 +882,7 @@ static int sclk_set_parent(struct clk_hw *hw, u8 index)
        return err;
 }
 
-static void sclk_init(struct clk_hw *hw)
+static int sclk_init(struct clk_hw *hw)
 {
        struct pic32_sys_clk *sclk = clkhw_to_sys_clk(hw);
        unsigned long flags;
@@ -899,6 +901,8 @@ static void sclk_init(struct clk_hw *hw)
                writel(v, sclk->slew_reg);
                spin_unlock_irqrestore(&sclk->core->reg_lock, flags);
        }
+
+       return 0;
 }
 
 /* sclk with post-divider */
index 90bf181..fabc09a 100644 (file)
@@ -109,7 +109,7 @@ static int clk_factor_set_rate(struct clk_hw *hw, unsigned long drate,
        return 0;
 }
 
-static void clk_factor_init(struct clk_hw *hw)
+static int clk_factor_init(struct clk_hw *hw)
 {
        struct mmp_clk_factor *factor = to_clk_factor(hw);
        struct mmp_clk_factor_masks *masks = factor->masks;
@@ -146,6 +146,8 @@ static void clk_factor_init(struct clk_hw *hw)
 
        if (factor->lock)
                spin_unlock_irqrestore(factor->lock, flags);
+
+       return 0;
 }
 
 static const struct clk_ops clk_factor_ops = {
index 90814b2..d2cd36c 100644 (file)
@@ -419,12 +419,14 @@ static int mmp_clk_set_rate(struct clk_hw *hw, unsigned long rate,
        }
 }
 
-static void mmp_clk_mix_init(struct clk_hw *hw)
+static int mmp_clk_mix_init(struct clk_hw *hw)
 {
        struct mmp_clk_mix *mix = to_clk_mix(hw);
 
        if (mix->table)
                _filter_clk_table(mix, mix->table, mix->table_size);
+
+       return 0;
 }
 
 const struct clk_ops mmp_clk_mix_ops = {
index b4a95cb..6e71591 100644 (file)
@@ -53,6 +53,8 @@
 #define APMU_DISP1     0x110
 #define APMU_CCIC0     0x50
 #define APMU_CCIC1     0xf4
+#define APMU_USBHSIC0  0xf8
+#define APMU_USBHSIC1  0xfc
 #define MPMU_UART_PLL  0x14
 
 struct mmp2_clk_unit {
@@ -194,6 +196,8 @@ static struct mmp_clk_mix_config sdh_mix_config = {
 };
 
 static DEFINE_SPINLOCK(usb_lock);
+static DEFINE_SPINLOCK(usbhsic0_lock);
+static DEFINE_SPINLOCK(usbhsic1_lock);
 
 static DEFINE_SPINLOCK(disp0_lock);
 static DEFINE_SPINLOCK(disp1_lock);
@@ -224,6 +228,8 @@ static struct mmp_param_div_clk apmu_div_clks[] = {
 
 static struct mmp_param_gate_clk apmu_gate_clks[] = {
        {MMP2_CLK_USB, "usb_clk", "usb_pll", 0, APMU_USB, 0x9, 0x9, 0x0, 0, &usb_lock},
+       {MMP2_CLK_USBHSIC0, "usbhsic0_clk", "usb_pll", 0, APMU_USBHSIC0, 0x1b, 0x1b, 0x0, 0, &usbhsic0_lock},
+       {MMP2_CLK_USBHSIC1, "usbhsic1_clk", "usb_pll", 0, APMU_USBHSIC1, 0x1b, 0x1b, 0x0, 0, &usbhsic1_lock},
        /* The gate clocks has mux parent. */
        {MMP2_CLK_SDH0, "sdh0_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH0, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
        {MMP2_CLK_SDH1, "sdh1_clk", "sdh_mix_clk", CLK_SET_RATE_PARENT, APMU_SDH1, 0x1b, 0x1b, 0x0, 0, &sdh_lock},
index 415e690..ded07b0 100644 (file)
@@ -29,7 +29,7 @@ config ARMADA_39X_CLK
        select MVEBU_CLK_COMMON
 
 config ARMADA_37XX_CLK
-       bool
+       bool
 
 config ARMADA_XP_CLK
        bool
index 3b33ef1..15cdcdc 100644 (file)
@@ -1,7 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config KRAIT_CLOCKS
-       bool
-       select KRAIT_L2_ACCESSORS
+       bool
+       select KRAIT_L2_ACCESSORS
 
 config QCOM_GDSC
        bool
@@ -14,6 +14,7 @@ menuconfig COMMON_CLK_QCOM
        tristate "Support for Qualcomm's clock controllers"
        depends on OF
        depends on ARCH_QCOM || COMPILE_TEST
+       select RATIONAL
        select REGMAP_MMIO
        select RESET_CONTROLLER
 
@@ -95,6 +96,14 @@ config IPQ_GCC_4019
          Say Y if you want to use peripheral devices such as UART, SPI,
          i2c, USB, SD/eMMC, etc.
 
+config IPQ_GCC_6018
+       tristate "IPQ6018 Global Clock Controller"
+       help
+         Support for global clock controller on ipq6018 devices.
+         Say Y if you want to use peripheral devices such as UART, SPI,
+         i2c, USB, SD/eMMC, etc. Select this for the root clock
+         of ipq6018.
+
 config IPQ_GCC_806X
        tristate "IPQ806x Global Clock Controller"
        help
@@ -229,6 +238,15 @@ config MSM_GPUCC_8998
          Say Y if you want to support graphics controller devices and
          functionality such as 3D graphics.
 
+config MSM_MMCC_8998
+       tristate "MSM8998 Multimedia Clock Controller"
+       select MSM_GCC_8998
+       select QCOM_GDSC
+       help
+         Support for the multimedia clock controller on msm8998 devices.
+         Say Y if you want to support multimedia devices such as display,
+         graphics, video encode/decode, camera, etc.
+
 config QCS_GCC_404
        tristate "QCS404 Global Clock Controller"
        help
@@ -236,6 +254,15 @@ config QCS_GCC_404
          Say Y if you want to use multimedia devices or peripheral
          devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
 
+config SC_DISPCC_7180
+       tristate "SC7180 Display Clock Controller"
+       select SC_GCC_7180
+       help
+         Support for the display clock controller on Qualcomm Technologies, Inc
+         SC7180 devices.
+         Say Y if you want to support display devices and functionality such as
+         splash screen.
+
 config SC_GCC_7180
        tristate "SC7180 Global Clock Controller"
        select QCOM_GDSC
@@ -245,6 +272,22 @@ config SC_GCC_7180
          Say Y if you want to use peripheral devices such as UART, SPI,
          I2C, USB, UFS, SDCC, etc.
 
+config SC_GPUCC_7180
+       tristate "SC7180 Graphics Clock Controller"
+       select SC_GCC_7180
+       help
+         Support for the graphics clock controller on SC7180 devices.
+         Say Y if you want to support graphics controller devices and
+         functionality such as 3D graphics.
+
+config SC_VIDEOCC_7180
+       tristate "SC7180 Video Clock Controller"
+       select SC_GCC_7180
+       help
+         Support for the video clock controller on SC7180 devices.
+         Say Y if you want to support video devices and functionality such as
+         video encode and decode.
+
 config SDM_CAMCC_845
        tristate "SDM845 Camera Clock Controller"
        select SDM_GCC_845
index d899661..656a87e 100644 (file)
@@ -20,6 +20,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
 obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
 obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
 obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
+obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o
 obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
 obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
 obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
@@ -37,6 +38,7 @@ obj-$(CONFIG_MSM_GPUCC_8998) += gpucc-msm8998.o
 obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
 obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
 obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
+obj-$(CONFIG_MSM_MMCC_8998) += mmcc-msm8998.o
 obj-$(CONFIG_QCOM_A53PLL) += a53-pll.o
 obj-$(CONFIG_QCOM_CLK_APCS_MSM8916) += apcs-msm8916.o
 obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
@@ -45,7 +47,10 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
 obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o
 obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o
 obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
+obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
 obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o
+obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
+obj-$(CONFIG_SC_VIDEOCC_7180) += videocc-sc7180.o
 obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
 obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
 obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
index a6c89a3..cf69a97 100644 (file)
@@ -19,9 +19,9 @@
 
 static const u32 gpll0_a53cc_map[] = { 4, 5 };
 
-static const char * const gpll0_a53cc[] = {
-       "gpll0_vote",
-       "a53pll",
+static const struct clk_parent_data pdata[] = {
+       { .fw_name = "aux", .name = "gpll0_vote", },
+       { .fw_name = "pll", .name = "a53pll", },
 };
 
 /*
@@ -62,8 +62,8 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        init.name = "a53mux";
-       init.parent_names = gpll0_a53cc;
-       init.num_parents = ARRAY_SIZE(gpll0_a53cc);
+       init.parent_data = pdata;
+       init.num_parents = ARRAY_SIZE(pdata);
        init.ops = &clk_regmap_mux_div_ops;
        init.flags = CLK_SET_RATE_PARENT;
 
@@ -79,7 +79,8 @@ static int qcom_apcs_msm8916_clk_probe(struct platform_device *pdev)
        a53cc->pclk = devm_clk_get(parent, NULL);
        if (IS_ERR(a53cc->pclk)) {
                ret = PTR_ERR(a53cc->pclk);
-               dev_err(dev, "failed to get clk: %d\n", ret);
+               if (ret != -EPROBE_DEFER)
+                       dev_err(dev, "failed to get clk: %d\n", ret);
                return ret;
        }
 
index 055318f..7c2936d 100644 (file)
@@ -878,6 +878,14 @@ static long clk_trion_pll_round_rate(struct clk_hw *hw, unsigned long rate,
        return clamp(rate, min_freq, max_freq);
 }
 
+const struct clk_ops clk_alpha_pll_fixed_ops = {
+       .enable = clk_alpha_pll_enable,
+       .disable = clk_alpha_pll_disable,
+       .is_enabled = clk_alpha_pll_is_enabled,
+       .recalc_rate = clk_alpha_pll_recalc_rate,
+};
+EXPORT_SYMBOL_GPL(clk_alpha_pll_fixed_ops);
+
 const struct clk_ops clk_alpha_pll_ops = {
        .enable = clk_alpha_pll_enable,
        .disable = clk_alpha_pll_disable,
@@ -1024,6 +1032,25 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
                regmap_write(regmap, PLL_CONFIG_CTL(pll),
                                                config->config_ctl_val);
 
+       if (config->config_ctl_hi_val)
+               regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
+                                               config->config_ctl_hi_val);
+
+       if (config->user_ctl_val)
+               regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
+
+       if (config->user_ctl_hi_val)
+               regmap_write(regmap, PLL_USER_CTL_U(pll),
+                                               config->user_ctl_hi_val);
+
+       if (config->test_ctl_val)
+               regmap_write(regmap, PLL_TEST_CTL(pll),
+                                               config->test_ctl_val);
+
+       if (config->test_ctl_hi_val)
+               regmap_write(regmap, PLL_TEST_CTL_U(pll),
+                                               config->test_ctl_hi_val);
+
        if (config->post_div_mask) {
                mask = config->post_div_mask;
                val = config->post_div_val;
@@ -1141,14 +1168,9 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate,
                                                unsigned long prate)
 {
        struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
-       u32 val, l, alpha_width = pll_alpha_width(pll);
+       u32 l, alpha_width = pll_alpha_width(pll);
        u64 a;
        unsigned long rrate;
-       int ret = 0;
-
-       ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
-       if (ret)
-               return ret;
 
        rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
 
@@ -1167,7 +1189,64 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate,
        return __clk_alpha_pll_update_latch(pll);
 }
 
+static int alpha_pll_fabia_prepare(struct clk_hw *hw)
+{
+       struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
+       const struct pll_vco *vco;
+       struct clk_hw *parent_hw;
+       unsigned long cal_freq, rrate;
+       u32 cal_l, val, alpha_width = pll_alpha_width(pll);
+       u64 a;
+       int ret;
+
+       /* Check if calibration needs to be done i.e. PLL is in reset */
+       ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val);
+       if (ret)
+               return ret;
+
+       /* Return early if calibration is not needed. */
+       if (val & PLL_RESET_N)
+               return 0;
+
+       vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw));
+       if (!vco) {
+               pr_err("alpha pll: not in a valid vco range\n");
+               return -EINVAL;
+       }
+
+       cal_freq = DIV_ROUND_CLOSEST((pll->vco_table[0].min_freq +
+                               pll->vco_table[0].max_freq) * 54, 100);
+
+       parent_hw = clk_hw_get_parent(hw);
+       if (!parent_hw)
+               return -EINVAL;
+
+       rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw),
+                                       &cal_l, &a, alpha_width);
+       /*
+        * Due to a limited number of bits for fractional rate programming, the
+        * rounded up rate could be marginally higher than the requested rate.
+        */
+       if (rrate > (cal_freq + FABIA_PLL_RATE_MARGIN) || rrate < cal_freq)
+               return -EINVAL;
+
+       /* Setup PLL for calibration frequency */
+       regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l);
+
+       /* Bringup the PLL at calibration frequency */
+       ret = clk_alpha_pll_enable(hw);
+       if (ret) {
+               pr_err("alpha pll calibration failed\n");
+               return ret;
+       }
+
+       clk_alpha_pll_disable(hw);
+
+       return 0;
+}
+
 const struct clk_ops clk_alpha_pll_fabia_ops = {
+       .prepare = alpha_pll_fabia_prepare,
        .enable = alpha_pll_fabia_enable,
        .disable = alpha_pll_fabia_disable,
        .is_enabled = clk_alpha_pll_is_enabled,
index 15f27f4..fbc1f67 100644 (file)
@@ -94,6 +94,10 @@ struct alpha_pll_config {
        u32 alpha_hi;
        u32 config_ctl_val;
        u32 config_ctl_hi_val;
+       u32 user_ctl_val;
+       u32 user_ctl_hi_val;
+       u32 test_ctl_val;
+       u32 test_ctl_hi_val;
        u32 main_output_mask;
        u32 aux_output_mask;
        u32 aux2_output_mask;
@@ -109,6 +113,7 @@ struct alpha_pll_config {
 };
 
 extern const struct clk_ops clk_alpha_pll_ops;
+extern const struct clk_ops clk_alpha_pll_fixed_ops;
 extern const struct clk_ops clk_alpha_pll_hwfsm_ops;
 extern const struct clk_ops clk_alpha_pll_postdiv_ops;
 extern const struct clk_ops clk_alpha_pll_huayra_ops;
index 3c04805..e847d58 100644 (file)
@@ -196,7 +196,7 @@ static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw,
        return l_val * parent_rate;
 }
 
-static void clk_hfpll_init(struct clk_hw *hw)
+static int clk_hfpll_init(struct clk_hw *hw)
 {
        struct clk_hfpll *h = to_clk_hfpll(hw);
        struct hfpll_data const *hd = h->d;
@@ -206,7 +206,7 @@ static void clk_hfpll_init(struct clk_hw *hw)
        regmap_read(regmap, hd->mode_reg, &mode);
        if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) {
                __clk_hfpll_init_once(hw);
-               return;
+               return 0;
        }
 
        if (hd->status_reg) {
@@ -218,6 +218,8 @@ static void clk_hfpll_init(struct clk_hw *hw)
                        __clk_hfpll_init_once(hw);
                }
        }
+
+       return 0;
 }
 
 static int hfpll_is_enabled(struct clk_hw *hw)
index 78358b8..86d2b8b 100644 (file)
@@ -161,6 +161,7 @@ extern const struct clk_ops clk_byte2_ops;
 extern const struct clk_ops clk_pixel_ops;
 extern const struct clk_ops clk_gfx3d_ops;
 extern const struct clk_ops clk_rcg2_shared_ops;
+extern const struct clk_ops clk_dp_ops;
 
 struct clk_rcg_dfs_data {
        struct clk_rcg2 *rcg;
index 8f4b9be..357159f 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/export.h>
 #include <linux/clk-provider.h>
 #include <linux/delay.h>
+#include <linux/rational.h>
 #include <linux/regmap.h>
 #include <linux/math64.h>
 #include <linux/slab.h>
@@ -217,6 +218,9 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
 
        clk_flags = clk_hw_get_flags(hw);
        p = clk_hw_get_parent_by_index(hw, index);
+       if (!p)
+               return -EINVAL;
+
        if (clk_flags & CLK_SET_RATE_PARENT) {
                rate = f->freq;
                if (f->pre_div) {
@@ -952,7 +956,7 @@ static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l,
        struct clk_rcg2 *rcg = to_clk_rcg2(hw);
        struct clk_hw *p;
        unsigned long prate = 0;
-       u32 val, mask, cfg, mode;
+       u32 val, mask, cfg, mode, src;
        int i, num_parents;
 
        regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + SE_PERF_DFSR(l), &cfg);
@@ -962,12 +966,12 @@ static void clk_rcg2_dfs_populate_freq(struct clk_hw *hw, unsigned int l,
        if (cfg & mask)
                f->pre_div = cfg & mask;
 
-       cfg &= CFG_SRC_SEL_MASK;
-       cfg >>= CFG_SRC_SEL_SHIFT;
+       src = cfg & CFG_SRC_SEL_MASK;
+       src >>= CFG_SRC_SEL_SHIFT;
 
        num_parents = clk_hw_get_num_parents(hw);
        for (i = 0; i < num_parents; i++) {
-               if (cfg == rcg->parent_map[i].cfg) {
+               if (src == rcg->parent_map[i].cfg) {
                        f->src = rcg->parent_map[i].src;
                        p = clk_hw_get_parent_by_index(&rcg->clkr.hw, i);
                        prate = clk_hw_get_rate(p);
@@ -1124,3 +1128,79 @@ int qcom_cc_register_rcg_dfs(struct regmap *regmap,
        return 0;
 }
 EXPORT_SYMBOL_GPL(qcom_cc_register_rcg_dfs);
+
+static int clk_rcg2_dp_set_rate(struct clk_hw *hw, unsigned long rate,
+                       unsigned long parent_rate)
+{
+       struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+       struct freq_tbl f = { 0 };
+       u32 mask = BIT(rcg->hid_width) - 1;
+       u32 hid_div, cfg;
+       int i, num_parents = clk_hw_get_num_parents(hw);
+       unsigned long num, den;
+
+       rational_best_approximation(parent_rate, rate,
+                       GENMASK(rcg->mnd_width - 1, 0),
+                       GENMASK(rcg->mnd_width - 1, 0), &den, &num);
+
+       if (!num || !den)
+               return -EINVAL;
+
+       regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
+       hid_div = cfg;
+       cfg &= CFG_SRC_SEL_MASK;
+       cfg >>= CFG_SRC_SEL_SHIFT;
+
+       for (i = 0; i < num_parents; i++) {
+               if (cfg == rcg->parent_map[i].cfg) {
+                       f.src = rcg->parent_map[i].src;
+                       break;
+               }
+       }
+
+       f.pre_div = hid_div;
+       f.pre_div >>= CFG_SRC_DIV_SHIFT;
+       f.pre_div &= mask;
+
+       if (num != den) {
+               f.m = num;
+               f.n = den;
+       } else {
+               f.m = 0;
+               f.n = 0;
+       }
+
+       return clk_rcg2_configure(rcg, &f);
+}
+
+static int clk_rcg2_dp_set_rate_and_parent(struct clk_hw *hw,
+               unsigned long rate, unsigned long parent_rate, u8 index)
+{
+       return clk_rcg2_dp_set_rate(hw, rate, parent_rate);
+}
+
+static int clk_rcg2_dp_determine_rate(struct clk_hw *hw,
+                               struct clk_rate_request *req)
+{
+       struct clk_rate_request parent_req = *req;
+       int ret;
+
+       ret = __clk_determine_rate(clk_hw_get_parent(hw), &parent_req);
+       if (ret)
+               return ret;
+
+       req->best_parent_rate = parent_req.rate;
+
+       return 0;
+}
+
+const struct clk_ops clk_dp_ops = {
+       .is_enabled = clk_rcg2_is_enabled,
+       .get_parent = clk_rcg2_get_parent,
+       .set_parent = clk_rcg2_set_parent,
+       .recalc_rate = clk_rcg2_recalc_rate,
+       .set_rate = clk_rcg2_dp_set_rate,
+       .set_rate_and_parent = clk_rcg2_dp_set_rate_and_parent,
+       .determine_rate = clk_rcg2_dp_determine_rate,
+};
+EXPORT_SYMBOL_GPL(clk_dp_ops);
index 7ed313a..98a118c 100644 (file)
@@ -396,6 +396,7 @@ static struct clk_hw *sc7180_rpmh_clocks[] = {
        [RPMH_RF_CLK1_A]        = &sdm845_rf_clk1_ao.hw,
        [RPMH_RF_CLK2]          = &sdm845_rf_clk2.hw,
        [RPMH_RF_CLK2_A]        = &sdm845_rf_clk2_ao.hw,
+       [RPMH_IPA_CLK]          = &sdm845_ipa.hw,
 };
 
 static const struct clk_rpmh_desc clk_rpmh_sc7180 = {
@@ -431,11 +432,16 @@ static int clk_rpmh_probe(struct platform_device *pdev)
        hw_clks = desc->clks;
 
        for (i = 0; i < desc->num_clks; i++) {
-               const char *name = hw_clks[i]->init->name;
+               const char *name;
                u32 res_addr;
                size_t aux_data_len;
                const struct bcm_db *data;
 
+               if (!hw_clks[i])
+                       continue;
+
+               name = hw_clks[i]->init->name;
+
                rpmh_clk = to_clk_rpmh(hw_clks[i]);
                res_addr = cmd_db_read_addr(rpmh_clk->res_name);
                if (!res_addr) {
@@ -481,9 +487,9 @@ static int clk_rpmh_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id clk_rpmh_match_table[] = {
+       { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
        { .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
        { .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
-       { .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
        { }
 };
 MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
index 930fa4a..0bbfef9 100644 (file)
@@ -485,6 +485,8 @@ static struct clk_smd_rpm *msm8974_clks[] = {
        [RPM_SMD_MMSSNOC_AHB_CLK]       = &msm8974_mmssnoc_ahb_clk,
        [RPM_SMD_MMSSNOC_AHB_A_CLK]     = &msm8974_mmssnoc_ahb_a_clk,
        [RPM_SMD_BIMC_CLK]              = &msm8974_bimc_clk,
+       [RPM_SMD_GFX3D_CLK_SRC]         = &msm8974_gfx3d_clk_src,
+       [RPM_SMD_GFX3D_A_CLK_SRC]       = &msm8974_gfx3d_a_clk_src,
        [RPM_SMD_BIMC_A_CLK]            = &msm8974_bimc_a_clk,
        [RPM_SMD_OCMEMGX_CLK]           = &msm8974_ocmemgx_clk,
        [RPM_SMD_OCMEMGX_A_CLK]         = &msm8974_ocmemgx_a_clk,
@@ -648,6 +650,7 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = {
 };
 
 /* msm8998 */
+DEFINE_CLK_SMD_RPM(msm8998, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
 DEFINE_CLK_SMD_RPM(msm8998, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
 DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
 DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
@@ -671,6 +674,8 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5);
 DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6);
 DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6);
 static struct clk_smd_rpm *msm8998_clks[] = {
+       [RPM_SMD_BIMC_CLK] = &msm8998_bimc_clk,
+       [RPM_SMD_BIMC_A_CLK] = &msm8998_bimc_a_clk,
        [RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk,
        [RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk,
        [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk,
diff --git a/drivers/clk/qcom/dispcc-sc7180.c b/drivers/clk/qcom/dispcc-sc7180.c
new file mode 100644 (file)
index 0000000..dd7af41
--- /dev/null
@@ -0,0 +1,761 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,dispcc-sc7180.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap-divider.h"
+#include "common.h"
+#include "gdsc.h"
+
+enum {
+       P_BI_TCXO,
+       P_CHIP_SLEEP_CLK,
+       P_CORE_BI_PLL_TEST_SE,
+       P_DISP_CC_PLL0_OUT_EVEN,
+       P_DISP_CC_PLL0_OUT_MAIN,
+       P_DP_PHY_PLL_LINK_CLK,
+       P_DP_PHY_PLL_VCO_DIV_CLK,
+       P_DSI0_PHY_PLL_OUT_BYTECLK,
+       P_DSI0_PHY_PLL_OUT_DSICLK,
+       P_GPLL0_OUT_MAIN,
+};
+
+static const struct pll_vco fabia_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+static struct clk_alpha_pll disp_cc_pll0 = {
+       .offset = 0x0,
+       .vco_table = fabia_vco,
+       .num_vco = ARRAY_SIZE(fabia_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_pll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fabia_ops,
+               },
+       },
+};
+
+static const struct clk_div_table post_div_table_disp_cc_pll0_out_even[] = {
+       { 0x0, 1 },
+       { }
+};
+
+static struct clk_alpha_pll_postdiv disp_cc_pll0_out_even = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_disp_cc_pll0_out_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_disp_cc_pll0_out_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_pll0_out_even",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &disp_cc_pll0.clkr.hw,
+               },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static const struct parent_map disp_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_0[] = {
+       { .fw_name = "bi_tcxo" },
+};
+
+static const struct parent_map disp_cc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_DP_PHY_PLL_LINK_CLK, 1 },
+       { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_1[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "dp_phy_pll_link_clk" },
+       { .fw_name = "dp_phy_pll_vco_div_clk" },
+};
+
+static const struct parent_map disp_cc_parent_map_2[] = {
+       { P_BI_TCXO, 0 },
+       { P_DSI0_PHY_PLL_OUT_BYTECLK, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_2[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "dsi0_phy_pll_out_byteclk" },
+};
+
+static const struct parent_map disp_cc_parent_map_3[] = {
+       { P_BI_TCXO, 0 },
+       { P_DISP_CC_PLL0_OUT_MAIN, 1 },
+       { P_GPLL0_OUT_MAIN, 4 },
+       { P_DISP_CC_PLL0_OUT_EVEN, 5 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_3[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &disp_cc_pll0.clkr.hw },
+       { .fw_name = "gcc_disp_gpll0_clk_src" },
+       { .hw = &disp_cc_pll0_out_even.clkr.hw },
+};
+
+static const struct parent_map disp_cc_parent_map_4[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPLL0_OUT_MAIN, 4 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_4[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "gcc_disp_gpll0_clk_src" },
+};
+
+static const struct parent_map disp_cc_parent_map_5[] = {
+       { P_BI_TCXO, 0 },
+       { P_DSI0_PHY_PLL_OUT_DSICLK, 1 },
+};
+
+static const struct clk_parent_data disp_cc_parent_data_5[] = {
+       { .fw_name = "bi_tcxo" },
+       { .fw_name = "dsi0_phy_pll_out_dsiclk" },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_ahb_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(37500000, P_GPLL0_OUT_MAIN, 16, 0, 0),
+       F(75000000, P_GPLL0_OUT_MAIN, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_ahb_clk_src = {
+       .cmd_rcgr = 0x22bc,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_4,
+       .freq_tbl = ftbl_disp_cc_mdss_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_ahb_clk_src",
+               .parent_data = disp_cc_parent_data_4,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_4),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_byte0_clk_src = {
+       .cmd_rcgr = 0x2110,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_byte0_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
+       .cmd_rcgr = 0x21dc,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_aux_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
+       .cmd_rcgr = 0x2194,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_crypto_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
+       .cmd_rcgr = 0x2178,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_link_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
+       .cmd_rcgr = 0x21ac,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_pixel_clk_src",
+               .parent_data = disp_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_esc0_clk_src = {
+       .cmd_rcgr = 0x2148,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_esc0_clk_src",
+               .parent_data = disp_cc_parent_data_2,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_2),
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_disp_cc_mdss_mdp_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN, 3, 0, 0),
+       F(300000000, P_GPLL0_OUT_MAIN, 2, 0, 0),
+       F(345000000, P_DISP_CC_PLL0_OUT_MAIN, 4, 0, 0),
+       F(460000000, P_DISP_CC_PLL0_OUT_MAIN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_mdp_clk_src = {
+       .cmd_rcgr = 0x20c8,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_mdp_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_pclk0_clk_src = {
+       .cmd_rcgr = 0x2098,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_5,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_pclk0_clk_src",
+               .parent_data = disp_cc_parent_data_5,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_5),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_pixel_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_rot_clk_src = {
+       .cmd_rcgr = 0x20e0,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_3,
+       .freq_tbl = ftbl_disp_cc_mdss_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_rot_clk_src",
+               .parent_data = disp_cc_parent_data_3,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_3),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_vsync_clk_src = {
+       .cmd_rcgr = 0x20f8,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_0,
+       .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_vsync_clk_src",
+               .parent_data = disp_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(disp_cc_parent_data_0),
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_branch disp_cc_mdss_ahb_clk = {
+       .halt_reg = 0x2080,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte0_clk = {
+       .halt_reg = 0x2028,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_byte0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_byte0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_byte0_div_clk_src = {
+       .reg = 0x2128,
+       .shift = 0,
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_byte0_div_clk_src",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &disp_cc_mdss_byte0_clk_src.clkr.hw
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ops,
+       },
+};
+
+static struct clk_regmap_div disp_cc_mdss_dp_link_div_clk_src = {
+       .reg = 0x2190,
+       .shift = 0,
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data) {
+               .name = "disp_cc_mdss_dp_link_div_clk_src",
+               .parent_data = &(const struct clk_parent_data){
+                       .hw = &disp_cc_mdss_dp_link_clk_src.clkr.hw
+               },
+               .num_parents = 1,
+               .ops = &clk_regmap_div_ops,
+       },
+};
+
+static struct clk_branch disp_cc_mdss_byte0_intf_clk = {
+       .halt_reg = 0x202c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x202c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_byte0_intf_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_byte0_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_aux_clk = {
+       .halt_reg = 0x2054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_aux_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_dp_aux_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
+       .halt_reg = 0x2048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_crypto_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_dp_crypto_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_link_clk = {
+       .halt_reg = 0x2040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_link_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_dp_link_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
+       .halt_reg = 0x2044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_link_intf_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_dp_link_div_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
+       .halt_reg = 0x204c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x204c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_pixel_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_dp_pixel_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_esc0_clk = {
+       .halt_reg = 0x2038,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_esc0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_esc0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_clk = {
+       .halt_reg = 0x200c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x200c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_mdp_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_mdp_lut_clk = {
+       .halt_reg = 0x201c,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x201c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_mdp_lut_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_mdp_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_non_gdsc_ahb_clk = {
+       .halt_reg = 0x4004,
+       .halt_check = BRANCH_VOTED,
+       .clkr = {
+               .enable_reg = 0x4004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_non_gdsc_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_pclk0_clk = {
+       .halt_reg = 0x2004,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_pclk0_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_pclk0_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rot_clk = {
+       .halt_reg = 0x2014,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_rot_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_rot_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rscc_ahb_clk = {
+       .halt_reg = 0x400c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_rscc_ahb_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_ahb_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_rscc_vsync_clk = {
+       .halt_reg = 0x4008,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x4008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_rscc_vsync_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_vsync_clk = {
+       .halt_reg = 0x2024,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_vsync_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &disp_cc_mdss_vsync_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x3000,
+       .pd = {
+               .name = "mdss_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL,
+};
+
+static struct gdsc *disp_cc_sc7180_gdscs[] = {
+       [MDSS_GDSC] = &mdss_gdsc,
+};
+
+static struct clk_regmap *disp_cc_sc7180_clocks[] = {
+       [DISP_CC_MDSS_AHB_CLK] = &disp_cc_mdss_ahb_clk.clkr,
+       [DISP_CC_MDSS_AHB_CLK_SRC] = &disp_cc_mdss_ahb_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_CLK] = &disp_cc_mdss_byte0_clk.clkr,
+       [DISP_CC_MDSS_BYTE0_CLK_SRC] = &disp_cc_mdss_byte0_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_DIV_CLK_SRC] = &disp_cc_mdss_byte0_div_clk_src.clkr,
+       [DISP_CC_MDSS_BYTE0_INTF_CLK] = &disp_cc_mdss_byte0_intf_clk.clkr,
+       [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
+       [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
+       [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
+       [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] = &disp_cc_mdss_dp_crypto_clk_src.clkr,
+       [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
+       [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
+       [DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC] =
+                               &disp_cc_mdss_dp_link_div_clk_src.clkr,
+       [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
+       [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
+       [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
+       [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
+       [DISP_CC_MDSS_MDP_CLK] = &disp_cc_mdss_mdp_clk.clkr,
+       [DISP_CC_MDSS_MDP_CLK_SRC] = &disp_cc_mdss_mdp_clk_src.clkr,
+       [DISP_CC_MDSS_MDP_LUT_CLK] = &disp_cc_mdss_mdp_lut_clk.clkr,
+       [DISP_CC_MDSS_NON_GDSC_AHB_CLK] = &disp_cc_mdss_non_gdsc_ahb_clk.clkr,
+       [DISP_CC_MDSS_PCLK0_CLK] = &disp_cc_mdss_pclk0_clk.clkr,
+       [DISP_CC_MDSS_PCLK0_CLK_SRC] = &disp_cc_mdss_pclk0_clk_src.clkr,
+       [DISP_CC_MDSS_ROT_CLK] = &disp_cc_mdss_rot_clk.clkr,
+       [DISP_CC_MDSS_ROT_CLK_SRC] = &disp_cc_mdss_rot_clk_src.clkr,
+       [DISP_CC_MDSS_RSCC_AHB_CLK] = &disp_cc_mdss_rscc_ahb_clk.clkr,
+       [DISP_CC_MDSS_RSCC_VSYNC_CLK] = &disp_cc_mdss_rscc_vsync_clk.clkr,
+       [DISP_CC_MDSS_VSYNC_CLK] = &disp_cc_mdss_vsync_clk.clkr,
+       [DISP_CC_MDSS_VSYNC_CLK_SRC] = &disp_cc_mdss_vsync_clk_src.clkr,
+       [DISP_CC_PLL0] = &disp_cc_pll0.clkr,
+       [DISP_CC_PLL0_OUT_EVEN] = &disp_cc_pll0_out_even.clkr,
+};
+
+static const struct regmap_config disp_cc_sc7180_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0x10000,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc disp_cc_sc7180_desc = {
+       .config = &disp_cc_sc7180_regmap_config,
+       .clks = disp_cc_sc7180_clocks,
+       .num_clks = ARRAY_SIZE(disp_cc_sc7180_clocks),
+       .gdscs = disp_cc_sc7180_gdscs,
+       .num_gdscs = ARRAY_SIZE(disp_cc_sc7180_gdscs),
+};
+
+static const struct of_device_id disp_cc_sc7180_match_table[] = {
+       { .compatible = "qcom,sc7180-dispcc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, disp_cc_sc7180_match_table);
+
+static int disp_cc_sc7180_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       struct alpha_pll_config disp_cc_pll_config = {};
+
+       regmap = qcom_cc_map(pdev, &disp_cc_sc7180_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /* 1380MHz configuration */
+       disp_cc_pll_config.l = 0x47;
+       disp_cc_pll_config.alpha = 0xe000;
+       disp_cc_pll_config.user_ctl_val = 0x00000001;
+       disp_cc_pll_config.user_ctl_hi_val = 0x00004805;
+
+       clk_fabia_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll_config);
+
+       return qcom_cc_really_probe(pdev, &disp_cc_sc7180_desc, regmap);
+}
+
+static struct platform_driver disp_cc_sc7180_driver = {
+       .probe = disp_cc_sc7180_probe,
+       .driver = {
+               .name = "sc7180-dispcc",
+               .of_match_table = disp_cc_sc7180_match_table,
+       },
+};
+
+static int __init disp_cc_sc7180_init(void)
+{
+       return platform_driver_register(&disp_cc_sc7180_driver);
+}
+subsys_initcall(disp_cc_sc7180_init);
+
+static void __exit disp_cc_sc7180_exit(void)
+{
+       platform_driver_unregister(&disp_cc_sc7180_driver);
+}
+module_exit(disp_cc_sc7180_exit);
+
+MODULE_DESCRIPTION("QTI DISP_CC SC7180 Driver");
+MODULE_LICENSE("GPL v2");
index 0cc4909..5c932cd 100644 (file)
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
  */
 
 #include <linux/clk-provider.h>
@@ -29,6 +29,8 @@ enum {
        P_DSI1_PHY_PLL_OUT_DSICLK,
        P_GPLL0_OUT_MAIN,
        P_GPLL0_OUT_MAIN_DIV,
+       P_DP_PHY_PLL_LINK_CLK,
+       P_DP_PHY_PLL_VCO_DIV_CLK,
 };
 
 static const struct parent_map disp_cc_parent_map_0[] = {
@@ -45,6 +47,20 @@ static const char * const disp_cc_parent_names_0[] = {
        "core_bi_pll_test_se",
 };
 
+static const struct parent_map disp_cc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_DP_PHY_PLL_LINK_CLK, 1 },
+       { P_DP_PHY_PLL_VCO_DIV_CLK, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 },
+};
+
+static const char * const disp_cc_parent_names_1[] = {
+       "bi_tcxo",
+       "dp_link_clk_divsel_ten",
+       "dp_vco_divided_clk_src_mux",
+       "core_bi_pll_test_se",
+};
+
 static const struct parent_map disp_cc_parent_map_2[] = {
        { P_BI_TCXO, 0 },
        { P_CORE_BI_PLL_TEST_SE, 7 },
@@ -128,6 +144,81 @@ static struct clk_rcg2 disp_cc_mdss_byte1_clk_src = {
        },
 };
 
+static const struct freq_tbl ftbl_disp_cc_mdss_dp_aux_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_aux_clk_src = {
+       .cmd_rcgr = 0x219c,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_2,
+       .freq_tbl = ftbl_disp_cc_mdss_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_aux_clk_src",
+               .parent_names = disp_cc_parent_names_2,
+               .num_parents = 2,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
+       .cmd_rcgr = 0x2154,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_crypto_clk_src",
+               .parent_names = disp_cc_parent_names_1,
+               .num_parents = 4,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
+       .cmd_rcgr = 0x2138,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_link_clk_src",
+               .parent_names = disp_cc_parent_names_1,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_byte2_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_pixel1_clk_src = {
+       .cmd_rcgr = 0x2184,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_pixel1_clk_src",
+               .parent_names = disp_cc_parent_names_1,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
+static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
+       .cmd_rcgr = 0x216c,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = disp_cc_parent_map_1,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "disp_cc_mdss_dp_pixel_clk_src",
+               .parent_names = disp_cc_parent_names_1,
+               .num_parents = 4,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_dp_ops,
+       },
+};
+
 static const struct freq_tbl ftbl_disp_cc_mdss_esc0_clk_src[] = {
        F(19200000, P_BI_TCXO, 1, 0, 0),
        { }
@@ -391,6 +482,114 @@ static struct clk_branch disp_cc_mdss_byte1_intf_clk = {
        },
 };
 
+static struct clk_branch disp_cc_mdss_dp_aux_clk = {
+       .halt_reg = 0x2054,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_aux_clk",
+                       .parent_names = (const char *[]){
+                               "disp_cc_mdss_dp_aux_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_crypto_clk = {
+       .halt_reg = 0x2048,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_crypto_clk",
+                       .parent_names = (const char *[]){
+                               "disp_cc_mdss_dp_crypto_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_link_clk = {
+       .halt_reg = 0x2040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_link_clk",
+                       .parent_names = (const char *[]){
+                               "disp_cc_mdss_dp_link_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+/* reset state of disp_cc_mdss_dp_link_div_clk_src divider is 0x3 (div 4) */
+static struct clk_branch disp_cc_mdss_dp_link_intf_clk = {
+       .halt_reg = 0x2044,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_link_intf_clk",
+                       .parent_names = (const char *[]){
+                               "disp_cc_mdss_dp_link_clk_src",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_pixel1_clk = {
+       .halt_reg = 0x2050,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x2050,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_pixel1_clk",
+                       .parent_names = (const char *[]){
+                               "disp_cc_mdss_dp_pixel1_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch disp_cc_mdss_dp_pixel_clk = {
+       .halt_reg = 0x204c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x204c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "disp_cc_mdss_dp_pixel_clk",
+                       .parent_names = (const char *[]){
+                               "disp_cc_mdss_dp_pixel_clk_src",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch disp_cc_mdss_esc0_clk = {
        .halt_reg = 0x2038,
        .halt_check = BRANCH_HALT,
@@ -589,6 +788,19 @@ static struct clk_regmap *disp_cc_sdm845_clocks[] = {
        [DISP_CC_MDSS_BYTE1_INTF_CLK] = &disp_cc_mdss_byte1_intf_clk.clkr,
        [DISP_CC_MDSS_BYTE1_DIV_CLK_SRC] =
                                        &disp_cc_mdss_byte1_div_clk_src.clkr,
+       [DISP_CC_MDSS_DP_AUX_CLK] = &disp_cc_mdss_dp_aux_clk.clkr,
+       [DISP_CC_MDSS_DP_AUX_CLK_SRC] = &disp_cc_mdss_dp_aux_clk_src.clkr,
+       [DISP_CC_MDSS_DP_CRYPTO_CLK] = &disp_cc_mdss_dp_crypto_clk.clkr,
+       [DISP_CC_MDSS_DP_CRYPTO_CLK_SRC] =
+                                       &disp_cc_mdss_dp_crypto_clk_src.clkr,
+       [DISP_CC_MDSS_DP_LINK_CLK] = &disp_cc_mdss_dp_link_clk.clkr,
+       [DISP_CC_MDSS_DP_LINK_CLK_SRC] = &disp_cc_mdss_dp_link_clk_src.clkr,
+       [DISP_CC_MDSS_DP_LINK_INTF_CLK] = &disp_cc_mdss_dp_link_intf_clk.clkr,
+       [DISP_CC_MDSS_DP_PIXEL1_CLK] = &disp_cc_mdss_dp_pixel1_clk.clkr,
+       [DISP_CC_MDSS_DP_PIXEL1_CLK_SRC] =
+                                       &disp_cc_mdss_dp_pixel1_clk_src.clkr,
+       [DISP_CC_MDSS_DP_PIXEL_CLK] = &disp_cc_mdss_dp_pixel_clk.clkr,
+       [DISP_CC_MDSS_DP_PIXEL_CLK_SRC] = &disp_cc_mdss_dp_pixel_clk_src.clkr,
        [DISP_CC_MDSS_ESC0_CLK] = &disp_cc_mdss_esc0_clk.clkr,
        [DISP_CC_MDSS_ESC0_CLK_SRC] = &disp_cc_mdss_esc0_clk_src.clkr,
        [DISP_CC_MDSS_ESC1_CLK] = &disp_cc_mdss_esc1_clk.clkr,
diff --git a/drivers/clk/qcom/gcc-ipq6018.c b/drivers/clk/qcom/gcc-ipq6018.c
new file mode 100644 (file)
index 0000000..3f9c2f6
--- /dev/null
@@ -0,0 +1,4635 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+
+#include <linux/reset-controller.h>
+#include <dt-bindings/clock/qcom,gcc-ipq6018.h>
+#include <dt-bindings/reset/qcom,gcc-ipq6018.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "clk-alpha-pll.h"
+#include "clk-regmap-divider.h"
+#include "clk-regmap-mux.h"
+#include "reset.h"
+
+#define F(f, s, h, m, n) { (f), (s), (2 * (h) - 1), (m), (n) }
+
+enum {
+       P_XO,
+       P_BIAS_PLL,
+       P_UNIPHY0_RX,
+       P_UNIPHY0_TX,
+       P_UNIPHY1_RX,
+       P_BIAS_PLL_NSS_NOC,
+       P_UNIPHY1_TX,
+       P_PCIE20_PHY0_PIPE,
+       P_USB3PHY_0_PIPE,
+       P_GPLL0,
+       P_GPLL0_DIV2,
+       P_GPLL2,
+       P_GPLL4,
+       P_GPLL6,
+       P_SLEEP_CLK,
+       P_UBI32_PLL,
+       P_NSS_CRYPTO_PLL,
+       P_PI_SLEEP,
+};
+
+static struct clk_alpha_pll gpll0_main = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll0_main",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_fixed_factor gpll0_out_main_div2 = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll0_out_main_div2",
+               .parent_hws = (const struct clk_hw *[]){
+                               &gpll0_main.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll0 = {
+       .offset = 0x21000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll0",
+               .parent_hws = (const struct clk_hw *[]){
+                               &gpll0_main.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll0_out_main_div2[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw},
+       { .hw = &gpll0_out_main_div2.hw},
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_alpha_pll ubi32_pll_main = {
+       .offset = 0x25000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA],
+       .flags = SUPPORTS_DYNAMIC_UPDATE,
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(6),
+               .hw.init = &(struct clk_init_data){
+                       .name = "ubi32_pll_main",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_huayra_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv ubi32_pll = {
+       .offset = 0x25000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_HUAYRA],
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ubi32_pll",
+               .parent_hws = (const struct clk_hw *[]){
+                               &ubi32_pll_main.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll gpll6_main = {
+       .offset = 0x37000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO],
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(7),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll6_main",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll6 = {
+       .offset = 0x37000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_BRAMMO],
+       .width = 2,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll6",
+               .parent_hws = (const struct clk_hw *[]){
+                               &gpll6_main.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll gpll4_main = {
+       .offset = 0x24000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(5),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll4_main",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll4 = {
+       .offset = 0x24000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll4",
+               .parent_hws = (const struct clk_hw *[]){
+                               &gpll4_main.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_pcnoc_bfdcd_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 pcnoc_bfdcd_clk_src = {
+       .cmd_rcgr = 0x27000,
+       .freq_tbl = ftbl_pcnoc_bfdcd_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcnoc_bfdcd_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_alpha_pll gpll2_main = {
+       .offset = 0x4a000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpll2_main",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv gpll2 = {
+       .offset = 0x4a000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpll2",
+               .parent_hws = (const struct clk_hw *[]){
+                               &gpll2_main.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_alpha_pll nss_crypto_pll_main = {
+       .offset = 0x22000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .clkr = {
+               .enable_reg = 0x0b000,
+               .enable_mask = BIT(4),
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_crypto_pll_main",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv nss_crypto_pll = {
+       .offset = 0x22000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
+       .width = 4,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_crypto_pll",
+               .parent_hws = (const struct clk_hw *[]){
+                               &nss_crypto_pll_main.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_ro_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_qdss_tsctr_clk_src[] = {
+       F(160000000, P_GPLL0_DIV2, 2.5, 0, 0),
+       F(320000000, P_GPLL0, 2.5, 0, 0),
+       F(600000000, P_GPLL4, 2, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_gpll4_gpll0_gpll6_gpll0_div2[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_out_main_div2.hw },
+};
+
+static const struct parent_map gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL4, 1 },
+       { P_GPLL0, 2 },
+       { P_GPLL6, 3 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_rcg2 qdss_tsctr_clk_src = {
+       .cmd_rcgr = 0x29064,
+       .freq_tbl = ftbl_qdss_tsctr_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "qdss_tsctr_clk_src",
+               .parent_data = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_fixed_factor qdss_dap_sync_clk_src = {
+       .mult = 1,
+       .div = 4,
+       .hw.init = &(struct clk_init_data){
+               .name = "qdss_dap_sync_clk_src",
+               .parent_hws = (const struct clk_hw *[]){
+                               &qdss_tsctr_clk_src.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_qdss_at_clk_src[] = {
+       F(66670000, P_GPLL0_DIV2, 6, 0, 0),
+       F(240000000, P_GPLL4, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 qdss_at_clk_src = {
+       .cmd_rcgr = 0x2900c,
+       .freq_tbl = ftbl_qdss_at_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "qdss_at_clk_src",
+               .parent_data = gcc_xo_gpll4_gpll0_gpll6_gpll0_div2,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_fixed_factor qdss_tsctr_div2_clk_src = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "qdss_tsctr_div2_clk_src",
+               .parent_hws = (const struct clk_hw *[]){
+                               &qdss_tsctr_clk_src.clkr.hw },
+               .num_parents = 1,
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_nss_ppe_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(300000000, P_BIAS_PLL, 1, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_bias_gpll0_gpll4_nss_ubi32[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "bias_pll_cc_clk" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &nss_crypto_pll.clkr.hw },
+       { .hw = &ubi32_pll.clkr.hw },
+};
+
+static const struct parent_map gcc_xo_bias_gpll0_gpll4_nss_ubi32_map[] = {
+       { P_XO, 0 },
+       { P_BIAS_PLL, 1 },
+       { P_GPLL0, 2 },
+       { P_GPLL4, 3 },
+       { P_NSS_CRYPTO_PLL, 4 },
+       { P_UBI32_PLL, 5 },
+};
+
+static struct clk_rcg2 nss_ppe_clk_src = {
+       .cmd_rcgr = 0x68080,
+       .freq_tbl = ftbl_nss_ppe_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_bias_gpll0_gpll4_nss_ubi32_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_ppe_clk_src",
+               .parent_data = gcc_xo_bias_gpll0_gpll4_nss_ubi32,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_xo_clk_src = {
+       .halt_reg = 0x30018,
+       .clkr = {
+               .enable_reg = 0x30018,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_xo_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_nss_ce_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_gpll0[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+};
+
+static struct clk_rcg2 nss_ce_clk_src = {
+       .cmd_rcgr = 0x68098,
+       .freq_tbl = ftbl_nss_ce_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_ce_clk_src",
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_sleep_clk_src = {
+       .halt_reg = 0x30000,
+       .clkr = {
+               .enable_reg = 0x30000,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sleep_clk_src",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "sleep_clk",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_snoc_nssnoc_bfdcd_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_DIV2, 8, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(133333333, P_GPLL0, 6, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266666667, P_GPLL0, 3, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data
+                       gcc_xo_gpll0_gpll6_gpll0_out_main_div2[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_out_main_div2.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL0_DIV2, 3 },
+};
+
+static struct clk_rcg2 snoc_nssnoc_bfdcd_clk_src = {
+       .cmd_rcgr = 0x76054,
+       .freq_tbl = ftbl_snoc_nssnoc_bfdcd_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "snoc_nssnoc_bfdcd_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll6_gpll0_out_main_div2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_apss_ahb_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_DIV2, 16, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 apss_ahb_clk_src = {
+       .cmd_rcgr = 0x46000,
+       .freq_tbl = ftbl_apss_ahb_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "apss_ahb_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_nss_port5_rx_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(25000000, P_UNIPHY1_RX, 12.5, 0, 0),
+       F(25000000, P_UNIPHY0_RX, 5, 0, 0),
+       F(78125000, P_UNIPHY1_RX, 4, 0, 0),
+       F(125000000, P_UNIPHY1_RX, 2.5, 0, 0),
+       F(125000000, P_UNIPHY0_RX, 1, 0, 0),
+       F(156250000, P_UNIPHY1_RX, 2, 0, 0),
+       F(312500000, P_UNIPHY1_RX, 1, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data
+gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "uniphy0_gcc_rx_clk" },
+       { .fw_name = "uniphy0_gcc_tx_clk" },
+       { .fw_name = "uniphy1_gcc_rx_clk" },
+       { .fw_name = "uniphy1_gcc_tx_clk" },
+       { .hw = &ubi32_pll.clkr.hw },
+       { .fw_name = "bias_pll_cc_clk" },
+};
+
+static const struct parent_map
+gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map[] = {
+       { P_XO, 0 },
+       { P_UNIPHY0_RX, 1 },
+       { P_UNIPHY0_TX, 2 },
+       { P_UNIPHY1_RX, 3 },
+       { P_UNIPHY1_TX, 4 },
+       { P_UBI32_PLL, 5 },
+       { P_BIAS_PLL, 6 },
+};
+
+static struct clk_rcg2 nss_port5_rx_clk_src = {
+       .cmd_rcgr = 0x68060,
+       .freq_tbl = ftbl_nss_port5_rx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port5_rx_clk_src",
+               .parent_data = gcc_xo_uniphy0_rx_tx_uniphy1_rx_tx_ubi32_bias,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_nss_port5_tx_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(25000000, P_UNIPHY1_TX, 12.5, 0, 0),
+       F(25000000, P_UNIPHY0_TX, 5, 0, 0),
+       F(78125000, P_UNIPHY1_TX, 4, 0, 0),
+       F(125000000, P_UNIPHY1_TX, 2.5, 0, 0),
+       F(125000000, P_UNIPHY0_TX, 1, 0, 0),
+       F(156250000, P_UNIPHY1_TX, 2, 0, 0),
+       F(312500000, P_UNIPHY1_TX, 1, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data
+gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "uniphy0_gcc_tx_clk" },
+       { .fw_name = "uniphy0_gcc_rx_clk" },
+       { .fw_name = "uniphy1_gcc_tx_clk" },
+       { .fw_name = "uniphy1_gcc_rx_clk" },
+       { .hw = &ubi32_pll.clkr.hw },
+       { .fw_name = "bias_pll_cc_clk" },
+};
+
+static const struct parent_map
+gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map[] = {
+       { P_XO, 0 },
+       { P_UNIPHY0_TX, 1 },
+       { P_UNIPHY0_RX, 2 },
+       { P_UNIPHY1_TX, 3 },
+       { P_UNIPHY1_RX, 4 },
+       { P_UBI32_PLL, 5 },
+       { P_BIAS_PLL, 6 },
+};
+
+static struct clk_rcg2 nss_port5_tx_clk_src = {
+       .cmd_rcgr = 0x68068,
+       .freq_tbl = ftbl_nss_port5_tx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port5_tx_clk_src",
+               .parent_data = gcc_xo_uniphy0_tx_rx_uniphy1_tx_rx_ubi32_bias,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_pcie_axi_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(240000000, P_GPLL4, 5, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll4[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL4, 2 },
+};
+
+static struct clk_rcg2 pcie0_axi_clk_src = {
+       .cmd_rcgr = 0x75054,
+       .freq_tbl = ftbl_pcie_axi_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll4_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcie0_axi_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll4,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb0_master_clk_src[] = {
+       F(80000000, P_GPLL0_DIV2, 5, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(133330000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_out_main_div2_gpll0[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0_out_main_div2.hw },
+       { .hw = &gpll0.clkr.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_out_main_div2_gpll0_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0_DIV2, 2 },
+       { P_GPLL0, 1 },
+};
+
+static struct clk_rcg2 usb0_master_clk_src = {
+       .cmd_rcgr = 0x3e00c,
+       .freq_tbl = ftbl_usb0_master_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_out_main_div2_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb0_master_clk_src",
+               .parent_data = gcc_xo_gpll0_out_main_div2_gpll0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_regmap_div apss_ahb_postdiv_clk_src = {
+       .reg = 0x46018,
+       .shift = 4,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "apss_ahb_postdiv_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &apss_ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+               },
+       },
+};
+
+static struct clk_fixed_factor gcc_xo_div4_clk_src = {
+       .mult = 1,
+       .div = 4,
+       .hw.init = &(struct clk_init_data){
+               .name = "gcc_xo_div4_clk_src",
+               .parent_hws = (const struct clk_hw *[]){
+                               &gcc_xo_clk_src.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_nss_port1_rx_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(25000000, P_UNIPHY0_RX, 5, 0, 0),
+       F(125000000, P_UNIPHY0_RX, 1, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_uniphy0_rx_tx_ubi32_bias[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "uniphy0_gcc_rx_clk" },
+       { .fw_name = "uniphy0_gcc_tx_clk" },
+       { .hw = &ubi32_pll.clkr.hw },
+       { .fw_name = "bias_pll_cc_clk" },
+};
+
+static const struct parent_map gcc_xo_uniphy0_rx_tx_ubi32_bias_map[] = {
+       { P_XO, 0 },
+       { P_UNIPHY0_RX, 1 },
+       { P_UNIPHY0_TX, 2 },
+       { P_UBI32_PLL, 5 },
+       { P_BIAS_PLL, 6 },
+};
+
+static struct clk_rcg2 nss_port1_rx_clk_src = {
+       .cmd_rcgr = 0x68020,
+       .freq_tbl = ftbl_nss_port1_rx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port1_rx_clk_src",
+               .parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_nss_port1_tx_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(25000000, P_UNIPHY0_TX, 5, 0, 0),
+       F(125000000, P_UNIPHY0_TX, 1, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_uniphy0_tx_rx_ubi32_bias[] = {
+       { .fw_name = "xo" },
+       { .fw_name = "uniphy0_gcc_tx_clk" },
+       { .fw_name = "uniphy0_gcc_rx_clk" },
+       { .hw = &ubi32_pll.clkr.hw },
+       { .fw_name = "bias_pll_cc_clk" },
+};
+
+static const struct parent_map gcc_xo_uniphy0_tx_rx_ubi32_bias_map[] = {
+       { P_XO, 0 },
+       { P_UNIPHY0_TX, 1 },
+       { P_UNIPHY0_RX, 2 },
+       { P_UBI32_PLL, 5 },
+       { P_BIAS_PLL, 6 },
+};
+
+static struct clk_rcg2 nss_port1_tx_clk_src = {
+       .cmd_rcgr = 0x68028,
+       .freq_tbl = ftbl_nss_port1_tx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port1_tx_clk_src",
+               .parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 nss_port2_rx_clk_src = {
+       .cmd_rcgr = 0x68030,
+       .freq_tbl = ftbl_nss_port1_rx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port2_rx_clk_src",
+               .parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 nss_port2_tx_clk_src = {
+       .cmd_rcgr = 0x68038,
+       .freq_tbl = ftbl_nss_port1_tx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port2_tx_clk_src",
+               .parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 nss_port3_rx_clk_src = {
+       .cmd_rcgr = 0x68040,
+       .freq_tbl = ftbl_nss_port1_rx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port3_rx_clk_src",
+               .parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 nss_port3_tx_clk_src = {
+       .cmd_rcgr = 0x68048,
+       .freq_tbl = ftbl_nss_port1_tx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port3_tx_clk_src",
+               .parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 nss_port4_rx_clk_src = {
+       .cmd_rcgr = 0x68050,
+       .freq_tbl = ftbl_nss_port1_rx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_rx_tx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port4_rx_clk_src",
+               .parent_data = gcc_xo_uniphy0_rx_tx_ubi32_bias,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 nss_port4_tx_clk_src = {
+       .cmd_rcgr = 0x68058,
+       .freq_tbl = ftbl_nss_port1_tx_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_uniphy0_tx_rx_ubi32_bias_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_port4_tx_clk_src",
+               .parent_data = gcc_xo_uniphy0_tx_rx_ubi32_bias,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_regmap_div nss_port5_rx_div_clk_src = {
+       .reg = 0x68440,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port5_rx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port5_rx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div nss_port5_tx_div_clk_src = {
+       .reg = 0x68444,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port5_tx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port5_tx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_apss_axi_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(100000000, P_GPLL0_DIV2, 4, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(308570000, P_GPLL6, 3.5, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       F(533000000, P_GPLL0, 1.5, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll6_ubi32_gpll0_div2[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &ubi32_pll.clkr.hw },
+       { .hw = &gpll0_out_main_div2.hw },
+};
+
+static const struct parent_map
+gcc_xo_gpll0_gpll6_ubi32_gpll0_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_UBI32_PLL, 3 },
+       { P_GPLL0_DIV2, 6 },
+};
+
+static struct clk_rcg2 apss_axi_clk_src = {
+       .cmd_rcgr = 0x38048,
+       .freq_tbl = ftbl_apss_axi_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll6_ubi32_gpll0_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "apss_axi_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll6_ubi32_gpll0_div2,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_nss_crypto_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(300000000, P_NSS_CRYPTO_PLL, 2, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_nss_crypto_pll_gpll0[] = {
+       { .fw_name = "xo" },
+       { .hw = &nss_crypto_pll.clkr.hw },
+       { .hw = &gpll0.clkr.hw },
+};
+
+static const struct parent_map gcc_xo_nss_crypto_pll_gpll0_map[] = {
+       { P_XO, 0 },
+       { P_NSS_CRYPTO_PLL, 1 },
+       { P_GPLL0, 2 },
+};
+
+static struct clk_rcg2 nss_crypto_clk_src = {
+       .cmd_rcgr = 0x68144,
+       .freq_tbl = ftbl_nss_crypto_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_nss_crypto_pll_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_crypto_clk_src",
+               .parent_data = gcc_xo_nss_crypto_pll_gpll0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_regmap_div nss_port1_rx_div_clk_src = {
+       .reg = 0x68400,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port1_rx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &nss_port1_rx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div nss_port1_tx_div_clk_src = {
+       .reg = 0x68404,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port1_tx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port1_tx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div nss_port2_rx_div_clk_src = {
+       .reg = 0x68410,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port2_rx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port2_rx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div nss_port2_tx_div_clk_src = {
+       .reg = 0x68414,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port2_tx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port2_tx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div nss_port3_rx_div_clk_src = {
+       .reg = 0x68420,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port3_rx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port3_rx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div nss_port3_tx_div_clk_src = {
+       .reg = 0x68424,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port3_tx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port3_tx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div nss_port4_rx_div_clk_src = {
+       .reg = 0x68430,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port4_rx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port4_rx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_regmap_div nss_port4_tx_div_clk_src = {
+       .reg = 0x68434,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_port4_tx_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port4_tx_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_nss_ubi_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(149760000, P_UBI32_PLL, 10, 0, 0),
+       F(187200000, P_UBI32_PLL, 8, 0, 0),
+       F(249600000, P_UBI32_PLL, 6, 0, 0),
+       F(374400000, P_UBI32_PLL, 4, 0, 0),
+       F(748800000, P_UBI32_PLL, 2, 0, 0),
+       F(1497600000, P_UBI32_PLL, 1, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data
+                       gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6[] = {
+       { .fw_name = "xo" },
+       { .hw = &ubi32_pll.clkr.hw },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+};
+
+static const struct parent_map gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map[] = {
+       { P_XO, 0 },
+       { P_UBI32_PLL, 1 },
+       { P_GPLL0, 2 },
+       { P_GPLL2, 3 },
+       { P_GPLL4, 4 },
+       { P_GPLL6, 5 },
+};
+
+static struct clk_rcg2 nss_ubi0_clk_src = {
+       .cmd_rcgr = 0x68104,
+       .freq_tbl = ftbl_nss_ubi_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_ubi32_gpll0_gpll2_gpll4_gpll6_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "nss_ubi0_clk_src",
+               .parent_data = gcc_xo_ubi32_pll_gpll0_gpll2_gpll4_gpll6,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_adss_pwm_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 adss_pwm_clk_src = {
+       .cmd_rcgr = 0x1c008,
+       .freq_tbl = ftbl_adss_pwm_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "adss_pwm_clk_src",
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup_i2c_apps_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0_DIV2, 16, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x0200c,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_qup_spi_apps_clk_src[] = {
+       F(960000, P_XO, 10, 2, 5),
+       F(4800000, P_XO, 5, 0, 0),
+       F(9600000, P_XO, 2, 4, 5),
+       F(12500000, P_GPLL0_DIV2, 16, 1, 2),
+       F(16000000, P_GPLL0, 10, 1, 5),
+       F(24000000, P_XO, 1, 0, 0),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 blsp1_qup1_spi_apps_clk_src = {
+       .cmd_rcgr = 0x02024,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup1_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x03000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup2_spi_apps_clk_src = {
+       .cmd_rcgr = 0x03014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup2_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x04000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup3_spi_apps_clk_src = {
+       .cmd_rcgr = 0x04014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup3_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x05000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup4_spi_apps_clk_src = {
+       .cmd_rcgr = 0x05014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup4_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup5_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x06000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup5_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup5_spi_apps_clk_src = {
+       .cmd_rcgr = 0x06014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup5_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup6_i2c_apps_clk_src = {
+       .cmd_rcgr = 0x07000,
+       .freq_tbl = ftbl_blsp1_qup_i2c_apps_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup6_i2c_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_qup6_spi_apps_clk_src = {
+       .cmd_rcgr = 0x07014,
+       .freq_tbl = ftbl_blsp1_qup_spi_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_qup6_spi_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_blsp1_uart_apps_clk_src[] = {
+       F(3686400, P_GPLL0_DIV2, 1, 144, 15625),
+       F(7372800, P_GPLL0_DIV2, 1, 288, 15625),
+       F(14745600, P_GPLL0_DIV2, 1, 576, 15625),
+       F(16000000, P_GPLL0_DIV2, 5, 1, 5),
+       F(24000000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0, 1, 3, 100),
+       F(25000000, P_GPLL0, 16, 1, 2),
+       F(32000000, P_GPLL0, 1, 1, 25),
+       F(40000000, P_GPLL0, 1, 1, 20),
+       F(46400000, P_GPLL0, 1, 29, 500),
+       F(48000000, P_GPLL0, 1, 3, 50),
+       F(51200000, P_GPLL0, 1, 8, 125),
+       F(56000000, P_GPLL0, 1, 7, 100),
+       F(58982400, P_GPLL0, 1, 1152, 15625),
+       F(60000000, P_GPLL0, 1, 3, 40),
+       F(64000000, P_GPLL0, 12.5, 1, 1),
+       { }
+};
+
+static struct clk_rcg2 blsp1_uart1_apps_clk_src = {
+       .cmd_rcgr = 0x02044,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart1_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart2_apps_clk_src = {
+       .cmd_rcgr = 0x03034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart2_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart3_apps_clk_src = {
+       .cmd_rcgr = 0x04034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart3_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart4_apps_clk_src = {
+       .cmd_rcgr = 0x05034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart4_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart5_apps_clk_src = {
+       .cmd_rcgr = 0x06034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart5_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
+       .cmd_rcgr = 0x07034,
+       .freq_tbl = ftbl_blsp1_uart_apps_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "blsp1_uart6_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_crypto_clk_src[] = {
+       F(40000000, P_GPLL0_DIV2, 10, 0, 0),
+       F(80000000, P_GPLL0, 10, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 crypto_clk_src = {
+       .cmd_rcgr = 0x16004,
+       .freq_tbl = ftbl_crypto_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "crypto_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_gp_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_DIV2, 8, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266666666, P_GPLL0, 3, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_sleep_clk[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_out_main_div2.hw },
+       { .fw_name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL0_DIV2, 4 },
+       { P_SLEEP_CLK, 6 },
+};
+
+static struct clk_rcg2 gp1_clk_src = {
+       .cmd_rcgr = 0x08004,
+       .freq_tbl = ftbl_gp_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp1_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gp2_clk_src = {
+       .cmd_rcgr = 0x09004,
+       .freq_tbl = ftbl_gp_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp2_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 gp3_clk_src = {
+       .cmd_rcgr = 0x0a004,
+       .freq_tbl = ftbl_gp_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll6_gpll0_sleep_clk_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gp3_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll6_gpll0_sleep_clk,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_fixed_factor nss_ppe_cdiv_clk_src = {
+       .mult = 1,
+       .div = 4,
+       .hw.init = &(struct clk_init_data){
+               .name = "nss_ppe_cdiv_clk_src",
+               .parent_hws = (const struct clk_hw *[]){
+                               &nss_ppe_clk_src.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_regmap_div nss_ubi0_div_clk_src = {
+       .reg = 0x68118,
+       .shift = 0,
+       .width = 4,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "nss_ubi0_div_clk_src",
+                       .parent_hws = (const struct clk_hw *[]){
+                               &nss_ubi0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_regmap_div_ro_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_pcie_aux_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_core_pi_sleep_clk[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .fw_name = "sleep_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll0_core_pi_sleep_clk_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 2 },
+       { P_PI_SLEEP, 6 },
+};
+
+static struct clk_rcg2 pcie0_aux_clk_src = {
+       .cmd_rcgr = 0x75024,
+       .freq_tbl = ftbl_pcie_aux_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_core_pi_sleep_clk_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcie0_aux_clk_src",
+               .parent_data = gcc_xo_gpll0_core_pi_sleep_clk,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct clk_parent_data gcc_pcie20_phy0_pipe_clk_xo[] = {
+       { .fw_name = "pcie20_phy0_pipe_clk" },
+       { .fw_name = "xo" },
+};
+
+static const struct parent_map gcc_pcie20_phy0_pipe_clk_xo_map[] = {
+       { P_PCIE20_PHY0_PIPE, 0 },
+       { P_XO, 2 },
+};
+
+static struct clk_regmap_mux pcie0_pipe_clk_src = {
+       .reg = 0x7501c,
+       .shift = 8,
+       .width = 2,
+       .parent_map = gcc_pcie20_phy0_pipe_clk_xo_map,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "pcie0_pipe_clk_src",
+                       .parent_data = gcc_pcie20_phy0_pipe_clk_xo,
+                       .num_parents = 2,
+                       .ops = &clk_regmap_mux_closest_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc_apps_clk_src[] = {
+       F(144000, P_XO, 16, 12, 125),
+       F(400000, P_XO, 12, 1, 5),
+       F(24000000, P_GPLL2, 12, 1, 4),
+       F(48000000, P_GPLL2, 12, 1, 2),
+       F(96000000, P_GPLL2, 12, 0, 0),
+       F(177777778, P_GPLL0, 4.5, 0, 0),
+       F(192000000, P_GPLL2, 6, 0, 0),
+       F(384000000, P_GPLL2, 3, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data
+                       gcc_xo_gpll0_gpll2_gpll0_out_main_div2[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .hw = &gpll0_out_main_div2.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL2, 2 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_rcg2 sdcc1_apps_clk_src = {
+       .cmd_rcgr = 0x42004,
+       .freq_tbl = ftbl_sdcc_apps_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll2_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_apps_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll2_gpll0_out_main_div2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb_aux_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 usb0_aux_clk_src = {
+       .cmd_rcgr = 0x3e05c,
+       .freq_tbl = ftbl_usb_aux_clk_src,
+       .mnd_width = 16,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_core_pi_sleep_clk_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb0_aux_clk_src",
+               .parent_data = gcc_xo_gpll0_core_pi_sleep_clk,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_usb_mock_utmi_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(60000000, P_GPLL6, 6, 1, 3),
+       { }
+};
+
+static const struct clk_parent_data
+                       gcc_xo_gpll6_gpll0_gpll0_out_main_div2[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_main_div2.hw },
+};
+
+static const struct parent_map gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL6, 1 },
+       { P_GPLL0, 3 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_rcg2 usb0_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x3e020,
+       .freq_tbl = ftbl_usb_mock_utmi_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb0_mock_utmi_clk_src",
+               .parent_data = gcc_xo_gpll6_gpll0_gpll0_out_main_div2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct clk_parent_data gcc_usb3phy_0_cc_pipe_clk_xo[] = {
+       { .fw_name = "usb3phy_0_cc_pipe_clk" },
+       { .fw_name = "xo" },
+};
+
+static const struct parent_map gcc_usb3phy_0_cc_pipe_clk_xo_map[] = {
+       { P_USB3PHY_0_PIPE, 0 },
+       { P_XO, 2 },
+};
+
+static struct clk_regmap_mux usb0_pipe_clk_src = {
+       .reg = 0x3e048,
+       .shift = 8,
+       .width = 2,
+       .parent_map = gcc_usb3phy_0_cc_pipe_clk_xo_map,
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "usb0_pipe_clk_src",
+                       .parent_data = gcc_usb3phy_0_cc_pipe_clk_xo,
+                       .num_parents = 2,
+                       .ops = &clk_regmap_mux_closest_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_sdcc_ice_core_clk_src[] = {
+       F(80000000, P_GPLL0_DIV2, 5, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(216000000, P_GPLL6, 5, 0, 0),
+       F(308570000, P_GPLL6, 3.5, 0, 0),
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll6_gpll0_div2[] = {
+       { .fw_name = "xo"},
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+       { .hw = &gpll0_out_main_div2.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll6_gpll0_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL6, 2 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_rcg2 sdcc1_ice_core_clk_src = {
+       .cmd_rcgr = 0x5d000,
+       .freq_tbl = ftbl_sdcc_ice_core_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll6_gpll0_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "sdcc1_ice_core_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll6_gpll0_div2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_qdss_stm_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_DIV2, 8, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 qdss_stm_clk_src = {
+       .cmd_rcgr = 0x2902C,
+       .freq_tbl = ftbl_qdss_stm_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "qdss_stm_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll0_out_main_div2,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_qdss_traceclkin_clk_src[] = {
+       F(80000000, P_GPLL0_DIV2, 5, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(300000000, P_GPLL4, 4, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data gcc_xo_gpll4_gpll0_gpll0_div2[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll0_out_main_div2.hw },
+};
+
+static const struct parent_map gcc_xo_gpll4_gpll0_gpll0_div2_map[] = {
+       { P_XO, 0 },
+       { P_GPLL4, 1 },
+       { P_GPLL0, 2 },
+       { P_GPLL0_DIV2, 4 },
+};
+
+static struct clk_rcg2 qdss_traceclkin_clk_src = {
+       .cmd_rcgr = 0x29048,
+       .freq_tbl = ftbl_qdss_traceclkin_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll4_gpll0_gpll0_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "qdss_traceclkin_clk_src",
+               .parent_data = gcc_xo_gpll4_gpll0_gpll0_div2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 usb1_mock_utmi_clk_src = {
+       .cmd_rcgr = 0x3f020,
+       .freq_tbl = ftbl_usb_mock_utmi_clk_src,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll6_gpll0_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "usb1_mock_utmi_clk_src",
+               .parent_data = gcc_xo_gpll6_gpll0_gpll0_out_main_div2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_adss_pwm_clk = {
+       .halt_reg = 0x1c020,
+       .clkr = {
+               .enable_reg = 0x1c020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_adss_pwm_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &adss_pwm_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_apss_ahb_clk = {
+       .halt_reg = 0x4601c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x0b004,
+               .enable_mask = BIT(14),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_apss_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &apss_ahb_postdiv_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_system_noc_bfdcd_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0_DIV2, 8, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       F(133333333, P_GPLL0, 6, 0, 0),
+       F(160000000, P_GPLL0, 5, 0, 0),
+       F(200000000, P_GPLL0, 4, 0, 0),
+       F(266666667, P_GPLL0, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 system_noc_bfdcd_clk_src = {
+       .cmd_rcgr = 0x26004,
+       .freq_tbl = ftbl_system_noc_bfdcd_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll6_gpll0_out_main_div2_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "system_noc_bfdcd_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll6_gpll0_out_main_div2,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_ubi32_mem_noc_bfdcd_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(307670000, P_BIAS_PLL_NSS_NOC, 1.5, 0, 0),
+       F(533333333, P_GPLL0, 1.5, 0, 0),
+       { }
+};
+
+static const struct clk_parent_data
+                       gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .fw_name = "bias_pll_nss_noc_clk" },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL2, 3 },
+       { P_BIAS_PLL_NSS_NOC, 4 },
+};
+
+static struct clk_rcg2 ubi32_mem_noc_bfdcd_clk_src = {
+       .cmd_rcgr = 0x68088,
+       .freq_tbl = ftbl_ubi32_mem_noc_bfdcd_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ubi32_mem_noc_bfdcd_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll2_bias_pll_nss_noc_clk,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_apss_axi_clk = {
+       .halt_reg = 0x46020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x0b004,
+               .enable_mask = BIT(13),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_apss_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &apss_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_ahb_clk = {
+       .halt_reg = 0x01008,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x0b004,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_i2c_apps_clk = {
+       .halt_reg = 0x02008,
+       .clkr = {
+               .enable_reg = 0x02008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup1_i2c_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup1_spi_apps_clk = {
+       .halt_reg = 0x02004,
+       .clkr = {
+               .enable_reg = 0x02004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup1_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup1_spi_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_i2c_apps_clk = {
+       .halt_reg = 0x03010,
+       .clkr = {
+               .enable_reg = 0x03010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup2_i2c_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup2_spi_apps_clk = {
+       .halt_reg = 0x0300c,
+       .clkr = {
+               .enable_reg = 0x0300c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup2_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup2_spi_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_i2c_apps_clk = {
+       .halt_reg = 0x04010,
+       .clkr = {
+               .enable_reg = 0x04010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup3_i2c_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup3_spi_apps_clk = {
+       .halt_reg = 0x0400c,
+       .clkr = {
+               .enable_reg = 0x0400c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup3_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup3_spi_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_i2c_apps_clk = {
+       .halt_reg = 0x05010,
+       .clkr = {
+               .enable_reg = 0x05010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup4_i2c_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup4_spi_apps_clk = {
+       .halt_reg = 0x0500c,
+       .clkr = {
+               .enable_reg = 0x0500c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup4_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup4_spi_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup5_i2c_apps_clk = {
+       .halt_reg = 0x06010,
+       .clkr = {
+               .enable_reg = 0x06010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup5_i2c_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup5_i2c_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
+       .halt_reg = 0x0600c,
+       .clkr = {
+               .enable_reg = 0x0600c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup5_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup5_spi_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
+       .halt_reg = 0x0700c,
+       .clkr = {
+               .enable_reg = 0x0700c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_qup6_spi_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_qup6_spi_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart1_apps_clk = {
+       .halt_reg = 0x0203c,
+       .clkr = {
+               .enable_reg = 0x0203c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart1_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_uart1_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart2_apps_clk = {
+       .halt_reg = 0x0302c,
+       .clkr = {
+               .enable_reg = 0x0302c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart2_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_uart2_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart3_apps_clk = {
+       .halt_reg = 0x0402c,
+       .clkr = {
+               .enable_reg = 0x0402c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart3_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_uart3_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart4_apps_clk = {
+       .halt_reg = 0x0502c,
+       .clkr = {
+               .enable_reg = 0x0502c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart4_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_uart4_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart5_apps_clk = {
+       .halt_reg = 0x0602c,
+       .clkr = {
+               .enable_reg = 0x0602c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart5_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_uart5_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_blsp1_uart6_apps_clk = {
+       .halt_reg = 0x0702c,
+       .clkr = {
+               .enable_reg = 0x0702c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_blsp1_uart6_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &blsp1_uart6_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_ahb_clk = {
+       .halt_reg = 0x16024,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x0b004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_axi_clk = {
+       .halt_reg = 0x16020,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x0b004,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_clk = {
+       .halt_reg = 0x1601c,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x0b004,
+               .enable_mask = BIT(2),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &crypto_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_fixed_factor gpll6_out_main_div2 = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "gpll6_out_main_div2",
+               .parent_hws = (const struct clk_hw *[]){
+                               &gpll6_main.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_branch gcc_xo_clk = {
+       .halt_reg = 0x30030,
+       .clkr = {
+               .enable_reg = 0x30030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_xo_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gcc_xo_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp1_clk = {
+       .halt_reg = 0x08000,
+       .clkr = {
+               .enable_reg = 0x08000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp1_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gp1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp2_clk = {
+       .halt_reg = 0x09000,
+       .clkr = {
+               .enable_reg = 0x09000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gp2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_gp3_clk = {
+       .halt_reg = 0x0a000,
+       .clkr = {
+               .enable_reg = 0x0a000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_gp3_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gp3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mdio_ahb_clk = {
+       .halt_reg = 0x58004,
+       .clkr = {
+               .enable_reg = 0x58004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mdio_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_crypto_ppe_clk = {
+       .halt_reg = 0x68310,
+       .clkr = {
+               .enable_reg = 0x68310,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_crypto_ppe_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_ce_apb_clk = {
+       .halt_reg = 0x68174,
+       .clkr = {
+               .enable_reg = 0x68174,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_ce_apb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ce_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_ce_axi_clk = {
+       .halt_reg = 0x68170,
+       .clkr = {
+               .enable_reg = 0x68170,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_ce_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ce_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_cfg_clk = {
+       .halt_reg = 0x68160,
+       .clkr = {
+               .enable_reg = 0x68160,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_cfg_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_crypto_clk = {
+       .halt_reg = 0x68164,
+       .clkr = {
+               .enable_reg = 0x68164,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_crypto_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_crypto_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_csr_clk = {
+       .halt_reg = 0x68318,
+       .clkr = {
+               .enable_reg = 0x68318,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_csr_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ce_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_edma_cfg_clk = {
+       .halt_reg = 0x6819C,
+       .clkr = {
+               .enable_reg = 0x6819C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_edma_cfg_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_edma_clk = {
+       .halt_reg = 0x68198,
+       .clkr = {
+               .enable_reg = 0x68198,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_edma_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_noc_clk = {
+       .halt_reg = 0x68168,
+       .clkr = {
+               .enable_reg = 0x68168,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_noc_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &snoc_nssnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ubi0_utcm_clk = {
+       .halt_reg = 0x2606c,
+       .clkr = {
+               .enable_reg = 0x2606c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ubi0_utcm_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &snoc_nssnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_snoc_nssnoc_clk = {
+       .halt_reg = 0x26070,
+       .clkr = {
+               .enable_reg = 0x26070,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_snoc_nssnoc_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &snoc_nssnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct freq_tbl ftbl_wcss_ahb_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(133333333, P_GPLL0, 6, 0, 0),
+       { }
+};
+
+static const struct freq_tbl ftbl_q6_axi_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 wcss_ahb_clk_src = {
+       .cmd_rcgr = 0x59020,
+       .freq_tbl = ftbl_wcss_ahb_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "wcss_ahb_clk_src",
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct clk_parent_data gcc_xo_gpll0_gpll2_gpll4_gpll6[] = {
+       { .fw_name = "xo" },
+       { .hw = &gpll0.clkr.hw },
+       { .hw = &gpll2.clkr.hw },
+       { .hw = &gpll4.clkr.hw },
+       { .hw = &gpll6.clkr.hw },
+};
+
+static const struct parent_map gcc_xo_gpll0_gpll2_gpll4_gpll6_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 1 },
+       { P_GPLL2, 2 },
+       { P_GPLL4, 3 },
+       { P_GPLL6, 4 },
+};
+
+static struct clk_rcg2 q6_axi_clk_src = {
+       .cmd_rcgr = 0x59120,
+       .freq_tbl = ftbl_q6_axi_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_gpll2_gpll4_gpll6_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "q6_axi_clk_src",
+               .parent_data = gcc_xo_gpll0_gpll2_gpll4_gpll6,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_lpass_core_axim_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(100000000, P_GPLL0, 8, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 lpass_core_axim_clk_src = {
+       .cmd_rcgr = 0x1F020,
+       .freq_tbl = ftbl_lpass_core_axim_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "lpass_core_axim_clk_src",
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_lpass_snoc_cfg_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(266666667, P_GPLL0, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 lpass_snoc_cfg_clk_src = {
+       .cmd_rcgr = 0x1F040,
+       .freq_tbl = ftbl_lpass_snoc_cfg_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "lpass_snoc_cfg_clk_src",
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_lpass_q6_axim_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(400000000, P_GPLL0, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 lpass_q6_axim_clk_src = {
+       .cmd_rcgr = 0x1F008,
+       .freq_tbl = ftbl_lpass_q6_axim_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "lpass_q6_axim_clk_src",
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct freq_tbl ftbl_rbcpr_wcss_clk_src[] = {
+       F(24000000, P_XO, 1, 0, 0),
+       F(50000000, P_GPLL0, 16, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 rbcpr_wcss_clk_src = {
+       .cmd_rcgr = 0x3a00c,
+       .freq_tbl = ftbl_rbcpr_wcss_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_out_main_div2_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "rbcpr_wcss_clk_src",
+               .parent_data = gcc_xo_gpll0_out_main_div2_gpll0,
+               .num_parents = 3,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_lpass_core_axim_clk = {
+       .halt_reg = 0x1F028,
+       .clkr = {
+               .enable_reg = 0x1F028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_lpass_core_axim_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &lpass_core_axim_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_lpass_snoc_cfg_clk = {
+       .halt_reg = 0x1F048,
+       .clkr = {
+               .enable_reg = 0x1F048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_lpass_snoc_cfg_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &lpass_snoc_cfg_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_lpass_q6_axim_clk = {
+       .halt_reg = 0x1F010,
+       .clkr = {
+               .enable_reg = 0x1F010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_lpass_q6_axim_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &lpass_q6_axim_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_lpass_q6_atbm_at_clk = {
+       .halt_reg = 0x1F018,
+       .clkr = {
+               .enable_reg = 0x1F018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_lpass_q6_atbm_at_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &qdss_at_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_lpass_q6_pclkdbg_clk = {
+       .halt_reg = 0x1F01C,
+       .clkr = {
+               .enable_reg = 0x1F01C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_lpass_q6_pclkdbg_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &qdss_dap_sync_clk_src.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_lpass_q6ss_tsctr_1to2_clk = {
+       .halt_reg = 0x1F014,
+       .clkr = {
+               .enable_reg = 0x1F014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_lpass_q6ss_tsctr_1to2_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &qdss_tsctr_div2_clk_src.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_lpass_q6ss_trig_clk = {
+       .halt_reg = 0x1F038,
+       .clkr = {
+               .enable_reg = 0x1F038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_lpass_q6ss_trig_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &qdss_dap_sync_clk_src.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_lpass_tbu_clk = {
+       .halt_reg = 0x12094,
+       .clkr = {
+               .enable_reg = 0xb00c,
+               .enable_mask = BIT(10),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_lpass_tbu_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &lpass_q6_axim_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcnoc_lpass_clk = {
+       .halt_reg = 0x27020,
+       .clkr = {
+               .enable_reg = 0x27020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcnoc_lpass_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &lpass_core_axim_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mem_noc_lpass_clk = {
+       .halt_reg = 0x1D044,
+       .clkr = {
+               .enable_reg = 0x1D044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mem_noc_lpass_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &lpass_q6_axim_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_snoc_lpass_cfg_clk = {
+       .halt_reg = 0x26074,
+       .clkr = {
+               .enable_reg = 0x26074,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_snoc_lpass_cfg_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &lpass_snoc_cfg_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_mem_noc_ubi32_clk = {
+       .halt_reg = 0x1D03C,
+       .clkr = {
+               .enable_reg = 0x1D03C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_mem_noc_ubi32_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &ubi32_mem_noc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port1_rx_clk = {
+       .halt_reg = 0x68240,
+       .clkr = {
+               .enable_reg = 0x68240,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port1_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port1_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port1_tx_clk = {
+       .halt_reg = 0x68244,
+       .clkr = {
+               .enable_reg = 0x68244,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port1_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port1_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port2_rx_clk = {
+       .halt_reg = 0x68248,
+       .clkr = {
+               .enable_reg = 0x68248,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port2_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port2_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port2_tx_clk = {
+       .halt_reg = 0x6824c,
+       .clkr = {
+               .enable_reg = 0x6824c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port2_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port2_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port3_rx_clk = {
+       .halt_reg = 0x68250,
+       .clkr = {
+               .enable_reg = 0x68250,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port3_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port3_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port3_tx_clk = {
+       .halt_reg = 0x68254,
+       .clkr = {
+               .enable_reg = 0x68254,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port3_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port3_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port4_rx_clk = {
+       .halt_reg = 0x68258,
+       .clkr = {
+               .enable_reg = 0x68258,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port4_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port4_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port4_tx_clk = {
+       .halt_reg = 0x6825c,
+       .clkr = {
+               .enable_reg = 0x6825c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port4_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port4_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port5_rx_clk = {
+       .halt_reg = 0x68260,
+       .clkr = {
+               .enable_reg = 0x68260,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port5_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port5_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_port5_tx_clk = {
+       .halt_reg = 0x68264,
+       .clkr = {
+               .enable_reg = 0x68264,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_port5_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port5_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_ppe_cfg_clk = {
+       .halt_reg = 0x68194,
+       .clkr = {
+               .enable_reg = 0x68194,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_ppe_cfg_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_ppe_clk = {
+       .halt_reg = 0x68190,
+       .clkr = {
+               .enable_reg = 0x68190,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_ppe_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_ppe_ipe_clk = {
+       .halt_reg = 0x68338,
+       .clkr = {
+               .enable_reg = 0x68338,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_ppe_ipe_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nss_ptp_ref_clk = {
+       .halt_reg = 0x6816C,
+       .clkr = {
+               .enable_reg = 0x6816C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nss_ptp_ref_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_cdiv_clk_src.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_ce_apb_clk = {
+       .halt_reg = 0x6830C,
+       .clkr = {
+               .enable_reg = 0x6830C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_ce_apb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ce_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_ce_axi_clk = {
+       .halt_reg = 0x68308,
+       .clkr = {
+               .enable_reg = 0x68308,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_ce_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ce_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_crypto_clk = {
+       .halt_reg = 0x68314,
+       .clkr = {
+               .enable_reg = 0x68314,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_crypto_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_crypto_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_ppe_cfg_clk = {
+       .halt_reg = 0x68304,
+       .clkr = {
+               .enable_reg = 0x68304,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_ppe_cfg_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_ppe_clk = {
+       .halt_reg = 0x68300,
+       .clkr = {
+               .enable_reg = 0x68300,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_ppe_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_qosgen_ref_clk = {
+       .halt_reg = 0x68180,
+       .clkr = {
+               .enable_reg = 0x68180,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_qosgen_ref_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gcc_xo_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_snoc_clk = {
+       .halt_reg = 0x68188,
+       .clkr = {
+               .enable_reg = 0x68188,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_snoc_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &system_noc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_timeout_ref_clk = {
+       .halt_reg = 0x68184,
+       .clkr = {
+               .enable_reg = 0x68184,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_timeout_ref_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gcc_xo_div4_clk_src.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_nssnoc_ubi0_ahb_clk = {
+       .halt_reg = 0x68270,
+       .clkr = {
+               .enable_reg = 0x68270,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_nssnoc_ubi0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ce_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_port1_mac_clk = {
+       .halt_reg = 0x68320,
+       .clkr = {
+               .enable_reg = 0x68320,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_port1_mac_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_port2_mac_clk = {
+       .halt_reg = 0x68324,
+       .clkr = {
+               .enable_reg = 0x68324,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_port2_mac_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_port3_mac_clk = {
+       .halt_reg = 0x68328,
+       .clkr = {
+               .enable_reg = 0x68328,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_port3_mac_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_port4_mac_clk = {
+       .halt_reg = 0x6832c,
+       .clkr = {
+               .enable_reg = 0x6832c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_port4_mac_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_port5_mac_clk = {
+       .halt_reg = 0x68330,
+       .clkr = {
+               .enable_reg = 0x68330,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_port5_mac_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ppe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ubi0_ahb_clk = {
+       .halt_reg = 0x6820C,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x6820C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ubi0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ce_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ubi0_axi_clk = {
+       .halt_reg = 0x68200,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68200,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ubi0_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &ubi32_mem_noc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ubi0_nc_axi_clk = {
+       .halt_reg = 0x68204,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68204,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ubi0_nc_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &snoc_nssnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_ubi0_core_clk = {
+       .halt_reg = 0x68210,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x68210,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_ubi0_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_ubi0_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie0_ahb_clk = {
+       .halt_reg = 0x75010,
+       .clkr = {
+               .enable_reg = 0x75010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie0_aux_clk = {
+       .halt_reg = 0x75014,
+       .clkr = {
+               .enable_reg = 0x75014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie0_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcie0_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie0_axi_m_clk = {
+       .halt_reg = 0x75008,
+       .clkr = {
+               .enable_reg = 0x75008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie0_axi_m_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcie0_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie0_axi_s_clk = {
+       .halt_reg = 0x7500c,
+       .clkr = {
+               .enable_reg = 0x7500c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie0_axi_s_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcie0_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_pcie0_axi_clk = {
+       .halt_reg = 0x26048,
+       .clkr = {
+               .enable_reg = 0x26048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_pcie0_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcie0_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie0_pipe_clk = {
+       .halt_reg = 0x75018,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x75018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie0_pipe_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcie0_pipe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_prng_ahb_clk = {
+       .halt_reg = 0x13004,
+       .halt_check = BRANCH_HALT_VOTED,
+       .clkr = {
+               .enable_reg = 0x0b004,
+               .enable_mask = BIT(8),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_prng_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qdss_dap_clk = {
+       .halt_reg = 0x29084,
+       .clkr = {
+               .enable_reg = 0x29084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qdss_dap_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &qdss_dap_sync_clk_src.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qpic_ahb_clk = {
+       .halt_reg = 0x57024,
+       .clkr = {
+               .enable_reg = 0x57024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qpic_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_qpic_clk = {
+       .halt_reg = 0x57020,
+       .clkr = {
+               .enable_reg = 0x57020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_qpic_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ahb_clk = {
+       .halt_reg = 0x4201c,
+       .clkr = {
+               .enable_reg = 0x4201c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_apps_clk = {
+       .halt_reg = 0x42018,
+       .clkr = {
+               .enable_reg = 0x42018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_apps_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &sdcc1_apps_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_ahb_clk = {
+       .halt_reg = 0x56008,
+       .clkr = {
+               .enable_reg = 0x56008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port1_rx_clk = {
+       .halt_reg = 0x56010,
+       .clkr = {
+               .enable_reg = 0x56010,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port1_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port1_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port1_tx_clk = {
+       .halt_reg = 0x56014,
+       .clkr = {
+               .enable_reg = 0x56014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port1_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port1_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port2_rx_clk = {
+       .halt_reg = 0x56018,
+       .clkr = {
+               .enable_reg = 0x56018,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port2_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port2_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port2_tx_clk = {
+       .halt_reg = 0x5601c,
+       .clkr = {
+               .enable_reg = 0x5601c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port2_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port2_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port3_rx_clk = {
+       .halt_reg = 0x56020,
+       .clkr = {
+               .enable_reg = 0x56020,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port3_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port3_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port3_tx_clk = {
+       .halt_reg = 0x56024,
+       .clkr = {
+               .enable_reg = 0x56024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port3_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port3_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port4_rx_clk = {
+       .halt_reg = 0x56028,
+       .clkr = {
+               .enable_reg = 0x56028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port4_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port4_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port4_tx_clk = {
+       .halt_reg = 0x5602c,
+       .clkr = {
+               .enable_reg = 0x5602c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port4_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port4_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port5_rx_clk = {
+       .halt_reg = 0x56030,
+       .clkr = {
+               .enable_reg = 0x56030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port5_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port5_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_port5_tx_clk = {
+       .halt_reg = 0x56034,
+       .clkr = {
+               .enable_reg = 0x56034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_port5_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port5_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy0_sys_clk = {
+       .halt_reg = 0x5600C,
+       .clkr = {
+               .enable_reg = 0x5600C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy0_sys_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gcc_xo_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy1_ahb_clk = {
+       .halt_reg = 0x56108,
+       .clkr = {
+               .enable_reg = 0x56108,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy1_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy1_port5_rx_clk = {
+       .halt_reg = 0x56110,
+       .clkr = {
+               .enable_reg = 0x56110,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy1_port5_rx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port5_rx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy1_port5_tx_clk = {
+       .halt_reg = 0x56114,
+       .clkr = {
+               .enable_reg = 0x56114,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy1_port5_tx_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &nss_port5_tx_div_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_uniphy1_sys_clk = {
+       .halt_reg = 0x5610C,
+       .clkr = {
+               .enable_reg = 0x5610C,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_uniphy1_sys_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gcc_xo_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb0_aux_clk = {
+       .halt_reg = 0x3e044,
+       .clkr = {
+               .enable_reg = 0x3e044,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb0_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &usb0_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb0_master_clk = {
+       .halt_reg = 0x3e000,
+       .clkr = {
+               .enable_reg = 0x3e000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb0_master_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &usb0_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_snoc_bus_timeout2_ahb_clk = {
+       .halt_reg = 0x47014,
+       .clkr = {
+               .enable_reg = 0x47014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_snoc_bus_timeout2_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &usb0_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_rcg2 pcie0_rchng_clk_src = {
+       .cmd_rcgr = 0x75070,
+       .freq_tbl = ftbl_pcie_rchng_clk_src,
+       .hid_width = 5,
+       .parent_map = gcc_xo_gpll0_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pcie0_rchng_clk_src",
+               .parent_data = gcc_xo_gpll0,
+               .num_parents = 2,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch gcc_pcie0_rchng_clk = {
+       .halt_reg = 0x75070,
+       .clkr = {
+               .enable_reg = 0x75070,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie0_rchng_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcie0_rchng_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_pcie0_axi_s_bridge_clk = {
+       .halt_reg = 0x75048,
+       .clkr = {
+               .enable_reg = 0x75048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_pcie0_axi_s_bridge_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcie0_axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sys_noc_usb0_axi_clk = {
+       .halt_reg = 0x26040,
+       .clkr = {
+               .enable_reg = 0x26040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sys_noc_usb0_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &usb0_master_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb0_mock_utmi_clk = {
+       .halt_reg = 0x3e008,
+       .clkr = {
+               .enable_reg = 0x3e008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb0_mock_utmi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &usb0_mock_utmi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb0_phy_cfg_ahb_clk = {
+       .halt_reg = 0x3e080,
+       .clkr = {
+               .enable_reg = 0x3e080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb0_phy_cfg_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb0_pipe_clk = {
+       .halt_reg = 0x3e040,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x3e040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb0_pipe_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &usb0_pipe_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb0_sleep_clk = {
+       .halt_reg = 0x3e004,
+       .clkr = {
+               .enable_reg = 0x3e004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb0_sleep_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gcc_sleep_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb1_master_clk = {
+       .halt_reg = 0x3f000,
+       .clkr = {
+               .enable_reg = 0x3f000,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb1_master_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb1_mock_utmi_clk = {
+       .halt_reg = 0x3f008,
+       .clkr = {
+               .enable_reg = 0x3f008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb1_mock_utmi_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &usb1_mock_utmi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb1_phy_cfg_ahb_clk = {
+       .halt_reg = 0x3f080,
+       .clkr = {
+               .enable_reg = 0x3f080,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb1_phy_cfg_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_usb1_sleep_clk = {
+       .halt_reg = 0x3f004,
+       .clkr = {
+               .enable_reg = 0x3f004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_usb1_sleep_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gcc_sleep_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cmn_12gpll_ahb_clk = {
+       .halt_reg = 0x56308,
+       .clkr = {
+               .enable_reg = 0x56308,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cmn_12gpll_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_cmn_12gpll_sys_clk = {
+       .halt_reg = 0x5630c,
+       .clkr = {
+               .enable_reg = 0x5630c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_cmn_12gpll_sys_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &gcc_xo_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_sdcc1_ice_core_clk = {
+       .halt_reg = 0x5d014,
+       .clkr = {
+               .enable_reg = 0x5d014,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_sdcc1_ice_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &sdcc1_ice_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gcc_dcc_clk = {
+       .halt_reg = 0x77004,
+       .clkr = {
+               .enable_reg = 0x77004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_dcc_clk",
+                       .parent_hws = (const struct clk_hw *[]){
+                                       &pcnoc_bfdcd_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static const struct alpha_pll_config ubi32_pll_config = {
+       .l = 0x3e,
+       .alpha = 0x57,
+       .config_ctl_val = 0x240d6aa8,
+       .config_ctl_hi_val = 0x3c2,
+       .main_output_mask = BIT(0),
+       .aux_output_mask = BIT(1),
+       .pre_div_val = 0x0,
+       .pre_div_mask = BIT(12),
+       .post_div_val = 0x0,
+       .post_div_mask = GENMASK(9, 8),
+};
+
+static const struct alpha_pll_config nss_crypto_pll_config = {
+       .l = 0x32,
+       .alpha = 0x0,
+       .alpha_hi = 0x0,
+       .config_ctl_val = 0x4001055b,
+       .main_output_mask = BIT(0),
+       .pre_div_val = 0x0,
+       .pre_div_mask = GENMASK(14, 12),
+       .post_div_val = 0x1 << 8,
+       .post_div_mask = GENMASK(11, 8),
+       .vco_mask = GENMASK(21, 20),
+       .vco_val = 0x0,
+       .alpha_en_mask = BIT(24),
+};
+
+static struct clk_hw *gcc_ipq6018_hws[] = {
+       &gpll0_out_main_div2.hw,
+       &gcc_xo_div4_clk_src.hw,
+       &nss_ppe_cdiv_clk_src.hw,
+       &gpll6_out_main_div2.hw,
+       &qdss_dap_sync_clk_src.hw,
+       &qdss_tsctr_div2_clk_src.hw,
+};
+
+static struct clk_regmap *gcc_ipq6018_clks[] = {
+       [GPLL0_MAIN] = &gpll0_main.clkr,
+       [GPLL0] = &gpll0.clkr,
+       [UBI32_PLL_MAIN] = &ubi32_pll_main.clkr,
+       [UBI32_PLL] = &ubi32_pll.clkr,
+       [GPLL6_MAIN] = &gpll6_main.clkr,
+       [GPLL6] = &gpll6.clkr,
+       [GPLL4_MAIN] = &gpll4_main.clkr,
+       [GPLL4] = &gpll4.clkr,
+       [PCNOC_BFDCD_CLK_SRC] = &pcnoc_bfdcd_clk_src.clkr,
+       [GPLL2_MAIN] = &gpll2_main.clkr,
+       [GPLL2] = &gpll2.clkr,
+       [NSS_CRYPTO_PLL_MAIN] = &nss_crypto_pll_main.clkr,
+       [NSS_CRYPTO_PLL] = &nss_crypto_pll.clkr,
+       [QDSS_TSCTR_CLK_SRC] = &qdss_tsctr_clk_src.clkr,
+       [QDSS_AT_CLK_SRC] = &qdss_at_clk_src.clkr,
+       [NSS_PPE_CLK_SRC] = &nss_ppe_clk_src.clkr,
+       [GCC_XO_CLK_SRC] = &gcc_xo_clk_src.clkr,
+       [SYSTEM_NOC_BFDCD_CLK_SRC] = &system_noc_bfdcd_clk_src.clkr,
+       [SNOC_NSSNOC_BFDCD_CLK_SRC] = &snoc_nssnoc_bfdcd_clk_src.clkr,
+       [NSS_CE_CLK_SRC] = &nss_ce_clk_src.clkr,
+       [GCC_SLEEP_CLK_SRC] = &gcc_sleep_clk_src.clkr,
+       [APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
+       [NSS_PORT5_RX_CLK_SRC] = &nss_port5_rx_clk_src.clkr,
+       [NSS_PORT5_TX_CLK_SRC] = &nss_port5_tx_clk_src.clkr,
+       [UBI32_MEM_NOC_BFDCD_CLK_SRC] = &ubi32_mem_noc_bfdcd_clk_src.clkr,
+       [PCIE0_AXI_CLK_SRC] = &pcie0_axi_clk_src.clkr,
+       [USB0_MASTER_CLK_SRC] = &usb0_master_clk_src.clkr,
+       [APSS_AHB_POSTDIV_CLK_SRC] = &apss_ahb_postdiv_clk_src.clkr,
+       [NSS_PORT1_RX_CLK_SRC] = &nss_port1_rx_clk_src.clkr,
+       [NSS_PORT1_TX_CLK_SRC] = &nss_port1_tx_clk_src.clkr,
+       [NSS_PORT2_RX_CLK_SRC] = &nss_port2_rx_clk_src.clkr,
+       [NSS_PORT2_TX_CLK_SRC] = &nss_port2_tx_clk_src.clkr,
+       [NSS_PORT3_RX_CLK_SRC] = &nss_port3_rx_clk_src.clkr,
+       [NSS_PORT3_TX_CLK_SRC] = &nss_port3_tx_clk_src.clkr,
+       [NSS_PORT4_RX_CLK_SRC] = &nss_port4_rx_clk_src.clkr,
+       [NSS_PORT4_TX_CLK_SRC] = &nss_port4_tx_clk_src.clkr,
+       [NSS_PORT5_RX_DIV_CLK_SRC] = &nss_port5_rx_div_clk_src.clkr,
+       [NSS_PORT5_TX_DIV_CLK_SRC] = &nss_port5_tx_div_clk_src.clkr,
+       [APSS_AXI_CLK_SRC] = &apss_axi_clk_src.clkr,
+       [NSS_CRYPTO_CLK_SRC] = &nss_crypto_clk_src.clkr,
+       [NSS_PORT1_RX_DIV_CLK_SRC] = &nss_port1_rx_div_clk_src.clkr,
+       [NSS_PORT1_TX_DIV_CLK_SRC] = &nss_port1_tx_div_clk_src.clkr,
+       [NSS_PORT2_RX_DIV_CLK_SRC] = &nss_port2_rx_div_clk_src.clkr,
+       [NSS_PORT2_TX_DIV_CLK_SRC] = &nss_port2_tx_div_clk_src.clkr,
+       [NSS_PORT3_RX_DIV_CLK_SRC] = &nss_port3_rx_div_clk_src.clkr,
+       [NSS_PORT3_TX_DIV_CLK_SRC] = &nss_port3_tx_div_clk_src.clkr,
+       [NSS_PORT4_RX_DIV_CLK_SRC] = &nss_port4_rx_div_clk_src.clkr,
+       [NSS_PORT4_TX_DIV_CLK_SRC] = &nss_port4_tx_div_clk_src.clkr,
+       [NSS_UBI0_CLK_SRC] = &nss_ubi0_clk_src.clkr,
+       [ADSS_PWM_CLK_SRC] = &adss_pwm_clk_src.clkr,
+       [BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP1_SPI_APPS_CLK_SRC] = &blsp1_qup1_spi_apps_clk_src.clkr,
+       [BLSP1_QUP2_I2C_APPS_CLK_SRC] = &blsp1_qup2_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP2_SPI_APPS_CLK_SRC] = &blsp1_qup2_spi_apps_clk_src.clkr,
+       [BLSP1_QUP3_I2C_APPS_CLK_SRC] = &blsp1_qup3_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP3_SPI_APPS_CLK_SRC] = &blsp1_qup3_spi_apps_clk_src.clkr,
+       [BLSP1_QUP4_I2C_APPS_CLK_SRC] = &blsp1_qup4_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP4_SPI_APPS_CLK_SRC] = &blsp1_qup4_spi_apps_clk_src.clkr,
+       [BLSP1_QUP5_I2C_APPS_CLK_SRC] = &blsp1_qup5_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP5_SPI_APPS_CLK_SRC] = &blsp1_qup5_spi_apps_clk_src.clkr,
+       [BLSP1_QUP6_I2C_APPS_CLK_SRC] = &blsp1_qup6_i2c_apps_clk_src.clkr,
+       [BLSP1_QUP6_SPI_APPS_CLK_SRC] = &blsp1_qup6_spi_apps_clk_src.clkr,
+       [BLSP1_UART1_APPS_CLK_SRC] = &blsp1_uart1_apps_clk_src.clkr,
+       [BLSP1_UART2_APPS_CLK_SRC] = &blsp1_uart2_apps_clk_src.clkr,
+       [BLSP1_UART3_APPS_CLK_SRC] = &blsp1_uart3_apps_clk_src.clkr,
+       [BLSP1_UART4_APPS_CLK_SRC] = &blsp1_uart4_apps_clk_src.clkr,
+       [BLSP1_UART5_APPS_CLK_SRC] = &blsp1_uart5_apps_clk_src.clkr,
+       [BLSP1_UART6_APPS_CLK_SRC] = &blsp1_uart6_apps_clk_src.clkr,
+       [CRYPTO_CLK_SRC] = &crypto_clk_src.clkr,
+       [GP1_CLK_SRC] = &gp1_clk_src.clkr,
+       [GP2_CLK_SRC] = &gp2_clk_src.clkr,
+       [GP3_CLK_SRC] = &gp3_clk_src.clkr,
+       [NSS_UBI0_DIV_CLK_SRC] = &nss_ubi0_div_clk_src.clkr,
+       [PCIE0_AUX_CLK_SRC] = &pcie0_aux_clk_src.clkr,
+       [PCIE0_PIPE_CLK_SRC] = &pcie0_pipe_clk_src.clkr,
+       [SDCC1_APPS_CLK_SRC] = &sdcc1_apps_clk_src.clkr,
+       [USB0_AUX_CLK_SRC] = &usb0_aux_clk_src.clkr,
+       [USB0_MOCK_UTMI_CLK_SRC] = &usb0_mock_utmi_clk_src.clkr,
+       [USB0_PIPE_CLK_SRC] = &usb0_pipe_clk_src.clkr,
+       [USB1_MOCK_UTMI_CLK_SRC] = &usb1_mock_utmi_clk_src.clkr,
+       [GCC_ADSS_PWM_CLK] = &gcc_adss_pwm_clk.clkr,
+       [GCC_APSS_AHB_CLK] = &gcc_apss_ahb_clk.clkr,
+       [GCC_APSS_AXI_CLK] = &gcc_apss_axi_clk.clkr,
+       [GCC_BLSP1_AHB_CLK] = &gcc_blsp1_ahb_clk.clkr,
+       [GCC_BLSP1_QUP1_I2C_APPS_CLK] = &gcc_blsp1_qup1_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP1_SPI_APPS_CLK] = &gcc_blsp1_qup1_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_I2C_APPS_CLK] = &gcc_blsp1_qup2_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP2_SPI_APPS_CLK] = &gcc_blsp1_qup2_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_I2C_APPS_CLK] = &gcc_blsp1_qup3_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP3_SPI_APPS_CLK] = &gcc_blsp1_qup3_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_I2C_APPS_CLK] = &gcc_blsp1_qup4_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr,
+       [GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr,
+       [GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr,
+       [GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
+       [GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,
+       [GCC_BLSP1_UART3_APPS_CLK] = &gcc_blsp1_uart3_apps_clk.clkr,
+       [GCC_BLSP1_UART4_APPS_CLK] = &gcc_blsp1_uart4_apps_clk.clkr,
+       [GCC_BLSP1_UART5_APPS_CLK] = &gcc_blsp1_uart5_apps_clk.clkr,
+       [GCC_BLSP1_UART6_APPS_CLK] = &gcc_blsp1_uart6_apps_clk.clkr,
+       [GCC_CRYPTO_AHB_CLK] = &gcc_crypto_ahb_clk.clkr,
+       [GCC_CRYPTO_AXI_CLK] = &gcc_crypto_axi_clk.clkr,
+       [GCC_CRYPTO_CLK] = &gcc_crypto_clk.clkr,
+       [GCC_XO_CLK] = &gcc_xo_clk.clkr,
+       [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
+       [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
+       [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_MDIO_AHB_CLK] = &gcc_mdio_ahb_clk.clkr,
+       [GCC_CRYPTO_PPE_CLK] = &gcc_crypto_ppe_clk.clkr,
+       [GCC_NSS_CE_APB_CLK] = &gcc_nss_ce_apb_clk.clkr,
+       [GCC_NSS_CE_AXI_CLK] = &gcc_nss_ce_axi_clk.clkr,
+       [GCC_NSS_CFG_CLK] = &gcc_nss_cfg_clk.clkr,
+       [GCC_NSS_CRYPTO_CLK] = &gcc_nss_crypto_clk.clkr,
+       [GCC_NSS_CSR_CLK] = &gcc_nss_csr_clk.clkr,
+       [GCC_NSS_EDMA_CFG_CLK] = &gcc_nss_edma_cfg_clk.clkr,
+       [GCC_NSS_EDMA_CLK] = &gcc_nss_edma_clk.clkr,
+       [GCC_NSS_NOC_CLK] = &gcc_nss_noc_clk.clkr,
+       [GCC_UBI0_UTCM_CLK] = &gcc_ubi0_utcm_clk.clkr,
+       [GCC_SNOC_NSSNOC_CLK] = &gcc_snoc_nssnoc_clk.clkr,
+       [GCC_NSS_PORT1_RX_CLK] = &gcc_nss_port1_rx_clk.clkr,
+       [GCC_NSS_PORT1_TX_CLK] = &gcc_nss_port1_tx_clk.clkr,
+       [GCC_NSS_PORT2_RX_CLK] = &gcc_nss_port2_rx_clk.clkr,
+       [GCC_NSS_PORT2_TX_CLK] = &gcc_nss_port2_tx_clk.clkr,
+       [GCC_NSS_PORT3_RX_CLK] = &gcc_nss_port3_rx_clk.clkr,
+       [GCC_NSS_PORT3_TX_CLK] = &gcc_nss_port3_tx_clk.clkr,
+       [GCC_NSS_PORT4_RX_CLK] = &gcc_nss_port4_rx_clk.clkr,
+       [GCC_NSS_PORT4_TX_CLK] = &gcc_nss_port4_tx_clk.clkr,
+       [GCC_NSS_PORT5_RX_CLK] = &gcc_nss_port5_rx_clk.clkr,
+       [GCC_NSS_PORT5_TX_CLK] = &gcc_nss_port5_tx_clk.clkr,
+       [GCC_NSS_PPE_CFG_CLK] = &gcc_nss_ppe_cfg_clk.clkr,
+       [GCC_NSS_PPE_CLK] = &gcc_nss_ppe_clk.clkr,
+       [GCC_NSS_PPE_IPE_CLK] = &gcc_nss_ppe_ipe_clk.clkr,
+       [GCC_NSS_PTP_REF_CLK] = &gcc_nss_ptp_ref_clk.clkr,
+       [GCC_NSSNOC_CE_APB_CLK] = &gcc_nssnoc_ce_apb_clk.clkr,
+       [GCC_NSSNOC_CE_AXI_CLK] = &gcc_nssnoc_ce_axi_clk.clkr,
+       [GCC_NSSNOC_CRYPTO_CLK] = &gcc_nssnoc_crypto_clk.clkr,
+       [GCC_NSSNOC_PPE_CFG_CLK] = &gcc_nssnoc_ppe_cfg_clk.clkr,
+       [GCC_NSSNOC_PPE_CLK] = &gcc_nssnoc_ppe_clk.clkr,
+       [GCC_NSSNOC_QOSGEN_REF_CLK] = &gcc_nssnoc_qosgen_ref_clk.clkr,
+       [GCC_NSSNOC_SNOC_CLK] = &gcc_nssnoc_snoc_clk.clkr,
+       [GCC_NSSNOC_TIMEOUT_REF_CLK] = &gcc_nssnoc_timeout_ref_clk.clkr,
+       [GCC_NSSNOC_UBI0_AHB_CLK] = &gcc_nssnoc_ubi0_ahb_clk.clkr,
+       [GCC_PORT1_MAC_CLK] = &gcc_port1_mac_clk.clkr,
+       [GCC_PORT2_MAC_CLK] = &gcc_port2_mac_clk.clkr,
+       [GCC_PORT3_MAC_CLK] = &gcc_port3_mac_clk.clkr,
+       [GCC_PORT4_MAC_CLK] = &gcc_port4_mac_clk.clkr,
+       [GCC_PORT5_MAC_CLK] = &gcc_port5_mac_clk.clkr,
+       [GCC_UBI0_AHB_CLK] = &gcc_ubi0_ahb_clk.clkr,
+       [GCC_UBI0_AXI_CLK] = &gcc_ubi0_axi_clk.clkr,
+       [GCC_UBI0_NC_AXI_CLK] = &gcc_ubi0_nc_axi_clk.clkr,
+       [GCC_UBI0_CORE_CLK] = &gcc_ubi0_core_clk.clkr,
+       [GCC_PCIE0_AHB_CLK] = &gcc_pcie0_ahb_clk.clkr,
+       [GCC_PCIE0_AUX_CLK] = &gcc_pcie0_aux_clk.clkr,
+       [GCC_PCIE0_AXI_M_CLK] = &gcc_pcie0_axi_m_clk.clkr,
+       [GCC_PCIE0_AXI_S_CLK] = &gcc_pcie0_axi_s_clk.clkr,
+       [GCC_SYS_NOC_PCIE0_AXI_CLK] = &gcc_sys_noc_pcie0_axi_clk.clkr,
+       [GCC_PCIE0_PIPE_CLK] = &gcc_pcie0_pipe_clk.clkr,
+       [GCC_PRNG_AHB_CLK] = &gcc_prng_ahb_clk.clkr,
+       [GCC_QDSS_DAP_CLK] = &gcc_qdss_dap_clk.clkr,
+       [GCC_QPIC_AHB_CLK] = &gcc_qpic_ahb_clk.clkr,
+       [GCC_QPIC_CLK] = &gcc_qpic_clk.clkr,
+       [GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
+       [GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
+       [GCC_UNIPHY0_AHB_CLK] = &gcc_uniphy0_ahb_clk.clkr,
+       [GCC_UNIPHY0_PORT1_RX_CLK] = &gcc_uniphy0_port1_rx_clk.clkr,
+       [GCC_UNIPHY0_PORT1_TX_CLK] = &gcc_uniphy0_port1_tx_clk.clkr,
+       [GCC_UNIPHY0_PORT2_RX_CLK] = &gcc_uniphy0_port2_rx_clk.clkr,
+       [GCC_UNIPHY0_PORT2_TX_CLK] = &gcc_uniphy0_port2_tx_clk.clkr,
+       [GCC_UNIPHY0_PORT3_RX_CLK] = &gcc_uniphy0_port3_rx_clk.clkr,
+       [GCC_UNIPHY0_PORT3_TX_CLK] = &gcc_uniphy0_port3_tx_clk.clkr,
+       [GCC_UNIPHY0_PORT4_RX_CLK] = &gcc_uniphy0_port4_rx_clk.clkr,
+       [GCC_UNIPHY0_PORT4_TX_CLK] = &gcc_uniphy0_port4_tx_clk.clkr,
+       [GCC_UNIPHY0_PORT5_RX_CLK] = &gcc_uniphy0_port5_rx_clk.clkr,
+       [GCC_UNIPHY0_PORT5_TX_CLK] = &gcc_uniphy0_port5_tx_clk.clkr,
+       [GCC_UNIPHY0_SYS_CLK] = &gcc_uniphy0_sys_clk.clkr,
+       [GCC_UNIPHY1_AHB_CLK] = &gcc_uniphy1_ahb_clk.clkr,
+       [GCC_UNIPHY1_PORT5_RX_CLK] = &gcc_uniphy1_port5_rx_clk.clkr,
+       [GCC_UNIPHY1_PORT5_TX_CLK] = &gcc_uniphy1_port5_tx_clk.clkr,
+       [GCC_UNIPHY1_SYS_CLK] = &gcc_uniphy1_sys_clk.clkr,
+       [GCC_USB0_AUX_CLK] = &gcc_usb0_aux_clk.clkr,
+       [GCC_SYS_NOC_USB0_AXI_CLK] = &gcc_sys_noc_usb0_axi_clk.clkr,
+       [GCC_SNOC_BUS_TIMEOUT2_AHB_CLK] = &gcc_snoc_bus_timeout2_ahb_clk.clkr,
+       [GCC_USB0_MASTER_CLK] = &gcc_usb0_master_clk.clkr,
+       [GCC_USB0_MOCK_UTMI_CLK] = &gcc_usb0_mock_utmi_clk.clkr,
+       [GCC_USB0_PHY_CFG_AHB_CLK] = &gcc_usb0_phy_cfg_ahb_clk.clkr,
+       [GCC_USB0_PIPE_CLK] = &gcc_usb0_pipe_clk.clkr,
+       [GCC_USB0_SLEEP_CLK] = &gcc_usb0_sleep_clk.clkr,
+       [GCC_USB1_MASTER_CLK] = &gcc_usb1_master_clk.clkr,
+       [GCC_USB1_MOCK_UTMI_CLK] = &gcc_usb1_mock_utmi_clk.clkr,
+       [GCC_USB1_PHY_CFG_AHB_CLK] = &gcc_usb1_phy_cfg_ahb_clk.clkr,
+       [GCC_USB1_SLEEP_CLK] = &gcc_usb1_sleep_clk.clkr,
+       [GCC_CMN_12GPLL_AHB_CLK] = &gcc_cmn_12gpll_ahb_clk.clkr,
+       [GCC_CMN_12GPLL_SYS_CLK] = &gcc_cmn_12gpll_sys_clk.clkr,
+       [GCC_SDCC1_ICE_CORE_CLK] = &gcc_sdcc1_ice_core_clk.clkr,
+       [SDCC1_ICE_CORE_CLK_SRC] = &sdcc1_ice_core_clk_src.clkr,
+       [GCC_DCC_CLK] = &gcc_dcc_clk.clkr,
+       [PCIE0_RCHNG_CLK_SRC] = &pcie0_rchng_clk_src.clkr,
+       [GCC_PCIE0_AXI_S_BRIDGE_CLK] = &gcc_pcie0_axi_s_bridge_clk.clkr,
+       [PCIE0_RCHNG_CLK] = &gcc_pcie0_rchng_clk.clkr,
+       [WCSS_AHB_CLK_SRC] = &wcss_ahb_clk_src.clkr,
+       [Q6_AXI_CLK_SRC] = &q6_axi_clk_src.clkr,
+       [RBCPR_WCSS_CLK_SRC] = &rbcpr_wcss_clk_src.clkr,
+       [GCC_LPASS_CORE_AXIM_CLK] = &gcc_lpass_core_axim_clk.clkr,
+       [LPASS_CORE_AXIM_CLK_SRC] = &lpass_core_axim_clk_src.clkr,
+       [GCC_LPASS_SNOC_CFG_CLK] = &gcc_lpass_snoc_cfg_clk.clkr,
+       [LPASS_SNOC_CFG_CLK_SRC] = &lpass_snoc_cfg_clk_src.clkr,
+       [GCC_LPASS_Q6_AXIM_CLK] = &gcc_lpass_q6_axim_clk.clkr,
+       [LPASS_Q6_AXIM_CLK_SRC] = &lpass_q6_axim_clk_src.clkr,
+       [GCC_LPASS_Q6_ATBM_AT_CLK] = &gcc_lpass_q6_atbm_at_clk.clkr,
+       [GCC_LPASS_Q6_PCLKDBG_CLK] = &gcc_lpass_q6_pclkdbg_clk.clkr,
+       [GCC_LPASS_Q6SS_TSCTR_1TO2_CLK] = &gcc_lpass_q6ss_tsctr_1to2_clk.clkr,
+       [GCC_LPASS_Q6SS_TRIG_CLK] = &gcc_lpass_q6ss_trig_clk.clkr,
+       [GCC_LPASS_TBU_CLK] = &gcc_lpass_tbu_clk.clkr,
+       [GCC_PCNOC_LPASS_CLK] = &gcc_pcnoc_lpass_clk.clkr,
+       [GCC_MEM_NOC_UBI32_CLK] = &gcc_mem_noc_ubi32_clk.clkr,
+       [GCC_MEM_NOC_LPASS_CLK] = &gcc_mem_noc_lpass_clk.clkr,
+       [GCC_SNOC_LPASS_CFG_CLK] = &gcc_snoc_lpass_cfg_clk.clkr,
+       [QDSS_STM_CLK_SRC] = &qdss_stm_clk_src.clkr,
+       [QDSS_TRACECLKIN_CLK_SRC] = &qdss_traceclkin_clk_src.clkr,
+};
+
+static const struct qcom_reset_map gcc_ipq6018_resets[] = {
+       [GCC_BLSP1_BCR] = { 0x01000, 0 },
+       [GCC_BLSP1_QUP1_BCR] = { 0x02000, 0 },
+       [GCC_BLSP1_UART1_BCR] = { 0x02038, 0 },
+       [GCC_BLSP1_QUP2_BCR] = { 0x03008, 0 },
+       [GCC_BLSP1_UART2_BCR] = { 0x03028, 0 },
+       [GCC_BLSP1_QUP3_BCR] = { 0x04008, 0 },
+       [GCC_BLSP1_UART3_BCR] = { 0x04028, 0 },
+       [GCC_BLSP1_QUP4_BCR] = { 0x05008, 0 },
+       [GCC_BLSP1_UART4_BCR] = { 0x05028, 0 },
+       [GCC_BLSP1_QUP5_BCR] = { 0x06008, 0 },
+       [GCC_BLSP1_UART5_BCR] = { 0x06028, 0 },
+       [GCC_BLSP1_QUP6_BCR] = { 0x07008, 0 },
+       [GCC_BLSP1_UART6_BCR] = { 0x07028, 0 },
+       [GCC_IMEM_BCR] = { 0x0e000, 0 },
+       [GCC_SMMU_BCR] = { 0x12000, 0 },
+       [GCC_APSS_TCU_BCR] = { 0x12050, 0 },
+       [GCC_SMMU_XPU_BCR] = { 0x12054, 0 },
+       [GCC_PCNOC_TBU_BCR] = { 0x12058, 0 },
+       [GCC_SMMU_CFG_BCR] = { 0x1208c, 0 },
+       [GCC_PRNG_BCR] = { 0x13000, 0 },
+       [GCC_BOOT_ROM_BCR] = { 0x13008, 0 },
+       [GCC_CRYPTO_BCR] = { 0x16000, 0 },
+       [GCC_WCSS_BCR] = { 0x18000, 0 },
+       [GCC_WCSS_Q6_BCR] = { 0x18100, 0 },
+       [GCC_NSS_BCR] = { 0x19000, 0 },
+       [GCC_SEC_CTRL_BCR] = { 0x1a000, 0 },
+       [GCC_ADSS_BCR] = { 0x1c000, 0 },
+       [GCC_DDRSS_BCR] = { 0x1e000, 0 },
+       [GCC_SYSTEM_NOC_BCR] = { 0x26000, 0 },
+       [GCC_PCNOC_BCR] = { 0x27018, 0 },
+       [GCC_TCSR_BCR] = { 0x28000, 0 },
+       [GCC_QDSS_BCR] = { 0x29000, 0 },
+       [GCC_DCD_BCR] = { 0x2a000, 0 },
+       [GCC_MSG_RAM_BCR] = { 0x2b000, 0 },
+       [GCC_MPM_BCR] = { 0x2c000, 0 },
+       [GCC_SPDM_BCR] = { 0x2f000, 0 },
+       [GCC_RBCPR_BCR] = { 0x33000, 0 },
+       [GCC_RBCPR_MX_BCR] = { 0x33014, 0 },
+       [GCC_TLMM_BCR] = { 0x34000, 0 },
+       [GCC_RBCPR_WCSS_BCR] = { 0x3a000, 0 },
+       [GCC_USB0_PHY_BCR] = { 0x3e034, 0 },
+       [GCC_USB3PHY_0_PHY_BCR] = { 0x3e03c, 0 },
+       [GCC_USB0_BCR] = { 0x3e070, 0 },
+       [GCC_USB1_BCR] = { 0x3f070, 0 },
+       [GCC_QUSB2_0_PHY_BCR] = { 0x4103c, 0 },
+       [GCC_QUSB2_1_PHY_BCR] = { 0x41040, 0 },
+       [GCC_SDCC1_BCR] = { 0x42000, 0 },
+       [GCC_SNOC_BUS_TIMEOUT0_BCR] = { 0x47000, 0 },
+       [GCC_SNOC_BUS_TIMEOUT1_BCR] = { 0x47008, 0 },
+       [GCC_SNOC_BUS_TIMEOUT2_BCR] = { 0x47010, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT0_BCR] = { 0x48000, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT1_BCR] = { 0x48008, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT2_BCR] = { 0x48010, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT3_BCR] = { 0x48018, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT4_BCR] = { 0x48020, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT5_BCR] = { 0x48028, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT6_BCR] = { 0x48030, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT7_BCR] = { 0x48038, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT8_BCR] = { 0x48040, 0 },
+       [GCC_PCNOC_BUS_TIMEOUT9_BCR] = { 0x48048, 0 },
+       [GCC_UNIPHY0_BCR] = { 0x56000, 0 },
+       [GCC_UNIPHY1_BCR] = { 0x56100, 0 },
+       [GCC_CMN_12GPLL_BCR] = { 0x56300, 0 },
+       [GCC_QPIC_BCR] = { 0x57018, 0 },
+       [GCC_MDIO_BCR] = { 0x58000, 0 },
+       [GCC_WCSS_CORE_TBU_BCR] = { 0x66000, 0 },
+       [GCC_WCSS_Q6_TBU_BCR] = { 0x67000, 0 },
+       [GCC_USB0_TBU_BCR] = { 0x6a000, 0 },
+       [GCC_PCIE0_TBU_BCR] = { 0x6b000, 0 },
+       [GCC_NSS_NOC_TBU_BCR] = { 0x6e000, 0 },
+       [GCC_PCIE0_BCR] = { 0x75004, 0 },
+       [GCC_PCIE0_PHY_BCR] = { 0x75038, 0 },
+       [GCC_PCIE0PHY_PHY_BCR] = { 0x7503c, 0 },
+       [GCC_PCIE0_LINK_DOWN_BCR] = { 0x75044, 0 },
+       [GCC_DCC_BCR] = { 0x77000, 0 },
+       [GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR] = { 0x78000, 0 },
+       [GCC_SMMU_CATS_BCR] = { 0x7c000, 0 },
+       [GCC_UBI0_AXI_ARES] = { 0x68010, 0 },
+       [GCC_UBI0_AHB_ARES] = { 0x68010, 1 },
+       [GCC_UBI0_NC_AXI_ARES] = { 0x68010, 2 },
+       [GCC_UBI0_DBG_ARES] = { 0x68010, 3 },
+       [GCC_UBI0_CORE_CLAMP_ENABLE] = { 0x68010, 4 },
+       [GCC_UBI0_CLKRST_CLAMP_ENABLE] = { 0x68010, 5 },
+       [GCC_UBI0_UTCM_ARES] = { 0x68010, 6 },
+       [GCC_UBI0_CORE_ARES] = { 0x68010, 7 },
+       [GCC_NSS_CFG_ARES] = { 0x68010, 16 },
+       [GCC_NSS_NOC_ARES] = { 0x68010, 18 },
+       [GCC_NSS_CRYPTO_ARES] = { 0x68010, 19 },
+       [GCC_NSS_CSR_ARES] = { 0x68010, 20 },
+       [GCC_NSS_CE_APB_ARES] = { 0x68010, 21 },
+       [GCC_NSS_CE_AXI_ARES] = { 0x68010, 22 },
+       [GCC_NSSNOC_CE_APB_ARES] = { 0x68010, 23 },
+       [GCC_NSSNOC_CE_AXI_ARES] = { 0x68010, 24 },
+       [GCC_NSSNOC_UBI0_AHB_ARES] = { 0x68010, 25 },
+       [GCC_NSSNOC_SNOC_ARES] = { 0x68010, 27 },
+       [GCC_NSSNOC_CRYPTO_ARES] = { 0x68010, 28 },
+       [GCC_NSSNOC_ATB_ARES] = { 0x68010, 29 },
+       [GCC_NSSNOC_QOSGEN_REF_ARES] = { 0x68010, 30 },
+       [GCC_NSSNOC_TIMEOUT_REF_ARES] = { 0x68010, 31 },
+       [GCC_PCIE0_PIPE_ARES] = { 0x75040, 0 },
+       [GCC_PCIE0_SLEEP_ARES] = { 0x75040, 1 },
+       [GCC_PCIE0_CORE_STICKY_ARES] = { 0x75040, 2 },
+       [GCC_PCIE0_AXI_MASTER_ARES] = { 0x75040, 3 },
+       [GCC_PCIE0_AXI_SLAVE_ARES] = { 0x75040, 4 },
+       [GCC_PCIE0_AHB_ARES] = { 0x75040, 5 },
+       [GCC_PCIE0_AXI_MASTER_STICKY_ARES] = { 0x75040, 6 },
+       [GCC_PCIE0_AXI_SLAVE_STICKY_ARES] = { 0x75040, 7 },
+       [GCC_PPE_FULL_RESET] = { 0x68014, 0 },
+       [GCC_UNIPHY0_SOFT_RESET] = { 0x56004, 0 },
+       [GCC_UNIPHY0_XPCS_RESET] = { 0x56004, 2 },
+       [GCC_UNIPHY1_SOFT_RESET] = { 0x56104, 0 },
+       [GCC_UNIPHY1_XPCS_RESET] = { 0x56104, 2 },
+       [GCC_EDMA_HW_RESET] = { 0x68014, 0 },
+       [GCC_NSSPORT1_RESET] = { 0x68014, 0 },
+       [GCC_NSSPORT2_RESET] = { 0x68014, 0 },
+       [GCC_NSSPORT3_RESET] = { 0x68014, 0 },
+       [GCC_NSSPORT4_RESET] = { 0x68014, 0 },
+       [GCC_NSSPORT5_RESET] = { 0x68014, 0 },
+       [GCC_UNIPHY0_PORT1_ARES] = { 0x56004, 0 },
+       [GCC_UNIPHY0_PORT2_ARES] = { 0x56004, 0 },
+       [GCC_UNIPHY0_PORT3_ARES] = { 0x56004, 0 },
+       [GCC_UNIPHY0_PORT4_ARES] = { 0x56004, 0 },
+       [GCC_UNIPHY0_PORT5_ARES] = { 0x56004, 0 },
+       [GCC_UNIPHY0_PORT_4_5_RESET] = { 0x56004, 0 },
+       [GCC_UNIPHY0_PORT_4_RESET] = { 0x56004, 0 },
+       [GCC_LPASS_BCR] = {0x1F000, 0},
+       [GCC_UBI32_TBU_BCR] = {0x65000, 0},
+       [GCC_LPASS_TBU_BCR] = {0x6C000, 0},
+       [GCC_WCSSAON_RESET] = {0x59010, 0},
+       [GCC_LPASS_Q6_AXIM_ARES] = {0x1F004, 0},
+       [GCC_LPASS_Q6SS_TSCTR_1TO2_ARES] = {0x1F004, 1},
+       [GCC_LPASS_Q6SS_TRIG_ARES] = {0x1F004, 2},
+       [GCC_LPASS_Q6_ATBM_AT_ARES] = {0x1F004, 3},
+       [GCC_LPASS_Q6_PCLKDBG_ARES] = {0x1F004, 4},
+       [GCC_LPASS_CORE_AXIM_ARES] = {0x1F004, 5},
+       [GCC_LPASS_SNOC_CFG_ARES] = {0x1F004, 6},
+       [GCC_WCSS_DBG_ARES] = {0x59008, 0},
+       [GCC_WCSS_ECAHB_ARES] = {0x59008, 1},
+       [GCC_WCSS_ACMT_ARES] = {0x59008, 2},
+       [GCC_WCSS_DBG_BDG_ARES] = {0x59008, 3},
+       [GCC_WCSS_AHB_S_ARES] = {0x59008, 4},
+       [GCC_WCSS_AXI_M_ARES] = {0x59008, 5},
+       [GCC_Q6SS_DBG_ARES] = {0x59110, 0},
+       [GCC_Q6_AHB_S_ARES] = {0x59110, 1},
+       [GCC_Q6_AHB_ARES] = {0x59110, 2},
+       [GCC_Q6_AXIM2_ARES] = {0x59110, 3},
+       [GCC_Q6_AXIM_ARES] = {0x59110, 4},
+};
+
+static const struct of_device_id gcc_ipq6018_match_table[] = {
+       { .compatible = "qcom,gcc-ipq6018" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gcc_ipq6018_match_table);
+
+static const struct regmap_config gcc_ipq6018_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x7fffc,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc gcc_ipq6018_desc = {
+       .config = &gcc_ipq6018_regmap_config,
+       .clks = gcc_ipq6018_clks,
+       .num_clks = ARRAY_SIZE(gcc_ipq6018_clks),
+       .resets = gcc_ipq6018_resets,
+       .num_resets = ARRAY_SIZE(gcc_ipq6018_resets),
+       .clk_hws = gcc_ipq6018_hws,
+       .num_clk_hws = ARRAY_SIZE(gcc_ipq6018_hws),
+};
+
+static int gcc_ipq6018_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &gcc_ipq6018_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /* Disable SW_COLLAPSE for USB0 GDSCR */
+       regmap_update_bits(regmap, 0x3e078, BIT(0), 0x0);
+       /* Enable SW_OVERRIDE for USB0 GDSCR */
+       regmap_update_bits(regmap, 0x3e078, BIT(2), BIT(2));
+       /* Disable SW_COLLAPSE for USB1 GDSCR */
+       regmap_update_bits(regmap, 0x3f078, BIT(0), 0x0);
+       /* Enable SW_OVERRIDE for USB1 GDSCR */
+       regmap_update_bits(regmap, 0x3f078, BIT(2), BIT(2));
+
+       /* SW Workaround for UBI Huyara PLL */
+       regmap_update_bits(regmap, 0x2501c, BIT(26), BIT(26));
+
+       clk_alpha_pll_configure(&ubi32_pll_main, regmap, &ubi32_pll_config);
+
+       clk_alpha_pll_configure(&nss_crypto_pll_main, regmap,
+                               &nss_crypto_pll_config);
+
+       return qcom_cc_really_probe(pdev, &gcc_ipq6018_desc, regmap);
+}
+
+static struct platform_driver gcc_ipq6018_driver = {
+       .probe = gcc_ipq6018_probe,
+       .driver = {
+               .name   = "qcom,gcc-ipq6018",
+               .of_match_table = gcc_ipq6018_match_table,
+       },
+};
+
+static int __init gcc_ipq6018_init(void)
+{
+       return platform_driver_register(&gcc_ipq6018_driver);
+}
+core_initcall(gcc_ipq6018_init);
+
+static void __exit gcc_ipq6018_exit(void)
+{
+       platform_driver_unregister(&gcc_ipq6018_driver);
+}
+module_exit(gcc_ipq6018_exit);
+
+MODULE_DESCRIPTION("Qualcomm Technologies, Inc. GCC IPQ6018 Driver");
+MODULE_LICENSE("GPL v2");
index d004cda..3c3a7ff 100644 (file)
@@ -3046,7 +3046,10 @@ static struct clk_branch gcc_usb3_clkref_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_usb3_clkref_clk",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "cxo2",
+                               .name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
@@ -3060,7 +3063,10 @@ static struct clk_branch gcc_hdmi_clkref_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_hdmi_clkref_clk",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "cxo2",
+                               .name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
@@ -3074,7 +3080,10 @@ static struct clk_branch gcc_edp_clkref_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_edp_clkref_clk",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "cxo2",
+                               .name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
@@ -3088,7 +3097,10 @@ static struct clk_branch gcc_ufs_clkref_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_ufs_clkref_clk",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "cxo2",
+                               .name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
@@ -3102,7 +3114,10 @@ static struct clk_branch gcc_pcie_clkref_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_pcie_clkref_clk",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "cxo2",
+                               .name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
@@ -3116,7 +3131,10 @@ static struct clk_branch gcc_rx2_usb2_clkref_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_rx2_usb2_clkref_clk",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "cxo2",
+                               .name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
@@ -3130,7 +3148,10 @@ static struct clk_branch gcc_rx1_usb2_clkref_clk = {
                .enable_mask = BIT(0),
                .hw.init = &(struct clk_init_data){
                        .name = "gcc_rx1_usb2_clkref_clk",
-                       .parent_names = (const char *[]){ "xo" },
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "cxo2",
+                               .name = "xo",
+                       },
                        .num_parents = 1,
                        .ops = &clk_branch2_ops,
                },
index cf31b5d..df1d705 100644 (file)
@@ -1996,6 +1996,19 @@ static struct clk_branch gcc_gp3_clk = {
        },
 };
 
+static struct clk_branch gcc_bimc_gfx_clk = {
+       .halt_reg = 0x46040,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x46040,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gcc_bimc_gfx_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
 static struct clk_branch gcc_gpu_bimc_gfx_clk = {
        .halt_reg = 0x71010,
        .halt_check = BRANCH_HALT,
@@ -2810,6 +2823,7 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
        [GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
        [GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
        [GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
+       [GCC_BIMC_GFX_CLK] = &gcc_bimc_gfx_clk.clkr,
        [GCC_GPU_BIMC_GFX_CLK] = &gcc_gpu_bimc_gfx_clk.clkr,
        [GCC_GPU_BIMC_GFX_SRC_CLK] = &gcc_gpu_bimc_gfx_src_clk.clkr,
        [GCC_GPU_CFG_AHB_CLK] = &gcc_gpu_cfg_ahb_clk.clkr,
index 9b0c4ce..46d314d 100644 (file)
@@ -330,7 +330,7 @@ static struct clk_alpha_pll gpll0_ao_out_main = {
                        .parent_names = (const char *[]){ "cxo" },
                        .num_parents = 1,
                        .flags = CLK_IS_CRITICAL,
-                       .ops = &clk_alpha_pll_ops,
+                       .ops = &clk_alpha_pll_fixed_ops,
                },
        },
 };
diff --git a/drivers/clk/qcom/gpucc-sc7180.c b/drivers/clk/qcom/gpucc-sc7180.c
new file mode 100644 (file)
index 0000000..a96c0b9
--- /dev/null
@@ -0,0 +1,264 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,gpucc-sc7180.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "common.h"
+#include "gdsc.h"
+
+#define CX_GMU_CBCR_SLEEP_MASK         0xF
+#define CX_GMU_CBCR_SLEEP_SHIFT                4
+#define CX_GMU_CBCR_WAKE_MASK          0xF
+#define CX_GMU_CBCR_WAKE_SHIFT         8
+#define CLK_DIS_WAIT_SHIFT             12
+#define CLK_DIS_WAIT_MASK              (0xf << CLK_DIS_WAIT_SHIFT)
+
+enum {
+       P_BI_TCXO,
+       P_CORE_BI_PLL_TEST_SE,
+       P_GPLL0_OUT_MAIN,
+       P_GPLL0_OUT_MAIN_DIV,
+       P_GPU_CC_PLL1_OUT_EVEN,
+       P_GPU_CC_PLL1_OUT_MAIN,
+       P_GPU_CC_PLL1_OUT_ODD,
+};
+
+static const struct pll_vco fabia_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+static struct clk_alpha_pll gpu_cc_pll1 = {
+       .offset = 0x100,
+       .vco_table = fabia_vco,
+       .num_vco = ARRAY_SIZE(fabia_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_pll1",
+                       .parent_data =  &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fabia_ops,
+               },
+       },
+};
+
+static const struct parent_map gpu_cc_parent_map_0[] = {
+       { P_BI_TCXO, 0 },
+       { P_GPU_CC_PLL1_OUT_MAIN, 3 },
+       { P_GPLL0_OUT_MAIN, 5 },
+       { P_GPLL0_OUT_MAIN_DIV, 6 },
+};
+
+static const struct clk_parent_data gpu_cc_parent_data_0[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &gpu_cc_pll1.clkr.hw },
+       { .fw_name = "gcc_gpu_gpll0_clk_src" },
+       { .fw_name = "gcc_gpu_gpll0_div_clk_src" },
+};
+
+static const struct freq_tbl ftbl_gpu_cc_gmu_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(200000000, P_GPLL0_OUT_MAIN_DIV, 1.5, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 gpu_cc_gmu_clk_src = {
+       .cmd_rcgr = 0x1120,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = gpu_cc_parent_map_0,
+       .freq_tbl = ftbl_gpu_cc_gmu_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "gpu_cc_gmu_clk_src",
+               .parent_data = gpu_cc_parent_data_0,
+               .num_parents = ARRAY_SIZE(gpu_cc_parent_data_0),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_branch gpu_cc_crc_ahb_clk = {
+       .halt_reg = 0x107c,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x107c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_crc_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cx_gmu_clk = {
+       .halt_reg = 0x1098,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x1098,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_cx_gmu_clk",
+                       .parent_data =  &(const struct clk_parent_data){
+                               .hw = &gpu_cc_gmu_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cx_snoc_dvm_clk = {
+       .halt_reg = 0x108c,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x108c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_cx_snoc_dvm_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cxo_aon_clk = {
+       .halt_reg = 0x1004,
+       .halt_check = BRANCH_HALT_DELAY,
+       .clkr = {
+               .enable_reg = 0x1004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_cxo_aon_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch gpu_cc_cxo_clk = {
+       .halt_reg = 0x109c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x109c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "gpu_cc_cxo_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc cx_gdsc = {
+       .gdscr = 0x106c,
+       .gds_hw_ctrl = 0x1540,
+       .pd = {
+               .name = "cx_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = VOTABLE,
+};
+
+static struct gdsc *gpu_cc_sc7180_gdscs[] = {
+       [CX_GDSC] = &cx_gdsc,
+};
+
+static struct clk_regmap *gpu_cc_sc7180_clocks[] = {
+       [GPU_CC_CXO_CLK] = &gpu_cc_cxo_clk.clkr,
+       [GPU_CC_CRC_AHB_CLK] = &gpu_cc_crc_ahb_clk.clkr,
+       [GPU_CC_CX_GMU_CLK] = &gpu_cc_cx_gmu_clk.clkr,
+       [GPU_CC_CX_SNOC_DVM_CLK] = &gpu_cc_cx_snoc_dvm_clk.clkr,
+       [GPU_CC_CXO_AON_CLK] = &gpu_cc_cxo_aon_clk.clkr,
+       [GPU_CC_GMU_CLK_SRC] = &gpu_cc_gmu_clk_src.clkr,
+       [GPU_CC_PLL1] = &gpu_cc_pll1.clkr,
+};
+
+static const struct regmap_config gpu_cc_sc7180_regmap_config = {
+       .reg_bits =     32,
+       .reg_stride =   4,
+       .val_bits =     32,
+       .max_register = 0x8008,
+       .fast_io =      true,
+};
+
+static const struct qcom_cc_desc gpu_cc_sc7180_desc = {
+       .config = &gpu_cc_sc7180_regmap_config,
+       .clks = gpu_cc_sc7180_clocks,
+       .num_clks = ARRAY_SIZE(gpu_cc_sc7180_clocks),
+       .gdscs = gpu_cc_sc7180_gdscs,
+       .num_gdscs = ARRAY_SIZE(gpu_cc_sc7180_gdscs),
+};
+
+static const struct of_device_id gpu_cc_sc7180_match_table[] = {
+       { .compatible = "qcom,sc7180-gpucc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, gpu_cc_sc7180_match_table);
+
+static int gpu_cc_sc7180_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       struct alpha_pll_config gpu_cc_pll_config = {};
+       unsigned int value, mask;
+
+       regmap = qcom_cc_map(pdev, &gpu_cc_sc7180_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       /* 360MHz Configuration */
+       gpu_cc_pll_config.l = 0x12;
+       gpu_cc_pll_config.alpha = 0xc000;
+       gpu_cc_pll_config.config_ctl_val = 0x20485699;
+       gpu_cc_pll_config.config_ctl_hi_val = 0x00002067;
+       gpu_cc_pll_config.user_ctl_val = 0x00000001;
+       gpu_cc_pll_config.user_ctl_hi_val = 0x00004805;
+       gpu_cc_pll_config.test_ctl_hi_val = 0x40000000;
+
+       clk_fabia_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll_config);
+
+       /* Recommended WAKEUP/SLEEP settings for the gpu_cc_cx_gmu_clk */
+       mask = CX_GMU_CBCR_WAKE_MASK << CX_GMU_CBCR_WAKE_SHIFT;
+       mask |= CX_GMU_CBCR_SLEEP_MASK << CX_GMU_CBCR_SLEEP_SHIFT;
+       value = 0xF << CX_GMU_CBCR_WAKE_SHIFT | 0xF << CX_GMU_CBCR_SLEEP_SHIFT;
+       regmap_update_bits(regmap, 0x1098, mask, value);
+
+       /* Configure clk_dis_wait for gpu_cx_gdsc */
+       regmap_update_bits(regmap, 0x106c, CLK_DIS_WAIT_MASK,
+                                               8 << CLK_DIS_WAIT_SHIFT);
+
+       return qcom_cc_really_probe(pdev, &gpu_cc_sc7180_desc, regmap);
+}
+
+static struct platform_driver gpu_cc_sc7180_driver = {
+       .probe = gpu_cc_sc7180_probe,
+       .driver = {
+               .name = "sc7180-gpucc",
+               .of_match_table = gpu_cc_sc7180_match_table,
+       },
+};
+
+static int __init gpu_cc_sc7180_init(void)
+{
+       return platform_driver_register(&gpu_cc_sc7180_driver);
+}
+subsys_initcall(gpu_cc_sc7180_init);
+
+static void __exit gpu_cc_sc7180_exit(void)
+{
+       platform_driver_unregister(&gpu_cc_sc7180_driver);
+}
+module_exit(gpu_cc_sc7180_exit);
+
+MODULE_DESCRIPTION("QTI GPU_CC SC7180 Driver");
+MODULE_LICENSE("GPL v2");
index a6de710..5ff7f5a 100644 (file)
@@ -53,10 +53,18 @@ static int qcom_hfpll_probe(struct platform_device *pdev)
        struct regmap *regmap;
        struct clk_hfpll *h;
        struct clk_init_data init = {
-               .parent_names = (const char *[]){ "xo" },
                .num_parents = 1,
                .ops = &clk_ops_hfpll,
+               /*
+                * rather than marking the clock critical and forcing the clock
+                * to be always enabled, we make sure that the clock is not
+                * disabled: the firmware remains responsible of enabling this
+                * clock (for more info check the commit log)
+                */
+               .flags = CLK_IGNORE_UNUSED,
        };
+       int ret;
+       struct clk_parent_data pdata = { .index = 0 };
 
        h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
        if (!h)
@@ -75,11 +83,20 @@ static int qcom_hfpll_probe(struct platform_device *pdev)
                                          0, &init.name))
                return -ENODEV;
 
+       init.parent_data = &pdata;
+
        h->d = &hdata;
        h->clkr.hw.init = &init;
        spin_lock_init(&h->lock);
 
-       return devm_clk_register_regmap(&pdev->dev, &h->clkr);
+       ret = devm_clk_register_regmap(dev, &h->clkr);
+       if (ret) {
+               dev_err(dev, "failed to register regmap clock: %d\n", ret);
+               return ret;
+       }
+
+       return devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get,
+                                          &h->clkr.hw);
 }
 
 static struct platform_driver qcom_hfpll_driver = {
index bcb0a39..0154262 100644 (file)
@@ -452,18 +452,6 @@ static struct clk_rcg2 mdp_clk_src = {
        },
 };
 
-static struct clk_rcg2 gfx3d_clk_src = {
-       .cmd_rcgr = 0x4000,
-       .hid_width = 5,
-       .parent_map = mmcc_xo_mmpll0_1_2_gpll0_map,
-       .clkr.hw.init = &(struct clk_init_data){
-               .name = "gfx3d_clk_src",
-               .parent_names = mmcc_xo_mmpll0_1_2_gpll0,
-               .num_parents = 5,
-               .ops = &clk_rcg2_ops,
-       },
-};
-
 static struct freq_tbl ftbl_camss_jpeg_jpeg0_2_clk[] = {
        F(75000000, P_GPLL0, 8, 0, 0),
        F(133330000, P_GPLL0, 4.5, 0, 0),
@@ -2411,7 +2399,6 @@ static struct clk_regmap *mmcc_msm8974_clocks[] = {
        [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
        [VFE1_CLK_SRC] = &vfe1_clk_src.clkr,
        [MDP_CLK_SRC] = &mdp_clk_src.clkr,
-       [GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
        [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
        [JPEG1_CLK_SRC] = &jpeg1_clk_src.clkr,
        [JPEG2_CLK_SRC] = &jpeg2_clk_src.clkr,
diff --git a/drivers/clk/qcom/mmcc-msm8998.c b/drivers/clk/qcom/mmcc-msm8998.c
new file mode 100644 (file)
index 0000000..dd68983
--- /dev/null
@@ -0,0 +1,2913 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/kernel.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/clk-provider.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#include <dt-bindings/clock/qcom,mmcc-msm8998.h>
+
+#include "common.h"
+#include "clk-regmap.h"
+#include "clk-regmap-divider.h"
+#include "clk-alpha-pll.h"
+#include "clk-rcg.h"
+#include "clk-branch.h"
+#include "reset.h"
+#include "gdsc.h"
+
+enum {
+       P_XO,
+       P_GPLL0,
+       P_GPLL0_DIV,
+       P_MMPLL0_OUT_EVEN,
+       P_MMPLL1_OUT_EVEN,
+       P_MMPLL3_OUT_EVEN,
+       P_MMPLL4_OUT_EVEN,
+       P_MMPLL5_OUT_EVEN,
+       P_MMPLL6_OUT_EVEN,
+       P_MMPLL7_OUT_EVEN,
+       P_MMPLL10_OUT_EVEN,
+       P_DSI0PLL,
+       P_DSI1PLL,
+       P_DSI0PLL_BYTE,
+       P_DSI1PLL_BYTE,
+       P_HDMIPLL,
+       P_DPVCO,
+       P_DPLINK,
+       P_CORE_BI_PLL_TEST_SE,
+};
+
+static struct clk_fixed_factor gpll0_div = {
+       .mult = 1,
+       .div = 2,
+       .hw.init = &(struct clk_init_data){
+               .name = "mmss_gpll0_div",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "gpll0",
+                       .name = "gpll0"
+               },
+               .num_parents = 1,
+               .ops = &clk_fixed_factor_ops,
+       },
+};
+
+static const struct clk_div_table post_div_table_fabia_even[] = {
+       { 0x0, 1 },
+       { 0x1, 2 },
+       { 0x3, 4 },
+       { 0x7, 8 },
+       { }
+};
+
+static struct clk_alpha_pll mmpll0 = {
+       .offset = 0xc000,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .enable_reg = 0x1e0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mmpll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                               .name = "xo"
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_fabia_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll0_out_even = {
+       .offset = 0xc000,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll0_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll0.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll mmpll1 = {
+       .offset = 0xc050,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .enable_reg = 0x1e0,
+               .enable_mask = BIT(1),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mmpll1",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "xo",
+                               .name = "xo"
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fixed_fabia_ops,
+               },
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll1_out_even = {
+       .offset = 0xc050,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll1_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll1.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll mmpll3 = {
+       .offset = 0x0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll3",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+                       .name = "xo"
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_fixed_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll3_out_even = {
+       .offset = 0x0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll3_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll3.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll mmpll4 = {
+       .offset = 0x50,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll4",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+                       .name = "xo"
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_fixed_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll4_out_even = {
+       .offset = 0x50,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll4_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll4.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll mmpll5 = {
+       .offset = 0xa0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll5",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+                       .name = "xo"
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_fixed_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll5_out_even = {
+       .offset = 0xa0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll5_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll5.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll mmpll6 = {
+       .offset = 0xf0,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll6",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+                       .name = "xo"
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_fixed_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll6_out_even = {
+       .offset = 0xf0,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll6_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll6.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll mmpll7 = {
+       .offset = 0x140,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll7",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+                       .name = "xo"
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_fixed_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll7_out_even = {
+       .offset = 0x140,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll7_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll7.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll mmpll10 = {
+       .offset = 0x190,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll10",
+               .parent_data = &(const struct clk_parent_data){
+                       .fw_name = "xo",
+                       .name = "xo"
+               },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_fixed_fabia_ops,
+       },
+};
+
+static struct clk_alpha_pll_postdiv mmpll10_out_even = {
+       .offset = 0x190,
+       .post_div_shift = 8,
+       .post_div_table = post_div_table_fabia_even,
+       .num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
+       .width = 4,
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mmpll10_out_even",
+               .parent_hws = (const struct clk_hw *[]){ &mmpll10.clkr.hw },
+               .num_parents = 1,
+               .ops = &clk_alpha_pll_postdiv_fabia_ops,
+       },
+};
+
+static const struct parent_map mmss_xo_hdmi_map[] = {
+       { P_XO, 0 },
+       { P_HDMIPLL, 1 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_hdmi[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .fw_name = "hdmipll", .name = "hdmipll" },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_dsi0pll_dsi1pll_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL, 1 },
+       { P_DSI1PLL, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_dsi0pll_dsi1pll[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .fw_name = "dsi0dsi", .name = "dsi0dsi" },
+       { .fw_name = "dsi1dsi", .name = "dsi1dsi" },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_dsibyte_map[] = {
+       { P_XO, 0 },
+       { P_DSI0PLL_BYTE, 1 },
+       { P_DSI1PLL_BYTE, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_dsibyte[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .fw_name = "dsi0byte", .name = "dsi0byte" },
+       { .fw_name = "dsi1byte", .name = "dsi1byte" },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_dp_map[] = {
+       { P_XO, 0 },
+       { P_DPLINK, 1 },
+       { P_DPVCO, 2 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_dp[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .fw_name = "dplink", .name = "dplink" },
+       { .fw_name = "dpvco", .name = "dpvco" },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_gpll0_gpll0_div_map[] = {
+       { P_XO, 0 },
+       { P_GPLL0, 5 },
+       { P_GPLL0_DIV, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_gpll0_gpll0_div[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .fw_name = "gpll0", .name = "gpll0" },
+       { .hw = &gpll0_div.hw },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_mmpll0_gpll0_gpll0_div_map[] = {
+       { P_XO, 0 },
+       { P_MMPLL0_OUT_EVEN, 1 },
+       { P_GPLL0, 5 },
+       { P_GPLL0_DIV, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_mmpll0_gpll0_gpll0_div[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .hw = &mmpll0_out_even.clkr.hw },
+       { .fw_name = "gpll0", .name = "gpll0" },
+       { .hw = &gpll0_div.hw },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map[] = {
+       { P_XO, 0 },
+       { P_MMPLL0_OUT_EVEN, 1 },
+       { P_MMPLL1_OUT_EVEN, 2 },
+       { P_GPLL0, 5 },
+       { P_GPLL0_DIV, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .hw = &mmpll0_out_even.clkr.hw },
+       { .hw = &mmpll1_out_even.clkr.hw },
+       { .fw_name = "gpll0", .name = "gpll0" },
+       { .hw = &gpll0_div.hw },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map[] = {
+       { P_XO, 0 },
+       { P_MMPLL0_OUT_EVEN, 1 },
+       { P_MMPLL5_OUT_EVEN, 2 },
+       { P_GPLL0, 5 },
+       { P_GPLL0_DIV, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .hw = &mmpll0_out_even.clkr.hw },
+       { .hw = &mmpll5_out_even.clkr.hw },
+       { .fw_name = "gpll0", .name = "gpll0" },
+       { .hw = &gpll0_div.hw },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map[] = {
+       { P_XO, 0 },
+       { P_MMPLL0_OUT_EVEN, 1 },
+       { P_MMPLL3_OUT_EVEN, 3 },
+       { P_MMPLL6_OUT_EVEN, 4 },
+       { P_GPLL0, 5 },
+       { P_GPLL0_DIV, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .hw = &mmpll0_out_even.clkr.hw },
+       { .hw = &mmpll3_out_even.clkr.hw },
+       { .hw = &mmpll6_out_even.clkr.hw },
+       { .fw_name = "gpll0", .name = "gpll0" },
+       { .hw = &gpll0_div.hw },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map[] = {
+       { P_XO, 0 },
+       { P_MMPLL4_OUT_EVEN, 1 },
+       { P_MMPLL7_OUT_EVEN, 2 },
+       { P_MMPLL10_OUT_EVEN, 3 },
+       { P_GPLL0, 5 },
+       { P_GPLL0_DIV, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .hw = &mmpll4_out_even.clkr.hw },
+       { .hw = &mmpll7_out_even.clkr.hw },
+       { .hw = &mmpll10_out_even.clkr.hw },
+       { .fw_name = "gpll0", .name = "gpll0" },
+       { .hw = &gpll0_div.hw },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div_map[] = {
+       { P_XO, 0 },
+       { P_MMPLL0_OUT_EVEN, 1 },
+       { P_MMPLL7_OUT_EVEN, 2 },
+       { P_MMPLL10_OUT_EVEN, 3 },
+       { P_GPLL0, 5 },
+       { P_GPLL0_DIV, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .hw = &mmpll0_out_even.clkr.hw },
+       { .hw = &mmpll7_out_even.clkr.hw },
+       { .hw = &mmpll10_out_even.clkr.hw },
+       { .fw_name = "gpll0", .name = "gpll0" },
+       { .hw = &gpll0_div.hw },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static const struct parent_map mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map[] = {
+       { P_XO, 0 },
+       { P_MMPLL0_OUT_EVEN, 1 },
+       { P_MMPLL4_OUT_EVEN, 2 },
+       { P_MMPLL7_OUT_EVEN, 3 },
+       { P_MMPLL10_OUT_EVEN, 4 },
+       { P_GPLL0, 5 },
+       { P_GPLL0_DIV, 6 },
+       { P_CORE_BI_PLL_TEST_SE, 7 }
+};
+
+static const struct clk_parent_data mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div[] = {
+       { .fw_name = "xo", .name = "xo" },
+       { .hw = &mmpll0_out_even.clkr.hw },
+       { .hw = &mmpll4_out_even.clkr.hw },
+       { .hw = &mmpll7_out_even.clkr.hw },
+       { .hw = &mmpll10_out_even.clkr.hw },
+       { .fw_name = "gpll0", .name = "gpll0" },
+       { .hw = &gpll0_div.hw },
+       { .fw_name = "core_bi_pll_test_se", .name = "core_bi_pll_test_se" },
+};
+
+static struct clk_rcg2 byte0_clk_src = {
+       .cmd_rcgr = 0x2120,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dsibyte_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "byte0_clk_src",
+               .parent_data = mmss_xo_dsibyte,
+               .num_parents = 4,
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_rcg2 byte1_clk_src = {
+       .cmd_rcgr = 0x2140,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dsibyte_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "byte1_clk_src",
+               .parent_data = mmss_xo_dsibyte,
+               .num_parents = 4,
+               .ops = &clk_byte2_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_cci_clk_src[] = {
+       F(37500000, P_GPLL0, 16, 0, 0),
+       F(50000000, P_GPLL0, 12, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cci_clk_src = {
+       .cmd_rcgr = 0x3300,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_cci_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cci_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_cpp_clk_src[] = {
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(384000000, P_MMPLL4_OUT_EVEN, 2, 0, 0),
+       F(404000000, P_MMPLL0_OUT_EVEN, 2, 0, 0),
+       F(480000000, P_MMPLL7_OUT_EVEN, 2, 0, 0),
+       F(576000000, P_MMPLL10_OUT_EVEN, 1, 0, 0),
+       F(600000000, P_GPLL0, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 cpp_clk_src = {
+       .cmd_rcgr = 0x3640,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_cpp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "cpp_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csi_clk_src[] = {
+       F(164571429, P_MMPLL10_OUT_EVEN, 3.5, 0, 0),
+       F(256000000, P_MMPLL4_OUT_EVEN, 3, 0, 0),
+       F(274290000, P_MMPLL7_OUT_EVEN, 3.5, 0, 0),
+       F(300000000, P_GPLL0, 2, 0, 0),
+       F(384000000, P_MMPLL4_OUT_EVEN, 2, 0, 0),
+       F(576000000, P_MMPLL10_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0_clk_src = {
+       .cmd_rcgr = 0x3090,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_csi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi0_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi1_clk_src = {
+       .cmd_rcgr = 0x3100,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_csi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi1_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi2_clk_src = {
+       .cmd_rcgr = 0x3160,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_csi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi2_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi3_clk_src = {
+       .cmd_rcgr = 0x31c0,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_csi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi3_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csiphy_clk_src[] = {
+       F(164571429, P_MMPLL10_OUT_EVEN, 3.5, 0, 0),
+       F(256000000, P_MMPLL4_OUT_EVEN, 3, 0, 0),
+       F(274290000, P_MMPLL7_OUT_EVEN, 3.5, 0, 0),
+       F(300000000, P_GPLL0, 2, 0, 0),
+       F(384000000, P_MMPLL4_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csiphy_clk_src = {
+       .cmd_rcgr = 0x3800,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_csiphy_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csiphy_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_csiphytimer_clk_src[] = {
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(269333333, P_MMPLL0_OUT_EVEN, 3, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 csi0phytimer_clk_src = {
+       .cmd_rcgr = 0x3000,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_csiphytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi0phytimer_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi1phytimer_clk_src = {
+       .cmd_rcgr = 0x3030,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_csiphytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi1phytimer_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 csi2phytimer_clk_src = {
+       .cmd_rcgr = 0x3060,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_csiphytimer_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "csi2phytimer_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_dp_aux_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 dp_aux_clk_src = {
+       .cmd_rcgr = 0x2260,
+       .hid_width = 5,
+       .parent_map = mmss_xo_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_dp_aux_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "dp_aux_clk_src",
+               .parent_data = mmss_xo_gpll0_gpll0_div,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_dp_crypto_clk_src[] = {
+       F(101250, P_DPLINK, 1, 5, 16),
+       F(168750, P_DPLINK, 1, 5, 16),
+       F(337500, P_DPLINK, 1, 5, 16),
+       { }
+};
+
+static struct clk_rcg2 dp_crypto_clk_src = {
+       .cmd_rcgr = 0x2220,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dp_map,
+       .freq_tbl = ftbl_dp_crypto_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "dp_crypto_clk_src",
+               .parent_data = mmss_xo_dp,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_dp_link_clk_src[] = {
+       F(162000, P_DPLINK, 2, 0, 0),
+       F(270000, P_DPLINK, 2, 0, 0),
+       F(540000, P_DPLINK, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 dp_link_clk_src = {
+       .cmd_rcgr = 0x2200,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dp_map,
+       .freq_tbl = ftbl_dp_link_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "dp_link_clk_src",
+               .parent_data = mmss_xo_dp,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_dp_pixel_clk_src[] = {
+       F(154000000, P_DPVCO, 1, 0, 0),
+       F(337500000, P_DPVCO, 2, 0, 0),
+       F(675000000, P_DPVCO, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 dp_pixel_clk_src = {
+       .cmd_rcgr = 0x2240,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dp_map,
+       .freq_tbl = ftbl_dp_pixel_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "dp_pixel_clk_src",
+               .parent_data = mmss_xo_dp,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_esc_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 esc0_clk_src = {
+       .cmd_rcgr = 0x2160,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dsibyte_map,
+       .freq_tbl = ftbl_esc_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "esc0_clk_src",
+               .parent_data = mmss_xo_dsibyte,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 esc1_clk_src = {
+       .cmd_rcgr = 0x2180,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dsibyte_map,
+       .freq_tbl = ftbl_esc_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "esc1_clk_src",
+               .parent_data = mmss_xo_dsibyte,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_extpclk_clk_src[] = {
+       { .src = P_HDMIPLL },
+       { }
+};
+
+static struct clk_rcg2 extpclk_clk_src = {
+       .cmd_rcgr = 0x2060,
+       .hid_width = 5,
+       .parent_map = mmss_xo_hdmi_map,
+       .freq_tbl = ftbl_extpclk_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "extpclk_clk_src",
+               .parent_data = mmss_xo_hdmi,
+               .num_parents = 3,
+               .ops = &clk_byte_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_fd_core_clk_src[] = {
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(404000000, P_MMPLL0_OUT_EVEN, 2, 0, 0),
+       F(480000000, P_MMPLL7_OUT_EVEN, 2, 0, 0),
+       F(576000000, P_MMPLL10_OUT_EVEN, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 fd_core_clk_src = {
+       .cmd_rcgr = 0x3b00,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_fd_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "fd_core_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_hdmi_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 hdmi_clk_src = {
+       .cmd_rcgr = 0x2100,
+       .hid_width = 5,
+       .parent_map = mmss_xo_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_hdmi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "hdmi_clk_src",
+               .parent_data = mmss_xo_gpll0_gpll0_div,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_jpeg0_clk_src[] = {
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(320000000, P_MMPLL7_OUT_EVEN, 3, 0, 0),
+       F(480000000, P_MMPLL7_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 jpeg0_clk_src = {
+       .cmd_rcgr = 0x3500,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_jpeg0_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "jpeg0_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_maxi_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(75000000, P_GPLL0_DIV, 4, 0, 0),
+       F(171428571, P_GPLL0, 3.5, 0, 0),
+       F(323200000, P_MMPLL0_OUT_EVEN, 2.5, 0, 0),
+       F(406000000, P_MMPLL1_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 maxi_clk_src = {
+       .cmd_rcgr = 0xf020,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_maxi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "maxi_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_mclk_clk_src[] = {
+       F(4800000, P_XO, 4, 0, 0),
+       F(6000000, P_GPLL0_DIV, 10, 1, 5),
+       F(8000000, P_GPLL0_DIV, 1, 2, 75),
+       F(9600000, P_XO, 2, 0, 0),
+       F(16666667, P_GPLL0_DIV, 2, 1, 9),
+       F(19200000, P_XO, 1, 0, 0),
+       F(24000000, P_GPLL0_DIV, 1, 2, 25),
+       F(33333333, P_GPLL0_DIV, 1, 2, 9),
+       F(48000000, P_GPLL0, 1, 2, 25),
+       F(66666667, P_GPLL0, 1, 2, 9),
+       { }
+};
+
+static struct clk_rcg2 mclk0_clk_src = {
+       .cmd_rcgr = 0x3360,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk0_clk_src",
+               .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mclk1_clk_src = {
+       .cmd_rcgr = 0x3390,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk1_clk_src",
+               .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mclk2_clk_src = {
+       .cmd_rcgr = 0x33c0,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk2_clk_src",
+               .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 mclk3_clk_src = {
+       .cmd_rcgr = 0x33f0,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_mclk_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mclk3_clk_src",
+               .parent_data = mmss_xo_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_mdp_clk_src[] = {
+       F(85714286, P_GPLL0, 7, 0, 0),
+       F(100000000, P_GPLL0, 6, 0, 0),
+       F(150000000, P_GPLL0, 4, 0, 0),
+       F(171428571, P_GPLL0, 3.5, 0, 0),
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(275000000, P_MMPLL5_OUT_EVEN, 3, 0, 0),
+       F(300000000, P_GPLL0, 2, 0, 0),
+       F(330000000, P_MMPLL5_OUT_EVEN, 2.5, 0, 0),
+       F(412500000, P_MMPLL5_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 mdp_clk_src = {
+       .cmd_rcgr = 0x2040,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_mdp_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "mdp_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_vsync_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vsync_clk_src = {
+       .cmd_rcgr = 0x2080,
+       .hid_width = 5,
+       .parent_map = mmss_xo_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_vsync_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vsync_clk_src",
+               .parent_data = mmss_xo_gpll0_gpll0_div,
+               .num_parents = 4,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_ahb_clk_src[] = {
+       F(19200000, P_XO, 1, 0, 0),
+       F(40000000, P_GPLL0, 15, 0, 0),
+       F(80800000, P_MMPLL0_OUT_EVEN, 10, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 ahb_clk_src = {
+       .cmd_rcgr = 0x5000,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_ahb_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "ahb_clk_src",
+               .parent_data = mmss_xo_mmpll0_gpll0_gpll0_div,
+               .num_parents = 5,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_axi_clk_src[] = {
+       F(75000000, P_GPLL0, 8, 0, 0),
+       F(171428571, P_GPLL0, 3.5, 0, 0),
+       F(240000000, P_GPLL0, 2.5, 0, 0),
+       F(323200000, P_MMPLL0_OUT_EVEN, 2.5, 0, 0),
+       F(406000000, P_MMPLL0_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+/* RO to linux */
+static struct clk_rcg2 axi_clk_src = {
+       .cmd_rcgr = 0xd000,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_axi_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "axi_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll1_gpll0_gpll0_div,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 pclk0_clk_src = {
+       .cmd_rcgr = 0x2000,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dsi0pll_dsi1pll_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pclk0_clk_src",
+               .parent_data = mmss_xo_dsi0pll_dsi1pll,
+               .num_parents = 4,
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static struct clk_rcg2 pclk1_clk_src = {
+       .cmd_rcgr = 0x2020,
+       .mnd_width = 8,
+       .hid_width = 5,
+       .parent_map = mmss_xo_dsi0pll_dsi1pll_map,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "pclk1_clk_src",
+               .parent_data = mmss_xo_dsi0pll_dsi1pll,
+               .num_parents = 4,
+               .ops = &clk_pixel_ops,
+               .flags = CLK_SET_RATE_PARENT,
+       },
+};
+
+static const struct freq_tbl ftbl_rot_clk_src[] = {
+       F(171428571, P_GPLL0, 3.5, 0, 0),
+       F(275000000, P_MMPLL5_OUT_EVEN, 3, 0, 0),
+       F(330000000, P_MMPLL5_OUT_EVEN, 2.5, 0, 0),
+       F(412500000, P_MMPLL5_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 rot_clk_src = {
+       .cmd_rcgr = 0x21a0,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_rot_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "rot_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll5_gpll0_gpll0_div,
+               .num_parents = 6,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_video_core_clk_src[] = {
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(269330000, P_MMPLL0_OUT_EVEN, 3, 0, 0),
+       F(355200000, P_MMPLL6_OUT_EVEN, 2.5, 0, 0),
+       F(444000000, P_MMPLL6_OUT_EVEN, 2, 0, 0),
+       F(533000000, P_MMPLL3_OUT_EVEN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 video_core_clk_src = {
+       .cmd_rcgr = 0x1000,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_video_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "video_core_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 video_subcore0_clk_src = {
+       .cmd_rcgr = 0x1060,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_video_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "video_subcore0_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 video_subcore1_clk_src = {
+       .cmd_rcgr = 0x1080,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_video_core_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "video_subcore1_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll3_mmpll6_gpll0_gpll0_div,
+               .num_parents = 7,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static const struct freq_tbl ftbl_vfe_clk_src[] = {
+       F(200000000, P_GPLL0, 3, 0, 0),
+       F(300000000, P_GPLL0, 2, 0, 0),
+       F(320000000, P_MMPLL7_OUT_EVEN, 3, 0, 0),
+       F(384000000, P_MMPLL4_OUT_EVEN, 2, 0, 0),
+       F(404000000, P_MMPLL0_OUT_EVEN, 2, 0, 0),
+       F(480000000, P_MMPLL7_OUT_EVEN, 2, 0, 0),
+       F(576000000, P_MMPLL10_OUT_EVEN, 1, 0, 0),
+       F(600000000, P_GPLL0, 1, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 vfe0_clk_src = {
+       .cmd_rcgr = 0x3600,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_vfe_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vfe0_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_rcg2 vfe1_clk_src = {
+       .cmd_rcgr = 0x3620,
+       .hid_width = 5,
+       .parent_map = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div_map,
+       .freq_tbl = ftbl_vfe_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "vfe1_clk_src",
+               .parent_data = mmss_xo_mmpll0_mmpll4_mmpll7_mmpll10_gpll0_gpll0_div,
+               .num_parents = 8,
+               .ops = &clk_rcg2_ops,
+       },
+};
+
+static struct clk_branch misc_ahb_clk = {
+       .halt_reg = 0x328,
+       .clkr = {
+               .enable_reg = 0x328,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "misc_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch video_core_clk = {
+       .halt_reg = 0x1028,
+       .clkr = {
+               .enable_reg = 0x1028,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &video_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch video_ahb_clk = {
+       .halt_reg = 0x1030,
+       .clkr = {
+               .enable_reg = 0x1030,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch video_axi_clk = {
+       .halt_reg = 0x1034,
+       .clkr = {
+               .enable_reg = 0x1034,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_maxi_clk = {
+       .halt_reg = 0x1038,
+       .clkr = {
+               .enable_reg = 0x1038,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_maxi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &maxi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch video_subcore0_clk = {
+       .halt_reg = 0x1048,
+       .clkr = {
+               .enable_reg = 0x1048,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_subcore0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &video_subcore0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch video_subcore1_clk = {
+       .halt_reg = 0x104c,
+       .clkr = {
+               .enable_reg = 0x104c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_subcore1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &video_subcore1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_ahb_clk = {
+       .halt_reg = 0x2308,
+       .clkr = {
+               .enable_reg = 0x2308,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_hdmi_dp_ahb_clk = {
+       .halt_reg = 0x230c,
+       .clkr = {
+               .enable_reg = 0x230c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_hdmi_dp_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_axi_clk = {
+       .halt_reg = 0x2310,
+       .clkr = {
+               .enable_reg = 0x2310,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mdss_pclk0_clk = {
+       .halt_reg = 0x2314,
+       .clkr = {
+               .enable_reg = 0x2314,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_pclk0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &pclk0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_pclk1_clk = {
+       .halt_reg = 0x2318,
+       .clkr = {
+               .enable_reg = 0x2318,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_pclk1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &pclk1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_mdp_clk = {
+       .halt_reg = 0x231c,
+       .clkr = {
+               .enable_reg = 0x231c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_mdp_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mdp_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_mdp_lut_clk = {
+       .halt_reg = 0x2320,
+       .clkr = {
+               .enable_reg = 0x2320,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_mdp_lut_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mdp_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_extpclk_clk = {
+       .halt_reg = 0x2324,
+       .clkr = {
+               .enable_reg = 0x2324,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_extpclk_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &extpclk_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_vsync_clk = {
+       .halt_reg = 0x2328,
+       .clkr = {
+               .enable_reg = 0x2328,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_vsync_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vsync_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_hdmi_clk = {
+       .halt_reg = 0x2338,
+       .clkr = {
+               .enable_reg = 0x2338,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_hdmi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &hdmi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_byte0_clk = {
+       .halt_reg = 0x233c,
+       .clkr = {
+               .enable_reg = 0x233c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_byte0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &byte0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_byte1_clk = {
+       .halt_reg = 0x2340,
+       .clkr = {
+               .enable_reg = 0x2340,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_byte1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &byte1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_esc0_clk = {
+       .halt_reg = 0x2344,
+       .clkr = {
+               .enable_reg = 0x2344,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_esc0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &esc0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_esc1_clk = {
+       .halt_reg = 0x2348,
+       .clkr = {
+               .enable_reg = 0x2348,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_esc1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &esc1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_rot_clk = {
+       .halt_reg = 0x2350,
+       .clkr = {
+               .enable_reg = 0x2350,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_rot_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &rot_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_dp_link_clk = {
+       .halt_reg = 0x2354,
+       .clkr = {
+               .enable_reg = 0x2354,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_dp_link_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &dp_link_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_dp_link_intf_clk = {
+       .halt_reg = 0x2358,
+       .clkr = {
+               .enable_reg = 0x2358,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_dp_link_intf_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &dp_link_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_dp_crypto_clk = {
+       .halt_reg = 0x235c,
+       .clkr = {
+               .enable_reg = 0x235c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_dp_crypto_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &dp_crypto_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_dp_pixel_clk = {
+       .halt_reg = 0x2360,
+       .clkr = {
+               .enable_reg = 0x2360,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_dp_pixel_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &dp_pixel_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_dp_aux_clk = {
+       .halt_reg = 0x2364,
+       .clkr = {
+               .enable_reg = 0x2364,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_dp_aux_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &dp_aux_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_byte0_intf_clk = {
+       .halt_reg = 0x2374,
+       .clkr = {
+               .enable_reg = 0x2374,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_byte0_intf_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &byte0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mdss_byte1_intf_clk = {
+       .halt_reg = 0x2378,
+       .clkr = {
+               .enable_reg = 0x2378,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mdss_byte1_intf_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &byte1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0phytimer_clk = {
+       .halt_reg = 0x3024,
+       .clkr = {
+               .enable_reg = 0x3024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0phytimer_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1phytimer_clk = {
+       .halt_reg = 0x3054,
+       .clkr = {
+               .enable_reg = 0x3054,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1phytimer_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2phytimer_clk = {
+       .halt_reg = 0x3084,
+       .clkr = {
+               .enable_reg = 0x3084,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2phytimer_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi2phytimer_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0_clk = {
+       .halt_reg = 0x30b4,
+       .clkr = {
+               .enable_reg = 0x30b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0_ahb_clk = {
+       .halt_reg = 0x30bc,
+       .clkr = {
+               .enable_reg = 0x30bc,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0rdi_clk = {
+       .halt_reg = 0x30d4,
+       .clkr = {
+               .enable_reg = 0x30d4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi0pix_clk = {
+       .halt_reg = 0x30e4,
+       .clkr = {
+               .enable_reg = 0x30e4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi0pix_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1_clk = {
+       .halt_reg = 0x3124,
+       .clkr = {
+               .enable_reg = 0x3124,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1_ahb_clk = {
+       .halt_reg = 0x3128,
+       .clkr = {
+               .enable_reg = 0x3128,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1rdi_clk = {
+       .halt_reg = 0x3144,
+       .clkr = {
+               .enable_reg = 0x3144,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi1pix_clk = {
+       .halt_reg = 0x3154,
+       .clkr = {
+               .enable_reg = 0x3154,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi1pix_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2_clk = {
+       .halt_reg = 0x3184,
+       .clkr = {
+               .enable_reg = 0x3184,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2_ahb_clk = {
+       .halt_reg = 0x3188,
+       .clkr = {
+               .enable_reg = 0x3188,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2rdi_clk = {
+       .halt_reg = 0x31a4,
+       .clkr = {
+               .enable_reg = 0x31a4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi2pix_clk = {
+       .halt_reg = 0x31b4,
+       .clkr = {
+               .enable_reg = 0x31b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi2pix_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3_clk = {
+       .halt_reg = 0x31e4,
+       .clkr = {
+               .enable_reg = 0x31e4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3_ahb_clk = {
+       .halt_reg = 0x31e8,
+       .clkr = {
+               .enable_reg = 0x31e8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3rdi_clk = {
+       .halt_reg = 0x3204,
+       .clkr = {
+               .enable_reg = 0x3204,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3rdi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi3pix_clk = {
+       .halt_reg = 0x3214,
+       .clkr = {
+               .enable_reg = 0x3214,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi3pix_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csi3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_ispif_ahb_clk = {
+       .halt_reg = 0x3224,
+       .clkr = {
+               .enable_reg = 0x3224,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_ispif_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_cci_clk = {
+       .halt_reg = 0x3344,
+       .clkr = {
+               .enable_reg = 0x3344,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cci_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &cci_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_cci_ahb_clk = {
+       .halt_reg = 0x3348,
+       .clkr = {
+               .enable_reg = 0x3348,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cci_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_mclk0_clk = {
+       .halt_reg = 0x3384,
+       .clkr = {
+               .enable_reg = 0x3384,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_mclk0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mclk0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_mclk1_clk = {
+       .halt_reg = 0x33b4,
+       .clkr = {
+               .enable_reg = 0x33b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_mclk1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mclk1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_mclk2_clk = {
+       .halt_reg = 0x33e4,
+       .clkr = {
+               .enable_reg = 0x33e4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_mclk2_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mclk2_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_mclk3_clk = {
+       .halt_reg = 0x3414,
+       .clkr = {
+               .enable_reg = 0x3414,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_mclk3_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &mclk3_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_top_ahb_clk = {
+       .halt_reg = 0x3484,
+       .clkr = {
+               .enable_reg = 0x3484,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_top_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_ahb_clk = {
+       .halt_reg = 0x348c,
+       .clkr = {
+               .enable_reg = 0x348c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_micro_ahb_clk = {
+       .halt_reg = 0x3494,
+       .clkr = {
+               .enable_reg = 0x3494,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_micro_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg0_clk = {
+       .halt_reg = 0x35a8,
+       .clkr = {
+               .enable_reg = 0x35a8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &jpeg0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg_ahb_clk = {
+       .halt_reg = 0x35b4,
+       .clkr = {
+               .enable_reg = 0x35b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_jpeg_axi_clk = {
+       .halt_reg = 0x35b8,
+       .clkr = {
+               .enable_reg = 0x35b8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_jpeg_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe0_ahb_clk = {
+       .halt_reg = 0x3668,
+       .clkr = {
+               .enable_reg = 0x3668,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe0_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe1_ahb_clk = {
+       .halt_reg = 0x3678,
+       .clkr = {
+               .enable_reg = 0x3678,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe1_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe0_clk = {
+       .halt_reg = 0x36a8,
+       .clkr = {
+               .enable_reg = 0x36a8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe1_clk = {
+       .halt_reg = 0x36ac,
+       .clkr = {
+               .enable_reg = 0x36ac,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_cpp_clk = {
+       .halt_reg = 0x36b0,
+       .clkr = {
+               .enable_reg = 0x36b0,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cpp_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &cpp_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_cpp_ahb_clk = {
+       .halt_reg = 0x36b4,
+       .clkr = {
+               .enable_reg = 0x36b4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cpp_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_vbif_ahb_clk = {
+       .halt_reg = 0x36b8,
+       .clkr = {
+               .enable_reg = 0x36b8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_vbif_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe_vbif_axi_clk = {
+       .halt_reg = 0x36bc,
+       .clkr = {
+               .enable_reg = 0x36bc,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe_vbif_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_cpp_axi_clk = {
+       .halt_reg = 0x36c4,
+       .clkr = {
+               .enable_reg = 0x36c4,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cpp_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch camss_cpp_vbif_ahb_clk = {
+       .halt_reg = 0x36c8,
+       .clkr = {
+               .enable_reg = 0x36c8,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cpp_vbif_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi_vfe0_clk = {
+       .halt_reg = 0x3704,
+       .clkr = {
+               .enable_reg = 0x3704,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi_vfe0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csi_vfe1_clk = {
+       .halt_reg = 0x3714,
+       .clkr = {
+               .enable_reg = 0x3714,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csi_vfe1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe0_stream_clk = {
+       .halt_reg = 0x3720,
+       .clkr = {
+               .enable_reg = 0x3720,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe0_stream_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe0_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_vfe1_stream_clk = {
+       .halt_reg = 0x3724,
+       .clkr = {
+               .enable_reg = 0x3724,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_vfe1_stream_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &vfe1_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_cphy_csid0_clk = {
+       .halt_reg = 0x3730,
+       .clkr = {
+               .enable_reg = 0x3730,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cphy_csid0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_cphy_csid1_clk = {
+       .halt_reg = 0x3734,
+       .clkr = {
+               .enable_reg = 0x3734,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cphy_csid1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_cphy_csid2_clk = {
+       .halt_reg = 0x3738,
+       .clkr = {
+               .enable_reg = 0x3738,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cphy_csid2_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_cphy_csid3_clk = {
+       .halt_reg = 0x373c,
+       .clkr = {
+               .enable_reg = 0x373c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_cphy_csid3_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csiphy0_clk = {
+       .halt_reg = 0x3740,
+       .clkr = {
+               .enable_reg = 0x3740,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csiphy0_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csiphy1_clk = {
+       .halt_reg = 0x3744,
+       .clkr = {
+               .enable_reg = 0x3744,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csiphy1_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch camss_csiphy2_clk = {
+       .halt_reg = 0x3748,
+       .clkr = {
+               .enable_reg = 0x3748,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "camss_csiphy2_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &csiphy_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch fd_core_clk = {
+       .halt_reg = 0x3b68,
+       .clkr = {
+               .enable_reg = 0x3b68,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "fd_core_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &fd_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch fd_core_uar_clk = {
+       .halt_reg = 0x3b6c,
+       .clkr = {
+               .enable_reg = 0x3b6c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "fd_core_uar_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &fd_core_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch fd_ahb_clk = {
+       .halt_reg = 0x3b74,
+       .clkr = {
+               .enable_reg = 0x3b74,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "fd_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch mnoc_ahb_clk = {
+       .halt_reg = 0x5024,
+       .clkr = {
+               .enable_reg = 0x5024,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mnoc_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch bimc_smmu_ahb_clk = {
+       .halt_reg = 0xe004,
+       .clkr = {
+               .enable_reg = 0xe004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "bimc_smmu_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch bimc_smmu_axi_clk = {
+       .halt_reg = 0xe008,
+       .clkr = {
+               .enable_reg = 0xe008,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "bimc_smmu_axi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &axi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch mnoc_maxi_clk = {
+       .halt_reg = 0xf004,
+       .clkr = {
+               .enable_reg = 0xf004,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "mnoc_maxi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &maxi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch vmem_maxi_clk = {
+       .halt_reg = 0xf064,
+       .clkr = {
+               .enable_reg = 0xf064,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "vmem_maxi_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &maxi_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_branch vmem_ahb_clk = {
+       .halt_reg = 0xf068,
+       .clkr = {
+               .enable_reg = 0xf068,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "vmem_ahb_clk",
+                       .parent_hws = (const struct clk_hw *[]){ &ahb_clk_src.clkr.hw },
+                       .num_parents = 1,
+                       .ops = &clk_branch2_ops,
+                       .flags = CLK_SET_RATE_PARENT,
+               },
+       },
+};
+
+static struct clk_hw *mmcc_msm8998_hws[] = {
+       &gpll0_div.hw,
+};
+
+static struct gdsc video_top_gdsc = {
+       .gdscr = 0x1024,
+       .pd = {
+               .name = "video_top",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc video_subcore0_gdsc = {
+       .gdscr = 0x1040,
+       .pd = {
+               .name = "video_subcore0",
+       },
+       .parent = &video_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc video_subcore1_gdsc = {
+       .gdscr = 0x1044,
+       .pd = {
+               .name = "video_subcore1",
+       },
+       .parent = &video_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc mdss_gdsc = {
+       .gdscr = 0x2304,
+       .cxcs = (unsigned int []){ 0x2310, 0x2350, 0x231c, 0x2320 },
+       .cxc_count = 4,
+       .pd = {
+               .name = "mdss",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_top_gdsc = {
+       .gdscr = 0x34a0,
+       .cxcs = (unsigned int []){ 0x35b8, 0x36c4, 0x3704, 0x3714, 0x3494,
+                                  0x35a8, 0x3868 },
+       .cxc_count = 7,
+       .pd = {
+               .name = "camss_top",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_vfe0_gdsc = {
+       .gdscr = 0x3664,
+       .pd = {
+               .name = "camss_vfe0",
+       },
+       .parent = &camss_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_vfe1_gdsc = {
+       .gdscr = 0x3674,
+       .pd = {
+               .name = "camss_vfe1_gdsc",
+       },
+       .parent = &camss_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc camss_cpp_gdsc = {
+       .gdscr = 0x36d4,
+       .pd = {
+               .name = "camss_cpp",
+       },
+       .parent = &camss_top_gdsc.pd,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc bimc_smmu_gdsc = {
+       .gdscr = 0xe020,
+       .gds_hw_ctrl = 0xe024,
+       .pd = {
+               .name = "bimc_smmu",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+       .flags = HW_CTRL,
+};
+
+static struct clk_regmap *mmcc_msm8998_clocks[] = {
+       [MMPLL0] = &mmpll0.clkr,
+       [MMPLL0_OUT_EVEN] = &mmpll0_out_even.clkr,
+       [MMPLL1] = &mmpll1.clkr,
+       [MMPLL1_OUT_EVEN] = &mmpll1_out_even.clkr,
+       [MMPLL3] = &mmpll3.clkr,
+       [MMPLL3_OUT_EVEN] = &mmpll3_out_even.clkr,
+       [MMPLL4] = &mmpll4.clkr,
+       [MMPLL4_OUT_EVEN] = &mmpll4_out_even.clkr,
+       [MMPLL5] = &mmpll5.clkr,
+       [MMPLL5_OUT_EVEN] = &mmpll5_out_even.clkr,
+       [MMPLL6] = &mmpll6.clkr,
+       [MMPLL6_OUT_EVEN] = &mmpll6_out_even.clkr,
+       [MMPLL7] = &mmpll7.clkr,
+       [MMPLL7_OUT_EVEN] = &mmpll7_out_even.clkr,
+       [MMPLL10] = &mmpll10.clkr,
+       [MMPLL10_OUT_EVEN] = &mmpll10_out_even.clkr,
+       [BYTE0_CLK_SRC] = &byte0_clk_src.clkr,
+       [BYTE1_CLK_SRC] = &byte1_clk_src.clkr,
+       [CCI_CLK_SRC] = &cci_clk_src.clkr,
+       [CPP_CLK_SRC] = &cpp_clk_src.clkr,
+       [CSI0_CLK_SRC] = &csi0_clk_src.clkr,
+       [CSI1_CLK_SRC] = &csi1_clk_src.clkr,
+       [CSI2_CLK_SRC] = &csi2_clk_src.clkr,
+       [CSI3_CLK_SRC] = &csi3_clk_src.clkr,
+       [CSIPHY_CLK_SRC] = &csiphy_clk_src.clkr,
+       [CSI0PHYTIMER_CLK_SRC] = &csi0phytimer_clk_src.clkr,
+       [CSI1PHYTIMER_CLK_SRC] = &csi1phytimer_clk_src.clkr,
+       [CSI2PHYTIMER_CLK_SRC] = &csi2phytimer_clk_src.clkr,
+       [DP_AUX_CLK_SRC] = &dp_aux_clk_src.clkr,
+       [DP_CRYPTO_CLK_SRC] = &dp_crypto_clk_src.clkr,
+       [DP_LINK_CLK_SRC] = &dp_link_clk_src.clkr,
+       [DP_PIXEL_CLK_SRC] = &dp_pixel_clk_src.clkr,
+       [ESC0_CLK_SRC] = &esc0_clk_src.clkr,
+       [ESC1_CLK_SRC] = &esc1_clk_src.clkr,
+       [EXTPCLK_CLK_SRC] = &extpclk_clk_src.clkr,
+       [FD_CORE_CLK_SRC] = &fd_core_clk_src.clkr,
+       [HDMI_CLK_SRC] = &hdmi_clk_src.clkr,
+       [JPEG0_CLK_SRC] = &jpeg0_clk_src.clkr,
+       [MAXI_CLK_SRC] = &maxi_clk_src.clkr,
+       [MCLK0_CLK_SRC] = &mclk0_clk_src.clkr,
+       [MCLK1_CLK_SRC] = &mclk1_clk_src.clkr,
+       [MCLK2_CLK_SRC] = &mclk2_clk_src.clkr,
+       [MCLK3_CLK_SRC] = &mclk3_clk_src.clkr,
+       [MDP_CLK_SRC] = &mdp_clk_src.clkr,
+       [VSYNC_CLK_SRC] = &vsync_clk_src.clkr,
+       [AHB_CLK_SRC] = &ahb_clk_src.clkr,
+       [AXI_CLK_SRC] = &axi_clk_src.clkr,
+       [PCLK0_CLK_SRC] = &pclk0_clk_src.clkr,
+       [PCLK1_CLK_SRC] = &pclk1_clk_src.clkr,
+       [ROT_CLK_SRC] = &rot_clk_src.clkr,
+       [VIDEO_CORE_CLK_SRC] = &video_core_clk_src.clkr,
+       [VIDEO_SUBCORE0_CLK_SRC] = &video_subcore0_clk_src.clkr,
+       [VIDEO_SUBCORE1_CLK_SRC] = &video_subcore1_clk_src.clkr,
+       [VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
+       [VFE1_CLK_SRC] = &vfe1_clk_src.clkr,
+       [MISC_AHB_CLK] = &misc_ahb_clk.clkr,
+       [VIDEO_CORE_CLK] = &video_core_clk.clkr,
+       [VIDEO_AHB_CLK] = &video_ahb_clk.clkr,
+       [VIDEO_AXI_CLK] = &video_axi_clk.clkr,
+       [VIDEO_MAXI_CLK] = &video_maxi_clk.clkr,
+       [VIDEO_SUBCORE0_CLK] = &video_subcore0_clk.clkr,
+       [VIDEO_SUBCORE1_CLK] = &video_subcore1_clk.clkr,
+       [MDSS_AHB_CLK] = &mdss_ahb_clk.clkr,
+       [MDSS_HDMI_DP_AHB_CLK] = &mdss_hdmi_dp_ahb_clk.clkr,
+       [MDSS_AXI_CLK] = &mdss_axi_clk.clkr,
+       [MDSS_PCLK0_CLK] = &mdss_pclk0_clk.clkr,
+       [MDSS_PCLK1_CLK] = &mdss_pclk1_clk.clkr,
+       [MDSS_MDP_CLK] = &mdss_mdp_clk.clkr,
+       [MDSS_MDP_LUT_CLK] = &mdss_mdp_lut_clk.clkr,
+       [MDSS_EXTPCLK_CLK] = &mdss_extpclk_clk.clkr,
+       [MDSS_VSYNC_CLK] = &mdss_vsync_clk.clkr,
+       [MDSS_HDMI_CLK] = &mdss_hdmi_clk.clkr,
+       [MDSS_BYTE0_CLK] = &mdss_byte0_clk.clkr,
+       [MDSS_BYTE1_CLK] = &mdss_byte1_clk.clkr,
+       [MDSS_ESC0_CLK] = &mdss_esc0_clk.clkr,
+       [MDSS_ESC1_CLK] = &mdss_esc1_clk.clkr,
+       [MDSS_ROT_CLK] = &mdss_rot_clk.clkr,
+       [MDSS_DP_LINK_CLK] = &mdss_dp_link_clk.clkr,
+       [MDSS_DP_LINK_INTF_CLK] = &mdss_dp_link_intf_clk.clkr,
+       [MDSS_DP_CRYPTO_CLK] = &mdss_dp_crypto_clk.clkr,
+       [MDSS_DP_PIXEL_CLK] = &mdss_dp_pixel_clk.clkr,
+       [MDSS_DP_AUX_CLK] = &mdss_dp_aux_clk.clkr,
+       [MDSS_BYTE0_INTF_CLK] = &mdss_byte0_intf_clk.clkr,
+       [MDSS_BYTE1_INTF_CLK] = &mdss_byte1_intf_clk.clkr,
+       [CAMSS_CSI0PHYTIMER_CLK] = &camss_csi0phytimer_clk.clkr,
+       [CAMSS_CSI1PHYTIMER_CLK] = &camss_csi1phytimer_clk.clkr,
+       [CAMSS_CSI2PHYTIMER_CLK] = &camss_csi2phytimer_clk.clkr,
+       [CAMSS_CSI0_CLK] = &camss_csi0_clk.clkr,
+       [CAMSS_CSI0_AHB_CLK] = &camss_csi0_ahb_clk.clkr,
+       [CAMSS_CSI0RDI_CLK] = &camss_csi0rdi_clk.clkr,
+       [CAMSS_CSI0PIX_CLK] = &camss_csi0pix_clk.clkr,
+       [CAMSS_CSI1_CLK] = &camss_csi1_clk.clkr,
+       [CAMSS_CSI1_AHB_CLK] = &camss_csi1_ahb_clk.clkr,
+       [CAMSS_CSI1RDI_CLK] = &camss_csi1rdi_clk.clkr,
+       [CAMSS_CSI1PIX_CLK] = &camss_csi1pix_clk.clkr,
+       [CAMSS_CSI2_CLK] = &camss_csi2_clk.clkr,
+       [CAMSS_CSI2_AHB_CLK] = &camss_csi2_ahb_clk.clkr,
+       [CAMSS_CSI2RDI_CLK] = &camss_csi2rdi_clk.clkr,
+       [CAMSS_CSI2PIX_CLK] = &camss_csi2pix_clk.clkr,
+       [CAMSS_CSI3_CLK] = &camss_csi3_clk.clkr,
+       [CAMSS_CSI3_AHB_CLK] = &camss_csi3_ahb_clk.clkr,
+       [CAMSS_CSI3RDI_CLK] = &camss_csi3rdi_clk.clkr,
+       [CAMSS_CSI3PIX_CLK] = &camss_csi3pix_clk.clkr,
+       [CAMSS_ISPIF_AHB_CLK] = &camss_ispif_ahb_clk.clkr,
+       [CAMSS_CCI_CLK] = &camss_cci_clk.clkr,
+       [CAMSS_CCI_AHB_CLK] = &camss_cci_ahb_clk.clkr,
+       [CAMSS_MCLK0_CLK] = &camss_mclk0_clk.clkr,
+       [CAMSS_MCLK1_CLK] = &camss_mclk1_clk.clkr,
+       [CAMSS_MCLK2_CLK] = &camss_mclk2_clk.clkr,
+       [CAMSS_MCLK3_CLK] = &camss_mclk3_clk.clkr,
+       [CAMSS_TOP_AHB_CLK] = &camss_top_ahb_clk.clkr,
+       [CAMSS_AHB_CLK] = &camss_ahb_clk.clkr,
+       [CAMSS_MICRO_AHB_CLK] = &camss_micro_ahb_clk.clkr,
+       [CAMSS_JPEG0_CLK] = &camss_jpeg0_clk.clkr,
+       [CAMSS_JPEG_AHB_CLK] = &camss_jpeg_ahb_clk.clkr,
+       [CAMSS_JPEG_AXI_CLK] = &camss_jpeg_axi_clk.clkr,
+       [CAMSS_VFE0_AHB_CLK] = &camss_vfe0_ahb_clk.clkr,
+       [CAMSS_VFE1_AHB_CLK] = &camss_vfe1_ahb_clk.clkr,
+       [CAMSS_VFE0_CLK] = &camss_vfe0_clk.clkr,
+       [CAMSS_VFE1_CLK] = &camss_vfe1_clk.clkr,
+       [CAMSS_CPP_CLK] = &camss_cpp_clk.clkr,
+       [CAMSS_CPP_AHB_CLK] = &camss_cpp_ahb_clk.clkr,
+       [CAMSS_VFE_VBIF_AHB_CLK] = &camss_vfe_vbif_ahb_clk.clkr,
+       [CAMSS_VFE_VBIF_AXI_CLK] = &camss_vfe_vbif_axi_clk.clkr,
+       [CAMSS_CPP_AXI_CLK] = &camss_cpp_axi_clk.clkr,
+       [CAMSS_CPP_VBIF_AHB_CLK] = &camss_cpp_vbif_ahb_clk.clkr,
+       [CAMSS_CSI_VFE0_CLK] = &camss_csi_vfe0_clk.clkr,
+       [CAMSS_CSI_VFE1_CLK] = &camss_csi_vfe1_clk.clkr,
+       [CAMSS_VFE0_STREAM_CLK] = &camss_vfe0_stream_clk.clkr,
+       [CAMSS_VFE1_STREAM_CLK] = &camss_vfe1_stream_clk.clkr,
+       [CAMSS_CPHY_CSID0_CLK] = &camss_cphy_csid0_clk.clkr,
+       [CAMSS_CPHY_CSID1_CLK] = &camss_cphy_csid1_clk.clkr,
+       [CAMSS_CPHY_CSID2_CLK] = &camss_cphy_csid2_clk.clkr,
+       [CAMSS_CPHY_CSID3_CLK] = &camss_cphy_csid3_clk.clkr,
+       [CAMSS_CSIPHY0_CLK] = &camss_csiphy0_clk.clkr,
+       [CAMSS_CSIPHY1_CLK] = &camss_csiphy1_clk.clkr,
+       [CAMSS_CSIPHY2_CLK] = &camss_csiphy2_clk.clkr,
+       [FD_CORE_CLK] = &fd_core_clk.clkr,
+       [FD_CORE_UAR_CLK] = &fd_core_uar_clk.clkr,
+       [FD_AHB_CLK] = &fd_ahb_clk.clkr,
+       [MNOC_AHB_CLK] = &mnoc_ahb_clk.clkr,
+       [BIMC_SMMU_AHB_CLK] = &bimc_smmu_ahb_clk.clkr,
+       [BIMC_SMMU_AXI_CLK] = &bimc_smmu_axi_clk.clkr,
+       [MNOC_MAXI_CLK] = &mnoc_maxi_clk.clkr,
+       [VMEM_MAXI_CLK] = &vmem_maxi_clk.clkr,
+       [VMEM_AHB_CLK] = &vmem_ahb_clk.clkr,
+};
+
+static struct gdsc *mmcc_msm8998_gdscs[] = {
+       [VIDEO_TOP_GDSC] = &video_top_gdsc,
+       [VIDEO_SUBCORE0_GDSC] = &video_subcore0_gdsc,
+       [VIDEO_SUBCORE1_GDSC] = &video_subcore1_gdsc,
+       [MDSS_GDSC] = &mdss_gdsc,
+       [CAMSS_TOP_GDSC] = &camss_top_gdsc,
+       [CAMSS_VFE0_GDSC] = &camss_vfe0_gdsc,
+       [CAMSS_VFE1_GDSC] = &camss_vfe1_gdsc,
+       [CAMSS_CPP_GDSC] = &camss_cpp_gdsc,
+       [BIMC_SMMU_GDSC] = &bimc_smmu_gdsc,
+};
+
+static const struct qcom_reset_map mmcc_msm8998_resets[] = {
+       [SPDM_BCR] = { 0x200 },
+       [SPDM_RM_BCR] = { 0x300 },
+       [MISC_BCR] = { 0x320 },
+       [VIDEO_TOP_BCR] = { 0x1020 },
+       [THROTTLE_VIDEO_BCR] = { 0x1180 },
+       [MDSS_BCR] = { 0x2300 },
+       [THROTTLE_MDSS_BCR] = { 0x2460 },
+       [CAMSS_PHY0_BCR] = { 0x3020 },
+       [CAMSS_PHY1_BCR] = { 0x3050 },
+       [CAMSS_PHY2_BCR] = { 0x3080 },
+       [CAMSS_CSI0_BCR] = { 0x30b0 },
+       [CAMSS_CSI0RDI_BCR] = { 0x30d0 },
+       [CAMSS_CSI0PIX_BCR] = { 0x30e0 },
+       [CAMSS_CSI1_BCR] = { 0x3120 },
+       [CAMSS_CSI1RDI_BCR] = { 0x3140 },
+       [CAMSS_CSI1PIX_BCR] = { 0x3150 },
+       [CAMSS_CSI2_BCR] = { 0x3180 },
+       [CAMSS_CSI2RDI_BCR] = { 0x31a0 },
+       [CAMSS_CSI2PIX_BCR] = { 0x31b0 },
+       [CAMSS_CSI3_BCR] = { 0x31e0 },
+       [CAMSS_CSI3RDI_BCR] = { 0x3200 },
+       [CAMSS_CSI3PIX_BCR] = { 0x3210 },
+       [CAMSS_ISPIF_BCR] = { 0x3220 },
+       [CAMSS_CCI_BCR] = { 0x3340 },
+       [CAMSS_TOP_BCR] = { 0x3480 },
+       [CAMSS_AHB_BCR] = { 0x3488 },
+       [CAMSS_MICRO_BCR] = { 0x3490 },
+       [CAMSS_JPEG_BCR] = { 0x35a0 },
+       [CAMSS_VFE0_BCR] = { 0x3660 },
+       [CAMSS_VFE1_BCR] = { 0x3670 },
+       [CAMSS_VFE_VBIF_BCR] = { 0x36a0 },
+       [CAMSS_CPP_TOP_BCR] = { 0x36c0 },
+       [CAMSS_CPP_BCR] = { 0x36d0 },
+       [CAMSS_CSI_VFE0_BCR] = { 0x3700 },
+       [CAMSS_CSI_VFE1_BCR] = { 0x3710 },
+       [CAMSS_FD_BCR] = { 0x3b60 },
+       [THROTTLE_CAMSS_BCR] = { 0x3c30 },
+       [MNOCAHB_BCR] = { 0x5020 },
+       [MNOCAXI_BCR] = { 0xd020 },
+       [BMIC_SMMU_BCR] = { 0xe000 },
+       [MNOC_MAXI_BCR] = { 0xf000 },
+       [VMEM_BCR] = { 0xf060 },
+       [BTO_BCR] = { 0x10004 },
+};
+
+static const struct regmap_config mmcc_msm8998_regmap_config = {
+       .reg_bits       = 32,
+       .reg_stride     = 4,
+       .val_bits       = 32,
+       .max_register   = 0x10004,
+       .fast_io        = true,
+};
+
+static const struct qcom_cc_desc mmcc_msm8998_desc = {
+       .config = &mmcc_msm8998_regmap_config,
+       .clks = mmcc_msm8998_clocks,
+       .num_clks = ARRAY_SIZE(mmcc_msm8998_clocks),
+       .resets = mmcc_msm8998_resets,
+       .num_resets = ARRAY_SIZE(mmcc_msm8998_resets),
+       .gdscs = mmcc_msm8998_gdscs,
+       .num_gdscs = ARRAY_SIZE(mmcc_msm8998_gdscs),
+       .clk_hws = mmcc_msm8998_hws,
+       .num_clk_hws = ARRAY_SIZE(mmcc_msm8998_hws),
+};
+
+static const struct of_device_id mmcc_msm8998_match_table[] = {
+       { .compatible = "qcom,mmcc-msm8998" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, mmcc_msm8998_match_table);
+
+static int mmcc_msm8998_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+
+       regmap = qcom_cc_map(pdev, &mmcc_msm8998_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       return qcom_cc_really_probe(pdev, &mmcc_msm8998_desc, regmap);
+}
+
+static struct platform_driver mmcc_msm8998_driver = {
+       .probe          = mmcc_msm8998_probe,
+       .driver         = {
+               .name   = "mmcc-msm8998",
+               .of_match_table = mmcc_msm8998_match_table,
+       },
+};
+module_platform_driver(mmcc_msm8998_driver);
+
+MODULE_DESCRIPTION("QCOM MMCC MSM8998 Driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/clk/qcom/videocc-sc7180.c b/drivers/clk/qcom/videocc-sc7180.c
new file mode 100644 (file)
index 0000000..c363c3c
--- /dev/null
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/clk-provider.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/clock/qcom,videocc-sc7180.h>
+
+#include "clk-alpha-pll.h"
+#include "clk-branch.h"
+#include "clk-rcg.h"
+#include "clk-regmap.h"
+#include "common.h"
+#include "gdsc.h"
+
+enum {
+       P_BI_TCXO,
+       P_CHIP_SLEEP_CLK,
+       P_CORE_BI_PLL_TEST_SE,
+       P_VIDEO_PLL0_OUT_EVEN,
+       P_VIDEO_PLL0_OUT_MAIN,
+       P_VIDEO_PLL0_OUT_ODD,
+};
+
+static const struct pll_vco fabia_vco[] = {
+       { 249600000, 2000000000, 0 },
+};
+
+static struct clk_alpha_pll video_pll0 = {
+       .offset = 0x42c,
+       .vco_table = fabia_vco,
+       .num_vco = ARRAY_SIZE(fabia_vco),
+       .regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
+       .clkr = {
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_pll0",
+                       .parent_data = &(const struct clk_parent_data){
+                               .fw_name = "bi_tcxo",
+                       },
+                       .num_parents = 1,
+                       .ops = &clk_alpha_pll_fabia_ops,
+               },
+       },
+};
+
+static const struct parent_map video_cc_parent_map_1[] = {
+       { P_BI_TCXO, 0 },
+       { P_VIDEO_PLL0_OUT_MAIN, 1 },
+};
+
+static const struct clk_parent_data video_cc_parent_data_1[] = {
+       { .fw_name = "bi_tcxo" },
+       { .hw = &video_pll0.clkr.hw },
+};
+
+static const struct freq_tbl ftbl_video_cc_venus_clk_src[] = {
+       F(19200000, P_BI_TCXO, 1, 0, 0),
+       F(150000000, P_VIDEO_PLL0_OUT_MAIN, 4, 0, 0),
+       F(270000000, P_VIDEO_PLL0_OUT_MAIN, 2.5, 0, 0),
+       F(340000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+       F(434000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+       F(500000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
+       { }
+};
+
+static struct clk_rcg2 video_cc_venus_clk_src = {
+       .cmd_rcgr = 0x7f0,
+       .mnd_width = 0,
+       .hid_width = 5,
+       .parent_map = video_cc_parent_map_1,
+       .freq_tbl = ftbl_video_cc_venus_clk_src,
+       .clkr.hw.init = &(struct clk_init_data){
+               .name = "video_cc_venus_clk_src",
+               .parent_data = video_cc_parent_data_1,
+               .num_parents = ARRAY_SIZE(video_cc_parent_data_1),
+               .flags = CLK_SET_RATE_PARENT,
+               .ops = &clk_rcg2_shared_ops,
+       },
+};
+
+static struct clk_branch video_cc_vcodec0_axi_clk = {
+       .halt_reg = 0x9ec,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9ec,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_vcodec0_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_vcodec0_core_clk = {
+       .halt_reg = 0x890,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x890,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_vcodec0_core_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &video_cc_venus_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_venus_ahb_clk = {
+       .halt_reg = 0xa4c,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0xa4c,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_venus_ahb_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_venus_ctl_axi_clk = {
+       .halt_reg = 0x9cc,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x9cc,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_venus_ctl_axi_clk",
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct clk_branch video_cc_venus_ctl_core_clk = {
+       .halt_reg = 0x850,
+       .halt_check = BRANCH_HALT,
+       .clkr = {
+               .enable_reg = 0x850,
+               .enable_mask = BIT(0),
+               .hw.init = &(struct clk_init_data){
+                       .name = "video_cc_venus_ctl_core_clk",
+                       .parent_data = &(const struct clk_parent_data){
+                               .hw = &video_cc_venus_clk_src.clkr.hw,
+                       },
+                       .num_parents = 1,
+                       .flags = CLK_SET_RATE_PARENT,
+                       .ops = &clk_branch2_ops,
+               },
+       },
+};
+
+static struct gdsc venus_gdsc = {
+       .gdscr = 0x814,
+       .pd = {
+               .name = "venus_gdsc",
+       },
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct gdsc vcodec0_gdsc = {
+       .gdscr = 0x874,
+       .pd = {
+               .name = "vcodec0_gdsc",
+       },
+       .flags = HW_CTRL,
+       .pwrsts = PWRSTS_OFF_ON,
+};
+
+static struct clk_regmap *video_cc_sc7180_clocks[] = {
+       [VIDEO_CC_VCODEC0_AXI_CLK] = &video_cc_vcodec0_axi_clk.clkr,
+       [VIDEO_CC_VCODEC0_CORE_CLK] = &video_cc_vcodec0_core_clk.clkr,
+       [VIDEO_CC_VENUS_AHB_CLK] = &video_cc_venus_ahb_clk.clkr,
+       [VIDEO_CC_VENUS_CLK_SRC] = &video_cc_venus_clk_src.clkr,
+       [VIDEO_CC_VENUS_CTL_AXI_CLK] = &video_cc_venus_ctl_axi_clk.clkr,
+       [VIDEO_CC_VENUS_CTL_CORE_CLK] = &video_cc_venus_ctl_core_clk.clkr,
+       [VIDEO_PLL0] = &video_pll0.clkr,
+};
+
+static struct gdsc *video_cc_sc7180_gdscs[] = {
+       [VENUS_GDSC] = &venus_gdsc,
+       [VCODEC0_GDSC] = &vcodec0_gdsc,
+};
+
+static const struct regmap_config video_cc_sc7180_regmap_config = {
+       .reg_bits = 32,
+       .reg_stride = 4,
+       .val_bits = 32,
+       .max_register = 0xb94,
+       .fast_io = true,
+};
+
+static const struct qcom_cc_desc video_cc_sc7180_desc = {
+       .config = &video_cc_sc7180_regmap_config,
+       .clks = video_cc_sc7180_clocks,
+       .num_clks = ARRAY_SIZE(video_cc_sc7180_clocks),
+       .gdscs = video_cc_sc7180_gdscs,
+       .num_gdscs = ARRAY_SIZE(video_cc_sc7180_gdscs),
+};
+
+static const struct of_device_id video_cc_sc7180_match_table[] = {
+       { .compatible = "qcom,sc7180-videocc" },
+       { }
+};
+MODULE_DEVICE_TABLE(of, video_cc_sc7180_match_table);
+
+static int video_cc_sc7180_probe(struct platform_device *pdev)
+{
+       struct regmap *regmap;
+       struct alpha_pll_config video_pll0_config = {};
+
+       regmap = qcom_cc_map(pdev, &video_cc_sc7180_desc);
+       if (IS_ERR(regmap))
+               return PTR_ERR(regmap);
+
+       video_pll0_config.l = 0x1f;
+       video_pll0_config.alpha = 0x4000;
+       video_pll0_config.user_ctl_val = 0x00000001;
+       video_pll0_config.user_ctl_hi_val = 0x00004805;
+
+       clk_fabia_pll_configure(&video_pll0, regmap, &video_pll0_config);
+
+       /* Keep VIDEO_CC_XO_CLK ALWAYS-ON */
+       regmap_update_bits(regmap, 0x984, 0x1, 0x1);
+
+       return qcom_cc_really_probe(pdev, &video_cc_sc7180_desc, regmap);
+}
+
+static struct platform_driver video_cc_sc7180_driver = {
+       .probe = video_cc_sc7180_probe,
+       .driver = {
+               .name = "sc7180-videocc",
+               .of_match_table = video_cc_sc7180_match_table,
+       },
+};
+
+static int __init video_cc_sc7180_init(void)
+{
+       return platform_driver_register(&video_cc_sc7180_driver);
+}
+subsys_initcall(video_cc_sc7180_init);
+
+static void __exit video_cc_sc7180_exit(void)
+{
+       platform_driver_unregister(&video_cc_sc7180_driver);
+}
+module_exit(video_cc_sc7180_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("QTI VIDEOCC SC7180 Driver");
index 4cd846b..250d816 100644 (file)
@@ -20,8 +20,8 @@ config CLK_RENESAS
        select CLK_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793
        select CLK_R8A7792 if ARCH_R8A7792
        select CLK_R8A7794 if ARCH_R8A7794
-       select CLK_R8A7795 if ARCH_R8A7795
-       select CLK_R8A77960 if ARCH_R8A77960 || ARCH_R8A7796
+       select CLK_R8A7795 if ARCH_R8A77950 || ARCH_R8A77951 || ARCH_R8A7795
+       select CLK_R8A77960 if ARCH_R8A77960
        select CLK_R8A77961 if ARCH_R8A77961
        select CLK_R8A77965 if ARCH_R8A77965
        select CLK_R8A77970 if ARCH_R8A77970
index cf65d4e..443bff0 100644 (file)
@@ -93,6 +93,7 @@ static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = {
        DEF_MOD_STB("ether1",    64,    R7S9210_CLK_B),
        DEF_MOD_STB("ether0",    65,    R7S9210_CLK_B),
 
+       DEF_MOD_STB("spibsc",    83,    R7S9210_CLK_P1),
        DEF_MOD_STB("i2c3",      84,    R7S9210_CLK_P1),
        DEF_MOD_STB("i2c2",      85,    R7S9210_CLK_P1),
        DEF_MOD_STB("i2c1",      86,    R7S9210_CLK_P1),
index db2f57e..bdcd4a3 100644 (file)
@@ -24,10 +24,10 @@ enum rcar_gen2_clk_types {
 };
 
 struct rcar_gen2_cpg_pll_config {
-       unsigned int extal_div;
-       unsigned int pll1_mult;
-       unsigned int pll3_mult;
-       unsigned int pll0_mult;         /* leave as zero if PLL0CR exists */
+       u8 extal_div;
+       u8 pll1_mult;
+       u8 pll3_mult;
+       u8 pll0_mult;           /* leave as zero if PLL0CR exists */
 };
 
 struct clk *rcar_gen2_cpg_clk_register(struct device *dev,
index c97b647..488f8b3 100644 (file)
@@ -470,7 +470,8 @@ static struct clk * __init cpg_rpc_clk_register(const char *name,
 
        clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
                                     &rpc->div.hw,  &clk_divider_ops,
-                                    &rpc->gate.hw, &clk_gate_ops, 0);
+                                    &rpc->gate.hw, &clk_gate_ops,
+                                    CLK_SET_RATE_PARENT);
        if (IS_ERR(clk)) {
                kfree(rpc);
                return clk;
@@ -506,7 +507,8 @@ static struct clk * __init cpg_rpcd2_clk_register(const char *name,
 
        clk = clk_register_composite(NULL, name, &parent_name, 1, NULL, NULL,
                                     &rpcd2->fixed.hw, &clk_fixed_factor_ops,
-                                    &rpcd2->gate.hw, &clk_gate_ops, 0);
+                                    &rpcd2->gate.hw, &clk_gate_ops,
+                                    CLK_SET_RATE_PARENT);
        if (IS_ERR(clk))
                kfree(rpcd2);
 
index 198417d..10560d9 100644 (file)
@@ -282,7 +282,7 @@ static int rockchip_rk3036_pll_is_enabled(struct clk_hw *hw)
        return !(pllcon & RK3036_PLLCON1_PWRDOWN);
 }
 
-static void rockchip_rk3036_pll_init(struct clk_hw *hw)
+static int rockchip_rk3036_pll_init(struct clk_hw *hw)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
@@ -290,14 +290,14 @@ static void rockchip_rk3036_pll_init(struct clk_hw *hw)
        unsigned long drate;
 
        if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
-               return;
+               return 0;
 
        drate = clk_hw_get_rate(hw);
        rate = rockchip_get_pll_settings(pll, drate);
 
        /* when no rate setting for the current rate, rely on clk_set_rate */
        if (!rate)
-               return;
+               return 0;
 
        rockchip_rk3036_pll_get_params(pll, &cur);
 
@@ -319,13 +319,15 @@ static void rockchip_rk3036_pll_init(struct clk_hw *hw)
                if (!parent) {
                        pr_warn("%s: parent of %s not available\n",
                                __func__, __clk_get_name(hw->clk));
-                       return;
+                       return 0;
                }
 
                pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
                         __func__, __clk_get_name(hw->clk));
                rockchip_rk3036_pll_set_params(pll, rate);
        }
+
+       return 0;
 }
 
 static const struct clk_ops rockchip_rk3036_pll_clk_norate_ops = {
@@ -515,7 +517,7 @@ static int rockchip_rk3066_pll_is_enabled(struct clk_hw *hw)
        return !(pllcon & RK3066_PLLCON3_PWRDOWN);
 }
 
-static void rockchip_rk3066_pll_init(struct clk_hw *hw)
+static int rockchip_rk3066_pll_init(struct clk_hw *hw)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
@@ -523,14 +525,14 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
        unsigned long drate;
 
        if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
-               return;
+               return 0;
 
        drate = clk_hw_get_rate(hw);
        rate = rockchip_get_pll_settings(pll, drate);
 
        /* when no rate setting for the current rate, rely on clk_set_rate */
        if (!rate)
-               return;
+               return 0;
 
        rockchip_rk3066_pll_get_params(pll, &cur);
 
@@ -543,6 +545,8 @@ static void rockchip_rk3066_pll_init(struct clk_hw *hw)
                         __func__, clk_hw_get_name(hw));
                rockchip_rk3066_pll_set_params(pll, rate);
        }
+
+       return 0;
 }
 
 static const struct clk_ops rockchip_rk3066_pll_clk_norate_ops = {
@@ -761,7 +765,7 @@ static int rockchip_rk3399_pll_is_enabled(struct clk_hw *hw)
        return !(pllcon & RK3399_PLLCON3_PWRDOWN);
 }
 
-static void rockchip_rk3399_pll_init(struct clk_hw *hw)
+static int rockchip_rk3399_pll_init(struct clk_hw *hw)
 {
        struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
        const struct rockchip_pll_rate_table *rate;
@@ -769,14 +773,14 @@ static void rockchip_rk3399_pll_init(struct clk_hw *hw)
        unsigned long drate;
 
        if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
-               return;
+               return 0;
 
        drate = clk_hw_get_rate(hw);
        rate = rockchip_get_pll_settings(pll, drate);
 
        /* when no rate setting for the current rate, rely on clk_set_rate */
        if (!rate)
-               return;
+               return 0;
 
        rockchip_rk3399_pll_get_params(pll, &cur);
 
@@ -798,13 +802,15 @@ static void rockchip_rk3399_pll_init(struct clk_hw *hw)
                if (!parent) {
                        pr_warn("%s: parent of %s not available\n",
                                __func__, __clk_get_name(hw->clk));
-                       return;
+                       return 0;
                }
 
                pr_debug("%s: pll %s: rate params do not match rate table, adjusting\n",
                         __func__, __clk_get_name(hw->clk));
                rockchip_rk3399_pll_set_params(pll, rate);
        }
+
+       return 0;
 }
 
 static const struct clk_ops rockchip_rk3399_pll_clk_norate_ops = {
index 49bd7a4..5f66bf8 100644 (file)
@@ -921,11 +921,26 @@ static const struct sunxi_ccu_desc sun50i_a64_ccu_desc = {
        .num_resets     = ARRAY_SIZE(sun50i_a64_ccu_resets),
 };
 
+static struct ccu_pll_nb sun50i_a64_pll_cpu_nb = {
+       .common = &pll_cpux_clk.common,
+       /* copy from pll_cpux_clk */
+       .enable = BIT(31),
+       .lock   = BIT(28),
+};
+
+static struct ccu_mux_nb sun50i_a64_cpu_nb = {
+       .common         = &cpux_clk.common,
+       .cm             = &cpux_clk.mux,
+       .delay_us       = 1, /* > 8 clock cycles at 24 MHz */
+       .bypass_index   = 1, /* index of 24 MHz oscillator */
+};
+
 static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 {
        struct resource *res;
        void __iomem *reg;
        u32 val;
+       int ret;
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        reg = devm_ioremap_resource(&pdev->dev, res);
@@ -939,7 +954,18 @@ static int sun50i_a64_ccu_probe(struct platform_device *pdev)
 
        writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
 
-       return sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+       ret = sunxi_ccu_probe(pdev->dev.of_node, reg, &sun50i_a64_ccu_desc);
+       if (ret)
+               return ret;
+
+       /* Gate then ungate PLL CPU after any rate changes */
+       ccu_pll_notifier_register(&sun50i_a64_pll_cpu_nb);
+
+       /* Reparent CPU during PLL CPU rate changes */
+       ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
+                                 &sun50i_a64_cpu_nb);
+
+       return 0;
 }
 
 static const struct of_device_id sun50i_a64_ccu_ids[] = {
index 9799292..116e6f8 100644 (file)
@@ -36,7 +36,6 @@
 #define CLK_PLL_HSIC                   18
 #define CLK_PLL_DE                     19
 #define CLK_PLL_DDR1                   20
-#define CLK_CPUX                       21
 #define CLK_AXI                                22
 #define CLK_APB                                23
 #define CLK_AHB1                       24
index a361388..3ed2a59 100644 (file)
@@ -32,7 +32,9 @@
 /* The PLL_VIDEO1_2X clock is exported */
 
 #define CLK_PLL_GPU            14
-#define CLK_PLL_MIPI           15
+
+/* The PLL_VIDEO1_2X clock is exported */
+
 #define CLK_PLL9               16
 #define CLK_PLL10              17
 
index 72df692..5bf5c4d 100644 (file)
@@ -24,7 +24,9 @@
 #define CLK_PLL_PERIPH         10
 #define CLK_PLL_PERIPH_2X      11
 #define CLK_PLL_GPU            12
-#define CLK_PLL_MIPI           13
+
+/* The PLL MIPI clock is exported */
+
 #define CLK_PLL_HSIC           14
 #define CLK_PLL_DE             15
 #define CLK_PLL_DDR1           16
index a69637b..6f7071d 100644 (file)
 
 /* Some more module clocks are exported */
 
-#define CLK_MBUS               155
-
-/* Another bunch of module clocks are exported */
-
 #define CLK_NUMBER             (CLK_OUTB + 1)
 
 #endif /* _CCU_SUN8I_R40_H_ */
index a165e71..4c75b07 100644 (file)
@@ -37,7 +37,6 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
 {
        struct device_node *np = pdev->dev.of_node;
        struct clk_onecell_data *clk_data;
-       const struct of_device_id *device;
        const struct gates_data *data;
        const char *clk_parent;
        const char *clk_name;
@@ -50,10 +49,9 @@ static int sun6i_a31_apb0_gates_clk_probe(struct platform_device *pdev)
        if (!np)
                return -ENODEV;
 
-       device = of_match_device(sun6i_a31_apb0_gates_clk_dt_ids, &pdev->dev);
-       if (!device)
+       data = of_device_get_match_data(&pdev->dev);
+       if (!data)
                return -ENODEV;
-       data = device->data;
 
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        reg = devm_ioremap_resource(&pdev->dev, r);
index c051d92..cfbaa90 100644 (file)
@@ -1487,7 +1487,6 @@ static int dfll_init(struct tegra_dfll *td)
        td->last_unrounded_rate = 0;
 
        pm_runtime_enable(td->dev);
-       pm_runtime_irq_safe(td->dev);
        pm_runtime_get_sync(td->dev);
 
        dfll_set_mode(td, DFLL_DISABLED);
@@ -1516,7 +1515,7 @@ di_err1:
 
 /**
  * tegra_dfll_suspend - check DFLL is disabled
- * @dev: DFLL device *
+ * @dev: DFLL instance
  *
  * DFLL clock should be disabled by the CPUFreq driver. So, make
  * sure it is disabled and disable all clocks needed by the DFLL.
index ca0de5f..38daf48 100644 (file)
@@ -40,8 +40,13 @@ static unsigned long clk_frac_div_recalc_rate(struct clk_hw *hw,
        int div, mul;
        u64 rate = parent_rate;
 
-       reg = readl_relaxed(divider->reg) >> divider->shift;
-       div = reg & div_mask(divider);
+       reg = readl_relaxed(divider->reg);
+
+       if ((divider->flags & TEGRA_DIVIDER_UART) &&
+           !(reg & PERIPH_CLK_UART_DIV_ENB))
+               return rate;
+
+       div = (reg >> divider->shift) & div_mask(divider);
 
        mul = get_mul(divider);
        div += mul;
index 0d07c0b..2b2a3b8 100644 (file)
@@ -777,7 +777,11 @@ static struct tegra_periph_init_data gate_clks[] = {
        GATE("ahbdma", "hclk", 33, 0, tegra_clk_ahbdma, 0),
        GATE("apbdma", "pclk", 34, 0, tegra_clk_apbdma, 0),
        GATE("kbc", "clk_32k", 36, TEGRA_PERIPH_ON_APB | TEGRA_PERIPH_NO_RESET, tegra_clk_kbc, 0),
-       GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, 0),
+       /*
+        * Critical for RAM re-repair operation, which must occur on resume
+        * from LP1 system suspend and as part of CCPLEX cluster switching.
+        */
+       GATE("fuse", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse, CLK_IS_CRITICAL),
        GATE("fuse_burn", "clk_m", 39, TEGRA_PERIPH_ON_APB, tegra_clk_fuse_burn, 0),
        GATE("kfuse", "clk_m", 40, TEGRA_PERIPH_ON_APB, tegra_clk_kfuse, 0),
        GATE("apbif", "clk_m", 107, TEGRA_PERIPH_ON_APB, tegra_clk_apbif, 0),
index 4d8222f..fff5cba 100644 (file)
@@ -1046,11 +1046,9 @@ static struct tegra_clk_init_table init_table[] __initdata = {
        { TEGRA20_CLK_SBC3, TEGRA20_CLK_PLL_P, 100000000, 0 },
        { TEGRA20_CLK_SBC4, TEGRA20_CLK_PLL_P, 100000000, 0 },
        { TEGRA20_CLK_HOST1X, TEGRA20_CLK_PLL_C, 150000000, 0 },
-       { TEGRA20_CLK_DISP1, TEGRA20_CLK_PLL_P, 600000000, 0 },
-       { TEGRA20_CLK_DISP2, TEGRA20_CLK_PLL_P, 600000000, 0 },
        { TEGRA20_CLK_GR2D, TEGRA20_CLK_PLL_C, 300000000, 0 },
        { TEGRA20_CLK_GR3D, TEGRA20_CLK_PLL_C, 300000000, 0 },
-       { TEGRA20_CLK_VDE, TEGRA20_CLK_CLK_MAX, 300000000, 0 },
+       { TEGRA20_CLK_VDE, TEGRA20_CLK_PLL_C, 300000000, 0 },
        /* must be the last entry */
        { TEGRA20_CLK_CLK_MAX, TEGRA20_CLK_CLK_MAX, 0, 0 },
 };
index c8bc18e..b208914 100644 (file)
@@ -1251,14 +1251,12 @@ static struct tegra_clk_init_table init_table[] __initdata = {
        { TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0 },
        { TEGRA30_CLK_PLL_C, TEGRA30_CLK_CLK_MAX, 600000000, 0 },
        { TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0 },
-       { TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0 },
-       { TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0 },
        { TEGRA30_CLK_TWD, TEGRA30_CLK_CLK_MAX, 0, 1 },
        { TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0 },
        { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 },
        { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 },
        { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 },
-       { TEGRA30_CLK_VDE, TEGRA30_CLK_CLK_MAX, 600000000, 0 },
+       { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 600000000, 0 },
        { TEGRA30_CLK_SPDIF_IN_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
        { TEGRA30_CLK_I2S0_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
        { TEGRA30_CLK_I2S1_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
index 2b4dab6..312a20f 100644 (file)
@@ -604,6 +604,18 @@ static const struct omap_clkctrl_reg_data omap4_l4_per_clkctrl_regs[] __initcons
        { 0 },
 };
 
+static const struct
+omap_clkctrl_reg_data omap4_l4_secure_clkctrl_regs[] __initconst = {
+       { OMAP4_AES1_CLKCTRL, NULL, CLKF_SW_SUP, "" },
+       { OMAP4_AES2_CLKCTRL, NULL, CLKF_SW_SUP, "" },
+       { OMAP4_DES3DES_CLKCTRL, NULL, CLKF_SW_SUP, "" },
+       { OMAP4_PKA_CLKCTRL, NULL, CLKF_SW_SUP, "" },
+       { OMAP4_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+       { OMAP4_SHA2MD5_CLKCTRL, NULL, CLKF_SW_SUP, "" },
+       { OMAP4_CRYPTODMA_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+       { 0 },
+};
+
 static const struct omap_clkctrl_bit_data omap4_gpio1_bit_data[] __initconst = {
        { 8, TI_CLK_GATE, omap4_gpio2_dbclk_parents, NULL },
        { 0 },
@@ -691,6 +703,7 @@ const struct omap_clkctrl_data omap4_clkctrl_data[] __initconst = {
        { 0x4a009220, omap4_l3_gfx_clkctrl_regs },
        { 0x4a009320, omap4_l3_init_clkctrl_regs },
        { 0x4a009420, omap4_l4_per_clkctrl_regs },
+       { 0x4a0095a0, omap4_l4_secure_clkctrl_regs },
        { 0x4a307820, omap4_l4_wkup_clkctrl_regs },
        { 0x4a307a20, omap4_emu_sys_clkctrl_regs },
        { 0 },
index c9608e5..92bf2dd 100644 (file)
@@ -35,6 +35,20 @@ static const struct omap_clkctrl_reg_data omap5_dsp_clkctrl_regs[] __initconst =
        { 0 },
 };
 
+static const char * const omap5_aess_fclk_parents[] __initconst = {
+       "abe_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data omap5_aess_fclk_data __initconst = {
+       .max_div = 2,
+};
+
+static const struct omap_clkctrl_bit_data omap5_aess_bit_data[] __initconst = {
+       { 24, TI_CLK_DIVIDER, omap5_aess_fclk_parents, &omap5_aess_fclk_data },
+       { 0 },
+};
+
 static const char * const omap5_dmic_gfclk_parents[] __initconst = {
        "abe_cm:clk:0018:26",
        "pad_clks_ck",
@@ -122,6 +136,7 @@ static const struct omap_clkctrl_bit_data omap5_timer8_bit_data[] __initconst =
 
 static const struct omap_clkctrl_reg_data omap5_abe_clkctrl_regs[] __initconst = {
        { OMAP5_L4_ABE_CLKCTRL, NULL, 0, "abe_iclk" },
+       { OMAP5_AESS_CLKCTRL, omap5_aess_bit_data, CLKF_SW_SUP, "abe_cm:clk:0008:24" },
        { OMAP5_MCPDM_CLKCTRL, NULL, CLKF_SW_SUP, "pad_clks_ck" },
        { OMAP5_DMIC_CLKCTRL, omap5_dmic_bit_data, CLKF_SW_SUP, "abe_cm:clk:0018:24" },
        { OMAP5_MCBSP1_CLKCTRL, omap5_mcbsp1_bit_data, CLKF_SW_SUP, "abe_cm:clk:0028:24" },
@@ -286,6 +301,18 @@ static const struct omap_clkctrl_reg_data omap5_l4per_clkctrl_regs[] __initconst
        { 0 },
 };
 
+static const struct
+omap_clkctrl_reg_data omap5_l4_secure_clkctrl_regs[] __initconst = {
+       { OMAP5_AES1_CLKCTRL, NULL, CLKF_HW_SUP, "" },
+       { OMAP5_AES2_CLKCTRL, NULL, CLKF_HW_SUP, "" },
+       { OMAP5_DES3DES_CLKCTRL, NULL, CLKF_HW_SUP, "" },
+       { OMAP5_FPKA_CLKCTRL, NULL, CLKF_SW_SUP, "" },
+       { OMAP5_RNG_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+       { OMAP5_SHA2MD5_CLKCTRL, NULL, CLKF_HW_SUP, "" },
+       { OMAP5_DMA_CRYPTO_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_SOC_NONSEC, "" },
+       { 0 },
+};
+
 static const struct omap_clkctrl_reg_data omap5_iva_clkctrl_regs[] __initconst = {
        { OMAP5_IVA_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h12x2_ck" },
        { OMAP5_SL2IF_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h12x2_ck" },
@@ -508,6 +535,7 @@ const struct omap_clkctrl_data omap5_clkctrl_data[] __initconst = {
        { 0x4a008d20, omap5_l4cfg_clkctrl_regs },
        { 0x4a008e20, omap5_l3instr_clkctrl_regs },
        { 0x4a009020, omap5_l4per_clkctrl_regs },
+       { 0x4a0091a0, omap5_l4_secure_clkctrl_regs },
        { 0x4a009220, omap5_iva_clkctrl_regs },
        { 0x4a009420, omap5_dss_clkctrl_regs },
        { 0x4a009520, omap5_gpu_clkctrl_regs },
index 5f46782..14b6450 100644 (file)
@@ -146,6 +146,29 @@ static const struct omap_clkctrl_reg_data dra7_rtc_clkctrl_regs[] __initconst =
        { 0 },
 };
 
+static const char * const dra7_cam_gfclk_mux_parents[] __initconst = {
+       "l3_iclk_div",
+       "core_iss_main_clk",
+       NULL,
+};
+
+static const struct omap_clkctrl_bit_data dra7_cam_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_cam_gfclk_mux_parents, NULL },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_cam_clkctrl_regs[] __initconst = {
+       { DRA7_CAM_VIP1_CLKCTRL, dra7_cam_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_CAM_VIP2_CLKCTRL, dra7_cam_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { DRA7_CAM_VIP3_CLKCTRL, dra7_cam_bit_data, CLKF_HW_SUP, "l3_iclk_div" },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_vpe_clkctrl_regs[] __initconst = {
+       { DRA7_VPE_VPE_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h23x2_ck" },
+       { 0 },
+};
+
 static const struct omap_clkctrl_reg_data dra7_coreaon_clkctrl_regs[] __initconst = {
        { DRA7_COREAON_SMARTREFLEX_MPU_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" },
        { DRA7_COREAON_SMARTREFLEX_CORE_CLKCTRL, NULL, CLKF_SW_SUP, "wkupaon_iclk_mux" },
@@ -275,6 +298,40 @@ static const struct omap_clkctrl_reg_data dra7_dss_clkctrl_regs[] __initconst =
        { 0 },
 };
 
+static const char * const dra7_gpu_core_mux_parents[] __initconst = {
+       "dpll_core_h14x2_ck",
+       "dpll_per_h14x2_ck",
+       "dpll_gpu_m2_ck",
+       NULL,
+};
+
+static const char * const dra7_gpu_hyd_mux_parents[] __initconst = {
+       "dpll_core_h14x2_ck",
+       "dpll_per_h14x2_ck",
+       "dpll_gpu_m2_ck",
+       NULL,
+};
+
+static const char * const dra7_gpu_sys_clk_parents[] __initconst = {
+       "sys_clkin",
+       NULL,
+};
+
+static const struct omap_clkctrl_div_data dra7_gpu_sys_clk_data __initconst = {
+       .max_div = 2,
+};
+
+static const struct omap_clkctrl_bit_data dra7_gpu_core_bit_data[] __initconst = {
+       { 24, TI_CLK_MUX, dra7_gpu_core_mux_parents, NULL, },
+       { 26, TI_CLK_MUX, dra7_gpu_hyd_mux_parents, NULL, },
+       { 0 },
+};
+
+static const struct omap_clkctrl_reg_data dra7_gpu_clkctrl_regs[] __initconst = {
+       { DRA7_GPU_CLKCTRL, dra7_gpu_core_bit_data, CLKF_SW_SUP, "gpu_cm:clk:0000:24", },
+       { 0 },
+};
+
 static const char * const dra7_mmc1_fclk_mux_parents[] __initconst = {
        "func_128m_clk",
        "dpll_per_m2x2_ck",
@@ -405,7 +462,7 @@ static const struct omap_clkctrl_bit_data dra7_gmac_bit_data[] __initconst = {
 };
 
 static const struct omap_clkctrl_reg_data dra7_gmac_clkctrl_regs[] __initconst = {
-       { DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "dpll_gmac_ck" },
+       { DRA7_GMAC_GMAC_CLKCTRL, dra7_gmac_bit_data, CLKF_SW_SUP, "gmac_main_clk" },
        { 0 },
 };
 
@@ -769,6 +826,7 @@ const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = {
        { 0x4a005550, dra7_ipu_clkctrl_regs },
        { 0x4a005620, dra7_dsp2_clkctrl_regs },
        { 0x4a005720, dra7_rtc_clkctrl_regs },
+       { 0x4a005760, dra7_vpe_clkctrl_regs },
        { 0x4a008620, dra7_coreaon_clkctrl_regs },
        { 0x4a008720, dra7_l3main1_clkctrl_regs },
        { 0x4a008920, dra7_ipu2_clkctrl_regs },
@@ -777,7 +835,9 @@ const struct omap_clkctrl_data dra7_clkctrl_data[] __initconst = {
        { 0x4a008c00, dra7_atl_clkctrl_regs },
        { 0x4a008d20, dra7_l4cfg_clkctrl_regs },
        { 0x4a008e20, dra7_l3instr_clkctrl_regs },
+       { 0x4a009020, dra7_cam_clkctrl_regs },
        { 0x4a009120, dra7_dss_clkctrl_regs },
+       { 0x4a009220, dra7_gpu_clkctrl_regs },
        { 0x4a009320, dra7_l3init_clkctrl_regs },
        { 0x4a0093b0, dra7_pcie_clkctrl_regs },
        { 0x4a0093d0, dra7_gmac_clkctrl_regs },
index e0b8ed3..3da33c7 100644 (file)
@@ -171,7 +171,9 @@ void __init ti_dt_clocks_register(struct ti_dt_clk oclks[])
                node = of_find_node_by_name(NULL, buf);
                if (num_args && compat_mode) {
                        parent = node;
-                       node = of_get_child_by_name(parent, "clk");
+                       node = of_get_child_by_name(parent, "clock");
+                       if (!node)
+                               node = of_get_child_by_name(parent, "clk");
                        of_node_put(parent);
                }
 
index 17b9a76..0622660 100644 (file)
@@ -440,6 +440,63 @@ static void __init _clkctrl_add_provider(void *data,
        of_clk_add_hw_provider(np, _ti_omap4_clkctrl_xlate, data);
 }
 
+/* Get clock name based on compatible string for clkctrl */
+static char * __init clkctrl_get_name(struct device_node *np)
+{
+       struct property *prop;
+       const int prefix_len = 11;
+       const char *compat;
+       char *name;
+
+       of_property_for_each_string(np, "compatible", prop, compat) {
+               if (!strncmp("ti,clkctrl-", compat, prefix_len)) {
+                       /* Two letter minimum name length for l3, l4 etc */
+                       if (strnlen(compat + prefix_len, 16) < 2)
+                               continue;
+                       name = kasprintf(GFP_KERNEL, "%s", compat + prefix_len);
+                       if (!name)
+                               continue;
+                       strreplace(name, '-', '_');
+
+                       return name;
+               }
+       }
+       of_node_put(np);
+
+       return NULL;
+}
+
+/* Get clkctrl clock base name based on clkctrl_name or dts node */
+static const char * __init clkctrl_get_clock_name(struct device_node *np,
+                                                 const char *clkctrl_name,
+                                                 int offset, int index,
+                                                 bool legacy_naming)
+{
+       char *clock_name;
+
+       /* l4per-clkctrl:1234:0 style naming based on clkctrl_name */
+       if (clkctrl_name && !legacy_naming) {
+               clock_name = kasprintf(GFP_KERNEL, "%s-clkctrl:%04x:%d",
+                                      clkctrl_name, offset, index);
+               strreplace(clock_name, '_', '-');
+
+               return clock_name;
+       }
+
+       /* l4per:1234:0 old style naming based on clkctrl_name */
+       if (clkctrl_name)
+               return kasprintf(GFP_KERNEL, "%s_cm:clk:%04x:%d",
+                                clkctrl_name, offset, index);
+
+       /* l4per_cm:1234:0 old style naming based on parent node name */
+       if (legacy_naming)
+               return kasprintf(GFP_KERNEL, "%pOFn:clk:%04x:%d",
+                                np->parent, offset, index);
+
+       /* l4per-clkctrl:1234:0 style naming based on node name */
+       return kasprintf(GFP_KERNEL, "%pOFn:%04x:%d", np, offset, index);
+}
+
 static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
 {
        struct omap_clkctrl_provider *provider;
@@ -448,8 +505,10 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
        struct clk_init_data init = { NULL };
        struct clk_hw_omap *hw;
        struct clk *clk;
-       struct omap_clkctrl_clk *clkctrl_clk;
+       struct omap_clkctrl_clk *clkctrl_clk = NULL;
        const __be32 *addrp;
+       bool legacy_naming;
+       char *clkctrl_name;
        u32 addr;
        int ret;
        char *c;
@@ -537,7 +596,19 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
 
        provider->base = of_iomap(node, 0);
 
-       if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT) {
+       legacy_naming = ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT;
+       clkctrl_name = clkctrl_get_name(node);
+       if (clkctrl_name) {
+               provider->clkdm_name = kasprintf(GFP_KERNEL,
+                                                "%s_clkdm", clkctrl_name);
+               goto clkdm_found;
+       }
+
+       /*
+        * The code below can be removed when all clkctrl nodes use domain
+        * specific compatible proprerty and standard clock node naming
+        */
+       if (legacy_naming) {
                provider->clkdm_name = kasprintf(GFP_KERNEL, "%pOFnxxx", node->parent);
                if (!provider->clkdm_name) {
                        kfree(provider);
@@ -573,7 +644,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
                        *c = '_';
                c++;
        }
-
+clkdm_found:
        INIT_LIST_HEAD(&provider->clocks);
 
        /* Generate clocks */
@@ -612,15 +683,15 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
                init.flags = 0;
                if (reg_data->flags & CLKF_SET_RATE_PARENT)
                        init.flags |= CLK_SET_RATE_PARENT;
-               if (ti_clk_get_features()->flags & TI_CLK_CLKCTRL_COMPAT)
-                       init.name = kasprintf(GFP_KERNEL, "%pOFn:%pOFn:%04x:%d",
-                                             node->parent, node,
-                                             reg_data->offset, 0);
-               else
-                       init.name = kasprintf(GFP_KERNEL, "%pOFn:%04x:%d",
-                                             node, reg_data->offset, 0);
+
+               init.name = clkctrl_get_clock_name(node, clkctrl_name,
+                                                  reg_data->offset, 0,
+                                                  legacy_naming);
+               if (!init.name)
+                       goto cleanup;
+
                clkctrl_clk = kzalloc(sizeof(*clkctrl_clk), GFP_KERNEL);
-               if (!init.name || !clkctrl_clk)
+               if (!clkctrl_clk)
                        goto cleanup;
 
                init.ops = &omap4_clkctrl_clk_ops;
@@ -642,11 +713,14 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
        if (ret == -EPROBE_DEFER)
                ti_clk_retry_init(node, provider, _clkctrl_add_provider);
 
+       kfree(clkctrl_name);
+
        return;
 
 cleanup:
        kfree(hw);
        kfree(init.name);
+       kfree(clkctrl_name);
        kfree(clkctrl_clk);
 }
 CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl",
index e6995c0..f1dd62d 100644 (file)
@@ -253,7 +253,7 @@ extern const struct clk_ops omap_gate_clk_ops;
 
 extern struct ti_clk_features ti_clk_features;
 
-void omap2_init_clk_clkdm(struct clk_hw *hw);
+int omap2_init_clk_clkdm(struct clk_hw *hw);
 int omap2_clkops_enable_clkdm(struct clk_hw *hw);
 void omap2_clkops_disable_clkdm(struct clk_hw *hw);
 
index 423a99b..ee56306 100644 (file)
@@ -101,16 +101,16 @@ void omap2_clkops_disable_clkdm(struct clk_hw *hw)
  *
  * Convert a clockdomain name stored in a struct clk 'clk' into a
  * clockdomain pointer, and save it into the struct clk.  Intended to be
- * called during clk_register().  No return value.
+ * called during clk_register(). Returns 0 on success, -EERROR otherwise.
  */
-void omap2_init_clk_clkdm(struct clk_hw *hw)
+int omap2_init_clk_clkdm(struct clk_hw *hw)
 {
        struct clk_hw_omap *clk = to_clk_hw_omap(hw);
        struct clockdomain *clkdm;
        const char *clk_name;
 
        if (!clk->clkdm_name)
-               return;
+               return 0;
 
        clk_name = __clk_get_name(hw->clk);
 
@@ -123,6 +123,8 @@ void omap2_init_clk_clkdm(struct clk_hw *hw)
                pr_debug("clock: could not associate clk %s to clkdm %s\n",
                         clk_name, clk->clkdm_name);
        }
+
+       return 0;
 }
 
 static void __init of_ti_clockdomain_setup(struct device_node *node)
index 9caa529..3e32db9 100644 (file)
@@ -18,8 +18,8 @@
 #define UNIPHIER_PERI_CLK_FI2C(idx, ch)                                        \
        UNIPHIER_CLK_GATE("i2c" #ch, (idx), "i2c", 0x24, 24 + (ch))
 
-#define UNIPHIER_PERI_CLK_SCSSI(idx)                                   \
-       UNIPHIER_CLK_GATE("scssi", (idx), "spi", 0x20, 17)
+#define UNIPHIER_PERI_CLK_SCSSI(idx, ch)                               \
+       UNIPHIER_CLK_GATE("scssi" #ch, (idx), "spi", 0x20, 17 + (ch))
 
 #define UNIPHIER_PERI_CLK_MCSSI(idx)                                   \
        UNIPHIER_CLK_GATE("mcssi", (idx), "spi", 0x24, 14)
@@ -35,7 +35,7 @@ const struct uniphier_clk_data uniphier_ld4_peri_clk_data[] = {
        UNIPHIER_PERI_CLK_I2C(6, 2),
        UNIPHIER_PERI_CLK_I2C(7, 3),
        UNIPHIER_PERI_CLK_I2C(8, 4),
-       UNIPHIER_PERI_CLK_SCSSI(11),
+       UNIPHIER_PERI_CLK_SCSSI(11, 0),
        { /* sentinel */ }
 };
 
@@ -51,7 +51,10 @@ const struct uniphier_clk_data uniphier_pro4_peri_clk_data[] = {
        UNIPHIER_PERI_CLK_FI2C(8, 4),
        UNIPHIER_PERI_CLK_FI2C(9, 5),
        UNIPHIER_PERI_CLK_FI2C(10, 6),
-       UNIPHIER_PERI_CLK_SCSSI(11),
-       UNIPHIER_PERI_CLK_MCSSI(12),
+       UNIPHIER_PERI_CLK_SCSSI(11, 0),
+       UNIPHIER_PERI_CLK_SCSSI(12, 1),
+       UNIPHIER_PERI_CLK_SCSSI(13, 2),
+       UNIPHIER_PERI_CLK_SCSSI(14, 3),
+       UNIPHIER_PERI_CLK_MCSSI(15),
        { /* sentinel */ }
 };
index 72ed97c..0aedd42 100644 (file)
@@ -99,8 +99,10 @@ static void u8500_clk_init(struct device_node *np)
        if (fw_version != NULL) {
                switch (fw_version->project) {
                case PRCMU_FW_PROJECT_U8500_C2:
+               case PRCMU_FW_PROJECT_U8500_MBL:
                case PRCMU_FW_PROJECT_U8520:
                case PRCMU_FW_PROJECT_U8420:
+               case PRCMU_FW_PROJECT_U8420_SYSCLK:
                        sgaclk_parent = "soc0_pll";
                        break;
                default:
index ac76685..c2618f1 100644 (file)
@@ -9,7 +9,7 @@ config COMMON_CLK_VERSATILE
                COMPILE_TEST
        select REGMAP_MMIO
        ---help---
-          Supports clocking on ARM Reference designs:
+         Supports clocking on ARM Reference designs:
          - Integrator/AP and Integrator/CP
          - RealView PB1176, EB, PB11MP and PBX
          - Versatile Express
index a11f93e..10e89f2 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Zynq UltraScale+ MPSoC clock controller
  *
- *  Copyright (C) 2016-2018 Xilinx
+ *  Copyright (C) 2016-2019 Xilinx
  *
  * Based on drivers/clk/zynq/clkc.c
  */
@@ -749,6 +749,7 @@ static int zynqmp_clock_probe(struct platform_device *pdev)
 
 static const struct of_device_id zynqmp_clock_of_match[] = {
        {.compatible = "xlnx,zynqmp-clk"},
+       {.compatible = "xlnx,versal-clk"},
        {},
 };
 MODULE_DEVICE_TABLE(of, zynqmp_clock_of_match);
index d8f5b70..4be2cc7 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Zynq UltraScale+ MPSoC Divider support
  *
- *  Copyright (C) 2016-2018 Xilinx
+ *  Copyright (C) 2016-2019 Xilinx
  *
  * Adjustable divider clock implementation
  */
@@ -41,12 +41,30 @@ struct zynqmp_clk_divider {
        bool is_frac;
        u32 clk_id;
        u32 div_type;
+       u16 max_div;
 };
 
 static inline int zynqmp_divider_get_val(unsigned long parent_rate,
-                                        unsigned long rate)
+                                        unsigned long rate, u16 flags)
 {
-       return DIV_ROUND_CLOSEST(parent_rate, rate);
+       int up, down;
+       unsigned long up_rate, down_rate;
+
+       if (flags & CLK_DIVIDER_POWER_OF_TWO) {
+               up = DIV_ROUND_UP_ULL((u64)parent_rate, rate);
+               down = DIV_ROUND_DOWN_ULL((u64)parent_rate, rate);
+
+               up = __roundup_pow_of_two(up);
+               down = __rounddown_pow_of_two(down);
+
+               up_rate = DIV_ROUND_UP_ULL((u64)parent_rate, up);
+               down_rate = DIV_ROUND_UP_ULL((u64)parent_rate, down);
+
+               return (rate - up_rate) <= (down_rate - rate) ? up : down;
+
+       } else {
+               return DIV_ROUND_CLOSEST(parent_rate, rate);
+       }
 }
 
 /**
@@ -78,6 +96,9 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
        else
                value = div >> 16;
 
+       if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+               value = 1 << value;
+
        if (!value) {
                WARN(!(divider->flags & CLK_DIVIDER_ALLOW_ZERO),
                     "%s: Zero divisor and CLK_DIVIDER_ALLOW_ZERO not set\n",
@@ -88,6 +109,42 @@ static unsigned long zynqmp_clk_divider_recalc_rate(struct clk_hw *hw,
        return DIV_ROUND_UP_ULL(parent_rate, value);
 }
 
+static void zynqmp_get_divider2_val(struct clk_hw *hw,
+                                   unsigned long rate,
+                                   unsigned long parent_rate,
+                                   struct zynqmp_clk_divider *divider,
+                                   int *bestdiv)
+{
+       int div1;
+       int div2;
+       long error = LONG_MAX;
+       struct clk_hw *parent_hw = clk_hw_get_parent(hw);
+       struct zynqmp_clk_divider *pdivider = to_zynqmp_clk_divider(parent_hw);
+
+       if (!pdivider)
+               return;
+
+       *bestdiv = 1;
+       for (div1 = 1; div1 <= pdivider->max_div;) {
+               for (div2 = 1; div2 <= divider->max_div;) {
+                       long new_error = ((parent_rate / div1) / div2) - rate;
+
+                       if (abs(new_error) < abs(error)) {
+                               *bestdiv = div2;
+                               error = new_error;
+                       }
+                       if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+                               div2 = div2 << 1;
+                       else
+                               div2++;
+               }
+               if (pdivider->flags & CLK_DIVIDER_POWER_OF_TWO)
+                       div1 = div1 << 1;
+               else
+                       div1++;
+       }
+}
+
 /**
  * zynqmp_clk_divider_round_rate() - Round rate of divider clock
  * @hw:                        handle between common and hardware-specific interfaces
@@ -120,10 +177,23 @@ static long zynqmp_clk_divider_round_rate(struct clk_hw *hw,
                else
                        bestdiv  = bestdiv >> 16;
 
+               if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+                       bestdiv = 1 << bestdiv;
+
                return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
        }
 
-       bestdiv = zynqmp_divider_get_val(*prate, rate);
+       bestdiv = zynqmp_divider_get_val(*prate, rate, divider->flags);
+
+       /*
+        * In case of two divisors, compute best divider values and return
+        * divider2 value based on compute value. div1 will  be automatically
+        * set to optimum based on required total divider value.
+        */
+       if (div_type == TYPE_DIV2 &&
+           (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
+               zynqmp_get_divider2_val(hw, rate, *prate, divider, &bestdiv);
+       }
 
        if ((clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) && divider->is_frac)
                bestdiv = rate % *prate ? 1 : bestdiv;
@@ -151,7 +221,7 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
        int ret;
        const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
 
-       value = zynqmp_divider_get_val(parent_rate, rate);
+       value = zynqmp_divider_get_val(parent_rate, rate, divider->flags);
        if (div_type == TYPE_DIV1) {
                div = value & 0xFFFF;
                div |= 0xffff << 16;
@@ -160,6 +230,9 @@ static int zynqmp_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
                div |= value << 16;
        }
 
+       if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
+               div = __ffs(div);
+
        ret = eemi_ops->clock_setdivider(clk_id, div);
 
        if (ret)
@@ -176,6 +249,35 @@ static const struct clk_ops zynqmp_clk_divider_ops = {
 };
 
 /**
+ * zynqmp_clk_get_max_divisor() - Get maximum supported divisor from firmware.
+ * @clk_id:            Id of clock
+ * @type:              Divider type
+ *
+ * Return: Maximum divisor of a clock if query data is successful
+ *        U16_MAX in case of query data is not success
+ */
+u32 zynqmp_clk_get_max_divisor(u32 clk_id, u32 type)
+{
+       const struct zynqmp_eemi_ops *eemi_ops = zynqmp_pm_get_eemi_ops();
+       struct zynqmp_pm_query_data qdata = {0};
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       int ret;
+
+       qdata.qid = PM_QID_CLOCK_GET_MAX_DIVISOR;
+       qdata.arg1 = clk_id;
+       qdata.arg2 = type;
+       ret = eemi_ops->query_data(qdata, ret_payload);
+       /*
+        * To maintain backward compatibility return maximum possible value
+        * (0xFFFF) if query for max divisor is not successful.
+        */
+       if (ret)
+               return U16_MAX;
+
+       return ret_payload[1];
+}
+
+/**
  * zynqmp_clk_register_divider() - Register a divider clock
  * @name:              Name of this clock
  * @clk_id:            Id of clock
@@ -215,6 +317,12 @@ struct clk_hw *zynqmp_clk_register_divider(const char *name,
        div->clk_id = clk_id;
        div->div_type = nodes->type;
 
+       /*
+        * To achieve best possible rate, maximum limit of divider is required
+        * while computation.
+        */
+       div->max_div = zynqmp_clk_get_max_divisor(clk_id, nodes->type);
+
        hw = &div->hw;
        ret = clk_hw_register(NULL, hw);
        if (ret) {
index a541397..89b5995 100644 (file)
@@ -188,10 +188,12 @@ static int zynqmp_pll_set_rate(struct clk_hw *hw, unsigned long rate,
                frac = (parent_rate * f) / FRAC_DIV;
 
                ret = eemi_ops->clock_setdivider(clk_id, m);
-               if (ret)
+               if (ret == -EUSERS)
+                       WARN(1, "More than allowed devices are using the %s, which is forbidden\n",
+                            clk_name);
+               else if (ret)
                        pr_warn_once("%s() set divider failed for %s, ret = %d\n",
                                     __func__, clk_name, ret);
-
                eemi_ops->ioctl(0, IOCTL_SET_PLL_FRAC_DATA, clk_id, f, NULL);
 
                return rate + frac;
index 62745c9..e421946 100644 (file)
@@ -302,10 +302,6 @@ int __init davinci_timer_register(struct clk *clk,
                return rv;
        }
 
-       clockevents_config_and_register(&clockevent->dev, tick_rate,
-                                       DAVINCI_TIMER_MIN_DELTA,
-                                       DAVINCI_TIMER_MAX_DELTA);
-
        davinci_clocksource.dev.rating = 300;
        davinci_clocksource.dev.read = davinci_clocksource_read;
        davinci_clocksource.dev.mask =
@@ -323,6 +319,10 @@ int __init davinci_timer_register(struct clk *clk,
                davinci_clocksource_init_tim34(base);
        }
 
+       clockevents_config_and_register(&clockevent->dev, tick_rate,
+                                       DAVINCI_TIMER_MIN_DELTA,
+                                       DAVINCI_TIMER_MAX_DELTA);
+
        rv = clocksource_register_hz(&davinci_clocksource.dev, tick_rate);
        if (rv) {
                pr_err("Unable to register clocksource");
index e6182c8..61623e2 100644 (file)
@@ -261,7 +261,7 @@ static void scmi_cpufreq_remove(struct scmi_device *sdev)
 }
 
 static const struct scmi_device_id scmi_id_table[] = {
-       { SCMI_PROTOCOL_PERF },
+       { SCMI_PROTOCOL_PERF, "cpufreq" },
        { },
 };
 MODULE_DEVICE_TABLE(scmi, scmi_id_table);
index ee70d5c..cc8c769 100644 (file)
@@ -21,7 +21,9 @@ obj-$(CONFIG_ARM_U8500_CPUIDLE)         += cpuidle-ux500.o
 obj-$(CONFIG_ARM_AT91_CPUIDLE)          += cpuidle-at91.o
 obj-$(CONFIG_ARM_EXYNOS_CPUIDLE)        += cpuidle-exynos.o
 obj-$(CONFIG_ARM_CPUIDLE)              += cpuidle-arm.o
-obj-$(CONFIG_ARM_PSCI_CPUIDLE)         += cpuidle-psci.o
+obj-$(CONFIG_ARM_PSCI_CPUIDLE)         += cpuidle_psci.o
+cpuidle_psci-y                         := cpuidle-psci.o
+cpuidle_psci-$(CONFIG_PM_GENERIC_DOMAINS_OF) += cpuidle-psci-domain.o
 
 ###############################################################################
 # MIPS drivers
diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c
new file mode 100644 (file)
index 0000000..423f03b
--- /dev/null
@@ -0,0 +1,308 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * PM domains for CPUs via genpd - managed by cpuidle-psci.
+ *
+ * Copyright (C) 2019 Linaro Ltd.
+ * Author: Ulf Hansson <ulf.hansson@linaro.org>
+ *
+ */
+
+#define pr_fmt(fmt) "CPUidle PSCI: " fmt
+
+#include <linux/cpu.h>
+#include <linux/device.h>
+#include <linux/kernel.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
+#include <linux/psci.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+
+#include "cpuidle-psci.h"
+
+struct psci_pd_provider {
+       struct list_head link;
+       struct device_node *node;
+};
+
+static LIST_HEAD(psci_pd_providers);
+static bool osi_mode_enabled __initdata;
+
+static int psci_pd_power_off(struct generic_pm_domain *pd)
+{
+       struct genpd_power_state *state = &pd->states[pd->state_idx];
+       u32 *pd_state;
+
+       if (!state->data)
+               return 0;
+
+       /* OSI mode is enabled, set the corresponding domain state. */
+       pd_state = state->data;
+       psci_set_domain_state(*pd_state);
+
+       return 0;
+}
+
+static int __init psci_pd_parse_state_nodes(struct genpd_power_state *states,
+                                       int state_count)
+{
+       int i, ret;
+       u32 psci_state, *psci_state_buf;
+
+       for (i = 0; i < state_count; i++) {
+               ret = psci_dt_parse_state_node(to_of_node(states[i].fwnode),
+                                       &psci_state);
+               if (ret)
+                       goto free_state;
+
+               psci_state_buf = kmalloc(sizeof(u32), GFP_KERNEL);
+               if (!psci_state_buf) {
+                       ret = -ENOMEM;
+                       goto free_state;
+               }
+               *psci_state_buf = psci_state;
+               states[i].data = psci_state_buf;
+       }
+
+       return 0;
+
+free_state:
+       i--;
+       for (; i >= 0; i--)
+               kfree(states[i].data);
+       return ret;
+}
+
+static int __init psci_pd_parse_states(struct device_node *np,
+                       struct genpd_power_state **states, int *state_count)
+{
+       int ret;
+
+       /* Parse the domain idle states. */
+       ret = of_genpd_parse_idle_states(np, states, state_count);
+       if (ret)
+               return ret;
+
+       /* Fill out the PSCI specifics for each found state. */
+       ret = psci_pd_parse_state_nodes(*states, *state_count);
+       if (ret)
+               kfree(*states);
+
+       return ret;
+}
+
+static void psci_pd_free_states(struct genpd_power_state *states,
+                               unsigned int state_count)
+{
+       int i;
+
+       for (i = 0; i < state_count; i++)
+               kfree(states[i].data);
+       kfree(states);
+}
+
+static int __init psci_pd_init(struct device_node *np)
+{
+       struct generic_pm_domain *pd;
+       struct psci_pd_provider *pd_provider;
+       struct dev_power_governor *pd_gov;
+       struct genpd_power_state *states = NULL;
+       int ret = -ENOMEM, state_count = 0;
+
+       pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+       if (!pd)
+               goto out;
+
+       pd_provider = kzalloc(sizeof(*pd_provider), GFP_KERNEL);
+       if (!pd_provider)
+               goto free_pd;
+
+       pd->name = kasprintf(GFP_KERNEL, "%pOF", np);
+       if (!pd->name)
+               goto free_pd_prov;
+
+       /*
+        * Parse the domain idle states and let genpd manage the state selection
+        * for those being compatible with "domain-idle-state".
+        */
+       ret = psci_pd_parse_states(np, &states, &state_count);
+       if (ret)
+               goto free_name;
+
+       pd->free_states = psci_pd_free_states;
+       pd->name = kbasename(pd->name);
+       pd->power_off = psci_pd_power_off;
+       pd->states = states;
+       pd->state_count = state_count;
+       pd->flags |= GENPD_FLAG_IRQ_SAFE | GENPD_FLAG_CPU_DOMAIN;
+
+       /* Use governor for CPU PM domains if it has some states to manage. */
+       pd_gov = state_count > 0 ? &pm_domain_cpu_gov : NULL;
+
+       ret = pm_genpd_init(pd, pd_gov, false);
+       if (ret) {
+               psci_pd_free_states(states, state_count);
+               goto free_name;
+       }
+
+       ret = of_genpd_add_provider_simple(np, pd);
+       if (ret)
+               goto remove_pd;
+
+       pd_provider->node = of_node_get(np);
+       list_add(&pd_provider->link, &psci_pd_providers);
+
+       pr_debug("init PM domain %s\n", pd->name);
+       return 0;
+
+remove_pd:
+       pm_genpd_remove(pd);
+free_name:
+       kfree(pd->name);
+free_pd_prov:
+       kfree(pd_provider);
+free_pd:
+       kfree(pd);
+out:
+       pr_err("failed to init PM domain ret=%d %pOF\n", ret, np);
+       return ret;
+}
+
+static void __init psci_pd_remove(void)
+{
+       struct psci_pd_provider *pd_provider, *it;
+       struct generic_pm_domain *genpd;
+
+       list_for_each_entry_safe(pd_provider, it, &psci_pd_providers, link) {
+               of_genpd_del_provider(pd_provider->node);
+
+               genpd = of_genpd_remove_last(pd_provider->node);
+               if (!IS_ERR(genpd))
+                       kfree(genpd);
+
+               of_node_put(pd_provider->node);
+               list_del(&pd_provider->link);
+               kfree(pd_provider);
+       }
+}
+
+static int __init psci_pd_init_topology(struct device_node *np, bool add)
+{
+       struct device_node *node;
+       struct of_phandle_args child, parent;
+       int ret;
+
+       for_each_child_of_node(np, node) {
+               if (of_parse_phandle_with_args(node, "power-domains",
+                                       "#power-domain-cells", 0, &parent))
+                       continue;
+
+               child.np = node;
+               child.args_count = 0;
+
+               ret = add ? of_genpd_add_subdomain(&parent, &child) :
+                       of_genpd_remove_subdomain(&parent, &child);
+               of_node_put(parent.np);
+               if (ret) {
+                       of_node_put(node);
+                       return ret;
+               }
+       }
+
+       return 0;
+}
+
+static int __init psci_pd_add_topology(struct device_node *np)
+{
+       return psci_pd_init_topology(np, true);
+}
+
+static void __init psci_pd_remove_topology(struct device_node *np)
+{
+       psci_pd_init_topology(np, false);
+}
+
+static const struct of_device_id psci_of_match[] __initconst = {
+       { .compatible = "arm,psci-1.0" },
+       {}
+};
+
+static int __init psci_idle_init_domains(void)
+{
+       struct device_node *np = of_find_matching_node(NULL, psci_of_match);
+       struct device_node *node;
+       int ret = 0, pd_count = 0;
+
+       if (!np)
+               return -ENODEV;
+
+       /* Currently limit the hierarchical topology to be used in OSI mode. */
+       if (!psci_has_osi_support())
+               goto out;
+
+       /*
+        * Parse child nodes for the "#power-domain-cells" property and
+        * initialize a genpd/genpd-of-provider pair when it's found.
+        */
+       for_each_child_of_node(np, node) {
+               if (!of_find_property(node, "#power-domain-cells", NULL))
+                       continue;
+
+               ret = psci_pd_init(node);
+               if (ret)
+                       goto put_node;
+
+               pd_count++;
+       }
+
+       /* Bail out if not using the hierarchical CPU topology. */
+       if (!pd_count)
+               goto out;
+
+       /* Link genpd masters/subdomains to model the CPU topology. */
+       ret = psci_pd_add_topology(np);
+       if (ret)
+               goto remove_pd;
+
+       /* Try to enable OSI mode. */
+       ret = psci_set_osi_mode();
+       if (ret) {
+               pr_warn("failed to enable OSI mode: %d\n", ret);
+               psci_pd_remove_topology(np);
+               goto remove_pd;
+       }
+
+       osi_mode_enabled = true;
+       of_node_put(np);
+       pr_info("Initialized CPU PM domain topology\n");
+       return pd_count;
+
+put_node:
+       of_node_put(node);
+remove_pd:
+       if (pd_count)
+               psci_pd_remove();
+       pr_err("failed to create CPU PM domains ret=%d\n", ret);
+out:
+       of_node_put(np);
+       return ret;
+}
+subsys_initcall(psci_idle_init_domains);
+
+struct device __init *psci_dt_attach_cpu(int cpu)
+{
+       struct device *dev;
+
+       if (!osi_mode_enabled)
+               return NULL;
+
+       dev = dev_pm_domain_attach_by_name(get_cpu_device(cpu), "psci");
+       if (IS_ERR_OR_NULL(dev))
+               return dev;
+
+       pm_runtime_irq_safe(dev);
+       if (cpu_online(cpu))
+               pm_runtime_get_sync(dev);
+
+       return dev;
+}
index f3c1a23..edd7a54 100644 (file)
@@ -8,6 +8,7 @@
 
 #define pr_fmt(fmt) "CPUidle PSCI: " fmt
 
+#include <linux/cpuhotplug.h>
 #include <linux/cpuidle.h>
 #include <linux/cpumask.h>
 #include <linux/cpu_pm.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/psci.h>
+#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 
 #include <asm/cpuidle.h>
 
+#include "cpuidle-psci.h"
 #include "dt_idle_states.h"
 
-static DEFINE_PER_CPU_READ_MOSTLY(u32 *, psci_power_state);
+struct psci_cpuidle_data {
+       u32 *psci_states;
+       struct device *dev;
+};
+
+static DEFINE_PER_CPU_READ_MOSTLY(struct psci_cpuidle_data, psci_cpuidle_data);
+static DEFINE_PER_CPU(u32, domain_state);
+static bool psci_cpuidle_use_cpuhp __initdata;
+
+void psci_set_domain_state(u32 state)
+{
+       __this_cpu_write(domain_state, state);
+}
+
+static inline u32 psci_get_domain_state(void)
+{
+       return __this_cpu_read(domain_state);
+}
+
+static inline int psci_enter_state(int idx, u32 state)
+{
+       return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter, idx, state);
+}
+
+static int psci_enter_domain_idle_state(struct cpuidle_device *dev,
+                                       struct cpuidle_driver *drv, int idx)
+{
+       struct psci_cpuidle_data *data = this_cpu_ptr(&psci_cpuidle_data);
+       u32 *states = data->psci_states;
+       struct device *pd_dev = data->dev;
+       u32 state;
+       int ret;
+
+       /* Do runtime PM to manage a hierarchical CPU toplogy. */
+       pm_runtime_put_sync_suspend(pd_dev);
+
+       state = psci_get_domain_state();
+       if (!state)
+               state = states[idx];
+
+       ret = psci_enter_state(idx, state);
+
+       pm_runtime_get_sync(pd_dev);
+
+       /* Clear the domain state to start fresh when back from idle. */
+       psci_set_domain_state(0);
+       return ret;
+}
+
+static int psci_idle_cpuhp_up(unsigned int cpu)
+{
+       struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev);
+
+       if (pd_dev)
+               pm_runtime_get_sync(pd_dev);
+
+       return 0;
+}
+
+static int psci_idle_cpuhp_down(unsigned int cpu)
+{
+       struct device *pd_dev = __this_cpu_read(psci_cpuidle_data.dev);
+
+       if (pd_dev) {
+               pm_runtime_put_sync(pd_dev);
+               /* Clear domain state to start fresh at next online. */
+               psci_set_domain_state(0);
+       }
+
+       return 0;
+}
+
+static void __init psci_idle_init_cpuhp(void)
+{
+       int err;
+
+       if (!psci_cpuidle_use_cpuhp)
+               return;
+
+       err = cpuhp_setup_state_nocalls(CPUHP_AP_CPU_PM_STARTING,
+                                       "cpuidle/psci:online",
+                                       psci_idle_cpuhp_up,
+                                       psci_idle_cpuhp_down);
+       if (err)
+               pr_warn("Failed %d while setup cpuhp state\n", err);
+}
 
 static int psci_enter_idle_state(struct cpuidle_device *dev,
                                struct cpuidle_driver *drv, int idx)
 {
-       u32 *state = __this_cpu_read(psci_power_state);
+       u32 *state = __this_cpu_read(psci_cpuidle_data.psci_states);
 
-       return CPU_PM_CPU_IDLE_ENTER_PARAM(psci_cpu_suspend_enter,
-                                          idx, state[idx - 1]);
+       return psci_enter_state(idx, state[idx]);
 }
 
 static struct cpuidle_driver psci_idle_driver __initdata = {
@@ -56,7 +143,7 @@ static const struct of_device_id psci_idle_state_match[] __initconst = {
        { },
 };
 
-static int __init psci_dt_parse_state_node(struct device_node *np, u32 *state)
+int __init psci_dt_parse_state_node(struct device_node *np, u32 *state)
 {
        int err = of_property_read_u32(np, "arm,psci-suspend-param", state);
 
@@ -73,28 +160,25 @@ static int __init psci_dt_parse_state_node(struct device_node *np, u32 *state)
        return 0;
 }
 
-static int __init psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
+static int __init psci_dt_cpu_init_idle(struct cpuidle_driver *drv,
+                                       struct device_node *cpu_node,
+                                       unsigned int state_count, int cpu)
 {
-       int i, ret = 0, count = 0;
+       int i, ret = 0;
        u32 *psci_states;
        struct device_node *state_node;
+       struct psci_cpuidle_data *data = per_cpu_ptr(&psci_cpuidle_data, cpu);
 
-       /* Count idle states */
-       while ((state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
-                                             count))) {
-               count++;
-               of_node_put(state_node);
-       }
-
-       if (!count)
-               return -ENODEV;
-
-       psci_states = kcalloc(count, sizeof(*psci_states), GFP_KERNEL);
+       state_count++; /* Add WFI state too */
+       psci_states = kcalloc(state_count, sizeof(*psci_states), GFP_KERNEL);
        if (!psci_states)
                return -ENOMEM;
 
-       for (i = 0; i < count; i++) {
-               state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+       for (i = 1; i < state_count; i++) {
+               state_node = of_get_cpu_state_node(cpu_node, i - 1);
+               if (!state_node)
+                       break;
+
                ret = psci_dt_parse_state_node(state_node, &psci_states[i]);
                of_node_put(state_node);
 
@@ -104,8 +188,33 @@ static int __init psci_dt_cpu_init_idle(struct device_node *cpu_node, int cpu)
                pr_debug("psci-power-state %#x index %d\n", psci_states[i], i);
        }
 
-       /* Idle states parsed correctly, initialize per-cpu pointer */
-       per_cpu(psci_power_state, cpu) = psci_states;
+       if (i != state_count) {
+               ret = -ENODEV;
+               goto free_mem;
+       }
+
+       /* Currently limit the hierarchical topology to be used in OSI mode. */
+       if (psci_has_osi_support()) {
+               data->dev = psci_dt_attach_cpu(cpu);
+               if (IS_ERR(data->dev)) {
+                       ret = PTR_ERR(data->dev);
+                       goto free_mem;
+               }
+
+               /*
+                * Using the deepest state for the CPU to trigger a potential
+                * selection of a shared state for the domain, assumes the
+                * domain states are all deeper states.
+                */
+               if (data->dev) {
+                       drv->states[state_count - 1].enter =
+                               psci_enter_domain_idle_state;
+                       psci_cpuidle_use_cpuhp = true;
+               }
+       }
+
+       /* Idle states parsed correctly, store them in the per-cpu struct. */
+       data->psci_states = psci_states;
        return 0;
 
 free_mem:
@@ -113,7 +222,8 @@ free_mem:
        return ret;
 }
 
-static __init int psci_cpu_init_idle(unsigned int cpu)
+static __init int psci_cpu_init_idle(struct cpuidle_driver *drv,
+                                    unsigned int cpu, unsigned int state_count)
 {
        struct device_node *cpu_node;
        int ret;
@@ -129,7 +239,7 @@ static __init int psci_cpu_init_idle(unsigned int cpu)
        if (!cpu_node)
                return -ENODEV;
 
-       ret = psci_dt_cpu_init_idle(cpu_node, cpu);
+       ret = psci_dt_cpu_init_idle(drv, cpu_node, state_count, cpu);
 
        of_node_put(cpu_node);
 
@@ -185,7 +295,7 @@ static int __init psci_idle_init_cpu(int cpu)
        /*
         * Initialize PSCI idle states.
         */
-       ret = psci_cpu_init_idle(cpu);
+       ret = psci_cpu_init_idle(drv, cpu, ret);
        if (ret) {
                pr_err("CPU %d failed to PSCI idle\n", cpu);
                goto out_kfree_drv;
@@ -221,6 +331,7 @@ static int __init psci_idle_init(void)
                        goto out_fail;
        }
 
+       psci_idle_init_cpuhp();
        return 0;
 
 out_fail:
diff --git a/drivers/cpuidle/cpuidle-psci.h b/drivers/cpuidle/cpuidle-psci.h
new file mode 100644 (file)
index 0000000..7299a04
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __CPUIDLE_PSCI_H
+#define __CPUIDLE_PSCI_H
+
+struct device_node;
+
+void psci_set_domain_state(u32 state);
+int __init psci_dt_parse_state_node(struct device_node *np, u32 *state);
+
+#ifdef CONFIG_PM_GENERIC_DOMAINS_OF
+struct device __init *psci_dt_attach_cpu(int cpu);
+#else
+static inline struct device __init *psci_dt_attach_cpu(int cpu) { return NULL; }
+#endif
+
+#endif /* __CPUIDLE_PSCI_H */
index d06d21a..252f2a9 100644 (file)
@@ -111,8 +111,7 @@ static bool idle_state_valid(struct device_node *state_node, unsigned int idx,
        for (cpu = cpumask_next(cpumask_first(cpumask), cpumask);
             cpu < nr_cpu_ids; cpu = cpumask_next(cpu, cpumask)) {
                cpu_node = of_cpu_device_node_get(cpu);
-               curr_state_node = of_parse_phandle(cpu_node, "cpu-idle-states",
-                                                  idx);
+               curr_state_node = of_get_cpu_state_node(cpu_node, idx);
                if (state_node != curr_state_node)
                        valid = false;
 
@@ -170,7 +169,7 @@ int dt_init_idle_driver(struct cpuidle_driver *drv,
        cpu_node = of_cpu_device_node_get(cpumask_first(cpumask));
 
        for (i = 0; ; i++) {
-               state_node = of_parse_phandle(cpu_node, "cpu-idle-states", i);
+               state_node = of_get_cpu_state_node(cpu_node, i);
                if (!state_node)
                        break;
 
index f3ef4ed..c3b1283 100644 (file)
@@ -756,22 +756,21 @@ struct dma_chan *dma_request_chan(struct device *dev, const char *name)
        }
        mutex_unlock(&dma_list_mutex);
 
-       if (!IS_ERR_OR_NULL(chan))
-               goto found;
-
-       return ERR_PTR(-EPROBE_DEFER);
+       if (IS_ERR_OR_NULL(chan))
+               return chan ? chan : ERR_PTR(-EPROBE_DEFER);
 
 found:
-       chan->slave = dev;
        chan->name = kasprintf(GFP_KERNEL, "dma:%s", name);
        if (!chan->name)
-               return ERR_PTR(-ENOMEM);
+               return chan;
+       chan->slave = dev;
 
        if (sysfs_create_link(&chan->dev->device.kobj, &dev->kobj,
                              DMA_SLAVE_NAME))
-               dev_err(dev, "Cannot create DMA %s symlink\n", DMA_SLAVE_NAME);
+               dev_warn(dev, "Cannot create DMA %s symlink\n", DMA_SLAVE_NAME);
        if (sysfs_create_link(&dev->kobj, &chan->dev->device.kobj, chan->name))
-               dev_err(dev, "Cannot create DMA %s symlink\n", chan->name);
+               dev_warn(dev, "Cannot create DMA %s symlink\n", chan->name);
+
        return chan;
 }
 EXPORT_SYMBOL_GPL(dma_request_chan);
@@ -830,13 +829,14 @@ void dma_release_channel(struct dma_chan *chan)
        /* drop PRIVATE cap enabled by __dma_request_channel() */
        if (--chan->device->privatecnt == 0)
                dma_cap_clear(DMA_PRIVATE, chan->device->cap_mask);
+
        if (chan->slave) {
+               sysfs_remove_link(&chan->dev->device.kobj, DMA_SLAVE_NAME);
                sysfs_remove_link(&chan->slave->kobj, chan->name);
                kfree(chan->name);
                chan->name = NULL;
                chan->slave = NULL;
        }
-       sysfs_remove_link(&chan->dev->device.kobj, DMA_SLAVE_NAME);
        mutex_unlock(&dma_list_mutex);
 }
 EXPORT_SYMBOL_GPL(dma_release_channel);
@@ -962,6 +962,9 @@ static int __dma_async_device_channel_register(struct dma_device *device,
 
        tchan = list_first_entry_or_null(&device->channels,
                                         struct dma_chan, device_node);
+       if (!tchan)
+               return -ENODEV;
+
        if (tchan->dev) {
                idr_ref = tchan->dev->idr_ref;
        } else {
index 849c50a..6d907fe 100644 (file)
@@ -66,7 +66,7 @@ static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq)
 
 static inline bool is_idxd_wq_cdev(struct idxd_wq *wq)
 {
-       return wq->type == IDXD_WQT_USER ? true : false;
+       return wq->type == IDXD_WQT_USER;
 }
 
 static int idxd_config_bus_match(struct device *dev,
index e3850f0..157c959 100644 (file)
@@ -750,7 +750,7 @@ static int mv_xor_v2_probe(struct platform_device *pdev)
        }
 
        xor_dev->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(xor_dev->clk) && PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) {
+       if (PTR_ERR(xor_dev->clk) == -EPROBE_DEFER) {
                ret = EPROBE_DEFER;
                goto disable_reg_clk;
        }
index 6b6ba23..a014ab9 100644 (file)
@@ -2,6 +2,7 @@
 /*
  * OMAP DMAengine support
  */
+#include <linux/cpu_pm.h>
 #include <linux/delay.h>
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #define OMAP_SDMA_REQUESTS     127
 #define OMAP_SDMA_CHANNELS     32
 
+struct omap_dma_config {
+       int lch_end;
+       unsigned int rw_priority:1;
+       unsigned int needs_busy_check:1;
+       unsigned int may_lose_context:1;
+       unsigned int needs_lch_clear:1;
+};
+
+struct omap_dma_context {
+       u32 irqenable_l0;
+       u32 irqenable_l1;
+       u32 ocp_sysconfig;
+       u32 gcr;
+};
+
 struct omap_dmadev {
        struct dma_device ddev;
        spinlock_t lock;
        void __iomem *base;
        const struct omap_dma_reg *reg_map;
        struct omap_system_dma_plat_info *plat;
+       const struct omap_dma_config *cfg;
+       struct notifier_block nb;
+       struct omap_dma_context context;
+       int lch_count;
+       DECLARE_BITMAP(lch_bitmap, OMAP_SDMA_CHANNELS);
+       struct mutex lch_lock;          /* for assigning logical channels */
        bool legacy;
        bool ll123_supported;
        struct dma_pool *desc_pool;
@@ -376,6 +398,19 @@ static unsigned omap_dma_get_csr(struct omap_chan *c)
        return val;
 }
 
+static void omap_dma_clear_lch(struct omap_dmadev *od, int lch)
+{
+       struct omap_chan *c;
+       int i;
+
+       c = od->lch_map[lch];
+       if (!c)
+               return;
+
+       for (i = CSDP; i <= od->cfg->lch_end; i++)
+               omap_dma_chan_write(c, i, 0);
+}
+
 static void omap_dma_assign(struct omap_dmadev *od, struct omap_chan *c,
        unsigned lch)
 {
@@ -633,6 +668,37 @@ static irqreturn_t omap_dma_irq(int irq, void *devid)
        return IRQ_HANDLED;
 }
 
+static int omap_dma_get_lch(struct omap_dmadev *od, int *lch)
+{
+       int channel;
+
+       mutex_lock(&od->lch_lock);
+       channel = find_first_zero_bit(od->lch_bitmap, od->lch_count);
+       if (channel >= od->lch_count)
+               goto out_busy;
+       set_bit(channel, od->lch_bitmap);
+       mutex_unlock(&od->lch_lock);
+
+       omap_dma_clear_lch(od, channel);
+       *lch = channel;
+
+       return 0;
+
+out_busy:
+       mutex_unlock(&od->lch_lock);
+       *lch = -EINVAL;
+
+       return -EBUSY;
+}
+
+static void omap_dma_put_lch(struct omap_dmadev *od, int lch)
+{
+       omap_dma_clear_lch(od, lch);
+       mutex_lock(&od->lch_lock);
+       clear_bit(lch, od->lch_bitmap);
+       mutex_unlock(&od->lch_lock);
+}
+
 static int omap_dma_alloc_chan_resources(struct dma_chan *chan)
 {
        struct omap_dmadev *od = to_omap_dma_dev(chan->device);
@@ -644,8 +710,7 @@ static int omap_dma_alloc_chan_resources(struct dma_chan *chan)
                ret = omap_request_dma(c->dma_sig, "DMA engine",
                                       omap_dma_callback, c, &c->dma_ch);
        } else {
-               ret = omap_request_dma(c->dma_sig, "DMA engine", NULL, NULL,
-                                      &c->dma_ch);
+               ret = omap_dma_get_lch(od, &c->dma_ch);
        }
 
        dev_dbg(dev, "allocating channel %u for %u\n", c->dma_ch, c->dma_sig);
@@ -702,7 +767,11 @@ static void omap_dma_free_chan_resources(struct dma_chan *chan)
        c->channel_base = NULL;
        od->lch_map[c->dma_ch] = NULL;
        vchan_free_chan_resources(&c->vc);
-       omap_free_dma(c->dma_ch);
+
+       if (od->legacy)
+               omap_free_dma(c->dma_ch);
+       else
+               omap_dma_put_lch(od, c->dma_ch);
 
        dev_dbg(od->ddev.dev, "freeing channel %u used for %u\n", c->dma_ch,
                c->dma_sig);
@@ -1453,16 +1522,128 @@ static void omap_dma_free(struct omap_dmadev *od)
        }
 }
 
+/* Currently only used for omap2. For omap1, also a check for lcd_dma is needed */
+static int omap_dma_busy_notifier(struct notifier_block *nb,
+                                 unsigned long cmd, void *v)
+{
+       struct omap_dmadev *od;
+       struct omap_chan *c;
+       int lch = -1;
+
+       od = container_of(nb, struct omap_dmadev, nb);
+
+       switch (cmd) {
+       case CPU_CLUSTER_PM_ENTER:
+               while (1) {
+                       lch = find_next_bit(od->lch_bitmap, od->lch_count,
+                                           lch + 1);
+                       if (lch >= od->lch_count)
+                               break;
+                       c = od->lch_map[lch];
+                       if (!c)
+                               continue;
+                       if (omap_dma_chan_read(c, CCR) & CCR_ENABLE)
+                               return NOTIFY_BAD;
+               }
+               break;
+       case CPU_CLUSTER_PM_ENTER_FAILED:
+       case CPU_CLUSTER_PM_EXIT:
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+/*
+ * We are using IRQENABLE_L1, and legacy DMA code was using IRQENABLE_L0.
+ * As the DSP may be using IRQENABLE_L2 and L3, let's not touch those for
+ * now. Context save seems to be only currently needed on omap3.
+ */
+static void omap_dma_context_save(struct omap_dmadev *od)
+{
+       od->context.irqenable_l0 = omap_dma_glbl_read(od, IRQENABLE_L0);
+       od->context.irqenable_l1 = omap_dma_glbl_read(od, IRQENABLE_L1);
+       od->context.ocp_sysconfig = omap_dma_glbl_read(od, OCP_SYSCONFIG);
+       od->context.gcr = omap_dma_glbl_read(od, GCR);
+}
+
+static void omap_dma_context_restore(struct omap_dmadev *od)
+{
+       int i;
+
+       omap_dma_glbl_write(od, GCR, od->context.gcr);
+       omap_dma_glbl_write(od, OCP_SYSCONFIG, od->context.ocp_sysconfig);
+       omap_dma_glbl_write(od, IRQENABLE_L0, od->context.irqenable_l0);
+       omap_dma_glbl_write(od, IRQENABLE_L1, od->context.irqenable_l1);
+
+       /* Clear IRQSTATUS_L0 as legacy DMA code is no longer doing it */
+       if (od->plat->errata & DMA_ROMCODE_BUG)
+               omap_dma_glbl_write(od, IRQSTATUS_L0, 0);
+
+       /* Clear dma channels */
+       for (i = 0; i < od->lch_count; i++)
+               omap_dma_clear_lch(od, i);
+}
+
+/* Currently only used for omap3 */
+static int omap_dma_context_notifier(struct notifier_block *nb,
+                                    unsigned long cmd, void *v)
+{
+       struct omap_dmadev *od;
+
+       od = container_of(nb, struct omap_dmadev, nb);
+
+       switch (cmd) {
+       case CPU_CLUSTER_PM_ENTER:
+               omap_dma_context_save(od);
+               break;
+       case CPU_CLUSTER_PM_ENTER_FAILED:
+       case CPU_CLUSTER_PM_EXIT:
+               omap_dma_context_restore(od);
+               break;
+       }
+
+       return NOTIFY_OK;
+}
+
+static void omap_dma_init_gcr(struct omap_dmadev *od, int arb_rate,
+                             int max_fifo_depth, int tparams)
+{
+       u32 val;
+
+       /* Set only for omap2430 and later */
+       if (!od->cfg->rw_priority)
+               return;
+
+       if (max_fifo_depth == 0)
+               max_fifo_depth = 1;
+       if (arb_rate == 0)
+               arb_rate = 1;
+
+       val = 0xff & max_fifo_depth;
+       val |= (0x3 & tparams) << 12;
+       val |= (arb_rate & 0xff) << 16;
+
+       omap_dma_glbl_write(od, GCR, val);
+}
+
 #define OMAP_DMA_BUSWIDTHS     (BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
                                 BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
                                 BIT(DMA_SLAVE_BUSWIDTH_4_BYTES))
 
+/*
+ * No flags currently set for default configuration as omap1 is still
+ * using platform data.
+ */
+static const struct omap_dma_config default_cfg;
+
 static int omap_dma_probe(struct platform_device *pdev)
 {
+       const struct omap_dma_config *conf;
        struct omap_dmadev *od;
        struct resource *res;
        int rc, i, irq;
-       u32 lch_count;
+       u32 val;
 
        od = devm_kzalloc(&pdev->dev, sizeof(*od), GFP_KERNEL);
        if (!od)
@@ -1473,9 +1654,21 @@ static int omap_dma_probe(struct platform_device *pdev)
        if (IS_ERR(od->base))
                return PTR_ERR(od->base);
 
-       od->plat = omap_get_plat_info();
-       if (!od->plat)
-               return -EPROBE_DEFER;
+       conf = of_device_get_match_data(&pdev->dev);
+       if (conf) {
+               od->cfg = conf;
+               od->plat = dev_get_platdata(&pdev->dev);
+               if (!od->plat) {
+                       dev_err(&pdev->dev, "omap_system_dma_plat_info is missing");
+                       return -ENODEV;
+               }
+       } else {
+               od->cfg = &default_cfg;
+
+               od->plat = omap_get_plat_info();
+               if (!od->plat)
+                       return -EPROBE_DEFER;
+       }
 
        od->reg_map = od->plat->reg_map;
 
@@ -1507,6 +1700,7 @@ static int omap_dma_probe(struct platform_device *pdev)
        od->ddev.max_burst = SZ_16M - 1; /* CCEN: 24bit unsigned */
        od->ddev.dev = &pdev->dev;
        INIT_LIST_HEAD(&od->ddev.channels);
+       mutex_init(&od->lch_lock);
        spin_lock_init(&od->lock);
        spin_lock_init(&od->irq_lock);
 
@@ -1522,18 +1716,30 @@ static int omap_dma_probe(struct platform_device *pdev)
 
        /* Number of available logical channels */
        if (!pdev->dev.of_node) {
-               lch_count = od->plat->dma_attr->lch_count;
-               if (unlikely(!lch_count))
-                       lch_count = OMAP_SDMA_CHANNELS;
+               od->lch_count = od->plat->dma_attr->lch_count;
+               if (unlikely(!od->lch_count))
+                       od->lch_count = OMAP_SDMA_CHANNELS;
        } else if (of_property_read_u32(pdev->dev.of_node, "dma-channels",
-                                       &lch_count)) {
+                                       &od->lch_count)) {
                dev_info(&pdev->dev,
                         "Missing dma-channels property, using %u.\n",
                         OMAP_SDMA_CHANNELS);
-               lch_count = OMAP_SDMA_CHANNELS;
+               od->lch_count = OMAP_SDMA_CHANNELS;
+       }
+
+       /* Mask of allowed logical channels */
+       if (pdev->dev.of_node && !of_property_read_u32(pdev->dev.of_node,
+                                                      "dma-channel-mask",
+                                                      &val)) {
+               /* Tag channels not in mask as reserved */
+               val = ~val;
+               bitmap_from_arr32(od->lch_bitmap, &val, od->lch_count);
        }
+       if (od->plat->dma_attr->dev_caps & HS_CHANNELS_RESERVED)
+               bitmap_set(od->lch_bitmap, 0, 2);
 
-       od->lch_map = devm_kcalloc(&pdev->dev, lch_count, sizeof(*od->lch_map),
+       od->lch_map = devm_kcalloc(&pdev->dev, od->lch_count,
+                                  sizeof(*od->lch_map),
                                   GFP_KERNEL);
        if (!od->lch_map)
                return -ENOMEM;
@@ -1605,6 +1811,16 @@ static int omap_dma_probe(struct platform_device *pdev)
                }
        }
 
+       omap_dma_init_gcr(od, DMA_DEFAULT_ARB_RATE, DMA_DEFAULT_FIFO_DEPTH, 0);
+
+       if (od->cfg->needs_busy_check) {
+               od->nb.notifier_call = omap_dma_busy_notifier;
+               cpu_pm_register_notifier(&od->nb);
+       } else if (od->cfg->may_lose_context) {
+               od->nb.notifier_call = omap_dma_context_notifier;
+               cpu_pm_register_notifier(&od->nb);
+       }
+
        dev_info(&pdev->dev, "OMAP DMA engine driver%s\n",
                 od->ll123_supported ? " (LinkedList1/2/3 supported)" : "");
 
@@ -1616,6 +1832,9 @@ static int omap_dma_remove(struct platform_device *pdev)
        struct omap_dmadev *od = platform_get_drvdata(pdev);
        int irq;
 
+       if (od->cfg->may_lose_context)
+               cpu_pm_unregister_notifier(&od->nb);
+
        if (pdev->dev.of_node)
                of_dma_controller_free(pdev->dev.of_node);
 
@@ -1637,12 +1856,45 @@ static int omap_dma_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct omap_dma_config omap2420_data = {
+       .lch_end = CCFN,
+       .rw_priority = true,
+       .needs_lch_clear = true,
+       .needs_busy_check = true,
+};
+
+static const struct omap_dma_config omap2430_data = {
+       .lch_end = CCFN,
+       .rw_priority = true,
+       .needs_lch_clear = true,
+};
+
+static const struct omap_dma_config omap3430_data = {
+       .lch_end = CCFN,
+       .rw_priority = true,
+       .needs_lch_clear = true,
+       .may_lose_context = true,
+};
+
+static const struct omap_dma_config omap3630_data = {
+       .lch_end = CCDN,
+       .rw_priority = true,
+       .needs_lch_clear = true,
+       .may_lose_context = true,
+};
+
+static const struct omap_dma_config omap4_data = {
+       .lch_end = CCDN,
+       .rw_priority = true,
+       .needs_lch_clear = true,
+};
+
 static const struct of_device_id omap_dma_match[] = {
-       { .compatible = "ti,omap2420-sdma", },
-       { .compatible = "ti,omap2430-sdma", },
-       { .compatible = "ti,omap3430-sdma", },
-       { .compatible = "ti,omap3630-sdma", },
-       { .compatible = "ti,omap4430-sdma", },
+       { .compatible = "ti,omap2420-sdma", .data = &omap2420_data, },
+       { .compatible = "ti,omap2430-sdma", .data = &omap2430_data, },
+       { .compatible = "ti,omap3430-sdma", .data = &omap3430_data, },
+       { .compatible = "ti,omap3630-sdma", .data = &omap3630_data, },
+       { .compatible = "ti,omap4430-sdma", .data = &omap4_data, },
        {},
 };
 MODULE_DEVICE_TABLE(of, omap_dma_match);
index e40a77b..ea869ad 100644 (file)
@@ -239,14 +239,6 @@ config QCOM_SCM
        depends on ARM || ARM64
        select RESET_CONTROLLER
 
-config QCOM_SCM_32
-       def_bool y
-       depends on QCOM_SCM && ARM
-
-config QCOM_SCM_64
-       def_bool y
-       depends on QCOM_SCM && ARM64
-
 config QCOM_SCM_DOWNLOAD_MODE_DEFAULT
        bool "Qualcomm download mode enabled by default"
        depends on QCOM_SCM
index 3fcb919..e9fb838 100644 (file)
@@ -17,10 +17,7 @@ obj-$(CONFIG_ISCSI_IBFT)     += iscsi_ibft.o
 obj-$(CONFIG_FIRMWARE_MEMMAP)  += memmap.o
 obj-$(CONFIG_RASPBERRYPI_FIRMWARE) += raspberrypi.o
 obj-$(CONFIG_FW_CFG_SYSFS)     += qemu_fw_cfg.o
-obj-$(CONFIG_QCOM_SCM)         += qcom_scm.o
-obj-$(CONFIG_QCOM_SCM_64)      += qcom_scm-64.o
-obj-$(CONFIG_QCOM_SCM_32)      += qcom_scm-32.o
-CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a
+obj-$(CONFIG_QCOM_SCM)         += qcom_scm.o qcom_scm-smc.o qcom_scm-legacy.o
 obj-$(CONFIG_TI_SCI_PROTOCOL)  += ti_sci.o
 obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
 obj-$(CONFIG_TURRIS_MOX_RWTM)  += turris-mox-rwtm.o
index 7a30952..db55c43 100644 (file)
@@ -28,8 +28,12 @@ scmi_dev_match_id(struct scmi_device *scmi_dev, struct scmi_driver *scmi_drv)
                return NULL;
 
        for (; id->protocol_id; id++)
-               if (id->protocol_id == scmi_dev->protocol_id)
-                       return id;
+               if (id->protocol_id == scmi_dev->protocol_id) {
+                       if (!id->name)
+                               return id;
+                       else if (!strcmp(id->name, scmi_dev->name))
+                               return id;
+               }
 
        return NULL;
 }
@@ -56,6 +60,11 @@ static int scmi_protocol_init(int protocol_id, struct scmi_handle *handle)
        return fn(handle);
 }
 
+static int scmi_protocol_dummy_init(struct scmi_handle *handle)
+{
+       return 0;
+}
+
 static int scmi_dev_probe(struct device *dev)
 {
        struct scmi_driver *scmi_drv = to_scmi_driver(dev->driver);
@@ -74,6 +83,10 @@ static int scmi_dev_probe(struct device *dev)
        if (ret)
                return ret;
 
+       /* Skip protocol initialisation for additional devices */
+       idr_replace(&scmi_protocols, &scmi_protocol_dummy_init,
+                   scmi_dev->protocol_id);
+
        return scmi_drv->probe(scmi_dev);
 }
 
@@ -125,7 +138,8 @@ static void scmi_device_release(struct device *dev)
 }
 
 struct scmi_device *
-scmi_device_create(struct device_node *np, struct device *parent, int protocol)
+scmi_device_create(struct device_node *np, struct device *parent, int protocol,
+                  const char *name)
 {
        int id, retval;
        struct scmi_device *scmi_dev;
@@ -134,8 +148,15 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
        if (!scmi_dev)
                return NULL;
 
+       scmi_dev->name = kstrdup_const(name ?: "unknown", GFP_KERNEL);
+       if (!scmi_dev->name) {
+               kfree(scmi_dev);
+               return NULL;
+       }
+
        id = ida_simple_get(&scmi_bus_id, 1, 0, GFP_KERNEL);
        if (id < 0) {
+               kfree_const(scmi_dev->name);
                kfree(scmi_dev);
                return NULL;
        }
@@ -154,6 +175,7 @@ scmi_device_create(struct device_node *np, struct device *parent, int protocol)
 
        return scmi_dev;
 put_dev:
+       kfree_const(scmi_dev->name);
        put_device(&scmi_dev->dev);
        ida_simple_remove(&scmi_bus_id, id);
        return NULL;
@@ -161,6 +183,7 @@ put_dev:
 
 void scmi_device_destroy(struct scmi_device *scmi_dev)
 {
+       kfree_const(scmi_dev->name);
        scmi_handle_put(scmi_dev->handle);
        ida_simple_remove(&scmi_bus_id, scmi_dev->id);
        device_unregister(&scmi_dev->dev);
index 32526a7..4c22276 100644 (file)
@@ -65,6 +65,7 @@ struct scmi_clock_set_rate {
 };
 
 struct clock_info {
+       u32 version;
        int num_clocks;
        int max_async_req;
        atomic_t cur_async_req;
@@ -340,6 +341,7 @@ static int scmi_clock_protocol_init(struct scmi_handle *handle)
                        scmi_clock_describe_rates_get(handle, clkid, clk);
        }
 
+       cinfo->version = version;
        handle->clk_ops = &clk_ops;
        handle->clk_priv = cinfo;
 
index 5237c2f..df35358 100644 (file)
@@ -81,6 +81,7 @@ struct scmi_msg {
 /**
  * struct scmi_xfer - Structure representing a message flow
  *
+ * @transfer_id: Unique ID for debug & profiling purpose
  * @hdr: Transmit message header
  * @tx: Transmit message
  * @rx: Receive message, the buffer should be pre-allocated to store
@@ -90,6 +91,7 @@ struct scmi_msg {
  * @async: pointer to delayed response message received event completion
  */
 struct scmi_xfer {
+       int transfer_id;
        struct scmi_msg_hdr hdr;
        struct scmi_msg tx;
        struct scmi_msg rx;
index 3eb0382..2c96f6b 100644 (file)
@@ -29,6 +29,9 @@
 
 #include "common.h"
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/scmi.h>
+
 #define MSG_ID_MASK            GENMASK(7, 0)
 #define MSG_XTRACT_ID(hdr)     FIELD_GET(MSG_ID_MASK, (hdr))
 #define MSG_TYPE_MASK          GENMASK(9, 8)
@@ -61,6 +64,8 @@ enum scmi_error_codes {
 static LIST_HEAD(scmi_list);
 /* Protection for the entire list */
 static DEFINE_MUTEX(scmi_list_mutex);
+/* Track the unique id for the transfers for debug & profiling purpose */
+static atomic_t transfer_last_id;
 
 /**
  * struct scmi_xfers_info - Structure to manage transfer information
@@ -304,6 +309,7 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle,
        xfer = &minfo->xfer_block[xfer_id];
        xfer->hdr.seq = xfer_id;
        reinit_completion(&xfer->done);
+       xfer->transfer_id = atomic_inc_return(&transfer_last_id);
 
        return xfer;
 }
@@ -374,6 +380,10 @@ static void scmi_rx_callback(struct mbox_client *cl, void *m)
 
        scmi_fetch_response(xfer, mem);
 
+       trace_scmi_rx_done(xfer->transfer_id, xfer->hdr.id,
+                          xfer->hdr.protocol_id, xfer->hdr.seq,
+                          msg_type);
+
        if (msg_type == MSG_TYPE_DELAYED_RESP)
                complete(xfer->async_done);
        else
@@ -439,6 +449,10 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
        if (unlikely(!cinfo))
                return -EINVAL;
 
+       trace_scmi_xfer_begin(xfer->transfer_id, xfer->hdr.id,
+                             xfer->hdr.protocol_id, xfer->hdr.seq,
+                             xfer->hdr.poll_completion);
+
        ret = mbox_send_message(cinfo->chan, xfer);
        if (ret < 0) {
                dev_dbg(dev, "mbox send fail %d\n", ret);
@@ -478,6 +492,10 @@ int scmi_do_xfer(const struct scmi_handle *handle, struct scmi_xfer *xfer)
         */
        mbox_client_txdone(cinfo->chan, ret);
 
+       trace_scmi_xfer_end(xfer->transfer_id, xfer->hdr.id,
+                           xfer->hdr.protocol_id, xfer->hdr.seq,
+                           xfer->hdr.status);
+
        return ret;
 }
 
@@ -735,6 +753,11 @@ static int scmi_mbox_chan_setup(struct scmi_info *info, struct device *dev,
        idx = tx ? 0 : 1;
        idr = tx ? &info->tx_idr : &info->rx_idr;
 
+       /* check if already allocated, used for multiple device per protocol */
+       cinfo = idr_find(idr, prot_id);
+       if (cinfo)
+               return 0;
+
        if (scmi_mailbox_check(np, idx)) {
                cinfo = idr_find(idr, SCMI_PROTOCOL_BASE);
                if (unlikely(!cinfo)) /* Possible only if platform has no Rx */
@@ -803,11 +826,11 @@ scmi_mbox_txrx_setup(struct scmi_info *info, struct device *dev, int prot_id)
 
 static inline void
 scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
-                           int prot_id)
+                           int prot_id, const char *name)
 {
        struct scmi_device *sdev;
 
-       sdev = scmi_device_create(np, info->dev, prot_id);
+       sdev = scmi_device_create(np, info->dev, prot_id, name);
        if (!sdev) {
                dev_err(info->dev, "failed to create %d protocol device\n",
                        prot_id);
@@ -824,6 +847,40 @@ scmi_create_protocol_device(struct device_node *np, struct scmi_info *info,
        scmi_set_handle(sdev);
 }
 
+#define MAX_SCMI_DEV_PER_PROTOCOL      2
+struct scmi_prot_devnames {
+       int protocol_id;
+       char *names[MAX_SCMI_DEV_PER_PROTOCOL];
+};
+
+static struct scmi_prot_devnames devnames[] = {
+       { SCMI_PROTOCOL_POWER,  { "genpd" },},
+       { SCMI_PROTOCOL_PERF,   { "cpufreq" },},
+       { SCMI_PROTOCOL_CLOCK,  { "clocks" },},
+       { SCMI_PROTOCOL_SENSOR, { "hwmon" },},
+       { SCMI_PROTOCOL_RESET,  { "reset" },},
+};
+
+static inline void
+scmi_create_protocol_devices(struct device_node *np, struct scmi_info *info,
+                            int prot_id)
+{
+       int loop, cnt;
+
+       for (loop = 0; loop < ARRAY_SIZE(devnames); loop++) {
+               if (devnames[loop].protocol_id != prot_id)
+                       continue;
+
+               for (cnt = 0; cnt < ARRAY_SIZE(devnames[loop].names); cnt++) {
+                       const char *name = devnames[loop].names[cnt];
+
+                       if (name)
+                               scmi_create_protocol_device(np, info, prot_id,
+                                                           name);
+               }
+       }
+}
+
 static int scmi_probe(struct platform_device *pdev)
 {
        int ret;
@@ -892,7 +949,7 @@ static int scmi_probe(struct platform_device *pdev)
                        continue;
                }
 
-               scmi_create_protocol_device(child, info, prot_id);
+               scmi_create_protocol_devices(child, info, prot_id);
        }
 
        return 0;
@@ -940,6 +997,52 @@ static int scmi_remove(struct platform_device *pdev)
        return ret;
 }
 
+static ssize_t protocol_version_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct scmi_info *info = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%u.%u\n", info->version.major_ver,
+                      info->version.minor_ver);
+}
+static DEVICE_ATTR_RO(protocol_version);
+
+static ssize_t firmware_version_show(struct device *dev,
+                                    struct device_attribute *attr, char *buf)
+{
+       struct scmi_info *info = dev_get_drvdata(dev);
+
+       return sprintf(buf, "0x%x\n", info->version.impl_ver);
+}
+static DEVICE_ATTR_RO(firmware_version);
+
+static ssize_t vendor_id_show(struct device *dev,
+                             struct device_attribute *attr, char *buf)
+{
+       struct scmi_info *info = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", info->version.vendor_id);
+}
+static DEVICE_ATTR_RO(vendor_id);
+
+static ssize_t sub_vendor_id_show(struct device *dev,
+                                 struct device_attribute *attr, char *buf)
+{
+       struct scmi_info *info = dev_get_drvdata(dev);
+
+       return sprintf(buf, "%s\n", info->version.sub_vendor_id);
+}
+static DEVICE_ATTR_RO(sub_vendor_id);
+
+static struct attribute *versions_attrs[] = {
+       &dev_attr_firmware_version.attr,
+       &dev_attr_protocol_version.attr,
+       &dev_attr_vendor_id.attr,
+       &dev_attr_sub_vendor_id.attr,
+       NULL,
+};
+ATTRIBUTE_GROUPS(versions);
+
 static const struct scmi_desc scmi_generic_desc = {
        .max_rx_timeout_ms = 30,        /* We may increase this if required */
        .max_msg = 20,          /* Limited by MBOX_TX_QUEUE_LEN */
@@ -958,6 +1061,7 @@ static struct platform_driver scmi_driver = {
        .driver = {
                   .name = "arm-scmi",
                   .of_match_table = scmi_of_match,
+                  .dev_groups = versions_groups,
                   },
        .probe = scmi_probe,
        .remove = scmi_remove,
index 601af4e..ec81e6f 100644 (file)
@@ -145,6 +145,7 @@ struct perf_dom_info {
 };
 
 struct scmi_perf_info {
+       u32 version;
        int num_domains;
        bool power_scale_mw;
        u64 stats_addr;
@@ -736,6 +737,7 @@ static int scmi_perf_protocol_init(struct scmi_handle *handle)
                        scmi_perf_domain_init_fc(handle, domain, &dom->fc_info);
        }
 
+       pinfo->version = version;
        handle->perf_ops = &perf_ops;
        handle->perf_priv = pinfo;
 
index 5abef70..214886c 100644 (file)
@@ -50,6 +50,7 @@ struct power_dom_info {
 };
 
 struct scmi_power_info {
+       u32 version;
        int num_domains;
        u64 stats_addr;
        u32 stats_size;
@@ -207,6 +208,7 @@ static int scmi_power_protocol_init(struct scmi_handle *handle)
                scmi_power_domain_attributes_get(handle, domain, dom);
        }
 
+       pinfo->version = version;
        handle->power_ops = &power_ops;
        handle->power_priv = pinfo;
 
index ab42c21..de73054 100644 (file)
@@ -48,6 +48,7 @@ struct reset_dom_info {
 };
 
 struct scmi_reset_info {
+       u32 version;
        int num_domains;
        struct reset_dom_info *dom_info;
 };
@@ -217,6 +218,7 @@ static int scmi_reset_protocol_init(struct scmi_handle *handle)
                scmi_reset_domain_attributes_get(handle, domain, dom);
        }
 
+       pinfo->version = version;
        handle->reset_ops = &reset_ops;
        handle->reset_priv = pinfo;
 
index 87f737e..bafbfe3 100644 (file)
@@ -112,7 +112,7 @@ static int scmi_pm_domain_probe(struct scmi_device *sdev)
 }
 
 static const struct scmi_device_id scmi_id_table[] = {
-       { SCMI_PROTOCOL_POWER },
+       { SCMI_PROTOCOL_POWER, "genpd" },
        { },
 };
 MODULE_DEVICE_TABLE(scmi, scmi_id_table);
index a400ea8..eba61b9 100644 (file)
@@ -68,6 +68,7 @@ struct scmi_msg_sensor_reading_get {
 };
 
 struct sensors_info {
+       u32 version;
        int num_sensors;
        int max_requests;
        u64 reg_addr;
@@ -294,6 +295,7 @@ static int scmi_sensors_protocol_init(struct scmi_handle *handle)
 
        scmi_sensor_description_get(handle, sinfo);
 
+       sinfo->version = version;
        handle->sensor_ops = &sensor_ops;
        handle->sensor_priv = sinfo;
 
index 899b803..9dda260 100644 (file)
@@ -27,7 +27,7 @@
 
 extern u64 efi_system_table;
 
-#ifdef CONFIG_ARM64_PTDUMP_DEBUGFS
+#if defined(CONFIG_PTDUMP_DEBUGFS) && defined(CONFIG_ARM64)
 #include <asm/ptdump.h>
 
 static struct ptdump_info efi_ptdump_info = {
index 0dbee32..1d2e5b8 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config IMX_DSP
-       bool "IMX DSP Protocol driver"
+       tristate "IMX DSP Protocol driver"
        depends on IMX_MBOX
        help
          This enables DSP IPC protocol between host AP (Linux)
index 7e12cbd..96758b7 100644 (file)
@@ -104,6 +104,7 @@ struct ibft_control {
        u16 tgt0_off;
        u16 nic1_off;
        u16 tgt1_off;
+       u16 expansion[0];
 } __attribute__((__packed__));
 
 struct ibft_initiator {
@@ -235,7 +236,7 @@ static int ibft_verify_hdr(char *t, struct ibft_hdr *hdr, int id, int length)
                                "found %d instead!\n", t, id, hdr->id);
                return -ENODEV;
        }
-       if (hdr->length != length) {
+       if (length && hdr->length != length) {
                printk(KERN_ERR "iBFT error: We expected the %s " \
                                "field header.length to have %d but " \
                                "found %d instead!\n", t, length, hdr->length);
@@ -749,16 +750,16 @@ static int __init ibft_register_kobjects(struct acpi_table_ibft *header)
        control = (void *)header + sizeof(*header);
        end = (void *)control + control->hdr.length;
        eot_offset = (void *)header + header->header.length - (void *)control;
-       rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control,
-                            sizeof(*control));
+       rc = ibft_verify_hdr("control", (struct ibft_hdr *)control, id_control, 0);
 
        /* iBFT table safety checking */
        rc |= ((control->hdr.index) ? -ENODEV : 0);
+       rc |= ((control->hdr.length < sizeof(*control)) ? -ENODEV : 0);
        if (rc) {
                printk(KERN_ERR "iBFT error: Control header is invalid!\n");
                return rc;
        }
-       for (ptr = &control->initiator_off; ptr < end; ptr += sizeof(u16)) {
+       for (ptr = &control->initiator_off; ptr + sizeof(u16) <= end; ptr += sizeof(u16)) {
                offset = *(u16 *)ptr;
                if (offset && offset < header->header.length &&
                                                offset < eot_offset) {
index b3b6c15..2937d44 100644 (file)
@@ -97,7 +97,7 @@ static inline bool psci_has_ext_power_state(void)
                                PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK;
 }
 
-static inline bool psci_has_osi_support(void)
+bool psci_has_osi_support(void)
 {
        return psci_cpu_suspend_feature & PSCI_1_0_OS_INITIATED;
 }
@@ -162,6 +162,15 @@ static u32 psci_get_version(void)
        return invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
 }
 
+int psci_set_osi_mode(void)
+{
+       int err;
+
+       err = invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE,
+                            PSCI_1_0_SUSPEND_MODE_OSI, 0, 0);
+       return psci_to_linux_errno(err);
+}
+
 static int psci_cpu_suspend(u32 state, unsigned long entry_point)
 {
        int err;
@@ -544,9 +553,14 @@ static int __init psci_1_0_init(struct device_node *np)
        if (err)
                return err;
 
-       if (psci_has_osi_support())
+       if (psci_has_osi_support()) {
                pr_info("OSI mode supported.\n");
 
+               /* Default to PC mode. */
+               invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE,
+                              PSCI_1_0_SUSPEND_MODE_PC, 0, 0);
+       }
+
        return 0;
 }
 
diff --git a/drivers/firmware/qcom_scm-32.c b/drivers/firmware/qcom_scm-32.c
deleted file mode 100644 (file)
index 48e2ef7..0000000
+++ /dev/null
@@ -1,671 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2010,2015, The Linux Foundation. All rights reserved.
- * Copyright (C) 2015 Linaro Ltd.
- */
-
-#include <linux/slab.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/mutex.h>
-#include <linux/errno.h>
-#include <linux/err.h>
-#include <linux/qcom_scm.h>
-#include <linux/dma-mapping.h>
-
-#include "qcom_scm.h"
-
-#define QCOM_SCM_FLAG_COLDBOOT_CPU0    0x00
-#define QCOM_SCM_FLAG_COLDBOOT_CPU1    0x01
-#define QCOM_SCM_FLAG_COLDBOOT_CPU2    0x08
-#define QCOM_SCM_FLAG_COLDBOOT_CPU3    0x20
-
-#define QCOM_SCM_FLAG_WARMBOOT_CPU0    0x04
-#define QCOM_SCM_FLAG_WARMBOOT_CPU1    0x02
-#define QCOM_SCM_FLAG_WARMBOOT_CPU2    0x10
-#define QCOM_SCM_FLAG_WARMBOOT_CPU3    0x40
-
-struct qcom_scm_entry {
-       int flag;
-       void *entry;
-};
-
-static struct qcom_scm_entry qcom_scm_wb[] = {
-       { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU0 },
-       { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU1 },
-       { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU2 },
-       { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 },
-};
-
-static DEFINE_MUTEX(qcom_scm_lock);
-
-/**
- * struct qcom_scm_command - one SCM command buffer
- * @len: total available memory for command and response
- * @buf_offset: start of command buffer
- * @resp_hdr_offset: start of response buffer
- * @id: command to be executed
- * @buf: buffer returned from qcom_scm_get_command_buffer()
- *
- * An SCM command is laid out in memory as follows:
- *
- *     ------------------- <--- struct qcom_scm_command
- *     | command header  |
- *     ------------------- <--- qcom_scm_get_command_buffer()
- *     | command buffer  |
- *     ------------------- <--- struct qcom_scm_response and
- *     | response header |      qcom_scm_command_to_response()
- *     ------------------- <--- qcom_scm_get_response_buffer()
- *     | response buffer |
- *     -------------------
- *
- * There can be arbitrary padding between the headers and buffers so
- * you should always use the appropriate qcom_scm_get_*_buffer() routines
- * to access the buffers in a safe manner.
- */
-struct qcom_scm_command {
-       __le32 len;
-       __le32 buf_offset;
-       __le32 resp_hdr_offset;
-       __le32 id;
-       __le32 buf[0];
-};
-
-/**
- * struct qcom_scm_response - one SCM response buffer
- * @len: total available memory for response
- * @buf_offset: start of response data relative to start of qcom_scm_response
- * @is_complete: indicates if the command has finished processing
- */
-struct qcom_scm_response {
-       __le32 len;
-       __le32 buf_offset;
-       __le32 is_complete;
-};
-
-/**
- * qcom_scm_command_to_response() - Get a pointer to a qcom_scm_response
- * @cmd: command
- *
- * Returns a pointer to a response for a command.
- */
-static inline struct qcom_scm_response *qcom_scm_command_to_response(
-               const struct qcom_scm_command *cmd)
-{
-       return (void *)cmd + le32_to_cpu(cmd->resp_hdr_offset);
-}
-
-/**
- * qcom_scm_get_command_buffer() - Get a pointer to a command buffer
- * @cmd: command
- *
- * Returns a pointer to the command buffer of a command.
- */
-static inline void *qcom_scm_get_command_buffer(const struct qcom_scm_command *cmd)
-{
-       return (void *)cmd->buf;
-}
-
-/**
- * qcom_scm_get_response_buffer() - Get a pointer to a response buffer
- * @rsp: response
- *
- * Returns a pointer to a response buffer of a response.
- */
-static inline void *qcom_scm_get_response_buffer(const struct qcom_scm_response *rsp)
-{
-       return (void *)rsp + le32_to_cpu(rsp->buf_offset);
-}
-
-static u32 smc(u32 cmd_addr)
-{
-       int context_id;
-       register u32 r0 asm("r0") = 1;
-       register u32 r1 asm("r1") = (u32)&context_id;
-       register u32 r2 asm("r2") = cmd_addr;
-       do {
-               asm volatile(
-                       __asmeq("%0", "r0")
-                       __asmeq("%1", "r0")
-                       __asmeq("%2", "r1")
-                       __asmeq("%3", "r2")
-#ifdef REQUIRES_SEC
-                       ".arch_extension sec\n"
-#endif
-                       "smc    #0      @ switch to secure world\n"
-                       : "=r" (r0)
-                       : "r" (r0), "r" (r1), "r" (r2)
-                       : "r3", "r12");
-       } while (r0 == QCOM_SCM_INTERRUPTED);
-
-       return r0;
-}
-
-/**
- * qcom_scm_call() - Send an SCM command
- * @dev: struct device
- * @svc_id: service identifier
- * @cmd_id: command identifier
- * @cmd_buf: command buffer
- * @cmd_len: length of the command buffer
- * @resp_buf: response buffer
- * @resp_len: length of the response buffer
- *
- * Sends a command to the SCM and waits for the command to finish processing.
- *
- * A note on cache maintenance:
- * Note that any buffers that are expected to be accessed by the secure world
- * must be flushed before invoking qcom_scm_call and invalidated in the cache
- * immediately after qcom_scm_call returns. Cache maintenance on the command
- * and response buffers is taken care of by qcom_scm_call; however, callers are
- * responsible for any other cached buffers passed over to the secure world.
- */
-static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
-                        const void *cmd_buf, size_t cmd_len, void *resp_buf,
-                        size_t resp_len)
-{
-       int ret;
-       struct qcom_scm_command *cmd;
-       struct qcom_scm_response *rsp;
-       size_t alloc_len = sizeof(*cmd) + cmd_len + sizeof(*rsp) + resp_len;
-       dma_addr_t cmd_phys;
-
-       cmd = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
-       if (!cmd)
-               return -ENOMEM;
-
-       cmd->len = cpu_to_le32(alloc_len);
-       cmd->buf_offset = cpu_to_le32(sizeof(*cmd));
-       cmd->resp_hdr_offset = cpu_to_le32(sizeof(*cmd) + cmd_len);
-
-       cmd->id = cpu_to_le32((svc_id << 10) | cmd_id);
-       if (cmd_buf)
-               memcpy(qcom_scm_get_command_buffer(cmd), cmd_buf, cmd_len);
-
-       rsp = qcom_scm_command_to_response(cmd);
-
-       cmd_phys = dma_map_single(dev, cmd, alloc_len, DMA_TO_DEVICE);
-       if (dma_mapping_error(dev, cmd_phys)) {
-               kfree(cmd);
-               return -ENOMEM;
-       }
-
-       mutex_lock(&qcom_scm_lock);
-       ret = smc(cmd_phys);
-       if (ret < 0)
-               ret = qcom_scm_remap_error(ret);
-       mutex_unlock(&qcom_scm_lock);
-       if (ret)
-               goto out;
-
-       do {
-               dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len,
-                                       sizeof(*rsp), DMA_FROM_DEVICE);
-       } while (!rsp->is_complete);
-
-       if (resp_buf) {
-               dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len +
-                                       le32_to_cpu(rsp->buf_offset),
-                                       resp_len, DMA_FROM_DEVICE);
-               memcpy(resp_buf, qcom_scm_get_response_buffer(rsp),
-                      resp_len);
-       }
-out:
-       dma_unmap_single(dev, cmd_phys, alloc_len, DMA_TO_DEVICE);
-       kfree(cmd);
-       return ret;
-}
-
-#define SCM_CLASS_REGISTER     (0x2 << 8)
-#define SCM_MASK_IRQS          BIT(5)
-#define SCM_ATOMIC(svc, cmd, n) (((((svc) << 10)|((cmd) & 0x3ff)) << 12) | \
-                               SCM_CLASS_REGISTER | \
-                               SCM_MASK_IRQS | \
-                               (n & 0xf))
-
-/**
- * qcom_scm_call_atomic1() - Send an atomic SCM command with one argument
- * @svc_id: service identifier
- * @cmd_id: command identifier
- * @arg1: first argument
- *
- * This shall only be used with commands that are guaranteed to be
- * uninterruptable, atomic and SMP safe.
- */
-static s32 qcom_scm_call_atomic1(u32 svc, u32 cmd, u32 arg1)
-{
-       int context_id;
-
-       register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 1);
-       register u32 r1 asm("r1") = (u32)&context_id;
-       register u32 r2 asm("r2") = arg1;
-
-       asm volatile(
-                       __asmeq("%0", "r0")
-                       __asmeq("%1", "r0")
-                       __asmeq("%2", "r1")
-                       __asmeq("%3", "r2")
-#ifdef REQUIRES_SEC
-                       ".arch_extension sec\n"
-#endif
-                       "smc    #0      @ switch to secure world\n"
-                       : "=r" (r0)
-                       : "r" (r0), "r" (r1), "r" (r2)
-                       : "r3", "r12");
-       return r0;
-}
-
-/**
- * qcom_scm_call_atomic2() - Send an atomic SCM command with two arguments
- * @svc_id:    service identifier
- * @cmd_id:    command identifier
- * @arg1:      first argument
- * @arg2:      second argument
- *
- * This shall only be used with commands that are guaranteed to be
- * uninterruptable, atomic and SMP safe.
- */
-static s32 qcom_scm_call_atomic2(u32 svc, u32 cmd, u32 arg1, u32 arg2)
-{
-       int context_id;
-
-       register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 2);
-       register u32 r1 asm("r1") = (u32)&context_id;
-       register u32 r2 asm("r2") = arg1;
-       register u32 r3 asm("r3") = arg2;
-
-       asm volatile(
-                       __asmeq("%0", "r0")
-                       __asmeq("%1", "r0")
-                       __asmeq("%2", "r1")
-                       __asmeq("%3", "r2")
-                       __asmeq("%4", "r3")
-#ifdef REQUIRES_SEC
-                       ".arch_extension sec\n"
-#endif
-                       "smc    #0      @ switch to secure world\n"
-                       : "=r" (r0)
-                       : "r" (r0), "r" (r1), "r" (r2), "r" (r3)
-                       : "r12");
-       return r0;
-}
-
-u32 qcom_scm_get_version(void)
-{
-       int context_id;
-       static u32 version = -1;
-       register u32 r0 asm("r0");
-       register u32 r1 asm("r1");
-
-       if (version != -1)
-               return version;
-
-       mutex_lock(&qcom_scm_lock);
-
-       r0 = 0x1 << 8;
-       r1 = (u32)&context_id;
-       do {
-               asm volatile(
-                       __asmeq("%0", "r0")
-                       __asmeq("%1", "r1")
-                       __asmeq("%2", "r0")
-                       __asmeq("%3", "r1")
-#ifdef REQUIRES_SEC
-                       ".arch_extension sec\n"
-#endif
-                       "smc    #0      @ switch to secure world\n"
-                       : "=r" (r0), "=r" (r1)
-                       : "r" (r0), "r" (r1)
-                       : "r2", "r3", "r12");
-       } while (r0 == QCOM_SCM_INTERRUPTED);
-
-       version = r1;
-       mutex_unlock(&qcom_scm_lock);
-
-       return version;
-}
-EXPORT_SYMBOL(qcom_scm_get_version);
-
-/**
- * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
- *
- * Set the cold boot address of the cpus. Any cpu outside the supported
- * range would be removed from the cpu present mask.
- */
-int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
-{
-       int flags = 0;
-       int cpu;
-       int scm_cb_flags[] = {
-               QCOM_SCM_FLAG_COLDBOOT_CPU0,
-               QCOM_SCM_FLAG_COLDBOOT_CPU1,
-               QCOM_SCM_FLAG_COLDBOOT_CPU2,
-               QCOM_SCM_FLAG_COLDBOOT_CPU3,
-       };
-
-       if (!cpus || (cpus && cpumask_empty(cpus)))
-               return -EINVAL;
-
-       for_each_cpu(cpu, cpus) {
-               if (cpu < ARRAY_SIZE(scm_cb_flags))
-                       flags |= scm_cb_flags[cpu];
-               else
-                       set_cpu_present(cpu, false);
-       }
-
-       return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR,
-                                   flags, virt_to_phys(entry));
-}
-
-/**
- * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
- *
- * Set the Linux entry point for the SCM to transfer control to when coming
- * out of a power down. CPU power down may be executed on cpuidle or hotplug.
- */
-int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
-                                 const cpumask_t *cpus)
-{
-       int ret;
-       int flags = 0;
-       int cpu;
-       struct {
-               __le32 flags;
-               __le32 addr;
-       } cmd;
-
-       /*
-        * Reassign only if we are switching from hotplug entry point
-        * to cpuidle entry point or vice versa.
-        */
-       for_each_cpu(cpu, cpus) {
-               if (entry == qcom_scm_wb[cpu].entry)
-                       continue;
-               flags |= qcom_scm_wb[cpu].flag;
-       }
-
-       /* No change in entry function */
-       if (!flags)
-               return 0;
-
-       cmd.addr = cpu_to_le32(virt_to_phys(entry));
-       cmd.flags = cpu_to_le32(flags);
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_BOOT_ADDR,
-                           &cmd, sizeof(cmd), NULL, 0);
-       if (!ret) {
-               for_each_cpu(cpu, cpus)
-                       qcom_scm_wb[cpu].entry = entry;
-       }
-
-       return ret;
-}
-
-/**
- * qcom_scm_cpu_power_down() - Power down the cpu
- * @flags - Flags to flush cache
- *
- * This is an end point to power down cpu. If there was a pending interrupt,
- * the control would return from this function, otherwise, the cpu jumps to the
- * warm boot entry point set for this cpu upon reset.
- */
-void __qcom_scm_cpu_power_down(u32 flags)
-{
-       qcom_scm_call_atomic1(QCOM_SCM_SVC_BOOT, QCOM_SCM_CMD_TERMINATE_PC,
-                       flags & QCOM_SCM_FLUSH_FLAG_MASK);
-}
-
-int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id)
-{
-       int ret;
-       __le32 svc_cmd = cpu_to_le32((svc_id << 10) | cmd_id);
-       __le32 ret_val = 0;
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD,
-                           &svc_cmd, sizeof(svc_cmd), &ret_val,
-                           sizeof(ret_val));
-       if (ret)
-               return ret;
-
-       return le32_to_cpu(ret_val);
-}
-
-int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
-                       u32 req_cnt, u32 *resp)
-{
-       if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT)
-               return -ERANGE;
-
-       return qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP,
-               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)
-{
-}
-
-bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral)
-{
-       __le32 out;
-       __le32 in;
-       int ret;
-
-       in = cpu_to_le32(peripheral);
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
-                           QCOM_SCM_PAS_IS_SUPPORTED_CMD,
-                           &in, sizeof(in),
-                           &out, sizeof(out));
-
-       return ret ? false : !!out;
-}
-
-int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral,
-                             dma_addr_t metadata_phys)
-{
-       __le32 scm_ret;
-       int ret;
-       struct {
-               __le32 proc;
-               __le32 image_addr;
-       } request;
-
-       request.proc = cpu_to_le32(peripheral);
-       request.image_addr = cpu_to_le32(metadata_phys);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
-                           QCOM_SCM_PAS_INIT_IMAGE_CMD,
-                           &request, sizeof(request),
-                           &scm_ret, sizeof(scm_ret));
-
-       return ret ? : le32_to_cpu(scm_ret);
-}
-
-int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral,
-                            phys_addr_t addr, phys_addr_t size)
-{
-       __le32 scm_ret;
-       int ret;
-       struct {
-               __le32 proc;
-               __le32 addr;
-               __le32 len;
-       } request;
-
-       request.proc = cpu_to_le32(peripheral);
-       request.addr = cpu_to_le32(addr);
-       request.len = cpu_to_le32(size);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
-                           QCOM_SCM_PAS_MEM_SETUP_CMD,
-                           &request, sizeof(request),
-                           &scm_ret, sizeof(scm_ret));
-
-       return ret ? : le32_to_cpu(scm_ret);
-}
-
-int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral)
-{
-       __le32 out;
-       __le32 in;
-       int ret;
-
-       in = cpu_to_le32(peripheral);
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
-                           QCOM_SCM_PAS_AUTH_AND_RESET_CMD,
-                           &in, sizeof(in),
-                           &out, sizeof(out));
-
-       return ret ? : le32_to_cpu(out);
-}
-
-int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral)
-{
-       __le32 out;
-       __le32 in;
-       int ret;
-
-       in = cpu_to_le32(peripheral);
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
-                           QCOM_SCM_PAS_SHUTDOWN_CMD,
-                           &in, sizeof(in),
-                           &out, sizeof(out));
-
-       return ret ? : le32_to_cpu(out);
-}
-
-int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
-{
-       __le32 out;
-       __le32 in = cpu_to_le32(reset);
-       int ret;
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MSS_RESET,
-                       &in, sizeof(in),
-                       &out, sizeof(out));
-
-       return ret ? : le32_to_cpu(out);
-}
-
-int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
-{
-       return qcom_scm_call_atomic2(QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_DLOAD_MODE,
-                                    enable ? QCOM_SCM_SET_DLOAD_MODE : 0, 0);
-}
-
-int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
-{
-       struct {
-               __le32 state;
-               __le32 id;
-       } req;
-       __le32 scm_ret = 0;
-       int ret;
-
-       req.state = cpu_to_le32(state);
-       req.id = cpu_to_le32(id);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
-                           &req, sizeof(req), &scm_ret, sizeof(scm_ret));
-
-       return ret ? : le32_to_cpu(scm_ret);
-}
-
-int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,
-                         size_t mem_sz, phys_addr_t src, size_t src_sz,
-                         phys_addr_t dest, size_t dest_sz)
-{
-       return -ENODEV;
-}
-
-int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
-                              u32 spare)
-{
-       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,
-                                     size_t *size)
-{
-       return -ENODEV;
-}
-
-int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size,
-                                     u32 spare)
-{
-       return -ENODEV;
-}
-
-int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr,
-                       unsigned int *val)
-{
-       int ret;
-
-       ret = qcom_scm_call_atomic1(QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ, addr);
-       if (ret >= 0)
-               *val = ret;
-
-       return ret < 0 ? ret : 0;
-}
-
-int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val)
-{
-       return qcom_scm_call_atomic2(QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE,
-                                    addr, val);
-}
-
-int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool enable)
-{
-       return -ENODEV;
-}
diff --git a/drivers/firmware/qcom_scm-64.c b/drivers/firmware/qcom_scm-64.c
deleted file mode 100644 (file)
index 3c58503..0000000
+++ /dev/null
@@ -1,579 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-only
-/* Copyright (c) 2015, The Linux Foundation. All rights reserved.
- */
-
-#include <linux/io.h>
-#include <linux/errno.h>
-#include <linux/delay.h>
-#include <linux/mutex.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/qcom_scm.h>
-#include <linux/arm-smccc.h>
-#include <linux/dma-mapping.h>
-
-#include "qcom_scm.h"
-
-#define QCOM_SCM_FNID(s, c) ((((s) & 0xFF) << 8) | ((c) & 0xFF))
-
-#define MAX_QCOM_SCM_ARGS 10
-#define MAX_QCOM_SCM_RETS 3
-
-enum qcom_scm_arg_types {
-       QCOM_SCM_VAL,
-       QCOM_SCM_RO,
-       QCOM_SCM_RW,
-       QCOM_SCM_BUFVAL,
-};
-
-#define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\
-                          (((a) & 0x3) << 4) | \
-                          (((b) & 0x3) << 6) | \
-                          (((c) & 0x3) << 8) | \
-                          (((d) & 0x3) << 10) | \
-                          (((e) & 0x3) << 12) | \
-                          (((f) & 0x3) << 14) | \
-                          (((g) & 0x3) << 16) | \
-                          (((h) & 0x3) << 18) | \
-                          (((i) & 0x3) << 20) | \
-                          (((j) & 0x3) << 22) | \
-                          ((num) & 0xf))
-
-#define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
-
-/**
- * struct qcom_scm_desc
- * @arginfo:   Metadata describing the arguments in args[]
- * @args:      The array of arguments for the secure syscall
- * @res:       The values returned by the secure syscall
- */
-struct qcom_scm_desc {
-       u32 arginfo;
-       u64 args[MAX_QCOM_SCM_ARGS];
-};
-
-static u64 qcom_smccc_convention = -1;
-static DEFINE_MUTEX(qcom_scm_lock);
-
-#define QCOM_SCM_EBUSY_WAIT_MS 30
-#define QCOM_SCM_EBUSY_MAX_RETRY 20
-
-#define N_EXT_QCOM_SCM_ARGS 7
-#define FIRST_EXT_ARG_IDX 3
-#define N_REGISTER_ARGS (MAX_QCOM_SCM_ARGS - N_EXT_QCOM_SCM_ARGS + 1)
-
-static void __qcom_scm_call_do(const struct qcom_scm_desc *desc,
-                              struct arm_smccc_res *res, u32 fn_id,
-                              u64 x5, u32 type)
-{
-       u64 cmd;
-       struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 };
-
-       cmd = ARM_SMCCC_CALL_VAL(type, qcom_smccc_convention,
-                                ARM_SMCCC_OWNER_SIP, fn_id);
-
-       quirk.state.a6 = 0;
-
-       do {
-               arm_smccc_smc_quirk(cmd, desc->arginfo, desc->args[0],
-                                   desc->args[1], desc->args[2], x5,
-                                   quirk.state.a6, 0, res, &quirk);
-
-               if (res->a0 == QCOM_SCM_INTERRUPTED)
-                       cmd = res->a0;
-
-       } while (res->a0 == QCOM_SCM_INTERRUPTED);
-}
-
-static void qcom_scm_call_do(const struct qcom_scm_desc *desc,
-                            struct arm_smccc_res *res, u32 fn_id,
-                            u64 x5, bool atomic)
-{
-       int retry_count = 0;
-
-       if (atomic) {
-               __qcom_scm_call_do(desc, res, fn_id, x5, ARM_SMCCC_FAST_CALL);
-               return;
-       }
-
-       do {
-               mutex_lock(&qcom_scm_lock);
-
-               __qcom_scm_call_do(desc, res, fn_id, x5,
-                                  ARM_SMCCC_STD_CALL);
-
-               mutex_unlock(&qcom_scm_lock);
-
-               if (res->a0 == QCOM_SCM_V2_EBUSY) {
-                       if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
-                               break;
-                       msleep(QCOM_SCM_EBUSY_WAIT_MS);
-               }
-       }  while (res->a0 == QCOM_SCM_V2_EBUSY);
-}
-
-static int ___qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
-                           const struct qcom_scm_desc *desc,
-                           struct arm_smccc_res *res, bool atomic)
-{
-       int arglen = desc->arginfo & 0xf;
-       int i;
-       u32 fn_id = QCOM_SCM_FNID(svc_id, cmd_id);
-       u64 x5 = desc->args[FIRST_EXT_ARG_IDX];
-       dma_addr_t args_phys = 0;
-       void *args_virt = NULL;
-       size_t alloc_len;
-       gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
-
-       if (unlikely(arglen > N_REGISTER_ARGS)) {
-               alloc_len = N_EXT_QCOM_SCM_ARGS * sizeof(u64);
-               args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
-
-               if (!args_virt)
-                       return -ENOMEM;
-
-               if (qcom_smccc_convention == ARM_SMCCC_SMC_32) {
-                       __le32 *args = args_virt;
-
-                       for (i = 0; i < N_EXT_QCOM_SCM_ARGS; i++)
-                               args[i] = cpu_to_le32(desc->args[i +
-                                                     FIRST_EXT_ARG_IDX]);
-               } else {
-                       __le64 *args = args_virt;
-
-                       for (i = 0; i < N_EXT_QCOM_SCM_ARGS; i++)
-                               args[i] = cpu_to_le64(desc->args[i +
-                                                     FIRST_EXT_ARG_IDX]);
-               }
-
-               args_phys = dma_map_single(dev, args_virt, alloc_len,
-                                          DMA_TO_DEVICE);
-
-               if (dma_mapping_error(dev, args_phys)) {
-                       kfree(args_virt);
-                       return -ENOMEM;
-               }
-
-               x5 = args_phys;
-       }
-
-       qcom_scm_call_do(desc, res, fn_id, x5, atomic);
-
-       if (args_virt) {
-               dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
-               kfree(args_virt);
-       }
-
-       if ((long)res->a0 < 0)
-               return qcom_scm_remap_error(res->a0);
-
-       return 0;
-}
-
-/**
- * qcom_scm_call() - Invoke a syscall in the secure world
- * @dev:       device
- * @svc_id:    service identifier
- * @cmd_id:    command identifier
- * @desc:      Descriptor structure containing arguments and return values
- *
- * Sends a command to the SCM and waits for the command to finish processing.
- * This should *only* be called in pre-emptible context.
- */
-static int qcom_scm_call(struct device *dev, u32 svc_id, u32 cmd_id,
-                        const struct qcom_scm_desc *desc,
-                        struct arm_smccc_res *res)
-{
-       might_sleep();
-       return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, false);
-}
-
-/**
- * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
- * @dev:       device
- * @svc_id:    service identifier
- * @cmd_id:    command identifier
- * @desc:      Descriptor structure containing arguments and return values
- * @res:       Structure containing results from SMC/HVC call
- *
- * Sends a command to the SCM and waits for the command to finish processing.
- * This can be called in atomic context.
- */
-static int qcom_scm_call_atomic(struct device *dev, u32 svc_id, u32 cmd_id,
-                               const struct qcom_scm_desc *desc,
-                               struct arm_smccc_res *res)
-{
-       return ___qcom_scm_call(dev, svc_id, cmd_id, desc, res, true);
-}
-
-/**
- * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
- *
- * Set the cold boot address of the cpus. Any cpu outside the supported
- * range would be removed from the cpu present mask.
- */
-int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
-{
-       return -ENOTSUPP;
-}
-
-/**
- * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
- * @dev: Device pointer
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
- *
- * Set the Linux entry point for the SCM to transfer control to when coming
- * out of a power down. CPU power down may be executed on cpuidle or hotplug.
- */
-int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
-                                 const cpumask_t *cpus)
-{
-       return -ENOTSUPP;
-}
-
-/**
- * qcom_scm_cpu_power_down() - Power down the cpu
- * @flags - Flags to flush cache
- *
- * This is an end point to power down cpu. If there was a pending interrupt,
- * the control would return from this function, otherwise, the cpu jumps to the
- * warm boot entry point set for this cpu upon reset.
- */
-void __qcom_scm_cpu_power_down(u32 flags)
-{
-}
-
-int __qcom_scm_is_call_available(struct device *dev, u32 svc_id, u32 cmd_id)
-{
-       int ret;
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.arginfo = QCOM_SCM_ARGS(1);
-       desc.args[0] = QCOM_SCM_FNID(svc_id, cmd_id) |
-                       (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD,
-                           &desc, &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_hdcp_req(struct device *dev, struct qcom_scm_hdcp_req *req,
-                       u32 req_cnt, u32 *resp)
-{
-       int ret;
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT)
-               return -ERANGE;
-
-       desc.args[0] = req[0].addr;
-       desc.args[1] = req[0].val;
-       desc.args[2] = req[1].addr;
-       desc.args[3] = req[1].val;
-       desc.args[4] = req[2].addr;
-       desc.args[5] = req[2].val;
-       desc.args[6] = req[3].addr;
-       desc.args[7] = req[3].val;
-       desc.args[8] = req[4].addr;
-       desc.args[9] = req[4].val;
-       desc.arginfo = QCOM_SCM_ARGS(10);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_HDCP, QCOM_SCM_CMD_HDCP, &desc,
-                           &res);
-       *resp = res.a1;
-
-       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;
-       struct arm_smccc_res res;
-       u32 function = QCOM_SCM_FNID(QCOM_SCM_SVC_INFO, QCOM_IS_CALL_AVAIL_CMD);
-
-       /* First try a SMC64 call */
-       cmd = ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_64,
-                                ARM_SMCCC_OWNER_SIP, function);
-
-       arm_smccc_smc(cmd, QCOM_SCM_ARGS(1), cmd & (~BIT(ARM_SMCCC_TYPE_SHIFT)),
-                     0, 0, 0, 0, 0, &res);
-
-       if (!res.a0 && res.a1)
-               qcom_smccc_convention = ARM_SMCCC_SMC_64;
-       else
-               qcom_smccc_convention = ARM_SMCCC_SMC_32;
-}
-
-bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral)
-{
-       int ret;
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = peripheral;
-       desc.arginfo = QCOM_SCM_ARGS(1);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
-                               QCOM_SCM_PAS_IS_SUPPORTED_CMD,
-                               &desc, &res);
-
-       return ret ? false : !!res.a1;
-}
-
-int __qcom_scm_pas_init_image(struct device *dev, u32 peripheral,
-                             dma_addr_t metadata_phys)
-{
-       int ret;
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = peripheral;
-       desc.args[1] = metadata_phys;
-       desc.arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_INIT_IMAGE_CMD,
-                               &desc, &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral,
-                             phys_addr_t addr, phys_addr_t size)
-{
-       int ret;
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = peripheral;
-       desc.args[1] = addr;
-       desc.args[2] = size;
-       desc.arginfo = QCOM_SCM_ARGS(3);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MEM_SETUP_CMD,
-                               &desc, &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral)
-{
-       int ret;
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = peripheral;
-       desc.arginfo = QCOM_SCM_ARGS(1);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL,
-                               QCOM_SCM_PAS_AUTH_AND_RESET_CMD,
-                               &desc, &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral)
-{
-       int ret;
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = peripheral;
-       desc.arginfo = QCOM_SCM_ARGS(1);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_SHUTDOWN_CMD,
-                       &desc, &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-       int ret;
-
-       desc.args[0] = reset;
-       desc.args[1] = 0;
-       desc.arginfo = QCOM_SCM_ARGS(2);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_PIL, QCOM_SCM_PAS_MSS_RESET, &desc,
-                           &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-       int ret;
-
-       desc.args[0] = state;
-       desc.args[1] = id;
-       desc.arginfo = QCOM_SCM_ARGS(2);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_REMOTE_STATE,
-                           &desc, &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,
-                         size_t mem_sz, phys_addr_t src, size_t src_sz,
-                         phys_addr_t dest, size_t dest_sz)
-{
-       int ret;
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = mem_region;
-       desc.args[1] = mem_sz;
-       desc.args[2] = src;
-       desc.args[3] = src_sz;
-       desc.args[4] = dest;
-       desc.args[5] = dest_sz;
-       desc.args[6] = 0;
-
-       desc.arginfo = QCOM_SCM_ARGS(7, QCOM_SCM_RO, QCOM_SCM_VAL,
-                                    QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO,
-                                    QCOM_SCM_VAL, QCOM_SCM_VAL);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP,
-                           QCOM_MEM_PROT_ASSIGN_ID,
-                           &desc, &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id, u32 spare)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-       int ret;
-
-       desc.args[0] = device_id;
-       desc.args[1] = spare;
-       desc.arginfo = QCOM_SCM_ARGS(2);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP, QCOM_SCM_RESTORE_SEC_CFG,
-                           &desc, &res);
-
-       return ret ? : res.a1;
-}
-
-int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare,
-                                     size_t *size)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-       int ret;
-
-       desc.args[0] = spare;
-       desc.arginfo = QCOM_SCM_ARGS(1);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP,
-                           QCOM_SCM_IOMMU_SECURE_PTBL_SIZE, &desc, &res);
-
-       if (size)
-               *size = res.a1;
-
-       return ret ? : res.a2;
-}
-
-int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr, u32 size,
-                                     u32 spare)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-       int ret;
-
-       desc.args[0] = addr;
-       desc.args[1] = size;
-       desc.args[2] = spare;
-       desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL,
-                                    QCOM_SCM_VAL);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_MP,
-                           QCOM_SCM_IOMMU_SECURE_PTBL_INIT, &desc, &res);
-
-       /* the pg table has been initialized already, ignore the error */
-       if (ret == -EPERM)
-               ret = 0;
-
-       return ret;
-}
-
-int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = QCOM_SCM_SET_DLOAD_MODE;
-       desc.args[1] = enable ? QCOM_SCM_SET_DLOAD_MODE : 0;
-       desc.arginfo = QCOM_SCM_ARGS(2);
-
-       return qcom_scm_call(dev, QCOM_SCM_SVC_BOOT, QCOM_SCM_SET_DLOAD_MODE,
-                            &desc, &res);
-}
-
-int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr,
-                       unsigned int *val)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-       int ret;
-
-       desc.args[0] = addr;
-       desc.arginfo = QCOM_SCM_ARGS(1);
-
-       ret = qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_READ,
-                           &desc, &res);
-       if (ret >= 0)
-               *val = res.a1;
-
-       return ret < 0 ? ret : 0;
-}
-
-int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = addr;
-       desc.args[1] = val;
-       desc.arginfo = QCOM_SCM_ARGS(2);
-
-       return qcom_scm_call(dev, QCOM_SCM_SVC_IO, QCOM_SCM_IO_WRITE,
-                            &desc, &res);
-}
-
-int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev, bool en)
-{
-       struct qcom_scm_desc desc = {0};
-       struct arm_smccc_res res;
-
-       desc.args[0] = QCOM_SCM_CONFIG_ERRATA1_CLIENT_ALL;
-       desc.args[1] = en;
-       desc.arginfo = QCOM_SCM_ARGS(2);
-
-       return qcom_scm_call_atomic(dev, QCOM_SCM_SVC_SMMU_PROGRAM,
-                                   QCOM_SCM_CONFIG_ERRATA1, &desc, &res);
-}
diff --git a/drivers/firmware/qcom_scm-legacy.c b/drivers/firmware/qcom_scm-legacy.c
new file mode 100644 (file)
index 0000000..8532e7c
--- /dev/null
@@ -0,0 +1,242 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2010,2015,2019 The Linux Foundation. All rights reserved.
+ * Copyright (C) 2015 Linaro Ltd.
+ */
+
+#include <linux/slab.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/qcom_scm.h>
+#include <linux/arm-smccc.h>
+#include <linux/dma-mapping.h>
+
+#include "qcom_scm.h"
+
+static DEFINE_MUTEX(qcom_scm_lock);
+
+
+/**
+ * struct arm_smccc_args
+ * @args:      The array of values used in registers in smc instruction
+ */
+struct arm_smccc_args {
+       unsigned long args[8];
+};
+
+
+/**
+ * struct scm_legacy_command - one SCM command buffer
+ * @len: total available memory for command and response
+ * @buf_offset: start of command buffer
+ * @resp_hdr_offset: start of response buffer
+ * @id: command to be executed
+ * @buf: buffer returned from scm_legacy_get_command_buffer()
+ *
+ * An SCM command is laid out in memory as follows:
+ *
+ *     ------------------- <--- struct scm_legacy_command
+ *     | command header  |
+ *     ------------------- <--- scm_legacy_get_command_buffer()
+ *     | command buffer  |
+ *     ------------------- <--- struct scm_legacy_response and
+ *     | response header |      scm_legacy_command_to_response()
+ *     ------------------- <--- scm_legacy_get_response_buffer()
+ *     | response buffer |
+ *     -------------------
+ *
+ * There can be arbitrary padding between the headers and buffers so
+ * you should always use the appropriate scm_legacy_get_*_buffer() routines
+ * to access the buffers in a safe manner.
+ */
+struct scm_legacy_command {
+       __le32 len;
+       __le32 buf_offset;
+       __le32 resp_hdr_offset;
+       __le32 id;
+       __le32 buf[0];
+};
+
+/**
+ * struct scm_legacy_response - one SCM response buffer
+ * @len: total available memory for response
+ * @buf_offset: start of response data relative to start of scm_legacy_response
+ * @is_complete: indicates if the command has finished processing
+ */
+struct scm_legacy_response {
+       __le32 len;
+       __le32 buf_offset;
+       __le32 is_complete;
+};
+
+/**
+ * scm_legacy_command_to_response() - Get a pointer to a scm_legacy_response
+ * @cmd: command
+ *
+ * Returns a pointer to a response for a command.
+ */
+static inline struct scm_legacy_response *scm_legacy_command_to_response(
+               const struct scm_legacy_command *cmd)
+{
+       return (void *)cmd + le32_to_cpu(cmd->resp_hdr_offset);
+}
+
+/**
+ * scm_legacy_get_command_buffer() - Get a pointer to a command buffer
+ * @cmd: command
+ *
+ * Returns a pointer to the command buffer of a command.
+ */
+static inline void *scm_legacy_get_command_buffer(
+               const struct scm_legacy_command *cmd)
+{
+       return (void *)cmd->buf;
+}
+
+/**
+ * scm_legacy_get_response_buffer() - Get a pointer to a response buffer
+ * @rsp: response
+ *
+ * Returns a pointer to a response buffer of a response.
+ */
+static inline void *scm_legacy_get_response_buffer(
+               const struct scm_legacy_response *rsp)
+{
+       return (void *)rsp + le32_to_cpu(rsp->buf_offset);
+}
+
+static void __scm_legacy_do(const struct arm_smccc_args *smc,
+                           struct arm_smccc_res *res)
+{
+       do {
+               arm_smccc_smc(smc->args[0], smc->args[1], smc->args[2],
+                             smc->args[3], smc->args[4], smc->args[5],
+                             smc->args[6], smc->args[7], res);
+       } while (res->a0 == QCOM_SCM_INTERRUPTED);
+}
+
+/**
+ * qcom_scm_call() - Sends a command to the SCM and waits for the command to
+ * finish processing.
+ *
+ * A note on cache maintenance:
+ * Note that any buffers that are expected to be accessed by the secure world
+ * must be flushed before invoking qcom_scm_call and invalidated in the cache
+ * immediately after qcom_scm_call returns. Cache maintenance on the command
+ * and response buffers is taken care of by qcom_scm_call; however, callers are
+ * responsible for any other cached buffers passed over to the secure world.
+ */
+int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
+                   struct qcom_scm_res *res)
+{
+       u8 arglen = desc->arginfo & 0xf;
+       int ret = 0, context_id;
+       unsigned int i;
+       struct scm_legacy_command *cmd;
+       struct scm_legacy_response *rsp;
+       struct arm_smccc_args smc = {0};
+       struct arm_smccc_res smc_res;
+       const size_t cmd_len = arglen * sizeof(__le32);
+       const size_t resp_len = MAX_QCOM_SCM_RETS * sizeof(__le32);
+       size_t alloc_len = sizeof(*cmd) + cmd_len + sizeof(*rsp) + resp_len;
+       dma_addr_t cmd_phys;
+       __le32 *arg_buf;
+       const __le32 *res_buf;
+
+       cmd = kzalloc(PAGE_ALIGN(alloc_len), GFP_KERNEL);
+       if (!cmd)
+               return -ENOMEM;
+
+       cmd->len = cpu_to_le32(alloc_len);
+       cmd->buf_offset = cpu_to_le32(sizeof(*cmd));
+       cmd->resp_hdr_offset = cpu_to_le32(sizeof(*cmd) + cmd_len);
+       cmd->id = cpu_to_le32(SCM_LEGACY_FNID(desc->svc, desc->cmd));
+
+       arg_buf = scm_legacy_get_command_buffer(cmd);
+       for (i = 0; i < arglen; i++)
+               arg_buf[i] = cpu_to_le32(desc->args[i]);
+
+       rsp = scm_legacy_command_to_response(cmd);
+
+       cmd_phys = dma_map_single(dev, cmd, alloc_len, DMA_TO_DEVICE);
+       if (dma_mapping_error(dev, cmd_phys)) {
+               kfree(cmd);
+               return -ENOMEM;
+       }
+
+       smc.args[0] = 1;
+       smc.args[1] = (unsigned long)&context_id;
+       smc.args[2] = cmd_phys;
+
+       mutex_lock(&qcom_scm_lock);
+       __scm_legacy_do(&smc, &smc_res);
+       if (smc_res.a0)
+               ret = qcom_scm_remap_error(smc_res.a0);
+       mutex_unlock(&qcom_scm_lock);
+       if (ret)
+               goto out;
+
+       do {
+               dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len,
+                                       sizeof(*rsp), DMA_FROM_DEVICE);
+       } while (!rsp->is_complete);
+
+       dma_sync_single_for_cpu(dev, cmd_phys + sizeof(*cmd) + cmd_len +
+                               le32_to_cpu(rsp->buf_offset),
+                               resp_len, DMA_FROM_DEVICE);
+
+       if (res) {
+               res_buf = scm_legacy_get_response_buffer(rsp);
+               for (i = 0; i < MAX_QCOM_SCM_RETS; i++)
+                       res->result[i] = le32_to_cpu(res_buf[i]);
+       }
+out:
+       dma_unmap_single(dev, cmd_phys, alloc_len, DMA_TO_DEVICE);
+       kfree(cmd);
+       return ret;
+}
+
+#define SCM_LEGACY_ATOMIC_N_REG_ARGS   5
+#define SCM_LEGACY_ATOMIC_FIRST_REG_IDX        2
+#define SCM_LEGACY_CLASS_REGISTER              (0x2 << 8)
+#define SCM_LEGACY_MASK_IRQS           BIT(5)
+#define SCM_LEGACY_ATOMIC_ID(svc, cmd, n) \
+                               ((SCM_LEGACY_FNID(svc, cmd) << 12) | \
+                               SCM_LEGACY_CLASS_REGISTER | \
+                               SCM_LEGACY_MASK_IRQS | \
+                               (n & 0xf))
+
+/**
+ * qcom_scm_call_atomic() - Send an atomic SCM command with up to 5 arguments
+ * and 3 return values
+ * @desc: SCM call descriptor containing arguments
+ * @res:  SCM call return values
+ *
+ * This shall only be used with commands that are guaranteed to be
+ * uninterruptable, atomic and SMP safe.
+ */
+int scm_legacy_call_atomic(struct device *unused,
+                          const struct qcom_scm_desc *desc,
+                          struct qcom_scm_res *res)
+{
+       int context_id;
+       struct arm_smccc_res smc_res;
+       size_t arglen = desc->arginfo & 0xf;
+
+       BUG_ON(arglen > SCM_LEGACY_ATOMIC_N_REG_ARGS);
+
+       arm_smccc_smc(SCM_LEGACY_ATOMIC_ID(desc->svc, desc->cmd, arglen),
+                     (unsigned long)&context_id,
+                     desc->args[0], desc->args[1], desc->args[2],
+                     desc->args[3], desc->args[4], 0, &smc_res);
+
+       if (res) {
+               res->result[0] = smc_res.a1;
+               res->result[1] = smc_res.a2;
+               res->result[2] = smc_res.a3;
+       }
+
+       return smc_res.a0;
+}
diff --git a/drivers/firmware/qcom_scm-smc.c b/drivers/firmware/qcom_scm-smc.c
new file mode 100644 (file)
index 0000000..497c13b
--- /dev/null
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/* Copyright (c) 2015,2019 The Linux Foundation. All rights reserved.
+ */
+
+#include <linux/io.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/mutex.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/qcom_scm.h>
+#include <linux/arm-smccc.h>
+#include <linux/dma-mapping.h>
+
+#include "qcom_scm.h"
+
+/**
+ * struct arm_smccc_args
+ * @args:      The array of values used in registers in smc instruction
+ */
+struct arm_smccc_args {
+       unsigned long args[8];
+};
+
+static DEFINE_MUTEX(qcom_scm_lock);
+
+#define QCOM_SCM_EBUSY_WAIT_MS 30
+#define QCOM_SCM_EBUSY_MAX_RETRY 20
+
+#define SCM_SMC_N_REG_ARGS     4
+#define SCM_SMC_FIRST_EXT_IDX  (SCM_SMC_N_REG_ARGS - 1)
+#define SCM_SMC_N_EXT_ARGS     (MAX_QCOM_SCM_ARGS - SCM_SMC_N_REG_ARGS + 1)
+#define SCM_SMC_FIRST_REG_IDX  2
+#define SCM_SMC_LAST_REG_IDX   (SCM_SMC_FIRST_REG_IDX + SCM_SMC_N_REG_ARGS - 1)
+
+static void __scm_smc_do_quirk(const struct arm_smccc_args *smc,
+                              struct arm_smccc_res *res)
+{
+       unsigned long a0 = smc->args[0];
+       struct arm_smccc_quirk quirk = { .id = ARM_SMCCC_QUIRK_QCOM_A6 };
+
+       quirk.state.a6 = 0;
+
+       do {
+               arm_smccc_smc_quirk(a0, smc->args[1], smc->args[2],
+                                   smc->args[3], smc->args[4], smc->args[5],
+                                   quirk.state.a6, smc->args[7], res, &quirk);
+
+               if (res->a0 == QCOM_SCM_INTERRUPTED)
+                       a0 = res->a0;
+
+       } while (res->a0 == QCOM_SCM_INTERRUPTED);
+}
+
+static void __scm_smc_do(const struct arm_smccc_args *smc,
+                        struct arm_smccc_res *res, bool atomic)
+{
+       int retry_count = 0;
+
+       if (atomic) {
+               __scm_smc_do_quirk(smc, res);
+               return;
+       }
+
+       do {
+               mutex_lock(&qcom_scm_lock);
+
+               __scm_smc_do_quirk(smc, res);
+
+               mutex_unlock(&qcom_scm_lock);
+
+               if (res->a0 == QCOM_SCM_V2_EBUSY) {
+                       if (retry_count++ > QCOM_SCM_EBUSY_MAX_RETRY)
+                               break;
+                       msleep(QCOM_SCM_EBUSY_WAIT_MS);
+               }
+       }  while (res->a0 == QCOM_SCM_V2_EBUSY);
+}
+
+int scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
+                struct qcom_scm_res *res, bool atomic)
+{
+       int arglen = desc->arginfo & 0xf;
+       int i;
+       dma_addr_t args_phys = 0;
+       void *args_virt = NULL;
+       size_t alloc_len;
+       gfp_t flag = atomic ? GFP_ATOMIC : GFP_KERNEL;
+       u32 smccc_call_type = atomic ? ARM_SMCCC_FAST_CALL : ARM_SMCCC_STD_CALL;
+       u32 qcom_smccc_convention =
+                       (qcom_scm_convention == SMC_CONVENTION_ARM_32) ?
+                       ARM_SMCCC_SMC_32 : ARM_SMCCC_SMC_64;
+       struct arm_smccc_res smc_res;
+       struct arm_smccc_args smc = {0};
+
+       smc.args[0] = ARM_SMCCC_CALL_VAL(
+               smccc_call_type,
+               qcom_smccc_convention,
+               desc->owner,
+               SCM_SMC_FNID(desc->svc, desc->cmd));
+       smc.args[1] = desc->arginfo;
+       for (i = 0; i < SCM_SMC_N_REG_ARGS; i++)
+               smc.args[i + SCM_SMC_FIRST_REG_IDX] = desc->args[i];
+
+       if (unlikely(arglen > SCM_SMC_N_REG_ARGS)) {
+               alloc_len = SCM_SMC_N_EXT_ARGS * sizeof(u64);
+               args_virt = kzalloc(PAGE_ALIGN(alloc_len), flag);
+
+               if (!args_virt)
+                       return -ENOMEM;
+
+               if (qcom_smccc_convention == ARM_SMCCC_SMC_32) {
+                       __le32 *args = args_virt;
+
+                       for (i = 0; i < SCM_SMC_N_EXT_ARGS; i++)
+                               args[i] = cpu_to_le32(desc->args[i +
+                                                     SCM_SMC_FIRST_EXT_IDX]);
+               } else {
+                       __le64 *args = args_virt;
+
+                       for (i = 0; i < SCM_SMC_N_EXT_ARGS; i++)
+                               args[i] = cpu_to_le64(desc->args[i +
+                                                     SCM_SMC_FIRST_EXT_IDX]);
+               }
+
+               args_phys = dma_map_single(dev, args_virt, alloc_len,
+                                          DMA_TO_DEVICE);
+
+               if (dma_mapping_error(dev, args_phys)) {
+                       kfree(args_virt);
+                       return -ENOMEM;
+               }
+
+               smc.args[SCM_SMC_LAST_REG_IDX] = args_phys;
+       }
+
+       __scm_smc_do(&smc, &smc_res, atomic);
+
+       if (args_virt) {
+               dma_unmap_single(dev, args_phys, alloc_len, DMA_TO_DEVICE);
+               kfree(args_virt);
+       }
+
+       if (res) {
+               res->result[0] = smc_res.a1;
+               res->result[1] = smc_res.a2;
+               res->result[2] = smc_res.a3;
+       }
+
+       return (long)smc_res.a0 ? qcom_scm_remap_error(smc_res.a0) : 0;
+}
index 1ba0df4..059bb0f 100644 (file)
@@ -1,8 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/*
- * Qualcomm SCM driver
- *
- * Copyright (c) 2010,2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010,2015,2019 The Linux Foundation. All rights reserved.
  * Copyright (C) 2015 Linaro Ltd.
  */
 #include <linux/platform_device.h>
@@ -19,6 +16,7 @@
 #include <linux/of_platform.h>
 #include <linux/clk.h>
 #include <linux/reset-controller.h>
+#include <linux/arm-smccc.h>
 
 #include "qcom_scm.h"
 
@@ -52,6 +50,35 @@ struct qcom_scm_mem_map_info {
        __le64 mem_size;
 };
 
+#define QCOM_SCM_FLAG_COLDBOOT_CPU0    0x00
+#define QCOM_SCM_FLAG_COLDBOOT_CPU1    0x01
+#define QCOM_SCM_FLAG_COLDBOOT_CPU2    0x08
+#define QCOM_SCM_FLAG_COLDBOOT_CPU3    0x20
+
+#define QCOM_SCM_FLAG_WARMBOOT_CPU0    0x04
+#define QCOM_SCM_FLAG_WARMBOOT_CPU1    0x02
+#define QCOM_SCM_FLAG_WARMBOOT_CPU2    0x10
+#define QCOM_SCM_FLAG_WARMBOOT_CPU3    0x40
+
+struct qcom_scm_wb_entry {
+       int flag;
+       void *entry;
+};
+
+static struct qcom_scm_wb_entry qcom_scm_wb[] = {
+       { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU0 },
+       { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU1 },
+       { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU2 },
+       { .flag = QCOM_SCM_FLAG_WARMBOOT_CPU3 },
+};
+
+static const char *qcom_scm_convention_names[] = {
+       [SMC_CONVENTION_UNKNOWN] = "unknown",
+       [SMC_CONVENTION_ARM_32] = "smc arm 32",
+       [SMC_CONVENTION_ARM_64] = "smc arm 64",
+       [SMC_CONVENTION_LEGACY] = "smc legacy",
+};
+
 static struct qcom_scm *__scm;
 
 static int qcom_scm_clk_enable(void)
@@ -87,149 +114,308 @@ static void qcom_scm_clk_disable(void)
        clk_disable_unprepare(__scm->bus_clk);
 }
 
-/**
- * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
- *
- * Set the cold boot address of the cpus. Any cpu outside the supported
- * range would be removed from the cpu present mask.
- */
-int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
+static int __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
+                                       u32 cmd_id);
+
+enum qcom_scm_convention qcom_scm_convention;
+static bool has_queried __read_mostly;
+static DEFINE_SPINLOCK(query_lock);
+
+static void __query_convention(void)
 {
-       return __qcom_scm_set_cold_boot_addr(entry, cpus);
+       unsigned long flags;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_INFO,
+               .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL,
+               .args[0] = SCM_SMC_FNID(QCOM_SCM_SVC_INFO,
+                                          QCOM_SCM_INFO_IS_CALL_AVAIL) |
+                          (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT),
+               .arginfo = QCOM_SCM_ARGS(1),
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+       int ret;
+
+       spin_lock_irqsave(&query_lock, flags);
+       if (has_queried)
+               goto out;
+
+       qcom_scm_convention = SMC_CONVENTION_ARM_64;
+       // Device isn't required as there is only one argument - no device
+       // needed to dma_map_single to secure world
+       ret = scm_smc_call(NULL, &desc, &res, true);
+       if (!ret && res.result[0] == 1)
+               goto out;
+
+       qcom_scm_convention = SMC_CONVENTION_ARM_32;
+       ret = scm_smc_call(NULL, &desc, &res, true);
+       if (!ret && res.result[0] == 1)
+               goto out;
+
+       qcom_scm_convention = SMC_CONVENTION_LEGACY;
+out:
+       has_queried = true;
+       spin_unlock_irqrestore(&query_lock, flags);
+       pr_info("qcom_scm: convention: %s\n",
+               qcom_scm_convention_names[qcom_scm_convention]);
 }
-EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
 
-/**
- * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
- * @entry: Entry point function for the cpus
- * @cpus: The cpumask of cpus that will use the entry point
- *
- * Set the Linux entry point for the SCM to transfer control to when coming
- * out of a power down. CPU power down may be executed on cpuidle or hotplug.
- */
-int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
+static inline enum qcom_scm_convention __get_convention(void)
 {
-       return __qcom_scm_set_warm_boot_addr(__scm->dev, entry, cpus);
+       if (unlikely(!has_queried))
+               __query_convention();
+       return qcom_scm_convention;
 }
-EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
 
 /**
- * qcom_scm_cpu_power_down() - Power down the cpu
- * @flags - Flags to flush cache
+ * qcom_scm_call() - Invoke a syscall in the secure world
+ * @dev:       device
+ * @svc_id:    service identifier
+ * @cmd_id:    command identifier
+ * @desc:      Descriptor structure containing arguments and return values
  *
- * This is an end point to power down cpu. If there was a pending interrupt,
- * the control would return from this function, otherwise, the cpu jumps to the
- * warm boot entry point set for this cpu upon reset.
+ * Sends a command to the SCM and waits for the command to finish processing.
+ * This should *only* be called in pre-emptible context.
  */
-void qcom_scm_cpu_power_down(u32 flags)
+static int qcom_scm_call(struct device *dev, const struct qcom_scm_desc *desc,
+                        struct qcom_scm_res *res)
 {
-       __qcom_scm_cpu_power_down(flags);
+       might_sleep();
+       switch (__get_convention()) {
+       case SMC_CONVENTION_ARM_32:
+       case SMC_CONVENTION_ARM_64:
+               return scm_smc_call(dev, desc, res, false);
+       case SMC_CONVENTION_LEGACY:
+               return scm_legacy_call(dev, desc, res);
+       default:
+               pr_err("Unknown current SCM calling convention.\n");
+               return -EINVAL;
+       }
 }
-EXPORT_SYMBOL(qcom_scm_cpu_power_down);
 
 /**
- * qcom_scm_hdcp_available() - Check if secure environment supports HDCP.
+ * qcom_scm_call_atomic() - atomic variation of qcom_scm_call()
+ * @dev:       device
+ * @svc_id:    service identifier
+ * @cmd_id:    command identifier
+ * @desc:      Descriptor structure containing arguments and return values
+ * @res:       Structure containing results from SMC/HVC call
  *
- * Return true if HDCP is supported, false if not.
+ * Sends a command to the SCM and waits for the command to finish processing.
+ * This can be called in atomic context.
  */
-bool qcom_scm_hdcp_available(void)
+static int qcom_scm_call_atomic(struct device *dev,
+                               const struct qcom_scm_desc *desc,
+                               struct qcom_scm_res *res)
 {
-       int ret = qcom_scm_clk_enable();
-
-       if (ret)
-               return ret;
+       switch (__get_convention()) {
+       case SMC_CONVENTION_ARM_32:
+       case SMC_CONVENTION_ARM_64:
+               return scm_smc_call(dev, desc, res, true);
+       case SMC_CONVENTION_LEGACY:
+               return scm_legacy_call_atomic(dev, desc, res);
+       default:
+               pr_err("Unknown current SCM calling convention.\n");
+               return -EINVAL;
+       }
+}
 
-       ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_HDCP,
-                                               QCOM_SCM_CMD_HDCP);
+static int __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
+                                       u32 cmd_id)
+{
+       int ret;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_INFO,
+               .cmd = QCOM_SCM_INFO_IS_CALL_AVAIL,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+
+       desc.arginfo = QCOM_SCM_ARGS(1);
+       switch (__get_convention()) {
+       case SMC_CONVENTION_ARM_32:
+       case SMC_CONVENTION_ARM_64:
+               desc.args[0] = SCM_SMC_FNID(svc_id, cmd_id) |
+                               (ARM_SMCCC_OWNER_SIP << ARM_SMCCC_OWNER_SHIFT);
+               break;
+       case SMC_CONVENTION_LEGACY:
+               desc.args[0] = SCM_LEGACY_FNID(svc_id, cmd_id);
+               break;
+       default:
+               pr_err("Unknown SMC convention being used\n");
+               return -EINVAL;
+       }
 
-       qcom_scm_clk_disable();
+       ret = qcom_scm_call(dev, &desc, &res);
 
-       return ret > 0 ? true : false;
+       return ret ? : res.result[0];
 }
-EXPORT_SYMBOL(qcom_scm_hdcp_available);
 
 /**
- * qcom_scm_hdcp_req() - Send HDCP request.
- * @req: HDCP request array
- * @req_cnt: HDCP request array count
- * @resp: response buffer passed to SCM
+ * qcom_scm_set_warm_boot_addr() - Set the warm boot address for cpus
+ * @entry: Entry point function for the cpus
+ * @cpus: The cpumask of cpus that will use the entry point
  *
- * Write HDCP register(s) through SCM.
+ * Set the Linux entry point for the SCM to transfer control to when coming
+ * out of a power down. CPU power down may be executed on cpuidle or hotplug.
  */
-int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
+int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
 {
-       int ret = qcom_scm_clk_enable();
+       int ret;
+       int flags = 0;
+       int cpu;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_BOOT,
+               .cmd = QCOM_SCM_BOOT_SET_ADDR,
+               .arginfo = QCOM_SCM_ARGS(2),
+       };
 
-       if (ret)
-               return ret;
+       /*
+        * Reassign only if we are switching from hotplug entry point
+        * to cpuidle entry point or vice versa.
+        */
+       for_each_cpu(cpu, cpus) {
+               if (entry == qcom_scm_wb[cpu].entry)
+                       continue;
+               flags |= qcom_scm_wb[cpu].flag;
+       }
+
+       /* No change in entry function */
+       if (!flags)
+               return 0;
+
+       desc.args[0] = flags;
+       desc.args[1] = virt_to_phys(entry);
+
+       ret = qcom_scm_call(__scm->dev, &desc, NULL);
+       if (!ret) {
+               for_each_cpu(cpu, cpus)
+                       qcom_scm_wb[cpu].entry = entry;
+       }
 
-       ret = __qcom_scm_hdcp_req(__scm->dev, req, req_cnt, resp);
-       qcom_scm_clk_disable();
        return ret;
 }
-EXPORT_SYMBOL(qcom_scm_hdcp_req);
+EXPORT_SYMBOL(qcom_scm_set_warm_boot_addr);
 
 /**
- * qcom_scm_pas_supported() - Check if the peripheral authentication service is
- *                           available for the given peripherial
- * @peripheral:        peripheral id
+ * qcom_scm_set_cold_boot_addr() - Set the cold boot address for cpus
+ * @entry: Entry point function for the cpus
+ * @cpus: The cpumask of cpus that will use the entry point
  *
- * Returns true if PAS is supported for this peripheral, otherwise false.
+ * Set the cold boot address of the cpus. Any cpu outside the supported
+ * range would be removed from the cpu present mask.
  */
-bool qcom_scm_pas_supported(u32 peripheral)
+int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
 {
-       int ret;
+       int flags = 0;
+       int cpu;
+       int scm_cb_flags[] = {
+               QCOM_SCM_FLAG_COLDBOOT_CPU0,
+               QCOM_SCM_FLAG_COLDBOOT_CPU1,
+               QCOM_SCM_FLAG_COLDBOOT_CPU2,
+               QCOM_SCM_FLAG_COLDBOOT_CPU3,
+       };
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_BOOT,
+               .cmd = QCOM_SCM_BOOT_SET_ADDR,
+               .arginfo = QCOM_SCM_ARGS(2),
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+
+       if (!cpus || (cpus && cpumask_empty(cpus)))
+               return -EINVAL;
 
-       ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL,
-                                          QCOM_SCM_PAS_IS_SUPPORTED_CMD);
-       if (ret <= 0)
-               return false;
+       for_each_cpu(cpu, cpus) {
+               if (cpu < ARRAY_SIZE(scm_cb_flags))
+                       flags |= scm_cb_flags[cpu];
+               else
+                       set_cpu_present(cpu, false);
+       }
+
+       desc.args[0] = flags;
+       desc.args[1] = virt_to_phys(entry);
 
-       return __qcom_scm_pas_supported(__scm->dev, peripheral);
+       return qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL);
 }
-EXPORT_SYMBOL(qcom_scm_pas_supported);
+EXPORT_SYMBOL(qcom_scm_set_cold_boot_addr);
 
 /**
- * qcom_scm_ocmem_lock_available() - is OCMEM lock/unlock interface available
+ * qcom_scm_cpu_power_down() - Power down the cpu
+ * @flags - Flags to flush cache
+ *
+ * This is an end point to power down cpu. If there was a pending interrupt,
+ * the control would return from this function, otherwise, the cpu jumps to the
+ * warm boot entry point set for this cpu upon reset.
  */
-bool qcom_scm_ocmem_lock_available(void)
+void qcom_scm_cpu_power_down(u32 flags)
 {
-       return __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_OCMEM_SVC,
-                                           QCOM_SCM_OCMEM_LOCK_CMD);
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_BOOT,
+               .cmd = QCOM_SCM_BOOT_TERMINATE_PC,
+               .args[0] = flags & QCOM_SCM_FLUSH_FLAG_MASK,
+               .arginfo = QCOM_SCM_ARGS(1),
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+
+       qcom_scm_call_atomic(__scm ? __scm->dev : NULL, &desc, NULL);
 }
-EXPORT_SYMBOL(qcom_scm_ocmem_lock_available);
+EXPORT_SYMBOL(qcom_scm_cpu_power_down);
 
-/**
- * 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)
+int qcom_scm_set_remote_state(u32 state, u32 id)
 {
-       return __qcom_scm_ocmem_lock(__scm->dev, id, offset, size, mode);
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_BOOT,
+               .cmd = QCOM_SCM_BOOT_SET_REMOTE_STATE,
+               .arginfo = QCOM_SCM_ARGS(2),
+               .args[0] = state,
+               .args[1] = id,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+       int ret;
+
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+       return ret ? : res.result[0];
 }
-EXPORT_SYMBOL(qcom_scm_ocmem_lock);
+EXPORT_SYMBOL(qcom_scm_set_remote_state);
 
-/**
- * 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)
+static int __qcom_scm_set_dload_mode(struct device *dev, bool enable)
 {
-       return __qcom_scm_ocmem_unlock(__scm->dev, id, offset, size);
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_BOOT,
+               .cmd = QCOM_SCM_BOOT_SET_DLOAD_MODE,
+               .arginfo = QCOM_SCM_ARGS(2),
+               .args[0] = QCOM_SCM_BOOT_SET_DLOAD_MODE,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+
+       desc.args[1] = enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0;
+
+       return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+
+static void qcom_scm_set_download_mode(bool enable)
+{
+       bool avail;
+       int ret = 0;
+
+       avail = __qcom_scm_is_call_available(__scm->dev,
+                                            QCOM_SCM_SVC_BOOT,
+                                            QCOM_SCM_BOOT_SET_DLOAD_MODE);
+       if (avail) {
+               ret = __qcom_scm_set_dload_mode(__scm->dev, enable);
+       } else if (__scm->dload_mode_addr) {
+               ret = qcom_scm_io_writel(__scm->dload_mode_addr,
+                               enable ? QCOM_SCM_BOOT_SET_DLOAD_MODE : 0);
+       } else {
+               dev_err(__scm->dev,
+                       "No available mechanism for setting download mode\n");
+       }
+
+       if (ret)
+               dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
 }
-EXPORT_SYMBOL(qcom_scm_ocmem_unlock);
 
 /**
  * qcom_scm_pas_init_image() - Initialize peripheral authentication service
@@ -248,6 +434,14 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
        dma_addr_t mdata_phys;
        void *mdata_buf;
        int ret;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_PIL,
+               .cmd = QCOM_SCM_PIL_PAS_INIT_IMAGE,
+               .arginfo = QCOM_SCM_ARGS(2, QCOM_SCM_VAL, QCOM_SCM_RW),
+               .args[0] = peripheral,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
 
        /*
         * During the scm call memory protection will be enabled for the meta
@@ -266,14 +460,16 @@ int qcom_scm_pas_init_image(u32 peripheral, const void *metadata, size_t size)
        if (ret)
                goto free_metadata;
 
-       ret = __qcom_scm_pas_init_image(__scm->dev, peripheral, mdata_phys);
+       desc.args[1] = mdata_phys;
+
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
 
        qcom_scm_clk_disable();
 
 free_metadata:
        dma_free_coherent(__scm->dev, size, mdata_buf, mdata_phys);
 
-       return ret;
+       return ret ? : res.result[0];
 }
 EXPORT_SYMBOL(qcom_scm_pas_init_image);
 
@@ -289,15 +485,25 @@ EXPORT_SYMBOL(qcom_scm_pas_init_image);
 int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr, phys_addr_t size)
 {
        int ret;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_PIL,
+               .cmd = QCOM_SCM_PIL_PAS_MEM_SETUP,
+               .arginfo = QCOM_SCM_ARGS(3),
+               .args[0] = peripheral,
+               .args[1] = addr,
+               .args[2] = size,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
 
        ret = qcom_scm_clk_enable();
        if (ret)
                return ret;
 
-       ret = __qcom_scm_pas_mem_setup(__scm->dev, peripheral, addr, size);
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
        qcom_scm_clk_disable();
 
-       return ret;
+       return ret ? : res.result[0];
 }
 EXPORT_SYMBOL(qcom_scm_pas_mem_setup);
 
@@ -311,15 +517,23 @@ EXPORT_SYMBOL(qcom_scm_pas_mem_setup);
 int qcom_scm_pas_auth_and_reset(u32 peripheral)
 {
        int ret;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_PIL,
+               .cmd = QCOM_SCM_PIL_PAS_AUTH_AND_RESET,
+               .arginfo = QCOM_SCM_ARGS(1),
+               .args[0] = peripheral,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
 
        ret = qcom_scm_clk_enable();
        if (ret)
                return ret;
 
-       ret = __qcom_scm_pas_auth_and_reset(__scm->dev, peripheral);
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
        qcom_scm_clk_disable();
 
-       return ret;
+       return ret ? : res.result[0];
 }
 EXPORT_SYMBOL(qcom_scm_pas_auth_and_reset);
 
@@ -332,18 +546,75 @@ EXPORT_SYMBOL(qcom_scm_pas_auth_and_reset);
 int qcom_scm_pas_shutdown(u32 peripheral)
 {
        int ret;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_PIL,
+               .cmd = QCOM_SCM_PIL_PAS_SHUTDOWN,
+               .arginfo = QCOM_SCM_ARGS(1),
+               .args[0] = peripheral,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
 
        ret = qcom_scm_clk_enable();
        if (ret)
                return ret;
 
-       ret = __qcom_scm_pas_shutdown(__scm->dev, peripheral);
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
+
        qcom_scm_clk_disable();
 
-       return ret;
+       return ret ? : res.result[0];
 }
 EXPORT_SYMBOL(qcom_scm_pas_shutdown);
 
+/**
+ * qcom_scm_pas_supported() - Check if the peripheral authentication service is
+ *                           available for the given peripherial
+ * @peripheral:        peripheral id
+ *
+ * Returns true if PAS is supported for this peripheral, otherwise false.
+ */
+bool qcom_scm_pas_supported(u32 peripheral)
+{
+       int ret;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_PIL,
+               .cmd = QCOM_SCM_PIL_PAS_IS_SUPPORTED,
+               .arginfo = QCOM_SCM_ARGS(1),
+               .args[0] = peripheral,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+
+       ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_PIL,
+                                          QCOM_SCM_PIL_PAS_IS_SUPPORTED);
+       if (ret <= 0)
+               return false;
+
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+       return ret ? false : !!res.result[0];
+}
+EXPORT_SYMBOL(qcom_scm_pas_supported);
+
+static int __qcom_scm_pas_mss_reset(struct device *dev, bool reset)
+{
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_PIL,
+               .cmd = QCOM_SCM_PIL_PAS_MSS_RESET,
+               .arginfo = QCOM_SCM_ARGS(2),
+               .args[0] = reset,
+               .args[1] = 0,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+       int ret;
+
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
+
+       return ret ? : res.result[0];
+}
+
 static int qcom_scm_pas_reset_assert(struct reset_controller_dev *rcdev,
                                     unsigned long idx)
 {
@@ -367,6 +638,43 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = {
        .deassert = qcom_scm_pas_reset_deassert,
 };
 
+int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)
+{
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_IO,
+               .cmd = QCOM_SCM_IO_READ,
+               .arginfo = QCOM_SCM_ARGS(1),
+               .args[0] = addr,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+       int ret;
+
+
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
+       if (ret >= 0)
+               *val = res.result[0];
+
+       return ret < 0 ? ret : 0;
+}
+EXPORT_SYMBOL(qcom_scm_io_readl);
+
+int qcom_scm_io_writel(phys_addr_t addr, unsigned int val)
+{
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_IO,
+               .cmd = QCOM_SCM_IO_WRITE,
+               .arginfo = QCOM_SCM_ARGS(2),
+               .args[0] = addr,
+               .args[1] = val,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+
+
+       return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL(qcom_scm_io_writel);
+
 /**
  * qcom_scm_restore_sec_cfg_available() - Check if secure environment
  * supports restore security config interface.
@@ -376,108 +684,106 @@ static const struct reset_control_ops qcom_scm_pas_reset_ops = {
 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);
+                                           QCOM_SCM_MP_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);
-}
-EXPORT_SYMBOL(qcom_scm_restore_sec_cfg);
-
-int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)
-{
-       return __qcom_scm_iommu_secure_ptbl_size(__scm->dev, spare, size);
-}
-EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_size);
-
-int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
-{
-       return __qcom_scm_iommu_secure_ptbl_init(__scm->dev, addr, size, spare);
-}
-EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_MP,
+               .cmd = QCOM_SCM_MP_RESTORE_SEC_CFG,
+               .arginfo = QCOM_SCM_ARGS(2),
+               .args[0] = device_id,
+               .args[1] = spare,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+       int ret;
 
-int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
-{
-       return __qcom_scm_qsmmu500_wait_safe_toggle(__scm->dev, en);
-}
-EXPORT_SYMBOL(qcom_scm_qsmmu500_wait_safe_toggle);
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
 
-int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)
-{
-       return __qcom_scm_io_readl(__scm->dev, addr, val);
+       return ret ? : res.result[0];
 }
-EXPORT_SYMBOL(qcom_scm_io_readl);
+EXPORT_SYMBOL(qcom_scm_restore_sec_cfg);
 
-int qcom_scm_io_writel(phys_addr_t addr, unsigned int val)
+int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)
 {
-       return __qcom_scm_io_writel(__scm->dev, addr, val);
-}
-EXPORT_SYMBOL(qcom_scm_io_writel);
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_MP,
+               .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE,
+               .arginfo = QCOM_SCM_ARGS(1),
+               .args[0] = spare,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+       int ret;
 
-static void qcom_scm_set_download_mode(bool enable)
-{
-       bool avail;
-       int ret = 0;
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
 
-       avail = __qcom_scm_is_call_available(__scm->dev,
-                                            QCOM_SCM_SVC_BOOT,
-                                            QCOM_SCM_SET_DLOAD_MODE);
-       if (avail) {
-               ret = __qcom_scm_set_dload_mode(__scm->dev, enable);
-       } else if (__scm->dload_mode_addr) {
-               ret = __qcom_scm_io_writel(__scm->dev, __scm->dload_mode_addr,
-                                          enable ? QCOM_SCM_SET_DLOAD_MODE : 0);
-       } else {
-               dev_err(__scm->dev,
-                       "No available mechanism for setting download mode\n");
-       }
+       if (size)
+               *size = res.result[0];
 
-       if (ret)
-               dev_err(__scm->dev, "failed to set download mode: %d\n", ret);
+       return ret ? : res.result[1];
 }
+EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_size);
 
-static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
+int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
 {
-       struct device_node *tcsr;
-       struct device_node *np = dev->of_node;
-       struct resource res;
-       u32 offset;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_MP,
+               .cmd = QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT,
+               .arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL,
+                                        QCOM_SCM_VAL),
+               .args[0] = addr,
+               .args[1] = size,
+               .args[2] = spare,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
        int ret;
 
-       tcsr = of_parse_phandle(np, "qcom,dload-mode", 0);
-       if (!tcsr)
-               return 0;
-
-       ret = of_address_to_resource(tcsr, 0, &res);
-       of_node_put(tcsr);
-       if (ret)
-               return ret;
-
-       ret = of_property_read_u32_index(np, "qcom,dload-mode", 1, &offset);
-       if (ret < 0)
-               return ret;
+       desc.args[0] = addr;
+       desc.args[1] = size;
+       desc.args[2] = spare;
+       desc.arginfo = QCOM_SCM_ARGS(3, QCOM_SCM_RW, QCOM_SCM_VAL,
+                                    QCOM_SCM_VAL);
 
-       *addr = res.start + offset;
+       ret = qcom_scm_call(__scm->dev, &desc, NULL);
 
-       return 0;
-}
+       /* the pg table has been initialized already, ignore the error */
+       if (ret == -EPERM)
+               ret = 0;
 
-/**
- * qcom_scm_is_available() - Checks if SCM is available
- */
-bool qcom_scm_is_available(void)
-{
-       return !!__scm;
+       return ret;
 }
-EXPORT_SYMBOL(qcom_scm_is_available);
+EXPORT_SYMBOL(qcom_scm_iommu_secure_ptbl_init);
 
-int qcom_scm_set_remote_state(u32 state, u32 id)
+static int __qcom_scm_assign_mem(struct device *dev, phys_addr_t mem_region,
+                                size_t mem_sz, phys_addr_t src, size_t src_sz,
+                                phys_addr_t dest, size_t dest_sz)
 {
-       return __qcom_scm_set_remote_state(__scm->dev, state, id);
+       int ret;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_MP,
+               .cmd = QCOM_SCM_MP_ASSIGN,
+               .arginfo = QCOM_SCM_ARGS(7, QCOM_SCM_RO, QCOM_SCM_VAL,
+                                        QCOM_SCM_RO, QCOM_SCM_VAL, QCOM_SCM_RO,
+                                        QCOM_SCM_VAL, QCOM_SCM_VAL),
+               .args[0] = mem_region,
+               .args[1] = mem_sz,
+               .args[2] = src,
+               .args[3] = src_sz,
+               .args[4] = dest,
+               .args[5] = dest_sz,
+               .args[6] = 0,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+
+       ret = qcom_scm_call(dev, &desc, &res);
+
+       return ret ? : res.result[0];
 }
-EXPORT_SYMBOL(qcom_scm_set_remote_state);
 
 /**
  * qcom_scm_assign_mem() - Make a secure call to reassign memory ownership
@@ -561,6 +867,184 @@ int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
 }
 EXPORT_SYMBOL(qcom_scm_assign_mem);
 
+/**
+ * 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_SVC_OCMEM,
+                                           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)
+{
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_OCMEM,
+               .cmd = QCOM_SCM_OCMEM_LOCK_CMD,
+               .args[0] = id,
+               .args[1] = offset,
+               .args[2] = size,
+               .args[3] = mode,
+               .arginfo = QCOM_SCM_ARGS(4),
+       };
+
+       return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+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)
+{
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_OCMEM,
+               .cmd = QCOM_SCM_OCMEM_UNLOCK_CMD,
+               .args[0] = id,
+               .args[1] = offset,
+               .args[2] = size,
+               .arginfo = QCOM_SCM_ARGS(3),
+       };
+
+       return qcom_scm_call(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL(qcom_scm_ocmem_unlock);
+
+/**
+ * qcom_scm_hdcp_available() - Check if secure environment supports HDCP.
+ *
+ * Return true if HDCP is supported, false if not.
+ */
+bool qcom_scm_hdcp_available(void)
+{
+       int ret = qcom_scm_clk_enable();
+
+       if (ret)
+               return ret;
+
+       ret = __qcom_scm_is_call_available(__scm->dev, QCOM_SCM_SVC_HDCP,
+                                               QCOM_SCM_HDCP_INVOKE);
+
+       qcom_scm_clk_disable();
+
+       return ret > 0 ? true : false;
+}
+EXPORT_SYMBOL(qcom_scm_hdcp_available);
+
+/**
+ * qcom_scm_hdcp_req() - Send HDCP request.
+ * @req: HDCP request array
+ * @req_cnt: HDCP request array count
+ * @resp: response buffer passed to SCM
+ *
+ * Write HDCP register(s) through SCM.
+ */
+int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp)
+{
+       int ret;
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_HDCP,
+               .cmd = QCOM_SCM_HDCP_INVOKE,
+               .arginfo = QCOM_SCM_ARGS(10),
+               .args = {
+                       req[0].addr,
+                       req[0].val,
+                       req[1].addr,
+                       req[1].val,
+                       req[2].addr,
+                       req[2].val,
+                       req[3].addr,
+                       req[3].val,
+                       req[4].addr,
+                       req[4].val
+               },
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+       struct qcom_scm_res res;
+
+       if (req_cnt > QCOM_SCM_HDCP_MAX_REQ_CNT)
+               return -ERANGE;
+
+       ret = qcom_scm_clk_enable();
+       if (ret)
+               return ret;
+
+       ret = qcom_scm_call(__scm->dev, &desc, &res);
+       *resp = res.result[0];
+
+       qcom_scm_clk_disable();
+
+       return ret;
+}
+EXPORT_SYMBOL(qcom_scm_hdcp_req);
+
+int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
+{
+       struct qcom_scm_desc desc = {
+               .svc = QCOM_SCM_SVC_SMMU_PROGRAM,
+               .cmd = QCOM_SCM_SMMU_CONFIG_ERRATA1,
+               .arginfo = QCOM_SCM_ARGS(2),
+               .args[0] = QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL,
+               .args[1] = en,
+               .owner = ARM_SMCCC_OWNER_SIP,
+       };
+
+
+       return qcom_scm_call_atomic(__scm->dev, &desc, NULL);
+}
+EXPORT_SYMBOL(qcom_scm_qsmmu500_wait_safe_toggle);
+
+static int qcom_scm_find_dload_address(struct device *dev, u64 *addr)
+{
+       struct device_node *tcsr;
+       struct device_node *np = dev->of_node;
+       struct resource res;
+       u32 offset;
+       int ret;
+
+       tcsr = of_parse_phandle(np, "qcom,dload-mode", 0);
+       if (!tcsr)
+               return 0;
+
+       ret = of_address_to_resource(tcsr, 0, &res);
+       of_node_put(tcsr);
+       if (ret)
+               return ret;
+
+       ret = of_property_read_u32_index(np, "qcom,dload-mode", 1, &offset);
+       if (ret < 0)
+               return ret;
+
+       *addr = res.start + offset;
+
+       return 0;
+}
+
+/**
+ * qcom_scm_is_available() - Checks if SCM is available
+ */
+bool qcom_scm_is_available(void)
+{
+       return !!__scm;
+}
+EXPORT_SYMBOL(qcom_scm_is_available);
+
 static int qcom_scm_probe(struct platform_device *pdev)
 {
        struct qcom_scm *scm;
@@ -631,7 +1115,7 @@ static int qcom_scm_probe(struct platform_device *pdev)
        __scm = scm;
        __scm->dev = &pdev->dev;
 
-       __qcom_scm_init();
+       __query_convention();
 
        /*
         * If requested enable "download mode", from this point on warmboot
index 81dcf5f..d9ed670 100644 (file)
 /* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2010-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2015,2019 The Linux Foundation. All rights reserved.
  */
 #ifndef __QCOM_SCM_INT_H
 #define __QCOM_SCM_INT_H
 
-#define QCOM_SCM_SVC_BOOT              0x1
-#define QCOM_SCM_BOOT_ADDR             0x1
-#define QCOM_SCM_SET_DLOAD_MODE                0x10
-#define QCOM_SCM_BOOT_ADDR_MC          0x11
-#define QCOM_SCM_SET_REMOTE_STATE      0xa
-extern int __qcom_scm_set_remote_state(struct device *dev, u32 state, u32 id);
-extern int __qcom_scm_set_dload_mode(struct device *dev, bool enable);
-
-#define QCOM_SCM_FLAG_HLOS             0x01
-#define QCOM_SCM_FLAG_COLDBOOT_MC      0x02
-#define QCOM_SCM_FLAG_WARMBOOT_MC      0x04
-extern int __qcom_scm_set_warm_boot_addr(struct device *dev, void *entry,
-               const cpumask_t *cpus);
-extern int __qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
-
-#define QCOM_SCM_CMD_TERMINATE_PC      0x2
+enum qcom_scm_convention {
+       SMC_CONVENTION_UNKNOWN,
+       SMC_CONVENTION_LEGACY,
+       SMC_CONVENTION_ARM_32,
+       SMC_CONVENTION_ARM_64,
+};
+
+extern enum qcom_scm_convention qcom_scm_convention;
+
+#define MAX_QCOM_SCM_ARGS 10
+#define MAX_QCOM_SCM_RETS 3
+
+enum qcom_scm_arg_types {
+       QCOM_SCM_VAL,
+       QCOM_SCM_RO,
+       QCOM_SCM_RW,
+       QCOM_SCM_BUFVAL,
+};
+
+#define QCOM_SCM_ARGS_IMPL(num, a, b, c, d, e, f, g, h, i, j, ...) (\
+                          (((a) & 0x3) << 4) | \
+                          (((b) & 0x3) << 6) | \
+                          (((c) & 0x3) << 8) | \
+                          (((d) & 0x3) << 10) | \
+                          (((e) & 0x3) << 12) | \
+                          (((f) & 0x3) << 14) | \
+                          (((g) & 0x3) << 16) | \
+                          (((h) & 0x3) << 18) | \
+                          (((i) & 0x3) << 20) | \
+                          (((j) & 0x3) << 22) | \
+                          ((num) & 0xf))
+
+#define QCOM_SCM_ARGS(...) QCOM_SCM_ARGS_IMPL(__VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
+
+
+/**
+ * struct qcom_scm_desc
+ * @arginfo:   Metadata describing the arguments in args[]
+ * @args:      The array of arguments for the secure syscall
+ */
+struct qcom_scm_desc {
+       u32 svc;
+       u32 cmd;
+       u32 arginfo;
+       u64 args[MAX_QCOM_SCM_ARGS];
+       u32 owner;
+};
+
+/**
+ * struct qcom_scm_res
+ * @result:    The values returned by the secure syscall
+ */
+struct qcom_scm_res {
+       u64 result[MAX_QCOM_SCM_RETS];
+};
+
+#define SCM_SMC_FNID(s, c)     ((((s) & 0xFF) << 8) | ((c) & 0xFF))
+extern int scm_smc_call(struct device *dev, const struct qcom_scm_desc *desc,
+                       struct qcom_scm_res *res, bool atomic);
+
+#define SCM_LEGACY_FNID(s, c)  (((s) << 10) | ((c) & 0x3ff))
+extern int scm_legacy_call_atomic(struct device *dev,
+                                 const struct qcom_scm_desc *desc,
+                                 struct qcom_scm_res *res);
+extern int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc,
+                          struct qcom_scm_res *res);
+
+#define QCOM_SCM_SVC_BOOT              0x01
+#define QCOM_SCM_BOOT_SET_ADDR         0x01
+#define QCOM_SCM_BOOT_TERMINATE_PC     0x02
+#define QCOM_SCM_BOOT_SET_DLOAD_MODE   0x10
+#define QCOM_SCM_BOOT_SET_REMOTE_STATE 0x0a
 #define QCOM_SCM_FLUSH_FLAG_MASK       0x3
-#define QCOM_SCM_CMD_CORE_HOTPLUGGED   0x10
-extern void __qcom_scm_cpu_power_down(u32 flags);
 
-#define QCOM_SCM_SVC_IO                        0x5
-#define QCOM_SCM_IO_READ               0x1
-#define QCOM_SCM_IO_WRITE              0x2
-extern int __qcom_scm_io_readl(struct device *dev, phys_addr_t addr, unsigned int *val);
-extern int __qcom_scm_io_writel(struct device *dev, phys_addr_t addr, unsigned int val);
+#define QCOM_SCM_SVC_PIL               0x02
+#define QCOM_SCM_PIL_PAS_INIT_IMAGE    0x01
+#define QCOM_SCM_PIL_PAS_MEM_SETUP     0x02
+#define QCOM_SCM_PIL_PAS_AUTH_AND_RESET        0x05
+#define QCOM_SCM_PIL_PAS_SHUTDOWN      0x06
+#define QCOM_SCM_PIL_PAS_IS_SUPPORTED  0x07
+#define QCOM_SCM_PIL_PAS_MSS_RESET     0x0a
+
+#define QCOM_SCM_SVC_IO                        0x05
+#define QCOM_SCM_IO_READ               0x01
+#define QCOM_SCM_IO_WRITE              0x02
+
+#define QCOM_SCM_SVC_INFO              0x06
+#define QCOM_SCM_INFO_IS_CALL_AVAIL    0x01
 
-#define QCOM_SCM_SVC_INFO              0x6
-#define QCOM_IS_CALL_AVAIL_CMD         0x1
-extern int __qcom_scm_is_call_available(struct device *dev, u32 svc_id,
-               u32 cmd_id);
+#define QCOM_SCM_SVC_MP                                0x0c
+#define QCOM_SCM_MP_RESTORE_SEC_CFG            0x02
+#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_SIZE     0x03
+#define QCOM_SCM_MP_IOMMU_SECURE_PTBL_INIT     0x04
+#define QCOM_SCM_MP_ASSIGN                     0x16
+
+#define QCOM_SCM_SVC_OCMEM             0x0f
+#define QCOM_SCM_OCMEM_LOCK_CMD                0x01
+#define QCOM_SCM_OCMEM_UNLOCK_CMD      0x02
 
 #define QCOM_SCM_SVC_HDCP              0x11
-#define QCOM_SCM_CMD_HDCP              0x01
-extern int __qcom_scm_hdcp_req(struct device *dev,
-               struct qcom_scm_hdcp_req *req, u32 req_cnt, u32 *resp);
+#define QCOM_SCM_HDCP_INVOKE           0x01
 
-extern void __qcom_scm_init(void);
+#define QCOM_SCM_SVC_SMMU_PROGRAM              0x15
+#define QCOM_SCM_SMMU_CONFIG_ERRATA1           0x03
+#define QCOM_SCM_SMMU_CONFIG_ERRATA1_CLIENT_ALL        0x02
 
-#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
-#define QCOM_SCM_PAS_AUTH_AND_RESET_CMD        0x5
-#define QCOM_SCM_PAS_SHUTDOWN_CMD      0x6
-#define QCOM_SCM_PAS_IS_SUPPORTED_CMD  0x7
-#define QCOM_SCM_PAS_MSS_RESET         0xa
-extern bool __qcom_scm_pas_supported(struct device *dev, u32 peripheral);
-extern int  __qcom_scm_pas_init_image(struct device *dev, u32 peripheral,
-               dma_addr_t metadata_phys);
-extern int  __qcom_scm_pas_mem_setup(struct device *dev, u32 peripheral,
-               phys_addr_t addr, phys_addr_t size);
-extern int  __qcom_scm_pas_auth_and_reset(struct device *dev, u32 peripheral);
-extern int  __qcom_scm_pas_shutdown(struct device *dev, u32 peripheral);
-extern int  __qcom_scm_pas_mss_reset(struct device *dev, bool reset);
+extern void __qcom_scm_init(void);
 
 /* common error codes */
 #define QCOM_SCM_V2_EBUSY      -12
@@ -94,25 +139,4 @@ static inline int qcom_scm_remap_error(int err)
        return -EINVAL;
 }
 
-#define QCOM_SCM_SVC_MP                        0xc
-#define QCOM_SCM_RESTORE_SEC_CFG       2
-extern int __qcom_scm_restore_sec_cfg(struct device *dev, u32 device_id,
-                                     u32 spare);
-#define QCOM_SCM_IOMMU_SECURE_PTBL_SIZE        3
-#define QCOM_SCM_IOMMU_SECURE_PTBL_INIT        4
-#define QCOM_SCM_SVC_SMMU_PROGRAM      0x15
-#define QCOM_SCM_CONFIG_ERRATA1                0x3
-#define QCOM_SCM_CONFIG_ERRATA1_CLIENT_ALL     0x2
-extern int __qcom_scm_iommu_secure_ptbl_size(struct device *dev, u32 spare,
-                                            size_t *size);
-extern int __qcom_scm_iommu_secure_ptbl_init(struct device *dev, u64 addr,
-                                            u32 size, u32 spare);
-extern int __qcom_scm_qsmmu500_wait_safe_toggle(struct device *dev,
-                                               bool enable);
-#define QCOM_MEM_PROT_ASSIGN_ID        0x16
-extern int  __qcom_scm_assign_mem(struct device *dev,
-                                 phys_addr_t mem_region, size_t mem_sz,
-                                 phys_addr_t src, size_t src_sz,
-                                 phys_addr_t dest, size_t dest_sz);
-
 #endif
index 72be589..e27f684 100644 (file)
@@ -197,7 +197,7 @@ static int mox_get_board_info(struct mox_rwtm *rwtm)
                rwtm->serial_number = reply->status[1];
                rwtm->serial_number <<= 32;
                rwtm->serial_number |= reply->status[0];
-                       rwtm->board_version = reply->status[2];
+               rwtm->board_version = reply->status[2];
                rwtm->ram_size = reply->status[3];
                reply_to_mac_addr(rwtm->mac_address1, reply->status[4],
                                  reply->status[5]);
index 75bdfaa..ecc339d 100644 (file)
@@ -26,6 +26,9 @@
 
 static const struct zynqmp_eemi_ops *eemi_ops_tbl;
 
+static bool feature_check_enabled;
+static u32 zynqmp_pm_features[PM_API_MAX];
+
 static const struct mfd_cell firmware_devs[] = {
        {
                .name = "zynqmp_power_controller",
@@ -44,10 +47,14 @@ static int zynqmp_pm_ret_code(u32 ret_status)
        case XST_PM_SUCCESS:
        case XST_PM_DOUBLE_REQ:
                return 0;
+       case XST_PM_NO_FEATURE:
+               return -ENOTSUPP;
        case XST_PM_NO_ACCESS:
                return -EACCES;
        case XST_PM_ABORT_SUSPEND:
                return -ECANCELED;
+       case XST_PM_MULT_USER:
+               return -EUSERS;
        case XST_PM_INTERNAL:
        case XST_PM_CONFLICT:
        case XST_PM_INVALID_NODE:
@@ -127,6 +134,39 @@ static noinline int do_fw_call_hvc(u64 arg0, u64 arg1, u64 arg2,
 }
 
 /**
+ * zynqmp_pm_feature() - Check weather given feature is supported or not
+ * @api_id:            API ID to check
+ *
+ * Return: Returns status, either success or error+reason
+ */
+static int zynqmp_pm_feature(u32 api_id)
+{
+       int ret;
+       u32 ret_payload[PAYLOAD_ARG_CNT];
+       u64 smc_arg[2];
+
+       if (!feature_check_enabled)
+               return 0;
+
+       /* Return value if feature is already checked */
+       if (zynqmp_pm_features[api_id] != PM_FEATURE_UNCHECKED)
+               return zynqmp_pm_features[api_id];
+
+       smc_arg[0] = PM_SIP_SVC | PM_FEATURE_CHECK;
+       smc_arg[1] = api_id;
+
+       ret = do_fw_call(smc_arg[0], smc_arg[1], 0, ret_payload);
+       if (ret) {
+               zynqmp_pm_features[api_id] = PM_FEATURE_INVALID;
+               return PM_FEATURE_INVALID;
+       }
+
+       zynqmp_pm_features[api_id] = ret_payload[1];
+
+       return zynqmp_pm_features[api_id];
+}
+
+/**
  * zynqmp_pm_invoke_fn() - Invoke the system-level platform management layer
  *                        caller function depending on the configuration
  * @pm_api_id:         Requested PM-API call
@@ -160,6 +200,9 @@ int zynqmp_pm_invoke_fn(u32 pm_api_id, u32 arg0, u32 arg1,
         */
        u64 smc_arg[4];
 
+       if (zynqmp_pm_feature(pm_api_id) == PM_FEATURE_INVALID)
+               return -ENOTSUPP;
+
        smc_arg[0] = PM_SIP_SVC | pm_api_id;
        smc_arg[1] = ((u64)arg1 << 32) | arg0;
        smc_arg[2] = ((u64)arg3 << 32) | arg2;
@@ -715,6 +758,8 @@ static int zynqmp_firmware_probe(struct platform_device *pdev)
                np = of_find_compatible_node(NULL, NULL, "xlnx,versal");
                if (!np)
                        return 0;
+
+               feature_check_enabled = true;
        }
        of_node_put(np);
 
index b585f2e..b8013cf 100644 (file)
@@ -1035,6 +1035,18 @@ config GPIO_BD70528
          This driver can also be built as a module. If so, the module
          will be called gpio-bd70528.
 
+config GPIO_BD71828
+       tristate "ROHM BD71828 GPIO support"
+       depends on MFD_ROHM_BD71828
+       help
+         Support for GPIOs on ROHM BD71828 PMIC. There are three GPIOs
+         available on the ROHM PMIC in total. The GPIOs are limited to
+         outputs only and pins must be configured to GPIO outputs by
+         OTP. Enable this only if you want to use these pins as outputs.
+
+         This driver can also be built as a module. If so, the module
+         will be called gpio-bd71828.
+
 config GPIO_BD9571MWV
        tristate "ROHM BD9571 GPIO support"
        depends on MFD_BD9571MWV
index 76ff2a5..0b57126 100644 (file)
@@ -37,6 +37,7 @@ obj-$(CONFIG_GPIO_ATH79)              += gpio-ath79.o
 obj-$(CONFIG_GPIO_BCM_KONA)            += gpio-bcm-kona.o
 obj-$(CONFIG_GPIO_BCM_XGS_IPROC)       += gpio-xgs-iproc.o
 obj-$(CONFIG_GPIO_BD70528)             += gpio-bd70528.o
+obj-$(CONFIG_GPIO_BD71828)             += gpio-bd71828.o
 obj-$(CONFIG_GPIO_BD9571MWV)           += gpio-bd9571mwv.o
 obj-$(CONFIG_GPIO_BRCMSTB)             += gpio-brcmstb.o
 obj-$(CONFIG_GPIO_BT8XX)               += gpio-bt8xx.o
diff --git a/drivers/gpio/gpio-bd71828.c b/drivers/gpio/gpio-bd71828.c
new file mode 100644 (file)
index 0000000..04aade9
--- /dev/null
@@ -0,0 +1,159 @@
+// SPDX-License-Identifier: GPL-2.0-only
+// Copyright (C) 2018 ROHM Semiconductors
+
+#include <linux/gpio/driver.h>
+#include <linux/mfd/rohm-bd71828.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+#define GPIO_OUT_REG(off) (BD71828_REG_GPIO_CTRL1 + (off))
+#define HALL_GPIO_OFFSET 3
+
+/*
+ * These defines can be removed when
+ * "gpio: Add definition for GPIO direction"
+ * (9208b1e77d6e8e9776f34f46ef4079ecac9c3c25 in GPIO tree) gets merged,
+ */
+#ifndef GPIO_LINE_DIRECTION_IN
+       #define GPIO_LINE_DIRECTION_IN 1
+       #define GPIO_LINE_DIRECTION_OUT 0
+#endif
+
+struct bd71828_gpio {
+       struct rohm_regmap_dev chip;
+       struct gpio_chip gpio;
+};
+
+static void bd71828_gpio_set(struct gpio_chip *chip, unsigned int offset,
+                            int value)
+{
+       int ret;
+       struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
+       u8 val = (value) ? BD71828_GPIO_OUT_HI : BD71828_GPIO_OUT_LO;
+
+       /*
+        * The HALL input pin can only be used as input. If this is the pin
+        * we are dealing with - then we are done
+        */
+       if (offset == HALL_GPIO_OFFSET)
+               return;
+
+       ret = regmap_update_bits(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
+                                BD71828_GPIO_OUT_MASK, val);
+       if (ret)
+               dev_err(bdgpio->chip.dev, "Could not set gpio to %d\n", value);
+}
+
+static int bd71828_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+       int ret;
+       unsigned int val;
+       struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
+
+       if (offset == HALL_GPIO_OFFSET)
+               ret = regmap_read(bdgpio->chip.regmap, BD71828_REG_IO_STAT,
+                                 &val);
+       else
+               ret = regmap_read(bdgpio->chip.regmap, GPIO_OUT_REG(offset),
+                                 &val);
+       if (!ret)
+               ret = (val & BD71828_GPIO_OUT_MASK);
+
+       return ret;
+}
+
+static int bd71828_gpio_set_config(struct gpio_chip *chip, unsigned int offset,
+                                  unsigned long config)
+{
+       struct bd71828_gpio *bdgpio = gpiochip_get_data(chip);
+
+       if (offset == HALL_GPIO_OFFSET)
+               return -ENOTSUPP;
+
+       switch (pinconf_to_config_param(config)) {
+       case PIN_CONFIG_DRIVE_OPEN_DRAIN:
+               return regmap_update_bits(bdgpio->chip.regmap,
+                                         GPIO_OUT_REG(offset),
+                                         BD71828_GPIO_DRIVE_MASK,
+                                         BD71828_GPIO_OPEN_DRAIN);
+       case PIN_CONFIG_DRIVE_PUSH_PULL:
+               return regmap_update_bits(bdgpio->chip.regmap,
+                                         GPIO_OUT_REG(offset),
+                                         BD71828_GPIO_DRIVE_MASK,
+                                         BD71828_GPIO_PUSH_PULL);
+       default:
+               break;
+       }
+       return -ENOTSUPP;
+}
+
+static int bd71828_get_direction(struct gpio_chip *chip, unsigned int offset)
+{
+       /*
+        * Pin usage is selected by OTP data. We can't read it runtime. Hence
+        * we trust that if the pin is not excluded by "gpio-reserved-ranges"
+        * the OTP configuration is set to OUT. (Other pins but HALL input pin
+        * on BD71828 can't really be used for general purpose input - input
+        * states are used for specific cases like regulator control or
+        * PMIC_ON_REQ.
+        */
+       if (offset == HALL_GPIO_OFFSET)
+               return GPIO_LINE_DIRECTION_IN;
+
+       return GPIO_LINE_DIRECTION_OUT;
+}
+
+static int bd71828_probe(struct platform_device *pdev)
+{
+       struct bd71828_gpio *bdgpio;
+       struct rohm_regmap_dev *bd71828;
+
+       bd71828 = dev_get_drvdata(pdev->dev.parent);
+       if (!bd71828) {
+               dev_err(&pdev->dev, "No MFD driver data\n");
+               return -EINVAL;
+       }
+
+       bdgpio = devm_kzalloc(&pdev->dev, sizeof(*bdgpio),
+                             GFP_KERNEL);
+       if (!bdgpio)
+               return -ENOMEM;
+
+       bdgpio->chip.dev = &pdev->dev;
+       bdgpio->gpio.parent = pdev->dev.parent;
+       bdgpio->gpio.label = "bd71828-gpio";
+       bdgpio->gpio.owner = THIS_MODULE;
+       bdgpio->gpio.get_direction = bd71828_get_direction;
+       bdgpio->gpio.set_config = bd71828_gpio_set_config;
+       bdgpio->gpio.can_sleep = true;
+       bdgpio->gpio.get = bd71828_gpio_get;
+       bdgpio->gpio.set = bd71828_gpio_set;
+       bdgpio->gpio.base = -1;
+
+       /*
+        * See if we need some implementation to mark some PINs as
+        * not controllable based on DT info or if core can handle
+        * "gpio-reserved-ranges" and exclude them from control
+        */
+       bdgpio->gpio.ngpio = 4;
+       bdgpio->gpio.of_node = pdev->dev.parent->of_node;
+       bdgpio->chip.regmap = bd71828->regmap;
+
+       return devm_gpiochip_add_data(&pdev->dev, &bdgpio->gpio,
+                                    bdgpio);
+}
+
+static struct platform_driver bd71828_gpio = {
+       .driver = {
+               .name = "bd71828-gpio"
+       },
+       .probe = bd71828_probe,
+};
+
+module_platform_driver(bd71828_gpio);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("BD71828 voltage regulator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:bd71828-gpio");
index 4421be0..72b6001 100644 (file)
@@ -308,7 +308,7 @@ devm_gpiod_get_array_optional(struct device *dev, const char *con_id,
        struct gpio_descs *descs;
 
        descs = devm_gpiod_get_array(dev, con_id, flags);
-       if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT))
+       if (PTR_ERR(descs) == -ENOENT)
                return NULL;
 
        return descs;
index 1b3f217..c6d30f7 100644 (file)
@@ -484,24 +484,24 @@ struct gpio_desc *of_find_gpio(struct device *dev, const char *con_id,
                        break;
        }
 
-       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
+       if (PTR_ERR(desc) == -ENOENT) {
                /* Special handling for SPI GPIOs if used */
                desc = of_find_spi_gpio(dev, con_id, &of_flags);
        }
 
-       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
+       if (PTR_ERR(desc) == -ENOENT) {
                /* This quirk looks up flags and all */
                desc = of_find_spi_cs_gpio(dev, con_id, idx, flags);
                if (!IS_ERR(desc))
                        return desc;
        }
 
-       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT) {
+       if (PTR_ERR(desc) == -ENOENT) {
                /* Special handling for regulator GPIOs if used */
                desc = of_find_regulator_gpio(dev, con_id, &of_flags);
        }
 
-       if (IS_ERR(desc) && PTR_ERR(desc) == -ENOENT)
+       if (PTR_ERR(desc) == -ENOENT)
                desc = of_find_arizona_gpio(dev, con_id, &of_flags);
 
        if (IS_ERR(desc))
index 99ac27a..7532834 100644 (file)
@@ -5039,7 +5039,7 @@ struct gpio_descs *__must_check gpiod_get_array_optional(struct device *dev,
        struct gpio_descs *descs;
 
        descs = gpiod_get_array(dev, con_id, flags);
-       if (IS_ERR(descs) && (PTR_ERR(descs) == -ENOENT))
+       if (PTR_ERR(descs) == -ENOENT)
                return NULL;
 
        return descs;
index 7ae3b22..c2bbcdd 100644 (file)
@@ -120,6 +120,7 @@ amdgpu-y += \
        amdgpu_rlc.o \
        gfx_v8_0.o \
        gfx_v9_0.o \
+       gfx_v9_4.o \
        gfx_v10_0.o
 
 # add async DMA block
index b1bb106..da3bcff 100644 (file)
@@ -1009,10 +1009,14 @@ int emu_soc_asic_init(struct amdgpu_device *adev);
 
 #define AMDGPU_REGS_IDX       (1<<0)
 #define AMDGPU_REGS_NO_KIQ    (1<<1)
+#define AMDGPU_REGS_KIQ       (1<<2)
 
 #define RREG32_NO_KIQ(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_NO_KIQ)
 #define WREG32_NO_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_NO_KIQ)
 
+#define RREG32_KIQ(reg) amdgpu_mm_rreg(adev, (reg), AMDGPU_REGS_KIQ)
+#define WREG32_KIQ(reg, v) amdgpu_mm_wreg(adev, (reg), (v), AMDGPU_REGS_KIQ)
+
 #define RREG8(reg) amdgpu_mm_rreg8(adev, (reg))
 #define WREG8(reg, v) amdgpu_mm_wreg8(adev, (reg), (v))
 
index 82155ac..12247a3 100644 (file)
@@ -527,7 +527,7 @@ static int acp_set_powergating_state(void *handle,
                                     enum amd_powergating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = state == AMD_PG_STATE_GATE ? true : false;
+       bool enable = (state == AMD_PG_STATE_GATE);
 
        if (adev->powerplay.pp_funcs &&
                adev->powerplay.pp_funcs->set_powergating_by_smu)
index b2487f4..fa8ac9d 100644 (file)
@@ -2129,6 +2129,7 @@ int amdgpu_amdkfd_add_gws_to_process(void *info, void *gws, struct kgd_mem **mem
                return -ENOMEM;
 
        mutex_init(&(*mem)->lock);
+       INIT_LIST_HEAD(&(*mem)->bo_va_list);
        (*mem)->bo = amdgpu_bo_ref(gws_bo);
        (*mem)->domain = AMDGPU_GEM_DOMAIN_GWS;
        (*mem)->process_info = process_info;
index 64e2bab..94a6c42 100644 (file)
@@ -42,19 +42,12 @@ const unsigned int amdgpu_ctx_num_entities[AMDGPU_HW_IP_NUM] = {
        [AMDGPU_HW_IP_VCN_JPEG] =       1,
 };
 
-static int amdgpu_ctx_total_num_entities(void)
-{
-       unsigned i, num_entities = 0;
-
-       for (i = 0; i < AMDGPU_HW_IP_NUM; ++i)
-               num_entities += amdgpu_ctx_num_entities[i];
-
-       return num_entities;
-}
-
 static int amdgpu_ctx_priority_permit(struct drm_file *filp,
                                      enum drm_sched_priority priority)
 {
+       if (priority < 0 || priority >= DRM_SCHED_PRIORITY_MAX)
+               return -EINVAL;
+
        /* NORMAL and below are accessible by everyone */
        if (priority <= DRM_SCHED_PRIORITY_NORMAL)
                return 0;
@@ -68,64 +61,24 @@ static int amdgpu_ctx_priority_permit(struct drm_file *filp,
        return -EACCES;
 }
 
-static int amdgpu_ctx_init(struct amdgpu_device *adev,
-                          enum drm_sched_priority priority,
-                          struct drm_file *filp,
-                          struct amdgpu_ctx *ctx)
+static int amdgpu_ctx_init_entity(struct amdgpu_ctx *ctx, const u32 hw_ip, const u32 ring)
 {
-       unsigned num_entities = amdgpu_ctx_total_num_entities();
-       unsigned i, j;
+       struct amdgpu_device *adev = ctx->adev;
+       struct amdgpu_ctx_entity *entity;
+       struct drm_gpu_scheduler **scheds = NULL, *sched = NULL;
+       unsigned num_scheds = 0;
+       enum drm_sched_priority priority;
        int r;
 
-       if (priority < 0 || priority >= DRM_SCHED_PRIORITY_MAX)
-               return -EINVAL;
-
-       r = amdgpu_ctx_priority_permit(filp, priority);
-       if (r)
-               return r;
+       entity = kcalloc(1, offsetof(typeof(*entity), fences[amdgpu_sched_jobs]),
+                        GFP_KERNEL);
+       if (!entity)
+               return  -ENOMEM;
 
-       memset(ctx, 0, sizeof(*ctx));
-       ctx->adev = adev;
-
-       ctx->fences = kcalloc(amdgpu_sched_jobs * num_entities,
-                             sizeof(struct dma_fence*), GFP_KERNEL);
-       if (!ctx->fences)
-               return -ENOMEM;
-
-       ctx->entities[0] = kcalloc(num_entities,
-                                  sizeof(struct amdgpu_ctx_entity),
-                                  GFP_KERNEL);
-       if (!ctx->entities[0]) {
-               r = -ENOMEM;
-               goto error_free_fences;
-       }
-
-       for (i = 0; i < num_entities; ++i) {
-               struct amdgpu_ctx_entity *entity = &ctx->entities[0][i];
-
-               entity->sequence = 1;
-               entity->fences = &ctx->fences[amdgpu_sched_jobs * i];
-       }
-       for (i = 1; i < AMDGPU_HW_IP_NUM; ++i)
-               ctx->entities[i] = ctx->entities[i - 1] +
-                       amdgpu_ctx_num_entities[i - 1];
-
-       kref_init(&ctx->refcount);
-       spin_lock_init(&ctx->ring_lock);
-       mutex_init(&ctx->lock);
-
-       ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
-       ctx->reset_counter_query = ctx->reset_counter;
-       ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
-       ctx->init_priority = priority;
-       ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
-
-       for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
-               struct drm_gpu_scheduler **scheds;
-               struct drm_gpu_scheduler *sched;
-               unsigned num_scheds = 0;
-
-               switch (i) {
+       entity->sequence = 1;
+       priority = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
+                               ctx->init_priority : ctx->override_priority;
+       switch (hw_ip) {
                case AMDGPU_HW_IP_GFX:
                        sched = &adev->gfx.gfx_ring[0].sched;
                        scheds = &sched;
@@ -166,53 +119,90 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev,
                        scheds = adev->jpeg.jpeg_sched;
                        num_scheds =  adev->jpeg.num_jpeg_sched;
                        break;
-               }
-
-               for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j)
-                       r = drm_sched_entity_init(&ctx->entities[i][j].entity,
-                                                 priority, scheds,
-                                                 num_scheds, &ctx->guilty);
-               if (r)
-                       goto error_cleanup_entities;
        }
 
+       r = drm_sched_entity_init(&entity->entity, priority, scheds, num_scheds,
+                                 &ctx->guilty);
+       if (r)
+               goto error_free_entity;
+
+       ctx->entities[hw_ip][ring] = entity;
        return 0;
 
-error_cleanup_entities:
-       for (i = 0; i < num_entities; ++i)
-               drm_sched_entity_destroy(&ctx->entities[0][i].entity);
-       kfree(ctx->entities[0]);
+error_free_entity:
+       kfree(entity);
 
-error_free_fences:
-       kfree(ctx->fences);
-       ctx->fences = NULL;
        return r;
 }
 
+static int amdgpu_ctx_init(struct amdgpu_device *adev,
+                          enum drm_sched_priority priority,
+                          struct drm_file *filp,
+                          struct amdgpu_ctx *ctx)
+{
+       int r;
+
+       r = amdgpu_ctx_priority_permit(filp, priority);
+       if (r)
+               return r;
+
+       memset(ctx, 0, sizeof(*ctx));
+
+       ctx->adev = adev;
+
+       kref_init(&ctx->refcount);
+       spin_lock_init(&ctx->ring_lock);
+       mutex_init(&ctx->lock);
+
+       ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
+       ctx->reset_counter_query = ctx->reset_counter;
+       ctx->vram_lost_counter = atomic_read(&adev->vram_lost_counter);
+       ctx->init_priority = priority;
+       ctx->override_priority = DRM_SCHED_PRIORITY_UNSET;
+
+       return 0;
+
+}
+
+static void amdgpu_ctx_fini_entity(struct amdgpu_ctx_entity *entity)
+{
+
+       int i;
+
+       if (!entity)
+               return;
+
+       for (i = 0; i < amdgpu_sched_jobs; ++i)
+               dma_fence_put(entity->fences[i]);
+
+       kfree(entity);
+}
+
 static void amdgpu_ctx_fini(struct kref *ref)
 {
        struct amdgpu_ctx *ctx = container_of(ref, struct amdgpu_ctx, refcount);
-       unsigned num_entities = amdgpu_ctx_total_num_entities();
        struct amdgpu_device *adev = ctx->adev;
        unsigned i, j;
 
        if (!adev)
                return;
 
-       for (i = 0; i < num_entities; ++i)
-               for (j = 0; j < amdgpu_sched_jobs; ++j)
-                       dma_fence_put(ctx->entities[0][i].fences[j]);
-       kfree(ctx->fences);
-       kfree(ctx->entities[0]);
+       for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+               for (j = 0; j < AMDGPU_MAX_ENTITY_NUM; ++j) {
+                       amdgpu_ctx_fini_entity(ctx->entities[i][j]);
+                       ctx->entities[i][j] = NULL;
+               }
+       }
 
        mutex_destroy(&ctx->lock);
-
        kfree(ctx);
 }
 
 int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
                          u32 ring, struct drm_sched_entity **entity)
 {
+       int r;
+
        if (hw_ip >= AMDGPU_HW_IP_NUM) {
                DRM_ERROR("unknown HW IP type: %d\n", hw_ip);
                return -EINVAL;
@@ -229,7 +219,13 @@ int amdgpu_ctx_get_entity(struct amdgpu_ctx *ctx, u32 hw_ip, u32 instance,
                return -EINVAL;
        }
 
-       *entity = &ctx->entities[hw_ip][ring].entity;
+       if (ctx->entities[hw_ip][ring] == NULL) {
+               r = amdgpu_ctx_init_entity(ctx, hw_ip, ring);
+               if (r)
+                       return r;
+       }
+
+       *entity = &ctx->entities[hw_ip][ring]->entity;
        return 0;
 }
 
@@ -269,14 +265,17 @@ static int amdgpu_ctx_alloc(struct amdgpu_device *adev,
 static void amdgpu_ctx_do_release(struct kref *ref)
 {
        struct amdgpu_ctx *ctx;
-       unsigned num_entities;
-       u32 i;
+       u32 i, j;
 
        ctx = container_of(ref, struct amdgpu_ctx, refcount);
+       for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+               for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+                       if (!ctx->entities[i][j])
+                               continue;
 
-       num_entities = amdgpu_ctx_total_num_entities();
-       for (i = 0; i < num_entities; i++)
-               drm_sched_entity_destroy(&ctx->entities[0][i].entity);
+                       drm_sched_entity_destroy(&ctx->entities[i][j]->entity);
+               }
+       }
 
        amdgpu_ctx_fini(ref);
 }
@@ -506,19 +505,23 @@ struct dma_fence *amdgpu_ctx_get_fence(struct amdgpu_ctx *ctx,
 void amdgpu_ctx_priority_override(struct amdgpu_ctx *ctx,
                                  enum drm_sched_priority priority)
 {
-       unsigned num_entities = amdgpu_ctx_total_num_entities();
        enum drm_sched_priority ctx_prio;
-       unsigned i;
+       unsigned i, j;
 
        ctx->override_priority = priority;
 
        ctx_prio = (ctx->override_priority == DRM_SCHED_PRIORITY_UNSET) ?
                        ctx->init_priority : ctx->override_priority;
+       for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+               for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+                       struct drm_sched_entity *entity;
 
-       for (i = 0; i < num_entities; i++) {
-               struct drm_sched_entity *entity = &ctx->entities[0][i].entity;
+                       if (!ctx->entities[i][j])
+                               continue;
 
-               drm_sched_entity_set_priority(entity, ctx_prio);
+                       entity = &ctx->entities[i][j]->entity;
+                       drm_sched_entity_set_priority(entity, ctx_prio);
+               }
        }
 }
 
@@ -554,20 +557,24 @@ void amdgpu_ctx_mgr_init(struct amdgpu_ctx_mgr *mgr)
 
 long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout)
 {
-       unsigned num_entities = amdgpu_ctx_total_num_entities();
        struct amdgpu_ctx *ctx;
        struct idr *idp;
-       uint32_t id, i;
+       uint32_t id, i, j;
 
        idp = &mgr->ctx_handles;
 
        mutex_lock(&mgr->lock);
        idr_for_each_entry(idp, ctx, id) {
-               for (i = 0; i < num_entities; i++) {
-                       struct drm_sched_entity *entity;
+               for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+                       for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+                               struct drm_sched_entity *entity;
+
+                               if (!ctx->entities[i][j])
+                                       continue;
 
-                       entity = &ctx->entities[0][i].entity;
-                       timeout = drm_sched_entity_flush(entity, timeout);
+                               entity = &ctx->entities[i][j]->entity;
+                               timeout = drm_sched_entity_flush(entity, timeout);
+                       }
                }
        }
        mutex_unlock(&mgr->lock);
@@ -576,10 +583,9 @@ long amdgpu_ctx_mgr_entity_flush(struct amdgpu_ctx_mgr *mgr, long timeout)
 
 void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
 {
-       unsigned num_entities = amdgpu_ctx_total_num_entities();
        struct amdgpu_ctx *ctx;
        struct idr *idp;
-       uint32_t id, i;
+       uint32_t id, i, j;
 
        idp = &mgr->ctx_handles;
 
@@ -589,8 +595,17 @@ void amdgpu_ctx_mgr_entity_fini(struct amdgpu_ctx_mgr *mgr)
                        continue;
                }
 
-               for (i = 0; i < num_entities; i++)
-                       drm_sched_entity_fini(&ctx->entities[0][i].entity);
+               for (i = 0; i < AMDGPU_HW_IP_NUM; ++i) {
+                       for (j = 0; j < amdgpu_ctx_num_entities[i]; ++j) {
+                               struct drm_sched_entity *entity;
+
+                               if (!ctx->entities[i][j])
+                                       continue;
+
+                               entity = &ctx->entities[i][j]->entity;
+                               drm_sched_entity_fini(entity);
+                       }
+               }
        }
 }
 
index 4ad90a4..de490f1 100644 (file)
@@ -29,10 +29,12 @@ struct drm_device;
 struct drm_file;
 struct amdgpu_fpriv;
 
+#define AMDGPU_MAX_ENTITY_NUM 4
+
 struct amdgpu_ctx_entity {
        uint64_t                sequence;
-       struct dma_fence        **fences;
        struct drm_sched_entity entity;
+       struct dma_fence        *fences[];
 };
 
 struct amdgpu_ctx {
@@ -42,8 +44,7 @@ struct amdgpu_ctx {
        unsigned                        reset_counter_query;
        uint32_t                        vram_lost_counter;
        spinlock_t                      ring_lock;
-       struct dma_fence                **fences;
-       struct amdgpu_ctx_entity        *entities[AMDGPU_HW_IP_NUM];
+       struct amdgpu_ctx_entity        *entities[AMDGPU_HW_IP_NUM][AMDGPU_MAX_ENTITY_NUM];
        bool                            preamble_presented;
        enum drm_sched_priority         init_priority;
        enum drm_sched_priority         override_priority;
index 53d8820..39cd545 100644 (file)
@@ -216,8 +216,8 @@ uint32_t amdgpu_mm_rreg(struct amdgpu_device *adev, uint32_t reg,
 {
        uint32_t ret;
 
-       if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
-               return amdgpu_virt_kiq_rreg(adev, reg);
+       if ((acc_flags & AMDGPU_REGS_KIQ) || (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)))
+               return amdgpu_kiq_rreg(adev, reg);
 
        if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX))
                ret = readl(((void __iomem *)adev->rmmio) + (reg * 4));
@@ -294,8 +294,8 @@ void amdgpu_mm_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v,
                adev->last_mm_index = v;
        }
 
-       if (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev))
-               return amdgpu_virt_kiq_wreg(adev, reg, v);
+       if ((acc_flags & AMDGPU_REGS_KIQ) || (!(acc_flags & AMDGPU_REGS_NO_KIQ) && amdgpu_sriov_runtime(adev)))
+               return amdgpu_kiq_wreg(adev, reg, v);
 
        if ((reg * 4) < adev->rmmio_size && !(acc_flags & AMDGPU_REGS_IDX))
                writel(v, ((void __iomem *)adev->rmmio) + (reg * 4));
@@ -985,7 +985,7 @@ static void amdgpu_device_check_vm_size(struct amdgpu_device *adev)
 static void amdgpu_device_check_smu_prv_buffer_size(struct amdgpu_device *adev)
 {
        struct sysinfo si;
-       bool is_os_64 = (sizeof(void *) == 8) ? true : false;
+       bool is_os_64 = (sizeof(void *) == 8);
        uint64_t total_memory;
        uint64_t dram_size_seven_GB = 0x1B8000000;
        uint64_t dram_size_three_GB = 0xB8000000;
@@ -3760,6 +3760,10 @@ bool amdgpu_device_should_recover_gpu(struct amdgpu_device *adev)
                case CHIP_VEGA12:
                case CHIP_RAVEN:
                case CHIP_ARCTURUS:
+               case CHIP_RENOIR:
+               case CHIP_NAVI10:
+               case CHIP_NAVI14:
+               case CHIP_NAVI12:
                        break;
                default:
                        goto disabled;
index 61a26c1..057f6ea 100644 (file)
@@ -52,6 +52,9 @@ struct amdgpu_df_funcs {
        uint64_t (*get_fica)(struct amdgpu_device *adev, uint32_t ficaa_val);
        void (*set_fica)(struct amdgpu_device *adev, uint32_t ficaa_val,
                         uint32_t ficadl_val, uint32_t ficadh_val);
+       uint64_t (*get_dram_base_addr)(struct amdgpu_device *adev,
+                                      uint32_t df_inst);
+       uint32_t (*get_df_inst_id)(struct amdgpu_device *adev);
 };
 
 struct amdgpu_df {
index b88b8b8..0f960b4 100644 (file)
@@ -296,7 +296,7 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
 
        spin_lock_init(&kiq->ring_lock);
 
-       r = amdgpu_device_wb_get(adev, &adev->virt.reg_val_offs);
+       r = amdgpu_device_wb_get(adev, &kiq->reg_val_offs);
        if (r)
                return r;
 
@@ -321,7 +321,7 @@ int amdgpu_gfx_kiq_init_ring(struct amdgpu_device *adev,
 
 void amdgpu_gfx_kiq_free_ring(struct amdgpu_ring *ring)
 {
-       amdgpu_device_wb_free(ring->adev, ring->adev->virt.reg_val_offs);
+       amdgpu_device_wb_free(ring->adev, ring->adev->gfx.kiq.reg_val_offs);
        amdgpu_ring_fini(ring);
 }
 
@@ -658,3 +658,95 @@ int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
        amdgpu_ras_interrupt_dispatch(adev, &ih_data);
        return 0;
 }
+
+uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
+{
+       signed long r, cnt = 0;
+       unsigned long flags;
+       uint32_t seq;
+       struct amdgpu_kiq *kiq = &adev->gfx.kiq;
+       struct amdgpu_ring *ring = &kiq->ring;
+
+       BUG_ON(!ring->funcs->emit_rreg);
+
+       spin_lock_irqsave(&kiq->ring_lock, flags);
+       amdgpu_ring_alloc(ring, 32);
+       amdgpu_ring_emit_rreg(ring, reg);
+       amdgpu_fence_emit_polling(ring, &seq);
+       amdgpu_ring_commit(ring);
+       spin_unlock_irqrestore(&kiq->ring_lock, flags);
+
+       r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
+
+       /* don't wait anymore for gpu reset case because this way may
+        * block gpu_recover() routine forever, e.g. this virt_kiq_rreg
+        * is triggered in TTM and ttm_bo_lock_delayed_workqueue() will
+        * never return if we keep waiting in virt_kiq_rreg, which cause
+        * gpu_recover() hang there.
+        *
+        * also don't wait anymore for IRQ context
+        * */
+       if (r < 1 && (adev->in_gpu_reset || in_interrupt()))
+               goto failed_kiq_read;
+
+       might_sleep();
+       while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
+               msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
+               r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
+       }
+
+       if (cnt > MAX_KIQ_REG_TRY)
+               goto failed_kiq_read;
+
+       return adev->wb.wb[kiq->reg_val_offs];
+
+failed_kiq_read:
+       pr_err("failed to read reg:%x\n", reg);
+       return ~0;
+}
+
+void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
+{
+       signed long r, cnt = 0;
+       unsigned long flags;
+       uint32_t seq;
+       struct amdgpu_kiq *kiq = &adev->gfx.kiq;
+       struct amdgpu_ring *ring = &kiq->ring;
+
+       BUG_ON(!ring->funcs->emit_wreg);
+
+       spin_lock_irqsave(&kiq->ring_lock, flags);
+       amdgpu_ring_alloc(ring, 32);
+       amdgpu_ring_emit_wreg(ring, reg, v);
+       amdgpu_fence_emit_polling(ring, &seq);
+       amdgpu_ring_commit(ring);
+       spin_unlock_irqrestore(&kiq->ring_lock, flags);
+
+       r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
+
+       /* don't wait anymore for gpu reset case because this way may
+        * block gpu_recover() routine forever, e.g. this virt_kiq_rreg
+        * is triggered in TTM and ttm_bo_lock_delayed_workqueue() will
+        * never return if we keep waiting in virt_kiq_rreg, which cause
+        * gpu_recover() hang there.
+        *
+        * also don't wait anymore for IRQ context
+        * */
+       if (r < 1 && (adev->in_gpu_reset || in_interrupt()))
+               goto failed_kiq_write;
+
+       might_sleep();
+       while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
+
+               msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
+               r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
+       }
+
+       if (cnt > MAX_KIQ_REG_TRY)
+               goto failed_kiq_write;
+
+       return;
+
+failed_kiq_write:
+       pr_err("failed to write reg:%x\n", reg);
+}
index af4bd27..ca17ffb 100644 (file)
@@ -94,6 +94,7 @@ struct amdgpu_kiq {
        struct amdgpu_ring      ring;
        struct amdgpu_irq_src   irq;
        const struct kiq_pm4_funcs *pmf;
+       uint32_t                        reg_val_offs;
 };
 
 /*
@@ -375,4 +376,6 @@ int amdgpu_gfx_process_ras_data_cb(struct amdgpu_device *adev,
 int amdgpu_gfx_cp_ecc_error_irq(struct amdgpu_device *adev,
                                  struct amdgpu_irq_src *source,
                                  struct amdgpu_iv_entry *entry);
+uint32_t amdgpu_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
+void amdgpu_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
 #endif
index 86267ba..d3c27a3 100644 (file)
  */
 #define AMDGPU_GMC_FAULT_TIMEOUT       5000ULL
 
-/*
- * Default stolen memory size, 1024 * 768 * 4
- */
-#define AMDGPU_STOLEN_BIST_TRAINING_DEFAULT_SIZE       0x300000ULL
-
 struct firmware;
 
 /*
index 3265487..6110215 100644 (file)
@@ -172,6 +172,8 @@ struct psp_dtm_context {
 #define MEM_TRAIN_SYSTEM_SIGNATURE             0x54534942
 #define GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES  0x1000
 #define GDDR6_MEM_TRAINING_OFFSET              0x8000
+/*Define the VRAM size that will be encroached by BIST training.*/
+#define GDDR6_MEM_TRAINING_ENCROACHED_SIZE     0x2000000
 
 enum psp_memory_training_init_flag {
        PSP_MEM_TRAIN_NOT_SUPPORT       = 0x0,
index 766be7f..cef94e2 100644 (file)
@@ -742,6 +742,20 @@ int amdgpu_ras_error_query(struct amdgpu_device *adev,
        return 0;
 }
 
+uint64_t get_xgmi_relative_phy_addr(struct amdgpu_device *adev, uint64_t addr)
+{
+       uint32_t df_inst_id;
+
+       if ((!adev->df.funcs)                 ||
+           (!adev->df.funcs->get_df_inst_id) ||
+           (!adev->df.funcs->get_dram_base_addr))
+               return addr;
+
+       df_inst_id = adev->df.funcs->get_df_inst_id(adev);
+
+       return addr + adev->df.funcs->get_dram_base_addr(adev, df_inst_id);
+}
+
 /* wrapper of psp_ras_trigger_error */
 int amdgpu_ras_error_inject(struct amdgpu_device *adev,
                struct ras_inject_if *info)
@@ -759,6 +773,12 @@ int amdgpu_ras_error_inject(struct amdgpu_device *adev,
        if (!obj)
                return -EINVAL;
 
+       /* Calculate XGMI relative offset */
+       if (adev->gmc.xgmi.num_physical_nodes > 1) {
+               block_info.address = get_xgmi_relative_phy_addr(adev,
+                                                               block_info.address);
+       }
+
        switch (info->head.block) {
        case AMDGPU_RAS_BLOCK__GFX:
                if (adev->gfx.funcs->ras_error_inject)
index ceb0dbf..59ddba1 100644 (file)
@@ -652,7 +652,7 @@ static int amdgpu_vce_cs_reloc(struct amdgpu_cs_parser *p, uint32_t ib_idx,
 
        if ((addr + (uint64_t)size) >
            (mapping->last + 1) * AMDGPU_GPU_PAGE_SIZE) {
-               DRM_ERROR("BO to small for addr 0x%010Lx %d %d\n",
+               DRM_ERROR("BO too small for addr 0x%010Lx %d %d\n",
                          addr, lo, hi);
                return -EINVAL;
        }
index c4984c5..d6deb0e 100644 (file)
 /* 1 second timeout */
 #define VCN_IDLE_TIMEOUT       msecs_to_jiffies(1000)
 
-#define RREG32_SOC15_DPG_MODE(ip, inst, reg, mask, sram_sel)                           \
-       ({      WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_MASK, mask);                       \
-               WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_CTL,                               \
+#define RREG32_SOC15_DPG_MODE(ip, inst_idx, reg, mask, sram_sel)                       \
+       ({      WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_MASK, mask);                   \
+               WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_CTL,                           \
                        UVD_DPG_LMA_CTL__MASK_EN_MASK |                                 \
-                       ((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)      \
+                       ((adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg)  \
                        << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) |                   \
                        (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT));                \
-               RREG32_SOC15(ip, inst, mmUVD_DPG_LMA_DATA);                             \
+               RREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_DATA);                         \
        })
 
-#define WREG32_SOC15_DPG_MODE(ip, inst, reg, value, mask, sram_sel)                    \
+#define WREG32_SOC15_DPG_MODE(ip, inst_idx, reg, value, mask, sram_sel)                \
        do {                                                                            \
-               WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_DATA, value);                      \
-               WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_MASK, mask);                       \
-               WREG32_SOC15(ip, inst, mmUVD_DPG_LMA_CTL,                               \
+               WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_DATA, value);                  \
+               WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_MASK, mask);                   \
+               WREG32_SOC15(ip, inst_idx, mmUVD_DPG_LMA_CTL,                           \
                        UVD_DPG_LMA_CTL__READ_WRITE_MASK |                              \
-                       ((adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg)      \
+                       ((adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg)  \
                        << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT) |                   \
                        (sram_sel << UVD_DPG_LMA_CTL__SRAM_SEL__SHIFT));                \
        } while (0)
 
-#define SOC15_DPG_MODE_OFFSET_2_0(ip, inst, reg)                                               \
+#define SOC15_DPG_MODE_OFFSET_2_0(ip, inst_idx, reg)                                           \
        ({                                                                                      \
                uint32_t internal_reg_offset, addr;                                             \
                bool video_range, aon_range;                                                    \
                                                                                                \
-               addr = (adev->reg_offset[ip##_HWIP][inst][reg##_BASE_IDX] + reg);               \
+               addr = (adev->reg_offset[ip##_HWIP][inst_idx][reg##_BASE_IDX] + reg);           \
                addr <<= 2;                                                                     \
                video_range = ((((0xFFFFF & addr) >= (VCN_VID_SOC_ADDRESS_2_0)) &&              \
                                ((0xFFFFF & addr) < ((VCN_VID_SOC_ADDRESS_2_0 + 0x2600)))));    \
 
 #define RREG32_SOC15_DPG_MODE_2_0(inst_idx, offset, mask_en)                                   \
        ({                                                                                      \
-               WREG32_SOC15(VCN, inst, mmUVD_DPG_LMA_CTL,                                      \
+               WREG32_SOC15(VCN, inst_idx, mmUVD_DPG_LMA_CTL,                                  \
                        (0x0 << UVD_DPG_LMA_CTL__READ_WRITE__SHIFT |                            \
                        mask_en << UVD_DPG_LMA_CTL__MASK_EN__SHIFT |                            \
                        offset << UVD_DPG_LMA_CTL__READ_WRITE_ADDR__SHIFT));                    \
index 103033f..adc813c 100644 (file)
@@ -45,98 +45,6 @@ void amdgpu_virt_init_setting(struct amdgpu_device *adev)
        adev->pg_flags = 0;
 }
 
-uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg)
-{
-       signed long r, cnt = 0;
-       unsigned long flags;
-       uint32_t seq;
-       struct amdgpu_kiq *kiq = &adev->gfx.kiq;
-       struct amdgpu_ring *ring = &kiq->ring;
-
-       BUG_ON(!ring->funcs->emit_rreg);
-
-       spin_lock_irqsave(&kiq->ring_lock, flags);
-       amdgpu_ring_alloc(ring, 32);
-       amdgpu_ring_emit_rreg(ring, reg);
-       amdgpu_fence_emit_polling(ring, &seq);
-       amdgpu_ring_commit(ring);
-       spin_unlock_irqrestore(&kiq->ring_lock, flags);
-
-       r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
-
-       /* don't wait anymore for gpu reset case because this way may
-        * block gpu_recover() routine forever, e.g. this virt_kiq_rreg
-        * is triggered in TTM and ttm_bo_lock_delayed_workqueue() will
-        * never return if we keep waiting in virt_kiq_rreg, which cause
-        * gpu_recover() hang there.
-        *
-        * also don't wait anymore for IRQ context
-        * */
-       if (r < 1 && (adev->in_gpu_reset || in_interrupt()))
-               goto failed_kiq_read;
-
-       might_sleep();
-       while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
-               msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
-               r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
-       }
-
-       if (cnt > MAX_KIQ_REG_TRY)
-               goto failed_kiq_read;
-
-       return adev->wb.wb[adev->virt.reg_val_offs];
-
-failed_kiq_read:
-       pr_err("failed to read reg:%x\n", reg);
-       return ~0;
-}
-
-void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v)
-{
-       signed long r, cnt = 0;
-       unsigned long flags;
-       uint32_t seq;
-       struct amdgpu_kiq *kiq = &adev->gfx.kiq;
-       struct amdgpu_ring *ring = &kiq->ring;
-
-       BUG_ON(!ring->funcs->emit_wreg);
-
-       spin_lock_irqsave(&kiq->ring_lock, flags);
-       amdgpu_ring_alloc(ring, 32);
-       amdgpu_ring_emit_wreg(ring, reg, v);
-       amdgpu_fence_emit_polling(ring, &seq);
-       amdgpu_ring_commit(ring);
-       spin_unlock_irqrestore(&kiq->ring_lock, flags);
-
-       r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
-
-       /* don't wait anymore for gpu reset case because this way may
-        * block gpu_recover() routine forever, e.g. this virt_kiq_rreg
-        * is triggered in TTM and ttm_bo_lock_delayed_workqueue() will
-        * never return if we keep waiting in virt_kiq_rreg, which cause
-        * gpu_recover() hang there.
-        *
-        * also don't wait anymore for IRQ context
-        * */
-       if (r < 1 && (adev->in_gpu_reset || in_interrupt()))
-               goto failed_kiq_write;
-
-       might_sleep();
-       while (r < 1 && cnt++ < MAX_KIQ_REG_TRY) {
-
-               msleep(MAX_KIQ_REG_BAILOUT_INTERVAL);
-               r = amdgpu_fence_wait_polling(ring, seq, MAX_KIQ_REG_WAIT);
-       }
-
-       if (cnt > MAX_KIQ_REG_TRY)
-               goto failed_kiq_write;
-
-       return;
-
-failed_kiq_write:
-       pr_err("failed to write reg:%x\n", reg);
-}
-
 void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
                                        uint32_t reg0, uint32_t reg1,
                                        uint32_t ref, uint32_t mask)
index 4d1ac76..daaf909 100644 (file)
@@ -287,8 +287,6 @@ static inline bool is_virtual_machine(void)
 
 bool amdgpu_virt_mmio_blocked(struct amdgpu_device *adev);
 void amdgpu_virt_init_setting(struct amdgpu_device *adev);
-uint32_t amdgpu_virt_kiq_rreg(struct amdgpu_device *adev, uint32_t reg);
-void amdgpu_virt_kiq_wreg(struct amdgpu_device *adev, uint32_t reg, uint32_t v);
 void amdgpu_virt_kiq_reg_write_reg_wait(struct amdgpu_device *adev,
                                        uint32_t reg0, uint32_t rreg1,
                                        uint32_t ref, uint32_t mask);
index d9cc746..847ca9b 100644 (file)
@@ -74,9 +74,9 @@ int athub_v1_0_set_clockgating(struct amdgpu_device *adev,
        case CHIP_VEGA20:
        case CHIP_RAVEN:
                athub_update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                athub_update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
index ceb9aa4..921a69a 100644 (file)
@@ -77,9 +77,9 @@ int athub_v2_0_set_clockgating(struct amdgpu_device *adev,
        case CHIP_NAVI14:
        case CHIP_NAVI12:
                athub_v2_0_update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                athub_v2_0_update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
index f513265..5a1bd8e 100644 (file)
@@ -27,6 +27,9 @@
 #include "df/df_3_6_offset.h"
 #include "df/df_3_6_sh_mask.h"
 
+#define DF_3_6_SMN_REG_INST_DIST        0x8
+#define DF_3_6_INST_CNT                 8
+
 static u32 df_v3_6_channel_number[] = {1, 2, 0, 4, 0, 8, 0,
                                       16, 32, 0, 0, 0, 2, 4, 8};
 
@@ -683,6 +686,58 @@ static void df_v3_6_pmc_get_count(struct amdgpu_device *adev,
        }
 }
 
+static uint64_t df_v3_6_get_dram_base_addr(struct amdgpu_device *adev,
+                                          uint32_t df_inst)
+{
+       uint32_t base_addr_reg_val      = 0;
+       uint64_t base_addr              = 0;
+
+       base_addr_reg_val = RREG32_PCIE(smnDF_CS_UMC_AON0_DramBaseAddress0 +
+                                       df_inst * DF_3_6_SMN_REG_INST_DIST);
+
+       if (REG_GET_FIELD(base_addr_reg_val,
+                         DF_CS_UMC_AON0_DramBaseAddress0,
+                         AddrRngVal) == 0) {
+               DRM_WARN("address range not valid");
+               return 0;
+       }
+
+       base_addr = REG_GET_FIELD(base_addr_reg_val,
+                                 DF_CS_UMC_AON0_DramBaseAddress0,
+                                 DramBaseAddr);
+
+       return base_addr << 28;
+}
+
+static uint32_t df_v3_6_get_df_inst_id(struct amdgpu_device *adev)
+{
+       uint32_t xgmi_node_id   = 0;
+       uint32_t df_inst_id     = 0;
+
+       /* Walk through DF dst nodes to find current XGMI node */
+       for (df_inst_id = 0; df_inst_id < DF_3_6_INST_CNT; df_inst_id++) {
+
+               xgmi_node_id = RREG32_PCIE(smnDF_CS_UMC_AON0_DramLimitAddress0 +
+                                          df_inst_id * DF_3_6_SMN_REG_INST_DIST);
+               xgmi_node_id = REG_GET_FIELD(xgmi_node_id,
+                                            DF_CS_UMC_AON0_DramLimitAddress0,
+                                            DstFabricID);
+
+               /* TODO: establish reason dest fabric id is offset by 7 */
+               xgmi_node_id = xgmi_node_id >> 7;
+
+               if (adev->gmc.xgmi.physical_node_id == xgmi_node_id)
+                       break;
+       }
+
+       if (df_inst_id == DF_3_6_INST_CNT) {
+               DRM_WARN("cant match df dst id with gpu node");
+               return 0;
+       }
+
+       return df_inst_id;
+}
+
 const struct amdgpu_df_funcs df_v3_6_funcs = {
        .sw_init = df_v3_6_sw_init,
        .sw_fini = df_v3_6_sw_fini,
@@ -696,5 +751,7 @@ const struct amdgpu_df_funcs df_v3_6_funcs = {
        .pmc_stop = df_v3_6_pmc_stop,
        .pmc_get_count = df_v3_6_pmc_get_count,
        .get_fica = df_v3_6_get_fica,
-       .set_fica = df_v3_6_set_fica
+       .set_fica = df_v3_6_set_fica,
+       .get_dram_base_addr = df_v3_6_get_dram_base_addr,
+       .get_df_inst_id = df_v3_6_get_df_inst_id
 };
index 874f641..1785fda 100644 (file)
@@ -368,7 +368,7 @@ static const struct kiq_pm4_funcs gfx_v10_0_kiq_pm4_funcs = {
        .map_queues_size = 7,
        .unmap_queues_size = 6,
        .query_status_size = 7,
-       .invalidate_tlbs_size = 12,
+       .invalidate_tlbs_size = 2,
 };
 
 static void gfx_v10_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)
@@ -4229,7 +4229,7 @@ static int gfx_v10_0_set_powergating_state(void *handle,
                                          enum amd_powergating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_PG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_PG_STATE_GATE);
        switch (adev->asic_type) {
        case CHIP_NAVI10:
        case CHIP_NAVI14:
@@ -4255,7 +4255,7 @@ static int gfx_v10_0_set_clockgating_state(void *handle,
        case CHIP_NAVI14:
        case CHIP_NAVI12:
                gfx_v10_0_update_gfx_clock_gating(adev,
-                                                state == AMD_CG_STATE_GATE ? true : false);
+                                                state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
@@ -4737,6 +4737,7 @@ static void gfx_v10_0_ring_emit_tmz(struct amdgpu_ring *ring, bool start)
 static void gfx_v10_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
 {
        struct amdgpu_device *adev = ring->adev;
+       struct amdgpu_kiq *kiq = &adev->gfx.kiq;
 
        amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));
        amdgpu_ring_write(ring, 0 |     /* src: register*/
@@ -4745,9 +4746,9 @@ static void gfx_v10_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
        amdgpu_ring_write(ring, reg);
        amdgpu_ring_write(ring, 0);
        amdgpu_ring_write(ring, lower_32_bits(adev->wb.gpu_addr +
-                               adev->virt.reg_val_offs * 4));
+                               kiq->reg_val_offs * 4));
        amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
-                               adev->virt.reg_val_offs * 4));
+                               kiq->reg_val_offs * 4));
 }
 
 static void gfx_v10_0_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg,
index 46f0533..fa24597 100644 (file)
@@ -6449,6 +6449,7 @@ static void gfx_v8_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigne
 static void gfx_v8_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
 {
        struct amdgpu_device *adev = ring->adev;
+       struct amdgpu_kiq *kiq = &adev->gfx.kiq;
 
        amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));
        amdgpu_ring_write(ring, 0 |     /* src: register*/
@@ -6457,9 +6458,9 @@ static void gfx_v8_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
        amdgpu_ring_write(ring, reg);
        amdgpu_ring_write(ring, 0);
        amdgpu_ring_write(ring, lower_32_bits(adev->wb.gpu_addr +
-                               adev->virt.reg_val_offs * 4));
+                               kiq->reg_val_offs * 4));
        amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
-                               adev->virt.reg_val_offs * 4));
+                               kiq->reg_val_offs * 4));
 }
 
 static void gfx_v8_0_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg,
index 46ab467..90f64b8 100644 (file)
@@ -48,6 +48,8 @@
 
 #include "amdgpu_ras.h"
 
+#include "gfx_v9_4.h"
+
 #define GFX9_NUM_GFX_RINGS     1
 #define GFX9_MEC_HPD_SIZE 4096
 #define RLCG_UCODE_LOADING_START_ADDRESS 0x00002000L
@@ -736,6 +738,7 @@ static void gfx_v9_0_ring_emit_de_meta(struct amdgpu_ring *ring);
 static u64 gfx_v9_0_ring_get_rptr_compute(struct amdgpu_ring *ring);
 static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
                                          void *ras_error_status);
+static void gfx_v9_0_clear_ras_edc_counter(struct amdgpu_device *adev);
 static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev,
                                     void *inject_if);
 
@@ -859,7 +862,7 @@ static const struct kiq_pm4_funcs gfx_v9_0_kiq_pm4_funcs = {
        .map_queues_size = 7,
        .unmap_queues_size = 6,
        .query_status_size = 7,
-       .invalidate_tlbs_size = 12,
+       .invalidate_tlbs_size = 2,
 };
 
 static void gfx_v9_0_set_kiq_pm4_funcs(struct amdgpu_device *adev)
@@ -1159,18 +1162,54 @@ static void gfx_v9_0_check_fw_write_wait(struct amdgpu_device *adev)
        }
 }
 
+struct amdgpu_gfxoff_quirk {
+       u16 chip_vendor;
+       u16 chip_device;
+       u16 subsys_vendor;
+       u16 subsys_device;
+       u8 revision;
+};
+
+static const struct amdgpu_gfxoff_quirk amdgpu_gfxoff_quirk_list[] = {
+       /* https://bugzilla.kernel.org/show_bug.cgi?id=204689 */
+       { 0x1002, 0x15dd, 0x1002, 0x15dd, 0xc8 },
+       { 0, 0, 0, 0, 0 },
+};
+
+static bool gfx_v9_0_should_disable_gfxoff(struct pci_dev *pdev)
+{
+       const struct amdgpu_gfxoff_quirk *p = amdgpu_gfxoff_quirk_list;
+
+       while (p && p->chip_device != 0) {
+               if (pdev->vendor == p->chip_vendor &&
+                   pdev->device == p->chip_device &&
+                   pdev->subsystem_vendor == p->subsys_vendor &&
+                   pdev->subsystem_device == p->subsys_device &&
+                   pdev->revision == p->revision) {
+                       return true;
+               }
+               ++p;
+       }
+       return false;
+}
+
 static void gfx_v9_0_check_if_need_gfxoff(struct amdgpu_device *adev)
 {
+       if (gfx_v9_0_should_disable_gfxoff(adev->pdev))
+               adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
+
        switch (adev->asic_type) {
        case CHIP_VEGA10:
        case CHIP_VEGA12:
        case CHIP_VEGA20:
                break;
        case CHIP_RAVEN:
-               if (!(adev->rev_id >= 0x8 ||
-                     adev->pdev->device == 0x15d8) &&
-                   (adev->pm.fw_version < 0x41e2b || /* not raven1 fresh */
-                    !adev->gfx.rlc.is_rlc_v2_1)) /* without rlc save restore ucodes */
+               if (!(adev->rev_id >= 0x8 || adev->pdev->device == 0x15d8) &&
+                   ((adev->gfx.rlc_fw_version != 106 &&
+                     adev->gfx.rlc_fw_version < 531) ||
+                    (adev->gfx.rlc_fw_version == 53815) ||
+                    (adev->gfx.rlc_feature_version < 1) ||
+                    !adev->gfx.rlc.is_rlc_v2_1))
                        adev->pm.pp_feature &= ~PP_GFXOFF_MASK;
 
                if (adev->pm.pp_feature & PP_GFXOFF_MASK)
@@ -1949,6 +1988,17 @@ static const struct amdgpu_gfx_funcs gfx_v9_0_gfx_funcs = {
        .query_ras_error_count = &gfx_v9_0_query_ras_error_count
 };
 
+static const struct amdgpu_gfx_funcs gfx_v9_4_gfx_funcs = {
+       .get_gpu_clock_counter = &gfx_v9_0_get_gpu_clock_counter,
+       .select_se_sh = &gfx_v9_0_select_se_sh,
+       .read_wave_data = &gfx_v9_0_read_wave_data,
+       .read_wave_sgprs = &gfx_v9_0_read_wave_sgprs,
+       .read_wave_vgprs = &gfx_v9_0_read_wave_vgprs,
+       .select_me_pipe_q = &gfx_v9_0_select_me_pipe_q,
+       .ras_error_inject = &gfx_v9_4_ras_error_inject,
+       .query_ras_error_count = &gfx_v9_4_query_ras_error_count
+};
+
 static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
 {
        u32 gb_addr_config;
@@ -2000,6 +2050,7 @@ static int gfx_v9_0_gpu_early_init(struct amdgpu_device *adev)
                        gb_addr_config = RAVEN_GB_ADDR_CONFIG_GOLDEN;
                break;
        case CHIP_ARCTURUS:
+               adev->gfx.funcs = &gfx_v9_4_gfx_funcs;
                adev->gfx.config.max_hw_contexts = 8;
                adev->gfx.config.sc_prim_fifo_size_frontend = 0x20;
                adev->gfx.config.sc_prim_fifo_size_backend = 0x100;
@@ -2390,6 +2441,22 @@ static void gfx_v9_0_init_gds_vmid(struct amdgpu_device *adev)
        }
 }
 
+static void gfx_v9_0_init_sq_config(struct amdgpu_device *adev)
+{
+       uint32_t tmp;
+
+       switch (adev->asic_type) {
+       case CHIP_ARCTURUS:
+               tmp = RREG32_SOC15(GC, 0, mmSQ_CONFIG);
+               tmp = REG_SET_FIELD(tmp, SQ_CONFIG,
+                                       DISABLE_BARRIER_WAITCNT, 1);
+               WREG32_SOC15(GC, 0, mmSQ_CONFIG, tmp);
+               break;
+       default:
+               break;
+       };
+}
+
 static void gfx_v9_0_constants_init(struct amdgpu_device *adev)
 {
        u32 tmp;
@@ -2435,6 +2502,7 @@ static void gfx_v9_0_constants_init(struct amdgpu_device *adev)
 
        gfx_v9_0_init_compute_vmid(adev);
        gfx_v9_0_init_gds_vmid(adev);
+       gfx_v9_0_init_sq_config(adev);
 }
 
 static void gfx_v9_0_wait_for_rlc_serdes(struct amdgpu_device *adev)
@@ -4029,7 +4097,7 @@ static const struct soc15_reg_entry sgpr2_init_regs[] = {
    { SOC15_REG_ENTRY(GC, 0, mmCOMPUTE_STATIC_THREAD_MGMT_SE7), 0x0000ff00 },
 };
 
-static const struct soc15_reg_entry sec_ded_counter_registers[] = {
+static const struct soc15_reg_entry gfx_v9_0_edc_counter_regs[] = {
    { SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), 0, 1, 1},
    { SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), 0, 1, 1},
    { SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1, 1},
@@ -4118,7 +4186,7 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
        struct amdgpu_ring *ring = &adev->gfx.compute_ring[0];
        struct amdgpu_ib ib;
        struct dma_fence *f = NULL;
-       int r, i, j, k;
+       int r, i;
        unsigned total_size, vgpr_offset, sgpr_offset;
        u64 gpu_addr;
 
@@ -4264,18 +4332,17 @@ static int gfx_v9_0_do_edc_gpr_workarounds(struct amdgpu_device *adev)
                goto fail;
        }
 
-       /* read back registers to clear the counters */
-       mutex_lock(&adev->grbm_idx_mutex);
-       for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++) {
-               for (j = 0; j < sec_ded_counter_registers[i].se_num; j++) {
-                       for (k = 0; k < sec_ded_counter_registers[i].instance; k++) {
-                               gfx_v9_0_select_se_sh(adev, j, 0x0, k);
-                               RREG32(SOC15_REG_ENTRY_OFFSET(sec_ded_counter_registers[i]));
-                       }
-               }
+       switch (adev->asic_type)
+       {
+       case CHIP_VEGA20:
+               gfx_v9_0_clear_ras_edc_counter(adev);
+               break;
+       case CHIP_ARCTURUS:
+               gfx_v9_4_clear_ras_edc_counter(adev);
+               break;
+       default:
+               break;
        }
-       WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xe0000000);
-       mutex_unlock(&adev->grbm_idx_mutex);
 
 fail:
        amdgpu_ib_free(adev, &ib, NULL);
@@ -4638,7 +4705,7 @@ static int gfx_v9_0_set_powergating_state(void *handle,
                                          enum amd_powergating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_PG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_PG_STATE_GATE);
 
        switch (adev->asic_type) {
        case CHIP_RAVEN:
@@ -4700,7 +4767,7 @@ static int gfx_v9_0_set_clockgating_state(void *handle,
        case CHIP_ARCTURUS:
        case CHIP_RENOIR:
                gfx_v9_0_update_gfx_clock_gating(adev,
-                                                state == AMD_CG_STATE_GATE ? true : false);
+                                                state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
@@ -4717,12 +4784,12 @@ static void gfx_v9_0_get_clockgating_state(void *handle, u32 *flags)
                *flags = 0;
 
        /* AMD_CG_SUPPORT_GFX_MGCG */
-       data = RREG32_SOC15(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE);
+       data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGTT_MGCG_OVERRIDE));
        if (!(data & RLC_CGTT_MGCG_OVERRIDE__GFXIP_MGCG_OVERRIDE_MASK))
                *flags |= AMD_CG_SUPPORT_GFX_MGCG;
 
        /* AMD_CG_SUPPORT_GFX_CGCG */
-       data = RREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL);
+       data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGCG_CGLS_CTRL));
        if (data & RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK)
                *flags |= AMD_CG_SUPPORT_GFX_CGCG;
 
@@ -4731,18 +4798,18 @@ static void gfx_v9_0_get_clockgating_state(void *handle, u32 *flags)
                *flags |= AMD_CG_SUPPORT_GFX_CGLS;
 
        /* AMD_CG_SUPPORT_GFX_RLC_LS */
-       data = RREG32_SOC15(GC, 0, mmRLC_MEM_SLP_CNTL);
+       data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_MEM_SLP_CNTL));
        if (data & RLC_MEM_SLP_CNTL__RLC_MEM_LS_EN_MASK)
                *flags |= AMD_CG_SUPPORT_GFX_RLC_LS | AMD_CG_SUPPORT_GFX_MGLS;
 
        /* AMD_CG_SUPPORT_GFX_CP_LS */
-       data = RREG32_SOC15(GC, 0, mmCP_MEM_SLP_CNTL);
+       data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmCP_MEM_SLP_CNTL));
        if (data & CP_MEM_SLP_CNTL__CP_MEM_LS_EN_MASK)
                *flags |= AMD_CG_SUPPORT_GFX_CP_LS | AMD_CG_SUPPORT_GFX_MGLS;
 
        if (adev->asic_type != CHIP_ARCTURUS) {
                /* AMD_CG_SUPPORT_GFX_3D_CGCG */
-               data = RREG32_SOC15(GC, 0, mmRLC_CGCG_CGLS_CTRL_3D);
+               data = RREG32_KIQ(SOC15_REG_OFFSET(GC, 0, mmRLC_CGCG_CGLS_CTRL_3D));
                if (data & RLC_CGCG_CGLS_CTRL_3D__CGCG_EN_MASK)
                        *flags |= AMD_CG_SUPPORT_GFX_3D_CGCG;
 
@@ -5213,6 +5280,7 @@ static void gfx_v9_0_ring_emit_patch_cond_exec(struct amdgpu_ring *ring, unsigne
 static void gfx_v9_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
 {
        struct amdgpu_device *adev = ring->adev;
+       struct amdgpu_kiq *kiq = &adev->gfx.kiq;
 
        amdgpu_ring_write(ring, PACKET3(PACKET3_COPY_DATA, 4));
        amdgpu_ring_write(ring, 0 |     /* src: register*/
@@ -5221,9 +5289,9 @@ static void gfx_v9_0_ring_emit_rreg(struct amdgpu_ring *ring, uint32_t reg)
        amdgpu_ring_write(ring, reg);
        amdgpu_ring_write(ring, 0);
        amdgpu_ring_write(ring, lower_32_bits(adev->wb.gpu_addr +
-                               adev->virt.reg_val_offs * 4));
+                               kiq->reg_val_offs * 4));
        amdgpu_ring_write(ring, upper_32_bits(adev->wb.gpu_addr +
-                               adev->virt.reg_val_offs * 4));
+                               kiq->reg_val_offs * 4));
 }
 
 static void gfx_v9_0_ring_emit_wreg(struct amdgpu_ring *ring, uint32_t reg,
@@ -5545,7 +5613,7 @@ static int gfx_v9_0_priv_inst_irq(struct amdgpu_device *adev,
 }
 
 
-static const struct soc15_ras_field_entry gc_ras_fields_vg20[] = {
+static const struct soc15_ras_field_entry gfx_v9_0_ras_fields[] = {
        { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT),
          SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, SEC_COUNT),
          SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, DED_COUNT)
@@ -5993,7 +6061,7 @@ static int gfx_v9_0_ras_error_inject(struct amdgpu_device *adev,
        int ret;
        struct ta_ras_trigger_error_input block_info = { 0 };
 
-       if (adev->asic_type != CHIP_VEGA20)
+       if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
                return -EINVAL;
 
        if (info->head.sub_block_index >= ARRAY_SIZE(ras_gfx_subblocks))
@@ -6118,7 +6186,7 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
        WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255);
        WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT, 0);
 
-       for (i = 0; i < 16; i++) {
+       for (i = 0; i < ARRAY_SIZE(vml2_mems); i++) {
                WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, i);
                data = RREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT);
 
@@ -6137,7 +6205,7 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
                }
        }
 
-       for (i = 0; i < 7; i++) {
+       for (i = 0; i < ARRAY_SIZE(vml2_walker_mems); i++) {
                WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, i);
                data = RREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT);
 
@@ -6158,7 +6226,7 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
                }
        }
 
-       for (i = 0; i < 4; i++) {
+       for (i = 0; i < ARRAY_SIZE(atc_l2_cache_2m_mems); i++) {
                WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, i);
                data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT);
 
@@ -6170,7 +6238,7 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
                }
        }
 
-       for (i = 0; i < 32; i++) {
+       for (i = 0; i < ARRAY_SIZE(atc_l2_cache_4k_mems); i++) {
                WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, i);
                data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT);
 
@@ -6197,36 +6265,36 @@ static int gfx_v9_0_query_utc_edc_status(struct amdgpu_device *adev,
        return 0;
 }
 
-static int __get_ras_error_count(const struct soc15_reg_entry *reg,
+static int gfx_v9_0_ras_error_count(const struct soc15_reg_entry *reg,
        uint32_t se_id, uint32_t inst_id, uint32_t value,
        uint32_t *sec_count, uint32_t *ded_count)
 {
        uint32_t i;
        uint32_t sec_cnt, ded_cnt;
 
-       for (i = 0; i < ARRAY_SIZE(gc_ras_fields_vg20); i++) {
-               if(gc_ras_fields_vg20[i].reg_offset != reg->reg_offset ||
-                       gc_ras_fields_vg20[i].seg != reg->seg ||
-                       gc_ras_fields_vg20[i].inst != reg->inst)
+       for (i = 0; i < ARRAY_SIZE(gfx_v9_0_ras_fields); i++) {
+               if(gfx_v9_0_ras_fields[i].reg_offset != reg->reg_offset ||
+                       gfx_v9_0_ras_fields[i].seg != reg->seg ||
+                       gfx_v9_0_ras_fields[i].inst != reg->inst)
                        continue;
 
                sec_cnt = (value &
-                               gc_ras_fields_vg20[i].sec_count_mask) >>
-                               gc_ras_fields_vg20[i].sec_count_shift;
+                               gfx_v9_0_ras_fields[i].sec_count_mask) >>
+                               gfx_v9_0_ras_fields[i].sec_count_shift;
                if (sec_cnt) {
                        DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n",
-                               gc_ras_fields_vg20[i].name,
+                               gfx_v9_0_ras_fields[i].name,
                                se_id, inst_id,
                                sec_cnt);
                        *sec_count += sec_cnt;
                }
 
                ded_cnt = (value &
-                               gc_ras_fields_vg20[i].ded_count_mask) >>
-                               gc_ras_fields_vg20[i].ded_count_shift;
+                               gfx_v9_0_ras_fields[i].ded_count_mask) >>
+                               gfx_v9_0_ras_fields[i].ded_count_shift;
                if (ded_cnt) {
                        DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n",
-                               gc_ras_fields_vg20[i].name,
+                               gfx_v9_0_ras_fields[i].name,
                                se_id, inst_id,
                                ded_cnt);
                        *ded_count += ded_cnt;
@@ -6236,6 +6304,58 @@ static int __get_ras_error_count(const struct soc15_reg_entry *reg,
        return 0;
 }
 
+static void gfx_v9_0_clear_ras_edc_counter(struct amdgpu_device *adev)
+{
+       int i, j, k;
+
+       /* read back registers to clear the counters */
+       mutex_lock(&adev->grbm_idx_mutex);
+       for (i = 0; i < ARRAY_SIZE(gfx_v9_0_edc_counter_regs); i++) {
+               for (j = 0; j < gfx_v9_0_edc_counter_regs[i].se_num; j++) {
+                       for (k = 0; k < gfx_v9_0_edc_counter_regs[i].instance; k++) {
+                               gfx_v9_0_select_se_sh(adev, j, 0x0, k);
+                               RREG32(SOC15_REG_ENTRY_OFFSET(gfx_v9_0_edc_counter_regs[i]));
+                       }
+               }
+       }
+       WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xe0000000);
+       mutex_unlock(&adev->grbm_idx_mutex);
+
+       WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT, 0);
+       WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT, 0);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT, 0);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT, 0);
+
+       for (i = 0; i < ARRAY_SIZE(vml2_mems); i++) {
+               WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, i);
+               RREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_CNT);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(vml2_walker_mems); i++) {
+               WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, i);
+               RREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_CNT);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(atc_l2_cache_2m_mems); i++) {
+               WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, i);
+               RREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_CNT);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(atc_l2_cache_4k_mems); i++) {
+               WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, i);
+               RREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_CNT);
+       }
+
+       WREG32_SOC15(GC, 0, mmVM_L2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVM_L2_WALKER_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_EDC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_EDC_INDEX, 255);
+}
+
 static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
                                          void *ras_error_status)
 {
@@ -6244,7 +6364,7 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
        uint32_t i, j, k;
        uint32_t reg_value;
 
-       if (adev->asic_type != CHIP_VEGA20)
+       if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
                return -EINVAL;
 
        err_data->ue_count = 0;
@@ -6252,14 +6372,14 @@ static int gfx_v9_0_query_ras_error_count(struct amdgpu_device *adev,
 
        mutex_lock(&adev->grbm_idx_mutex);
 
-       for (i = 0; i < ARRAY_SIZE(sec_ded_counter_registers); i++) {
-               for (j = 0; j < sec_ded_counter_registers[i].se_num; j++) {
-                       for (k = 0; k < sec_ded_counter_registers[i].instance; k++) {
+       for (i = 0; i < ARRAY_SIZE(gfx_v9_0_edc_counter_regs); i++) {
+               for (j = 0; j < gfx_v9_0_edc_counter_regs[i].se_num; j++) {
+                       for (k = 0; k < gfx_v9_0_edc_counter_regs[i].instance; k++) {
                                gfx_v9_0_select_se_sh(adev, j, 0, k);
                                reg_value =
-                                       RREG32(SOC15_REG_ENTRY_OFFSET(sec_ded_counter_registers[i]));
+                                       RREG32(SOC15_REG_ENTRY_OFFSET(gfx_v9_0_edc_counter_regs[i]));
                                if (reg_value)
-                                       __get_ras_error_count(&sec_ded_counter_registers[i],
+                                       gfx_v9_0_ras_error_count(&gfx_v9_0_edc_counter_regs[i],
                                                        j, k, reg_value,
                                                        &sec_count, &ded_count);
                        }
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.c
new file mode 100644 (file)
index 0000000..f099f13
--- /dev/null
@@ -0,0 +1,978 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#include <linux/kernel.h>
+
+#include "amdgpu.h"
+#include "amdgpu_gfx.h"
+#include "soc15.h"
+#include "soc15d.h"
+#include "amdgpu_atomfirmware.h"
+#include "amdgpu_pm.h"
+
+#include "gc/gc_9_4_1_offset.h"
+#include "gc/gc_9_4_1_sh_mask.h"
+#include "soc15_common.h"
+
+#include "gfx_v9_4.h"
+#include "amdgpu_ras.h"
+
+static const struct soc15_reg_entry gfx_v9_4_edc_counter_regs[] = {
+       /* CPC */
+       { SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT), 0, 1, 1 },
+       /* DC */
+       { SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT), 0, 1, 1 },
+       /* CPF */
+       { SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT), 0, 1, 1 },
+       /* GDS */
+       { SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_GRBM_CNT), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_DED), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT), 0, 1, 1 },
+       /* SPI */
+       { SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT), 0, 4, 1 },
+       /* SQ */
+       { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT), 0, 4, 16 },
+       { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_DED_CNT), 0, 4, 16 },
+       { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_INFO), 0, 4, 16 },
+       { SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_SEC_CNT), 0, 4, 16 },
+       /* SQC */
+       { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT), 0, 4, 6 },
+       { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2), 0, 4, 6 },
+       { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3), 0, 4, 6 },
+       { SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3), 0, 4, 6 },
+       /* TA */
+       { SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT), 0, 4, 16 },
+       /* TCA */
+       { SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT), 0, 1, 2 },
+       /* TCC */
+       { SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT), 0, 1, 16 },
+       { SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2), 0, 1, 16 },
+       /* TCI */
+       { SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT), 0, 1, 72 },
+       /* TCP */
+       { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW), 0, 4, 16 },
+       { SOC15_REG_ENTRY(GC, 0, mmTCP_ATC_EDC_GATCL1_CNT), 0, 4, 16 },
+       { SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT), 0, 4, 16 },
+       /* TD */
+       { SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT), 0, 4, 16 },
+       /* GCEA */
+       { SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT), 0, 1, 32 },
+       { SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2), 0, 1, 32 },
+       { SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 1, 32 },
+       /* RLC */
+       { SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT), 0, 1, 1 },
+       { SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2), 0, 1, 1 },
+};
+
+static void gfx_v9_4_select_se_sh(struct amdgpu_device *adev, u32 se_num,
+                                 u32 sh_num, u32 instance)
+{
+       u32 data;
+
+       if (instance == 0xffffffff)
+               data = REG_SET_FIELD(0, GRBM_GFX_INDEX,
+                                    INSTANCE_BROADCAST_WRITES, 1);
+       else
+               data = REG_SET_FIELD(0, GRBM_GFX_INDEX, INSTANCE_INDEX,
+                                    instance);
+
+       if (se_num == 0xffffffff)
+               data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_BROADCAST_WRITES,
+                                    1);
+       else
+               data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SE_INDEX, se_num);
+
+       if (sh_num == 0xffffffff)
+               data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_BROADCAST_WRITES,
+                                    1);
+       else
+               data = REG_SET_FIELD(data, GRBM_GFX_INDEX, SH_INDEX, sh_num);
+
+       WREG32_SOC15_RLC_SHADOW(GC, 0, mmGRBM_GFX_INDEX, data);
+}
+
+static const struct soc15_ras_field_entry gfx_v9_4_ras_fields[] = {
+       /* CPC */
+       { "CPC_SCRATCH", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_SCRATCH_CNT),
+         SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, SEC_COUNT),
+         SOC15_REG_FIELD(CPC_EDC_SCRATCH_CNT, DED_COUNT) },
+       { "CPC_UCODE", SOC15_REG_ENTRY(GC, 0, mmCPC_EDC_UCODE_CNT),
+         SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, SEC_COUNT),
+         SOC15_REG_FIELD(CPC_EDC_UCODE_CNT, DED_COUNT) },
+       { "CPC_DC_STATE_RAM_ME1", SOC15_REG_ENTRY(GC, 0, mmDC_EDC_STATE_CNT),
+         SOC15_REG_FIELD(DC_EDC_STATE_CNT, SEC_COUNT_ME1),
+         SOC15_REG_FIELD(DC_EDC_STATE_CNT, DED_COUNT_ME1) },
+       { "CPC_DC_CSINVOC_RAM_ME1",
+         SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT),
+         SOC15_REG_FIELD(DC_EDC_CSINVOC_CNT, SEC_COUNT_ME1),
+         SOC15_REG_FIELD(DC_EDC_CSINVOC_CNT, DED_COUNT_ME1) },
+       { "CPC_DC_RESTORE_RAM_ME1",
+         SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT),
+         SOC15_REG_FIELD(DC_EDC_RESTORE_CNT, SEC_COUNT_ME1),
+         SOC15_REG_FIELD(DC_EDC_RESTORE_CNT, DED_COUNT_ME1) },
+       { "CPC_DC_CSINVOC_RAM1_ME1",
+         SOC15_REG_ENTRY(GC, 0, mmDC_EDC_CSINVOC_CNT),
+         SOC15_REG_FIELD(DC_EDC_CSINVOC_CNT, SEC_COUNT1_ME1),
+         SOC15_REG_FIELD(DC_EDC_CSINVOC_CNT, DED_COUNT1_ME1) },
+       { "CPC_DC_RESTORE_RAM1_ME1",
+         SOC15_REG_ENTRY(GC, 0, mmDC_EDC_RESTORE_CNT),
+         SOC15_REG_FIELD(DC_EDC_RESTORE_CNT, SEC_COUNT1_ME1),
+         SOC15_REG_FIELD(DC_EDC_RESTORE_CNT, DED_COUNT1_ME1) },
+
+       /* CPF */
+       { "CPF_ROQ_ME2", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT),
+         SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, SEC_COUNT_ME2),
+         SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, DED_COUNT_ME2) },
+       { "CPF_ROQ_ME1", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_ROQ_CNT),
+         SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, SEC_COUNT_ME1),
+         SOC15_REG_FIELD(CPF_EDC_ROQ_CNT, DED_COUNT_ME1) },
+       { "CPF_TCIU_TAG", SOC15_REG_ENTRY(GC, 0, mmCPF_EDC_TAG_CNT),
+         SOC15_REG_FIELD(CPF_EDC_TAG_CNT, SEC_COUNT),
+         SOC15_REG_FIELD(CPF_EDC_TAG_CNT, DED_COUNT) },
+
+       /* GDS */
+       { "GDS_GRBM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_GRBM_CNT),
+         SOC15_REG_FIELD(GDS_EDC_GRBM_CNT, SEC),
+         SOC15_REG_FIELD(GDS_EDC_GRBM_CNT, DED) },
+       { "GDS_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_CNT),
+         SOC15_REG_FIELD(GDS_EDC_CNT, GDS_MEM_SEC),
+         SOC15_REG_FIELD(GDS_EDC_CNT, GDS_MEM_DED) },
+       { "GDS_PHY_CMD_RAM_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT),
+         SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_SEC),
+         SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_CMD_RAM_MEM_DED) },
+       { "GDS_PHY_DATA_RAM_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT),
+         SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_SEC),
+         SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, PHY_DATA_RAM_MEM_DED) },
+       { "GDS_ME0_CS_PIPE_MEM", SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PHY_CNT),
+         SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_SEC),
+         SOC15_REG_FIELD(GDS_EDC_OA_PHY_CNT, ME0_CS_PIPE_MEM_DED) },
+       { "GDS_ME1_PIPE0_PIPE_MEM",
+         SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT),
+         SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_SEC),
+         SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE0_PIPE_MEM_DED) },
+       { "GDS_ME1_PIPE1_PIPE_MEM",
+         SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT),
+         SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_SEC),
+         SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE1_PIPE_MEM_DED) },
+       { "GDS_ME1_PIPE2_PIPE_MEM",
+         SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT),
+         SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_SEC),
+         SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE2_PIPE_MEM_DED) },
+       { "GDS_ME1_PIPE3_PIPE_MEM",
+         SOC15_REG_ENTRY(GC, 0, mmGDS_EDC_OA_PIPE_CNT),
+         SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_SEC),
+         SOC15_REG_FIELD(GDS_EDC_OA_PIPE_CNT, ME1_PIPE3_PIPE_MEM_DED) },
+
+       /* SPI */
+       { "SPI_SR_MEM", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_SR_MEM_SEC_COUNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_SR_MEM_DED_COUNT) },
+       { "SPI_GDS_EXPREQ", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_GDS_EXPREQ_SEC_COUNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_GDS_EXPREQ_DED_COUNT) },
+       { "SPI_WB_GRANT_30", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_WB_GRANT_30_SEC_COUNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_WB_GRANT_30_DED_COUNT) },
+       { "SPI_WB_GRANT_61", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_WB_GRANT_61_SEC_COUNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_WB_GRANT_61_DED_COUNT) },
+       { "SPI_LIFE_CNT", SOC15_REG_ENTRY(GC, 0, mmSPI_EDC_CNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_LIFE_CNT_SEC_COUNT),
+         SOC15_REG_FIELD(SPI_EDC_CNT, SPI_LIFE_CNT_DED_COUNT) },
+
+       /* SQ */
+       { "SQ_SGPR", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, SGPR_SEC_COUNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, SGPR_DED_COUNT) },
+       { "SQ_LDS_D", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, LDS_D_SEC_COUNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, LDS_D_DED_COUNT) },
+       { "SQ_LDS_I", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, LDS_I_SEC_COUNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, LDS_I_DED_COUNT) },
+       { "SQ_VGPR0", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, VGPR0_SEC_COUNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, VGPR0_DED_COUNT) },
+       { "SQ_VGPR1", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, VGPR1_SEC_COUNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, VGPR1_DED_COUNT) },
+       { "SQ_VGPR2", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, VGPR2_SEC_COUNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, VGPR2_DED_COUNT) },
+       { "SQ_VGPR3", SOC15_REG_ENTRY(GC, 0, mmSQ_EDC_CNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, VGPR3_SEC_COUNT),
+         SOC15_REG_FIELD(SQ_EDC_CNT, VGPR3_DED_COUNT) },
+
+       /* SQC */
+       { "SQC_INST_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, INST_UTCL1_LFIFO_DED_COUNT) },
+       { "SQC_DATA_CU0_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_WRITE_DATA_BUF_DED_COUNT) },
+       { "SQC_DATA_CU0_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU0_UTCL1_LFIFO_DED_COUNT) },
+       { "SQC_DATA_CU1_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_WRITE_DATA_BUF_DED_COUNT) },
+       { "SQC_DATA_CU1_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU1_UTCL1_LFIFO_DED_COUNT) },
+       { "SQC_DATA_CU2_WRITE_DATA_BUF", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_WRITE_DATA_BUF_DED_COUNT) },
+       { "SQC_DATA_CU2_UTCL1_LFIFO", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT, DATA_CU2_UTCL1_LFIFO_DED_COUNT) },
+       { "SQC_INST_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_TAG_RAM_DED_COUNT) },
+       { "SQC_INST_BANKA_UTCL1_MISS_FIFO",
+         SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3,
+                         INST_BANKA_UTCL1_MISS_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3,
+                         INST_BANKA_UTCL1_MISS_FIFO_DED_COUNT) },
+       { "SQC_INST_BANKA_MISS_FIFO",
+         SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3, INST_BANKA_MISS_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3,
+                         INST_BANKA_MISS_FIFO_DED_COUNT) },
+       { "SQC_INST_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, INST_BANKA_BANK_RAM_DED_COUNT) },
+       { "SQC_DATA_BANKA_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_TAG_RAM_DED_COUNT) },
+       { "SQC_DATA_BANKA_HIT_FIFO",
+         SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3, DATA_BANKA_HIT_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3, DATA_BANKA_HIT_FIFO_DED_COUNT) },
+       { "SQC_DATA_BANKA_MISS_FIFO",
+         SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3, DATA_BANKA_MISS_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3,
+                         DATA_BANKA_MISS_FIFO_DED_COUNT) },
+       { "SQC_DATA_BANKA_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT2),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT2, DATA_BANKA_BANK_RAM_DED_COUNT) },
+       { "SQC_INST_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_TAG_RAM_DED_COUNT) },
+       { "SQC_INST_BANKB_UTCL1_MISS_FIFO",
+         SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3,
+                         INST_BANKB_UTCL1_MISS_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3,
+                         INST_BANKB_UTCL1_MISS_FIFO_DED_COUNT) },
+       { "SQC_INST_BANKB_MISS_FIFO",
+         SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3, INST_BANKB_MISS_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3,
+                         INST_BANKB_MISS_FIFO_DED_COUNT) },
+       { "SQC_INST_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT3, INST_BANKB_BANK_RAM_DED_COUNT) },
+       { "SQC_DATA_BANKB_TAG_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_TAG_RAM_DED_COUNT) },
+       { "SQC_DATA_BANKB_HIT_FIFO",
+         SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3, DATA_BANKB_HIT_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3, DATA_BANKB_HIT_FIFO_DED_COUNT) },
+       { "SQC_DATA_BANKB_MISS_FIFO",
+         SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_PARITY_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3, DATA_BANKB_MISS_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_PARITY_CNT3,
+                         DATA_BANKB_MISS_FIFO_DED_COUNT) },
+       { "SQC_DATA_BANKB_BANK_RAM", SOC15_REG_ENTRY(GC, 0, mmSQC_EDC_CNT3),
+         SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(SQC_EDC_CNT3, DATA_BANKB_BANK_RAM_DED_COUNT) },
+
+       /* TA */
+       { "TA_FS_DFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_DFIFO_DED_COUNT) },
+       { "TA_FS_AFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_AFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_AFIFO_DED_COUNT) },
+       { "TA_FL_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FL_LFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FL_LFIFO_DED_COUNT) },
+       { "TA_FX_LFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FX_LFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FX_LFIFO_DED_COUNT) },
+       { "TA_FS_CFIFO", SOC15_REG_ENTRY(GC, 0, mmTA_EDC_CNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_CFIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TA_EDC_CNT, TA_FS_CFIFO_DED_COUNT) },
+
+       /* TCA */
+       { "TCA_HOLE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT),
+         SOC15_REG_FIELD(TCA_EDC_CNT, HOLE_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TCA_EDC_CNT, HOLE_FIFO_DED_COUNT) },
+       { "TCA_REQ_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCA_EDC_CNT),
+         SOC15_REG_FIELD(TCA_EDC_CNT, REQ_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TCA_EDC_CNT, REQ_FIFO_DED_COUNT) },
+
+       /* TCC */
+       { "TCC_CACHE_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DATA_DED_COUNT) },
+       { "TCC_CACHE_DIRTY", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, CACHE_DIRTY_DED_COUNT) },
+       { "TCC_HIGH_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, HIGH_RATE_TAG_DED_COUNT) },
+       { "TCC_LOW_RATE_TAG", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, LOW_RATE_TAG_DED_COUNT) },
+       { "TCC_IN_USE_DEC", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, IN_USE_DEC_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, IN_USE_DEC_DED_COUNT) },
+       { "TCC_IN_USE_TRANSFER", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, IN_USE_TRANSFER_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, IN_USE_TRANSFER_DED_COUNT) },
+       { "TCC_RETURN_DATA", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, RETURN_DATA_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, RETURN_DATA_DED_COUNT) },
+       { "TCC_RETURN_CONTROL", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, RETURN_CONTROL_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, RETURN_CONTROL_DED_COUNT) },
+       { "TCC_UC_ATOMIC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, UC_ATOMIC_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, UC_ATOMIC_FIFO_DED_COUNT) },
+       { "TCC_WRITE_RETURN", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_RETURN_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_RETURN_DED_COUNT) },
+       { "TCC_WRITE_CACHE_READ", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_CACHE_READ_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, WRITE_CACHE_READ_DED_COUNT) },
+       { "TCC_SRC_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, SRC_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, SRC_FIFO_DED_COUNT) },
+       { "TCC_CACHE_TAG_PROBE_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT2),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT2, CACHE_TAG_PROBE_FIFO_DED_COUNT) },
+       { "TCC_LATENCY_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, LATENCY_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, LATENCY_FIFO_DED_COUNT) },
+       { "TCC_LATENCY_FIFO_NEXT_RAM", SOC15_REG_ENTRY(GC, 0, mmTCC_EDC_CNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, LATENCY_FIFO_NEXT_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(TCC_EDC_CNT, LATENCY_FIFO_NEXT_RAM_DED_COUNT) },
+
+       /* TCI */
+       { "TCI_WRITE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCI_EDC_CNT),
+         SOC15_REG_FIELD(TCI_EDC_CNT, WRITE_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(TCI_EDC_CNT, WRITE_RAM_DED_COUNT) },
+
+       /* TCP */
+       { "TCP_CACHE_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CACHE_RAM_DED_COUNT) },
+       { "TCP_LFIFO_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, LFIFO_RAM_DED_COUNT) },
+       { "TCP_CMD_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CMD_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, CMD_FIFO_DED_COUNT) },
+       { "TCP_VM_FIFO", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, VM_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, VM_FIFO_DED_COUNT) },
+       { "TCP_DB_RAM", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, DB_RAM_SED_COUNT), 0, 0 },
+       { "TCP_UTCL1_LFIFO0", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_SEC_COUNT),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO0_DED_COUNT) },
+       { "TCP_UTCL1_LFIFO1", SOC15_REG_ENTRY(GC, 0, mmTCP_EDC_CNT_NEW),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_SEC_COUNT),
+         SOC15_REG_FIELD(TCP_EDC_CNT_NEW, UTCL1_LFIFO1_DED_COUNT) },
+
+       /* TD */
+       { "TD_SS_FIFO_LO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT),
+         SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_SEC_COUNT),
+         SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_LO_DED_COUNT) },
+       { "TD_SS_FIFO_HI", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT),
+         SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_SEC_COUNT),
+         SOC15_REG_FIELD(TD_EDC_CNT, SS_FIFO_HI_DED_COUNT) },
+       { "TD_CS_FIFO", SOC15_REG_ENTRY(GC, 0, mmTD_EDC_CNT),
+         SOC15_REG_FIELD(TD_EDC_CNT, CS_FIFO_SEC_COUNT),
+         SOC15_REG_FIELD(TD_EDC_CNT, CS_FIFO_DED_COUNT) },
+
+       /* EA */
+       { "EA_DRAMRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT) },
+       { "EA_DRAMWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT) },
+       { "EA_DRAMWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT) },
+       { "EA_RRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, RRET_TAGMEM_DED_COUNT) },
+       { "EA_WRET_TAGMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, WRET_TAGMEM_DED_COUNT) },
+       { "EA_GMIRD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT) },
+       { "EA_GMIWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT) },
+       { "EA_GMIWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT) },
+       { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT), 0, 0 },
+       { "EA_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 0,
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, DRAMRD_PAGEMEM_DED_COUNT) },
+       { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT), 0, 0 },
+       { "EA_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 0,
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, DRAMWR_PAGEMEM_DED_COUNT) },
+       { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, IORD_CMDMEM_SED_COUNT), 0, 0 },
+       { "EA_IORD_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 0,
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, IORD_CMDMEM_DED_COUNT) },
+       { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, IOWR_CMDMEM_SED_COUNT), 0, 0 },
+       { "EA_IOWR_CMDMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 0,
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, IOWR_CMDMEM_DED_COUNT) },
+       { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, IOWR_DATAMEM_SED_COUNT), 0, 0 },
+       { "EA_IOWR_DATAMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 0,
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, IOWR_DATAMEM_DED_COUNT) },
+       { "EA_GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT), 0, 0 },
+       { "EA_GMIRD_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 0,
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, GMIRD_PAGEMEM_DED_COUNT) },
+       { "EA_GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT), 0, 0 },
+       { "EA_GMIWR_PAGEMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 0,
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT) },
+       { "EA_MAM_D0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D0MEM_DED_COUNT) },
+       { "EA_MAM_D1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D1MEM_DED_COUNT) },
+       { "EA_MAM_D2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D2MEM_DED_COUNT) },
+       { "EA_MAM_D3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT2),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT2, MAM_D3MEM_DED_COUNT) },
+       { "EA_MAM_A0MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3),
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_A0MEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_A0MEM_DED_COUNT) },
+       { "EA_MAM_A1MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3),
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_A1MEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_A1MEM_DED_COUNT) },
+       { "EA_MAM_A2MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3),
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_A2MEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_A2MEM_DED_COUNT) },
+       { "EA_MAM_A3MEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3),
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_A3MEM_SEC_COUNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_A3MEM_DED_COUNT) },
+       { "EA_MAM_AFMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT),
+         SOC15_REG_FIELD(GCEA_EDC_CNT, MAM_AFMEM_SEC_COUNT), 0, 0 },
+       { "EA_MAM_AFMEM", SOC15_REG_ENTRY(GC, 0, mmGCEA_EDC_CNT3), 0, 0,
+         SOC15_REG_FIELD(GCEA_EDC_CNT3, MAM_AFMEM_DED_COUNT) },
+
+       /* RLC */
+       { "RLCG_INSTR_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLCG_INSTR_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLCG_INSTR_RAM_DED_COUNT) },
+       { "RLCG_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLCG_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLCG_SCRATCH_RAM_DED_COUNT) },
+       { "RLCV_INSTR_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLCV_INSTR_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLCV_INSTR_RAM_DED_COUNT) },
+       { "RLCV_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLCV_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLCV_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_TCTAG_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLC_TCTAG_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLC_TCTAG_RAM_DED_COUNT) },
+       { "RLC_SPM_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLC_SPM_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLC_SPM_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_SRM_DATA_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLC_SRM_DATA_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLC_SRM_DATA_RAM_DED_COUNT) },
+       { "RLC_SRM_ADDR_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLC_SRM_ADDR_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT, RLC_SRM_ADDR_RAM_DED_COUNT) },
+       { "RLC_SPM_SE0_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE0_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE0_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_SPM_SE1_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE1_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE1_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_SPM_SE2_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE2_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE2_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_SPM_SE3_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE3_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE3_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_SPM_SE4_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE4_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE4_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_SPM_SE5_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE5_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE5_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_SPM_SE6_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE6_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE6_SCRATCH_RAM_DED_COUNT) },
+       { "RLC_SPM_SE7_SCRATCH_RAM", SOC15_REG_ENTRY(GC, 0, mmRLC_EDC_CNT2),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE7_SCRATCH_RAM_SEC_COUNT),
+         SOC15_REG_FIELD(RLC_EDC_CNT2, RLC_SPM_SE7_SCRATCH_RAM_DED_COUNT) },
+};
+
+static const char * const vml2_mems[] = {
+       "UTC_VML2_BANK_CACHE_0_BIGK_MEM0",
+       "UTC_VML2_BANK_CACHE_0_BIGK_MEM1",
+       "UTC_VML2_BANK_CACHE_0_4K_MEM0",
+       "UTC_VML2_BANK_CACHE_0_4K_MEM1",
+       "UTC_VML2_BANK_CACHE_1_BIGK_MEM0",
+       "UTC_VML2_BANK_CACHE_1_BIGK_MEM1",
+       "UTC_VML2_BANK_CACHE_1_4K_MEM0",
+       "UTC_VML2_BANK_CACHE_1_4K_MEM1",
+       "UTC_VML2_BANK_CACHE_2_BIGK_MEM0",
+       "UTC_VML2_BANK_CACHE_2_BIGK_MEM1",
+       "UTC_VML2_BANK_CACHE_2_4K_MEM0",
+       "UTC_VML2_BANK_CACHE_2_4K_MEM1",
+       "UTC_VML2_BANK_CACHE_3_BIGK_MEM0",
+       "UTC_VML2_BANK_CACHE_3_BIGK_MEM1",
+       "UTC_VML2_BANK_CACHE_3_4K_MEM0",
+       "UTC_VML2_BANK_CACHE_3_4K_MEM1",
+       "UTC_VML2_IFIFO_GROUP0",
+       "UTC_VML2_IFIFO_GROUP1",
+       "UTC_VML2_IFIFO_GROUP2",
+       "UTC_VML2_IFIFO_GROUP3",
+       "UTC_VML2_IFIFO_GROUP4",
+       "UTC_VML2_IFIFO_GROUP5",
+       "UTC_VML2_IFIFO_GROUP6",
+       "UTC_VML2_IFIFO_GROUP7",
+       "UTC_VML2_IFIFO_GROUP8",
+       "UTC_VML2_IFIFO_GROUP9",
+       "UTC_VML2_IFIFO_GROUP10",
+       "UTC_VML2_IFIFO_GROUP11",
+       "UTC_VML2_IFIFO_GROUP12",
+       "UTC_VML2_IFIFO_GROUP13",
+       "UTC_VML2_IFIFO_GROUP14",
+       "UTC_VML2_IFIFO_GROUP15",
+       "UTC_VML2_IFIFO_GROUP16",
+       "UTC_VML2_IFIFO_GROUP17",
+       "UTC_VML2_IFIFO_GROUP18",
+       "UTC_VML2_IFIFO_GROUP19",
+       "UTC_VML2_IFIFO_GROUP20",
+       "UTC_VML2_IFIFO_GROUP21",
+       "UTC_VML2_IFIFO_GROUP22",
+       "UTC_VML2_IFIFO_GROUP23",
+       "UTC_VML2_IFIFO_GROUP24",
+};
+
+static const char * const vml2_walker_mems[] = {
+       "UTC_VML2_CACHE_PDE0_MEM0",
+       "UTC_VML2_CACHE_PDE0_MEM1",
+       "UTC_VML2_CACHE_PDE1_MEM0",
+       "UTC_VML2_CACHE_PDE1_MEM1",
+       "UTC_VML2_CACHE_PDE2_MEM0",
+       "UTC_VML2_CACHE_PDE2_MEM1",
+       "UTC_VML2_RDIF_ARADDRS",
+       "UTC_VML2_RDIF_LOG_FIFO",
+       "UTC_VML2_QUEUE_REQ",
+       "UTC_VML2_QUEUE_RET",
+};
+
+static const char * const utcl2_router_mems[] = {
+       "UTCL2_ROUTER_GROUP0_VML2_REQ_FIFO0",
+       "UTCL2_ROUTER_GROUP1_VML2_REQ_FIFO1",
+       "UTCL2_ROUTER_GROUP2_VML2_REQ_FIFO2",
+       "UTCL2_ROUTER_GROUP3_VML2_REQ_FIFO3",
+       "UTCL2_ROUTER_GROUP4_VML2_REQ_FIFO4",
+       "UTCL2_ROUTER_GROUP5_VML2_REQ_FIFO5",
+       "UTCL2_ROUTER_GROUP6_VML2_REQ_FIFO6",
+       "UTCL2_ROUTER_GROUP7_VML2_REQ_FIFO7",
+       "UTCL2_ROUTER_GROUP8_VML2_REQ_FIFO8",
+       "UTCL2_ROUTER_GROUP9_VML2_REQ_FIFO9",
+       "UTCL2_ROUTER_GROUP10_VML2_REQ_FIFO10",
+       "UTCL2_ROUTER_GROUP11_VML2_REQ_FIFO11",
+       "UTCL2_ROUTER_GROUP12_VML2_REQ_FIFO12",
+       "UTCL2_ROUTER_GROUP13_VML2_REQ_FIFO13",
+       "UTCL2_ROUTER_GROUP14_VML2_REQ_FIFO14",
+       "UTCL2_ROUTER_GROUP15_VML2_REQ_FIFO15",
+       "UTCL2_ROUTER_GROUP16_VML2_REQ_FIFO16",
+       "UTCL2_ROUTER_GROUP17_VML2_REQ_FIFO17",
+       "UTCL2_ROUTER_GROUP18_VML2_REQ_FIFO18",
+       "UTCL2_ROUTER_GROUP19_VML2_REQ_FIFO19",
+       "UTCL2_ROUTER_GROUP20_VML2_REQ_FIFO20",
+       "UTCL2_ROUTER_GROUP21_VML2_REQ_FIFO21",
+       "UTCL2_ROUTER_GROUP22_VML2_REQ_FIFO22",
+       "UTCL2_ROUTER_GROUP23_VML2_REQ_FIFO23",
+       "UTCL2_ROUTER_GROUP24_VML2_REQ_FIFO24",
+};
+
+static const char * const atc_l2_cache_2m_mems[] = {
+       "UTC_ATCL2_CACHE_2M_BANK0_WAY0_MEM",
+       "UTC_ATCL2_CACHE_2M_BANK0_WAY1_MEM",
+       "UTC_ATCL2_CACHE_2M_BANK1_WAY0_MEM",
+       "UTC_ATCL2_CACHE_2M_BANK1_WAY1_MEM",
+};
+
+static const char * const atc_l2_cache_4k_mems[] = {
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM0",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM1",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM2",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM3",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM4",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM5",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM6",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY0_MEM7",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM0",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM1",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM2",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM3",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM4",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM5",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM6",
+       "UTC_ATCL2_CACHE_4K_BANK0_WAY1_MEM7",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM0",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM1",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM2",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM3",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM4",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM5",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM6",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY0_MEM7",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM0",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM1",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM2",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM3",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM4",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM5",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM6",
+       "UTC_ATCL2_CACHE_4K_BANK1_WAY1_MEM7",
+};
+
+static int gfx_v9_4_query_utc_edc_status(struct amdgpu_device *adev,
+                                        struct ras_err_data *err_data)
+{
+       uint32_t i, data;
+       uint32_t sec_count, ded_count;
+
+       WREG32_SOC15(GC, 0, mmVML2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVML2_MEM_ECC_CNTL, 0);
+       WREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_CNTL, 0);
+       WREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_CNTL, 0);
+
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_CNTL, 0);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_DSM_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_CNTL, 0);
+
+       for (i = 0; i < ARRAY_SIZE(vml2_mems); i++) {
+               WREG32_SOC15(GC, 0, mmVML2_MEM_ECC_INDEX, i);
+               data = RREG32_SOC15(GC, 0, mmVML2_MEM_ECC_CNTL);
+
+               sec_count = REG_GET_FIELD(data, VML2_MEM_ECC_CNTL, SEC_COUNT);
+               if (sec_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
+                                vml2_mems[i], sec_count);
+                       err_data->ce_count += sec_count;
+               }
+
+               ded_count = REG_GET_FIELD(data, VML2_MEM_ECC_CNTL, DED_COUNT);
+               if (ded_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
+                                vml2_mems[i], ded_count);
+                       err_data->ue_count += ded_count;
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(vml2_walker_mems); i++) {
+               WREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_INDEX, i);
+               data = RREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_CNTL);
+
+               sec_count = REG_GET_FIELD(data, VML2_WALKER_MEM_ECC_CNTL,
+                                         SEC_COUNT);
+               if (sec_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
+                                vml2_walker_mems[i], sec_count);
+                       err_data->ce_count += sec_count;
+               }
+
+               ded_count = REG_GET_FIELD(data, VML2_WALKER_MEM_ECC_CNTL,
+                                         DED_COUNT);
+               if (ded_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
+                                vml2_walker_mems[i], ded_count);
+                       err_data->ue_count += ded_count;
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(utcl2_router_mems); i++) {
+               WREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_INDEX, i);
+               data = RREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_CNTL);
+
+               sec_count = REG_GET_FIELD(data, UTCL2_MEM_ECC_CNTL, SEC_COUNT);
+               if (sec_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
+                                utcl2_router_mems[i], sec_count);
+                       err_data->ce_count += sec_count;
+               }
+
+               ded_count = REG_GET_FIELD(data, UTCL2_MEM_ECC_CNTL, DED_COUNT);
+               if (ded_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
+                                utcl2_router_mems[i], ded_count);
+                       err_data->ue_count += ded_count;
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(atc_l2_cache_2m_mems); i++) {
+               WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_INDEX, i);
+               data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_CNTL);
+
+               sec_count = REG_GET_FIELD(data, ATC_L2_CACHE_2M_DSM_CNTL,
+                                         SEC_COUNT);
+               if (sec_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
+                                atc_l2_cache_2m_mems[i], sec_count);
+                       err_data->ce_count += sec_count;
+               }
+
+               ded_count = REG_GET_FIELD(data, ATC_L2_CACHE_2M_DSM_CNTL,
+                                         DED_COUNT);
+               if (ded_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
+                                atc_l2_cache_2m_mems[i], ded_count);
+                       err_data->ue_count += ded_count;
+               }
+       }
+
+       for (i = 0; i < ARRAY_SIZE(atc_l2_cache_4k_mems); i++) {
+               WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_DSM_INDEX, i);
+               data = RREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_DSM_CNTL);
+
+               sec_count = REG_GET_FIELD(data, ATC_L2_CACHE_4K_DSM_CNTL,
+                                         SEC_COUNT);
+               if (sec_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, SEC %d\n", i,
+                                atc_l2_cache_4k_mems[i], sec_count);
+                       err_data->ce_count += sec_count;
+               }
+
+               ded_count = REG_GET_FIELD(data, ATC_L2_CACHE_4K_DSM_CNTL,
+                                         DED_COUNT);
+               if (ded_count) {
+                       DRM_INFO("Instance[%d]: SubBlock %s, DED %d\n", i,
+                                atc_l2_cache_4k_mems[i], ded_count);
+                       err_data->ue_count += ded_count;
+               }
+       }
+
+       WREG32_SOC15(GC, 0, mmVML2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_DSM_INDEX, 255);
+
+       return 0;
+}
+
+static int gfx_v9_4_ras_error_count(const struct soc15_reg_entry *reg,
+                                   uint32_t se_id, uint32_t inst_id,
+                                   uint32_t value, uint32_t *sec_count,
+                                   uint32_t *ded_count)
+{
+       uint32_t i;
+       uint32_t sec_cnt, ded_cnt;
+
+       for (i = 0; i < ARRAY_SIZE(gfx_v9_4_ras_fields); i++) {
+               if (gfx_v9_4_ras_fields[i].reg_offset != reg->reg_offset ||
+                   gfx_v9_4_ras_fields[i].seg != reg->seg ||
+                   gfx_v9_4_ras_fields[i].inst != reg->inst)
+                       continue;
+
+               sec_cnt = (value & gfx_v9_4_ras_fields[i].sec_count_mask) >>
+                         gfx_v9_4_ras_fields[i].sec_count_shift;
+               if (sec_cnt) {
+                       DRM_INFO("GFX SubBlock %s, Instance[%d][%d], SEC %d\n",
+                                gfx_v9_4_ras_fields[i].name, se_id, inst_id,
+                                sec_cnt);
+                       *sec_count += sec_cnt;
+               }
+
+               ded_cnt = (value & gfx_v9_4_ras_fields[i].ded_count_mask) >>
+                         gfx_v9_4_ras_fields[i].ded_count_shift;
+               if (ded_cnt) {
+                       DRM_INFO("GFX SubBlock %s, Instance[%d][%d], DED %d\n",
+                                gfx_v9_4_ras_fields[i].name, se_id, inst_id,
+                                ded_cnt);
+                       *ded_count += ded_cnt;
+               }
+       }
+
+       return 0;
+}
+
+int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
+                                  void *ras_error_status)
+{
+       struct ras_err_data *err_data = (struct ras_err_data *)ras_error_status;
+       uint32_t sec_count = 0, ded_count = 0;
+       uint32_t i, j, k;
+       uint32_t reg_value;
+
+       if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
+               return -EINVAL;
+
+       err_data->ue_count = 0;
+       err_data->ce_count = 0;
+
+       mutex_lock(&adev->grbm_idx_mutex);
+
+       for (i = 0; i < ARRAY_SIZE(gfx_v9_4_edc_counter_regs); i++) {
+               for (j = 0; j < gfx_v9_4_edc_counter_regs[i].se_num; j++) {
+                       for (k = 0; k < gfx_v9_4_edc_counter_regs[i].instance;
+                            k++) {
+                               gfx_v9_4_select_se_sh(adev, j, 0, k);
+                               reg_value = RREG32(SOC15_REG_ENTRY_OFFSET(
+                                       gfx_v9_4_edc_counter_regs[i]));
+                               if (reg_value)
+                                       gfx_v9_4_ras_error_count(
+                                               &gfx_v9_4_edc_counter_regs[i],
+                                               j, k, reg_value, &sec_count,
+                                               &ded_count);
+                       }
+               }
+       }
+
+       err_data->ce_count += sec_count;
+       err_data->ue_count += ded_count;
+
+       gfx_v9_4_select_se_sh(adev, 0xffffffff, 0xffffffff, 0xffffffff);
+       mutex_unlock(&adev->grbm_idx_mutex);
+
+       gfx_v9_4_query_utc_edc_status(adev, err_data);
+
+       return 0;
+}
+
+void gfx_v9_4_clear_ras_edc_counter(struct amdgpu_device *adev)
+{
+       int i, j, k;
+
+       mutex_lock(&adev->grbm_idx_mutex);
+       for (i = 0; i < ARRAY_SIZE(gfx_v9_4_edc_counter_regs); i++) {
+               for (j = 0; j < gfx_v9_4_edc_counter_regs[i].se_num; j++) {
+                       for (k = 0; k < gfx_v9_4_edc_counter_regs[i].instance;
+                            k++) {
+                               gfx_v9_4_select_se_sh(adev, j, 0x0, k);
+                               RREG32(SOC15_REG_ENTRY_OFFSET(
+                                       gfx_v9_4_edc_counter_regs[i]));
+                       }
+               }
+       }
+       WREG32_SOC15(GC, 0, mmGRBM_GFX_INDEX, 0xe0000000);
+       mutex_unlock(&adev->grbm_idx_mutex);
+
+       WREG32_SOC15(GC, 0, mmVML2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVML2_MEM_ECC_CNTL, 0);
+       WREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_CNTL, 0);
+       WREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_CNTL, 0);
+
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_CNTL, 0);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_DSM_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_CNTL, 0);
+
+       for (i = 0; i < ARRAY_SIZE(vml2_mems); i++) {
+               WREG32_SOC15(GC, 0, mmVML2_MEM_ECC_INDEX, i);
+               RREG32_SOC15(GC, 0, mmVML2_MEM_ECC_CNTL);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(vml2_walker_mems); i++) {
+               WREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_INDEX, i);
+               RREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_CNTL);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(utcl2_router_mems); i++) {
+               WREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_INDEX, i);
+               RREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_CNTL);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(atc_l2_cache_2m_mems); i++) {
+               WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_INDEX, i);
+               RREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_CNTL);
+       }
+
+       for (i = 0; i < ARRAY_SIZE(atc_l2_cache_4k_mems); i++) {
+               WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_DSM_INDEX, i);
+               RREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_DSM_CNTL);
+       }
+
+       WREG32_SOC15(GC, 0, mmVML2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmVML2_WALKER_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmUTCL2_MEM_ECC_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_2M_DSM_INDEX, 255);
+       WREG32_SOC15(GC, 0, mmATC_L2_CACHE_4K_DSM_INDEX, 255);
+}
+
+int gfx_v9_4_ras_error_inject(struct amdgpu_device *adev, void *inject_if)
+{
+       struct ras_inject_if *info = (struct ras_inject_if *)inject_if;
+       int ret;
+       struct ta_ras_trigger_error_input block_info = { 0 };
+
+       if (!amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__GFX))
+               return -EINVAL;
+
+       block_info.block_id = amdgpu_ras_block_to_ta(info->head.block);
+       block_info.sub_block_index = info->head.sub_block_index;
+       block_info.inject_error_type = amdgpu_ras_error_to_ta(info->head.type);
+       block_info.address = info->address;
+       block_info.value = info->value;
+
+       mutex_lock(&adev->grbm_idx_mutex);
+       ret = psp_ras_trigger_error(&adev->psp, &block_info);
+       mutex_unlock(&adev->grbm_idx_mutex);
+
+       return ret;
+}
diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.h b/drivers/gpu/drm/amd/amdgpu/gfx_v9_4.h
new file mode 100644 (file)
index 0000000..2e3f6f7
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2020 Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ *
+ */
+
+#ifndef __GFX_V9_4_H__
+#define __GFX_V9_4_H__
+
+void gfx_v9_4_clear_ras_edc_counter(struct amdgpu_device *adev);
+
+int gfx_v9_4_query_ras_error_count(struct amdgpu_device *adev,
+                                  void *ras_error_status);
+
+int gfx_v9_4_ras_error_inject(struct amdgpu_device *adev,
+                                    void *inject_if);
+
+#endif /* __GFX_V9_4_H__ */
index bbede09..9775eca 100644 (file)
@@ -262,7 +262,8 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
 {
        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);
+       u32 inv_req = gmc_v10_0_get_invalidate_req(vmid, flush_type);
+       u32 tmp;
        /* Use register 17 for GART */
        const unsigned eng = 17;
        unsigned int i;
@@ -289,7 +290,7 @@ static void gmc_v10_0_flush_vm_hub(struct amdgpu_device *adev, uint32_t vmid,
                        DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n");
        }
 
-       WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp);
+       WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, inv_req);
 
        /*
         * Issue a dummy read to wait for the ACK register to be cleared
@@ -418,7 +419,8 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
 
        if (amdgpu_emu_mode == 0 && ring->sched.ready) {
                spin_lock(&adev->gfx.kiq.ring_lock);
-               amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size);
+               /* 2 dwords flush + 8 dwords fence */
+               amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size + 8);
                kiq->pmf->kiq_invalidate_tlbs(ring,
                                        pasid, flush_type, all_hub);
                amdgpu_fence_emit_polling(ring, &seq);
@@ -441,10 +443,10 @@ static int gmc_v10_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
                        if (all_hub) {
                                for (i = 0; i < adev->num_vmhubs; i++)
                                        gmc_v10_0_flush_gpu_tlb(adev, vmid,
-                                                       i, 0);
+                                                       i, flush_type);
                        } else {
                                gmc_v10_0_flush_gpu_tlb(adev, vmid,
-                                               AMDGPU_GFXHUB_0, 0);
+                                               AMDGPU_GFXHUB_0, flush_type);
                        }
                        break;
                }
@@ -640,12 +642,7 @@ static int gmc_v10_0_late_init(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        int r;
 
-       /*
-        * Can't free the stolen VGA memory when it might be used for memory
-        * training again.
-        */
-       if (!adev->fw_vram_usage.mem_train_support)
-               amdgpu_bo_late_init(adev);
+       amdgpu_bo_late_init(adev);
 
        r = amdgpu_gmc_allocate_vm_inv_eng(adev);
        if (r)
@@ -829,19 +826,6 @@ static int gmc_v10_0_sw_init(void *handle)
 
        adev->gmc.stolen_size = gmc_v10_0_get_vbios_fb_size(adev);
 
-       /*
-        * In dual GPUs scenario, stolen_size is assigned to zero on the
-        * secondary GPU, since there is no pre-OS console using that memory.
-        * Then the bottom region of VRAM was allocated as GTT, unfortunately a
-        * small region of bottom VRAM was encroached by UMC firmware during
-        * GDDR6 BIST training, this cause page fault.
-        * The page fault can be fixed by forcing stolen_size to 3MB, then the
-        * bottom region of VRAM was allocated as stolen memory, GTT corruption
-        * avoid.
-        */
-       adev->gmc.stolen_size = max(adev->gmc.stolen_size,
-                                   AMDGPU_STOLEN_BIST_TRAINING_DEFAULT_SIZE);
-
        /* Memory manager */
        r = amdgpu_bo_init(adev);
        if (r)
@@ -881,13 +865,6 @@ static void gmc_v10_0_gart_fini(struct amdgpu_device *adev)
 static int gmc_v10_0_sw_fini(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       void *stolen_vga_buf;
-
-       /*
-        * Free the stolen memory if it wasn't already freed in late_init
-        * because of memory training.
-        */
-       amdgpu_bo_free_kernel(&adev->stolen_vga_memory, NULL, &stolen_vga_buf);
 
        amdgpu_vm_manager_fini(adev);
        gmc_v10_0_gart_fini(adev);
index 19d5b13..9da9596 100644 (file)
@@ -381,7 +381,8 @@ static int gmc_v7_0_mc_init(struct amdgpu_device *adev)
        adev->gmc.aper_size = pci_resource_len(adev->pdev, 0);
 
 #ifdef CONFIG_X86_64
-       if (adev->flags & AMD_IS_APU) {
+       if (adev->flags & AMD_IS_APU &&
+           adev->gmc.real_vram_size > adev->gmc.aper_size) {
                adev->gmc.aper_base = ((u64)RREG32(mmMC_VM_FB_OFFSET)) << 22;
                adev->gmc.aper_size = adev->gmc.real_vram_size;
        }
index 40a4968..90216ab 100644 (file)
@@ -476,13 +476,13 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
 {
        bool use_semaphore = gmc_v9_0_use_invalidate_semaphore(adev, vmhub);
        const unsigned eng = 17;
-       u32 j, tmp;
+       u32 j, inv_req, tmp;
        struct amdgpu_vmhub *hub;
 
        BUG_ON(vmhub >= adev->num_vmhubs);
 
        hub = &adev->vmhub[vmhub];
-       tmp = gmc_v9_0_get_invalidate_req(vmid, flush_type);
+       inv_req = gmc_v9_0_get_invalidate_req(vmid, flush_type);
 
        /* This is necessary for a HW workaround under SRIOV as well
         * as GFXOFF under bare metal
@@ -493,7 +493,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
                uint32_t req = hub->vm_inv_eng0_req + eng;
                uint32_t ack = hub->vm_inv_eng0_ack + eng;
 
-               amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, tmp,
+               amdgpu_virt_kiq_reg_write_reg_wait(adev, req, ack, inv_req,
                                1 << vmid);
                return;
        }
@@ -521,7 +521,7 @@ static void gmc_v9_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
                        DRM_ERROR("Timeout waiting for sem acquire in VM flush!\n");
        }
 
-       WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, tmp);
+       WREG32_NO_KIQ(hub->vm_inv_eng0_req + eng, inv_req);
 
        /*
         * Issue a dummy read to wait for the ACK register to be cleared
@@ -578,7 +578,8 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
 
        if (ring->sched.ready) {
                spin_lock(&adev->gfx.kiq.ring_lock);
-               amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size);
+               /* 2 dwords flush + 8 dwords fence */
+               amdgpu_ring_alloc(ring, kiq->pmf->invalidate_tlbs_size + 8);
                kiq->pmf->kiq_invalidate_tlbs(ring,
                                        pasid, flush_type, all_hub);
                amdgpu_fence_emit_polling(ring, &seq);
@@ -601,10 +602,10 @@ static int gmc_v9_0_flush_gpu_tlb_pasid(struct amdgpu_device *adev,
                        if (all_hub) {
                                for (i = 0; i < adev->num_vmhubs; i++)
                                        gmc_v9_0_flush_gpu_tlb(adev, vmid,
-                                                       i, 0);
+                                                       i, flush_type);
                        } else {
                                gmc_v9_0_flush_gpu_tlb(adev, vmid,
-                                               AMDGPU_GFXHUB_0, 0);
+                                               AMDGPU_GFXHUB_0, flush_type);
                        }
                        break;
                }
index a78292d..ff2e6e1 100644 (file)
@@ -690,7 +690,7 @@ static int jpeg_v2_0_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
 
        if (enable) {
                if (jpeg_v2_0_is_idle(handle))
index 2c58939..c6d046d 100644 (file)
@@ -469,7 +469,7 @@ static int jpeg_v2_5_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
        int i;
 
        for (i = 0; i < adev->jpeg.num_jpeg_inst; ++i) {
index adfd8a6..49a3a56 100644 (file)
@@ -523,9 +523,9 @@ int mmhub_v1_0_set_clockgating(struct amdgpu_device *adev,
        case CHIP_RAVEN:
        case CHIP_RENOIR:
                mmhub_v1_0_update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                mmhub_v1_0_update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
index a7cb185..bde1896 100644 (file)
@@ -427,9 +427,9 @@ int mmhub_v2_0_set_clockgating(struct amdgpu_device *adev,
        case CHIP_NAVI14:
        case CHIP_NAVI12:
                mmhub_v2_0_update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                mmhub_v2_0_update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
index 5c42387..a5281df 100644 (file)
@@ -625,9 +625,9 @@ int mmhub_v9_4_set_clockgating(struct amdgpu_device *adev,
        switch (adev->asic_type) {
        case CHIP_ARCTURUS:
                mmhub_v9_4_update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                mmhub_v9_4_update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
@@ -663,6 +663,7 @@ void mmhub_v9_4_get_clockgating(struct amdgpu_device *adev, u32 *flags)
 }
 
 static const struct soc15_ras_field_entry mmhub_v9_4_ras_fields[] = {
+       /* MMHUB Range 0 */
        { "MMEA0_DRAMRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT),
        SOC15_REG_FIELD(MMEA0_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
        SOC15_REG_FIELD(MMEA0_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT),
@@ -751,6 +752,24 @@ static const struct soc15_ras_field_entry mmhub_v9_4_ras_fields[] = {
        0, 0,
        SOC15_REG_FIELD(MMEA0_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT),
        },
+       { "MMEA0_MAM_D0MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA0_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA0_EDC_CNT2, MAM_D0MEM_DED_COUNT),
+       },
+       { "MMEA0_MAM_D1MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA0_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA0_EDC_CNT2, MAM_D1MEM_DED_COUNT),
+       },
+       { "MMEA0_MAM_D2MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA0_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA0_EDC_CNT2, MAM_D2MEM_DED_COUNT),
+       },
+       { "MMEA0_MAM_D3MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA0_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA0_EDC_CNT2, MAM_D3MEM_DED_COUNT),
+       },
+
+       /* MMHUB Range 1 */
        { "MMEA1_DRAMRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT),
        SOC15_REG_FIELD(MMEA1_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
        SOC15_REG_FIELD(MMEA1_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT),
@@ -838,16 +857,686 @@ static const struct soc15_ras_field_entry mmhub_v9_4_ras_fields[] = {
        { "MMEA1_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT3),
        0, 0,
        SOC15_REG_FIELD(MMEA1_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA1_MAM_D0MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA1_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA1_EDC_CNT2, MAM_D0MEM_DED_COUNT),
+       },
+       { "MMEA1_MAM_D1MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA1_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA1_EDC_CNT2, MAM_D1MEM_DED_COUNT),
+       },
+       { "MMEA1_MAM_D2MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA1_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA1_EDC_CNT2, MAM_D2MEM_DED_COUNT),
+       },
+       { "MMEA1_MAM_D3MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA1_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA1_EDC_CNT2, MAM_D3MEM_DED_COUNT),
+       },
+
+       /* MMHAB Range 2*/
+       { "MMEA2_DRAMRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA2_DRAMWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA2_DRAMWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA2_RRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, RRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA2_WRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, WRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA2_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA2_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA2_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, IORD_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA2_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, IOWR_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA2_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT, IOWR_DATAMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA2_GMIRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA2_GMIWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA2_GMIWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA2_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA2_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA2_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA2_EDC_CNT3, DRAMRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA2_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA2_EDC_CNT3, DRAMWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA2_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA2_EDC_CNT3, IORD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA2_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA2_EDC_CNT3, IOWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA2_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA2_EDC_CNT3, IOWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA2_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA2_EDC_CNT3, GMIRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA2_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA2_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA2_MAM_D0MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, MAM_D0MEM_DED_COUNT),
+       },
+       { "MMEA2_MAM_D1MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, MAM_D1MEM_DED_COUNT),
+       },
+       { "MMEA2_MAM_D2MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, MAM_D2MEM_DED_COUNT),
+       },
+       { "MMEA2_MAM_D3MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA2_EDC_CNT2, MAM_D3MEM_DED_COUNT),
+       },
+
+       /* MMHUB Rang 3 */
+       { "MMEA3_DRAMRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA3_DRAMWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA3_DRAMWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA3_RRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, RRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA3_WRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, WRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA3_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA3_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA3_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, IORD_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA3_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, IOWR_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA3_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT, IOWR_DATAMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA3_GMIRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA3_GMIWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA3_GMIWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA3_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA3_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA3_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA3_EDC_CNT3, DRAMRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA3_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA3_EDC_CNT3, DRAMWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA3_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA3_EDC_CNT3, IORD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA3_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA3_EDC_CNT3, IOWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA3_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA3_EDC_CNT3, IOWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA3_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA3_EDC_CNT3, GMIRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA3_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA3_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA3_MAM_D0MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, MAM_D0MEM_DED_COUNT),
+       },
+       { "MMEA3_MAM_D1MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, MAM_D1MEM_DED_COUNT),
+       },
+       { "MMEA3_MAM_D2MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, MAM_D2MEM_DED_COUNT),
+       },
+       { "MMEA3_MAM_D3MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA3_EDC_CNT2, MAM_D3MEM_DED_COUNT),
+       },
+
+       /* MMHUB Range 4 */
+       { "MMEA4_DRAMRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA4_DRAMWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA4_DRAMWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA4_RRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, RRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA4_WRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, WRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA4_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA4_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA4_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, IORD_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA4_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, IOWR_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA4_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT, IOWR_DATAMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA4_GMIRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA4_GMIWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA4_GMIWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA4_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA4_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA4_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA4_EDC_CNT3, DRAMRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA4_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA4_EDC_CNT3, DRAMWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA4_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA4_EDC_CNT3, IORD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA4_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA4_EDC_CNT3, IOWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA4_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA4_EDC_CNT3, IOWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA4_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA4_EDC_CNT3, GMIRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA4_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA4_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA4_MAM_D0MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, MAM_D0MEM_DED_COUNT),
+       },
+       { "MMEA4_MAM_D1MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, MAM_D1MEM_DED_COUNT),
+       },
+       { "MMEA4_MAM_D2MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, MAM_D2MEM_DED_COUNT),
+       },
+       { "MMEA4_MAM_D3MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA4_EDC_CNT2, MAM_D3MEM_DED_COUNT),
+       },
+
+       /* MMHUAB Range 5 */
+       { "MMEA5_DRAMRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA5_DRAMWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA5_DRAMWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA5_RRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, RRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA5_WRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, WRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA5_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA5_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA5_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, IORD_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA5_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, IOWR_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA5_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT, IOWR_DATAMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA5_GMIRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA5_GMIWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA5_GMIWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA5_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA5_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA5_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA5_EDC_CNT3, DRAMRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA5_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA5_EDC_CNT3, DRAMWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA5_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA5_EDC_CNT3, IORD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA5_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA5_EDC_CNT3, IOWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA5_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA5_EDC_CNT3, IOWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA5_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA5_EDC_CNT3, GMIRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA5_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA5_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA5_MAM_D0MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, MAM_D0MEM_DED_COUNT),
+       },
+       { "MMEA5_MAM_D1MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, MAM_D1MEM_DED_COUNT),
+       },
+       { "MMEA5_MAM_D2MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, MAM_D2MEM_DED_COUNT),
+       },
+       { "MMEA5_MAM_D3MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA5_EDC_CNT2, MAM_D3MEM_DED_COUNT),
+       },
+
+       /* MMHUB Range 6 */
+       { "MMEA6_DRAMRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA6_DRAMWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA6_DRAMWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA6_RRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, RRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA6_WRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, WRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA6_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA6_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA6_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, IORD_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA6_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, IOWR_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA6_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT, IOWR_DATAMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA6_GMIRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA6_GMIWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA6_GMIWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA6_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA6_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA6_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA6_EDC_CNT3, DRAMRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA6_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA6_EDC_CNT3, DRAMWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA6_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA6_EDC_CNT3, IORD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA6_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA6_EDC_CNT3, IOWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA6_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA6_EDC_CNT3, IOWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA6_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA6_EDC_CNT3, GMIRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA6_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA6_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA6_MAM_D0MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, MAM_D0MEM_DED_COUNT),
+       },
+       { "MMEA6_MAM_D1MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, MAM_D1MEM_DED_COUNT),
+       },
+       { "MMEA6_MAM_D2MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, MAM_D2MEM_DED_COUNT),
+       },
+       { "MMEA6_MAM_D3MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA6_EDC_CNT2, MAM_D3MEM_DED_COUNT),
+       },
+
+       /* MMHUB Range 7*/
+       { "MMEA7_DRAMRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, DRAMRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, DRAMRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA7_DRAMWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, DRAMWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, DRAMWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA7_DRAMWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, DRAMWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, DRAMWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA7_RRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, RRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, RRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA7_WRET_TAGMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, WRET_TAGMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, WRET_TAGMEM_DED_COUNT),
+       },
+       { "MMEA7_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, DRAMRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA7_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, DRAMWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA7_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, IORD_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA7_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, IOWR_CMDMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA7_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT, IOWR_DATAMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA7_GMIRD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, GMIRD_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, GMIRD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA7_GMIWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, GMIWR_CMDMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, GMIWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA7_GMIWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, GMIWR_DATAMEM_SEC_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, GMIWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA7_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, GMIRD_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA7_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, GMIWR_PAGEMEM_SED_COUNT),
+       0, 0,
+       },
+       { "MMEA7_DRAMRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA7_EDC_CNT3, DRAMRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA7_DRAMWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA7_EDC_CNT3, DRAMWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA7_IORD_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA7_EDC_CNT3, IORD_CMDMEM_DED_COUNT),
+       },
+       { "MMEA7_IOWR_CMDMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA7_EDC_CNT3, IOWR_CMDMEM_DED_COUNT),
+       },
+       { "MMEA7_IOWR_DATAMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA7_EDC_CNT3, IOWR_DATAMEM_DED_COUNT),
+       },
+       { "MMEA7_GMIRD_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA7_EDC_CNT3, GMIRD_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA7_GMIWR_PAGEMEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT3),
+       0, 0,
+       SOC15_REG_FIELD(MMEA7_EDC_CNT3, GMIWR_PAGEMEM_DED_COUNT),
+       },
+       { "MMEA7_MAM_D0MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, MAM_D0MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, MAM_D0MEM_DED_COUNT),
+       },
+       { "MMEA7_MAM_D1MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, MAM_D1MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, MAM_D1MEM_DED_COUNT),
+       },
+       { "MMEA7_MAM_D2MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, MAM_D2MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, MAM_D2MEM_DED_COUNT),
+       },
+       { "MMEA7_MAM_D3MEM", SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, MAM_D3MEM_SED_COUNT),
+       SOC15_REG_FIELD(MMEA7_EDC_CNT2, MAM_D3MEM_DED_COUNT),
        }
 };
 
 static const struct soc15_reg_entry mmhub_v9_4_edc_cnt_regs[] = {
-   { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT), 0, 0, 0},
-   { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT2), 0, 0, 0},
-   { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT3), 0, 0, 0},
-   { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT), 0, 0, 0},
-   { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT2), 0, 0, 0},
-   { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT3), 0, 0, 0},
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT2), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA0_EDC_CNT3), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT2), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA1_EDC_CNT3), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT2), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA2_EDC_CNT3), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT2), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA3_EDC_CNT3), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT2), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA4_EDC_CNT3), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT2), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA5_EDC_CNT3), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT2), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA6_EDC_CNT3), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT2), 0, 0, 0 },
+       { SOC15_REG_ENTRY(MMHUB, 0, mmMMEA7_EDC_CNT3), 0, 0, 0 },
 };
 
 static int mmhub_v9_4_get_ras_error_count(const struct soc15_reg_entry *reg,
index f737ce4..cf557a4 100644 (file)
@@ -426,7 +426,7 @@ static int navi10_ih_set_clockgating_state(void *handle,
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        navi10_ih_update_clockgating_state(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
        return 0;
 }
 
index 2e0f893..2d1bebd 100644 (file)
@@ -950,13 +950,13 @@ static int nv_common_set_clockgating_state(void *handle,
        case CHIP_NAVI14:
        case CHIP_NAVI12:
                adev->nbio.funcs->update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                adev->nbio.funcs->update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                nv_update_hdp_mem_power_gating(adev,
-                                  state == AMD_CG_STATE_GATE ? true : false);
+                                  state == AMD_CG_STATE_GATE);
                nv_update_hdp_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
index 685dd97..0829188 100644 (file)
@@ -22,6 +22,7 @@
 
 #include <linux/firmware.h>
 #include <linux/module.h>
+#include <linux/vmalloc.h>
 
 #include "amdgpu.h"
 #include "amdgpu_psp.h"
@@ -971,10 +972,13 @@ Err_out:
  */
 static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
 {
-       int ret;
-       uint32_t p2c_header[4];
        struct psp_memory_training_context *ctx = &psp->mem_train_ctx;
        uint32_t *pcache = (uint32_t*)ctx->sys_cache;
+       struct amdgpu_device *adev = psp->adev;
+       uint32_t p2c_header[4];
+       uint32_t sz;
+       void *buf;
+       int ret;
 
        if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) {
                DRM_DEBUG("Memory training is not supported.\n");
@@ -989,7 +993,7 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
                return 0;
        }
 
-       amdgpu_device_vram_access(psp->adev, ctx->p2c_train_data_offset, p2c_header, sizeof(p2c_header), false);
+       amdgpu_device_vram_access(adev, ctx->p2c_train_data_offset, p2c_header, sizeof(p2c_header), false);
        DRM_DEBUG("sys_cache[%08x,%08x,%08x,%08x] p2c_header[%08x,%08x,%08x,%08x]\n",
                  pcache[0], pcache[1], pcache[2], pcache[3],
                  p2c_header[0], p2c_header[1], p2c_header[2], p2c_header[3]);
@@ -1026,11 +1030,38 @@ static int psp_v11_0_memory_training(struct psp_context *psp, uint32_t ops)
        DRM_DEBUG("Memory training ops:%x.\n", ops);
 
        if (ops & PSP_MEM_TRAIN_SEND_LONG_MSG) {
+               /*
+                * Long traing will encroach certain mount of bottom VRAM,
+                * saving the content of this bottom VRAM to system memory
+                * before training, and restoring it after training to avoid
+                * VRAM corruption.
+                */
+               sz = GDDR6_MEM_TRAINING_ENCROACHED_SIZE;
+
+               if (adev->gmc.visible_vram_size < sz || !adev->mman.aper_base_kaddr) {
+                       DRM_ERROR("visible_vram_size %llx or aper_base_kaddr %p is not initialized.\n",
+                                 adev->gmc.visible_vram_size,
+                                 adev->mman.aper_base_kaddr);
+                       return -EINVAL;
+               }
+
+               buf = vmalloc(sz);
+               if (!buf) {
+                       DRM_ERROR("failed to allocate system memory.\n");
+                       return -ENOMEM;
+               }
+
+               memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz);
                ret = psp_v11_0_memory_training_send_msg(psp, PSP_BL__DRAM_LONG_TRAIN);
                if (ret) {
                        DRM_ERROR("Send long training msg failed.\n");
+                       vfree(buf);
                        return ret;
                }
+
+               memcpy_toio(adev->mman.aper_base_kaddr, buf, sz);
+               adev->nbio.funcs->hdp_flush(adev, NULL);
+               vfree(buf);
        }
 
        if (ops & PSP_MEM_TRAIN_SAVE) {
index 27c7001..e55884d 100644 (file)
@@ -2176,9 +2176,9 @@ static int sdma_v4_0_set_clockgating_state(void *handle,
        case CHIP_ARCTURUS:
        case CHIP_RENOIR:
                sdma_v4_0_update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                sdma_v4_0_update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
index 4c6bf1f..67b9830 100644 (file)
@@ -1525,9 +1525,9 @@ static int sdma_v5_0_set_clockgating_state(void *handle,
        case CHIP_NAVI14:
        case CHIP_NAVI12:
                sdma_v5_0_update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                sdma_v5_0_update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
index 9aac9f9..42d5601 100644 (file)
@@ -648,7 +648,7 @@ static int si_dma_set_clockgating_state(void *handle,
        bool enable;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       enable = (state == AMD_CG_STATE_GATE);
 
        if (enable && (adev->cg_flags & AMD_CG_SUPPORT_SDMA_MGCG)) {
                for (i = 0; i < adev->sdma.num_instances; i++) {
index 317803f..15f3424 100644 (file)
@@ -537,6 +537,10 @@ soc15_asic_reset_method(struct amdgpu_device *adev)
 
 static int soc15_asic_reset(struct amdgpu_device *adev)
 {
+       /* original raven doesn't have full asic reset */
+       if (adev->pdev->device == 0x15dd && adev->rev_id < 0x8)
+               return 0;
+
        switch (soc15_asic_reset_method(adev)) {
                case AMD_RESET_METHOD_BACO:
                        if (!adev->in_suspend)
@@ -1467,38 +1471,38 @@ static int soc15_common_set_clockgating_state(void *handle,
        case CHIP_VEGA12:
        case CHIP_VEGA20:
                adev->nbio.funcs->update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                adev->nbio.funcs->update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                soc15_update_hdp_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                soc15_update_drm_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                soc15_update_drm_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                soc15_update_rom_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                adev->df.funcs->update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        case CHIP_RAVEN:
        case CHIP_RENOIR:
                adev->nbio.funcs->update_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                adev->nbio.funcs->update_medium_grain_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                soc15_update_hdp_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                soc15_update_drm_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                soc15_update_drm_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                soc15_update_rom_medium_grain_clock_gating(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        case CHIP_ARCTURUS:
                soc15_update_hdp_light_sleep(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
                break;
        default:
                break;
index 01e62fb..0fa8aae 100644 (file)
@@ -763,7 +763,7 @@ static int uvd_v5_0_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
 
        if (enable) {
                /* wait for STATUS to clear */
index 217084d..e0aadca 100644 (file)
@@ -1421,7 +1421,7 @@ static int uvd_v6_0_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
 
        if (enable) {
                /* wait for STATUS to clear */
index 475ae68..217db18 100644 (file)
@@ -739,7 +739,7 @@ static int vce_v3_0_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
        int i;
 
        if (!(adev->cg_flags & AMD_CG_SUPPORT_VCE_MGCG))
index 683701c..3fd102e 100644 (file)
@@ -887,7 +887,7 @@ static int vce_v4_0_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
        int i;
 
        if ((adev->asic_type == CHIP_POLARIS10) ||
index e654938..1a24fad 100644 (file)
@@ -1346,7 +1346,7 @@ static int vcn_v1_0_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
 
        if (enable) {
                /* wait for STATUS to clear */
index f4db8af..4f72167 100644 (file)
@@ -1213,7 +1213,7 @@ static int vcn_v2_0_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
 
        if (enable) {
                /* wait for STATUS to clear */
@@ -1624,7 +1624,7 @@ static int vcn_v2_0_process_interrupt(struct amdgpu_device *adev,
        return 0;
 }
 
-static int vcn_v2_0_dec_ring_test_ring(struct amdgpu_ring *ring)
+int vcn_v2_0_dec_ring_test_ring(struct amdgpu_ring *ring)
 {
        struct amdgpu_device *adev = ring->adev;
        uint32_t tmp = 0;
index ef749b0..6c9de18 100644 (file)
@@ -37,6 +37,7 @@ extern void vcn_v2_0_dec_ring_emit_vm_flush(struct amdgpu_ring *ring,
                                unsigned vmid, uint64_t pd_addr);
 extern void vcn_v2_0_dec_ring_emit_wreg(struct amdgpu_ring *ring,
                                uint32_t reg, uint32_t val);
+extern int vcn_v2_0_dec_ring_test_ring(struct amdgpu_ring *ring);
 
 extern void vcn_v2_0_enc_ring_insert_end(struct amdgpu_ring *ring);
 extern void vcn_v2_0_enc_ring_emit_fence(struct amdgpu_ring *ring, u64 addr,
index c8b63d5..70fae79 100644 (file)
@@ -435,88 +435,88 @@ static void vcn_v2_5_mc_resume_dpg_mode(struct amdgpu_device *adev, int inst_idx
        if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) {
                if (!indirect) {
                        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                               UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
+                               UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
                                (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_lo), 0, indirect);
                        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                               UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
+                               UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
                                (adev->firmware.ucode[AMDGPU_UCODE_ID_VCN + inst_idx].tmr_mc_addr_hi), 0, indirect);
                        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                               UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
+                               UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
                } else {
                        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                               UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
+                               UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW), 0, 0, indirect);
                        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                               UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
+                               UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH), 0, 0, indirect);
                        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                               UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
+                               UVD, 0, mmUVD_VCPU_CACHE_OFFSET0), 0, 0, indirect);
                }
                offset = 0;
        } else {
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
+                       UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_LOW),
                        lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
+                       UVD, 0, mmUVD_LMI_VCPU_CACHE_64BIT_BAR_HIGH),
                        upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr), 0, indirect);
                offset = size;
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET0),
+                       UVD, 0, mmUVD_VCPU_CACHE_OFFSET0),
                        AMDGPU_UVD_FIRMWARE_OFFSET >> 3, 0, indirect);
        }
 
        if (!indirect)
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
+                       UVD, 0, mmUVD_VCPU_CACHE_SIZE0), size, 0, indirect);
        else
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
+                       UVD, 0, mmUVD_VCPU_CACHE_SIZE0), 0, 0, indirect);
 
        /* cache window 1: stack */
        if (!indirect) {
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
+                       UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW),
                        lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
+                       UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH),
                        upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset), 0, indirect);
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
+                       UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
        } else {
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
+                       UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_LOW), 0, 0, indirect);
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
+                       UVD, 0, mmUVD_LMI_VCPU_CACHE1_64BIT_BAR_HIGH), 0, 0, indirect);
                WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-                       UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
+                       UVD, 0, mmUVD_VCPU_CACHE_OFFSET1), 0, 0, indirect);
        }
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
+               UVD, 0, mmUVD_VCPU_CACHE_SIZE1), AMDGPU_VCN_STACK_SIZE, 0, indirect);
 
        /* cache window 2: context */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
+               UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_LOW),
                lower_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
+               UVD, 0, mmUVD_LMI_VCPU_CACHE2_64BIT_BAR_HIGH),
                upper_32_bits(adev->vcn.inst[inst_idx].gpu_addr + offset + AMDGPU_VCN_STACK_SIZE), 0, indirect);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
+               UVD, 0, mmUVD_VCPU_CACHE_OFFSET2), 0, 0, indirect);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
+               UVD, 0, mmUVD_VCPU_CACHE_SIZE2), AMDGPU_VCN_CONTEXT_SIZE, 0, indirect);
 
        /* non-cache window */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 0, 0, indirect);
+               UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_LOW), 0, 0, indirect);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 0, 0, indirect);
+               UVD, 0, mmUVD_LMI_VCPU_NC0_64BIT_BAR_HIGH), 0, 0, indirect);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
+               UVD, 0, mmUVD_VCPU_NONCACHE_OFFSET0), 0, 0, indirect);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_VCPU_NONCACHE_SIZE0), 0, 0, indirect);
+               UVD, 0, mmUVD_VCPU_NONCACHE_SIZE0), 0, 0, indirect);
 
        /* VCN global tiling registers */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
+               UVD, 0, mmUVD_GFX8_ADDR_CONFIG), adev->gfx.config.gb_addr_config, 0, indirect);
 }
 
 /**
@@ -670,19 +670,19 @@ static void vcn_v2_5_clock_gating_dpg_mode(struct amdgpu_device *adev,
                 UVD_CGC_CTRL__VCPU_MODE_MASK |
                 UVD_CGC_CTRL__MMSCH_MODE_MASK);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
+               UVD, 0, mmUVD_CGC_CTRL), reg_data, sram_sel, indirect);
 
        /* turn off clock gating */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_CGC_GATE), 0, sram_sel, indirect);
+               UVD, 0, mmUVD_CGC_GATE), 0, sram_sel, indirect);
 
        /* turn on SUVD clock gating */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
+               UVD, 0, mmUVD_SUVD_CGC_GATE), 1, sram_sel, indirect);
 
        /* turn on sw mode in UVD_SUVD_CGC_CTRL */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
+               UVD, 0, mmUVD_SUVD_CGC_CTRL), 0, sram_sel, indirect);
 }
 
 /**
@@ -772,11 +772,11 @@ static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo
        tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
        tmp |= UVD_VCPU_CNTL__BLK_RST_MASK;
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
+               UVD, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
 
        /* disable master interupt */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_MASTINT_EN), 0, 0, indirect);
+               UVD, 0, mmUVD_MASTINT_EN), 0, 0, indirect);
 
        /* setup mmUVD_LMI_CTRL */
        tmp = (0x8 | UVD_LMI_CTRL__WRITE_CLEAN_TIMER_EN_MASK |
@@ -788,28 +788,28 @@ static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo
                (8 << UVD_LMI_CTRL__WRITE_CLEAN_TIMER__SHIFT) |
                0x00100000L);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_LMI_CTRL), tmp, 0, indirect);
+               UVD, 0, mmUVD_LMI_CTRL), tmp, 0, indirect);
 
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_MPC_CNTL),
+               UVD, 0, mmUVD_MPC_CNTL),
                0x2 << UVD_MPC_CNTL__REPLACEMENT_MODE__SHIFT, 0, indirect);
 
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_MPC_SET_MUXA0),
+               UVD, 0, mmUVD_MPC_SET_MUXA0),
                ((0x1 << UVD_MPC_SET_MUXA0__VARA_1__SHIFT) |
                 (0x2 << UVD_MPC_SET_MUXA0__VARA_2__SHIFT) |
                 (0x3 << UVD_MPC_SET_MUXA0__VARA_3__SHIFT) |
                 (0x4 << UVD_MPC_SET_MUXA0__VARA_4__SHIFT)), 0, indirect);
 
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_MPC_SET_MUXB0),
+               UVD, 0, mmUVD_MPC_SET_MUXB0),
                ((0x1 << UVD_MPC_SET_MUXB0__VARB_1__SHIFT) |
                 (0x2 << UVD_MPC_SET_MUXB0__VARB_2__SHIFT) |
                 (0x3 << UVD_MPC_SET_MUXB0__VARB_3__SHIFT) |
                 (0x4 << UVD_MPC_SET_MUXB0__VARB_4__SHIFT)), 0, indirect);
 
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_MPC_SET_MUX),
+               UVD, 0, mmUVD_MPC_SET_MUX),
                ((0x0 << UVD_MPC_SET_MUX__SET_0__SHIFT) |
                 (0x1 << UVD_MPC_SET_MUX__SET_1__SHIFT) |
                 (0x2 << UVD_MPC_SET_MUX__SET_2__SHIFT)), 0, indirect);
@@ -817,26 +817,26 @@ static int vcn_v2_5_start_dpg_mode(struct amdgpu_device *adev, int inst_idx, boo
        vcn_v2_5_mc_resume_dpg_mode(adev, inst_idx, indirect);
 
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
+               UVD, 0, mmUVD_REG_XX_MASK), 0x10, 0, indirect);
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
+               UVD, 0, mmUVD_RBC_XX_IB_REG_CHECK), 0x3, 0, indirect);
 
        /* enable LMI MC and UMC channels */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_LMI_CTRL2), 0, 0, indirect);
+               UVD, 0, mmUVD_LMI_CTRL2), 0, 0, indirect);
 
        /* unblock VCPU register access */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
+               UVD, 0, mmUVD_RB_ARB_CTRL), 0, 0, indirect);
 
        tmp = (0xFF << UVD_VCPU_CNTL__PRB_TIMEOUT_VAL__SHIFT);
        tmp |= UVD_VCPU_CNTL__CLK_EN_MASK;
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_VCPU_CNTL), tmp, 0, indirect);
+               UVD, 0, mmUVD_VCPU_CNTL), tmp, 0, indirect);
 
        /* enable master interrupt */
        WREG32_SOC15_DPG_MODE_2_0(inst_idx, SOC15_DPG_MODE_OFFSET_2_0(
-               UVD, inst_idx, mmUVD_MASTINT_EN),
+               UVD, 0, mmUVD_MASTINT_EN),
                UVD_MASTINT_EN__VCPU_EN_MASK, 0, indirect);
 
        if (indirect)
@@ -891,8 +891,10 @@ static int vcn_v2_5_start(struct amdgpu_device *adev)
        for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
                if (adev->vcn.harvest_config & (1 << i))
                        continue;
-               if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
-                       return vcn_v2_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
+               if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
+                       r = vcn_v2_5_start_dpg_mode(adev, i, adev->vcn.indirect_sram);
+                       continue;
+               }
 
                /* disable register anti-hang mechanism */
                WREG32_P(SOC15_REG_OFFSET(UVD, i, mmUVD_POWER_STATUS), 0,
@@ -903,6 +905,9 @@ static int vcn_v2_5_start(struct amdgpu_device *adev)
                WREG32_SOC15(UVD, i, mmUVD_STATUS, tmp);
        }
 
+       if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG)
+               return 0;
+
        /*SW clock gating */
        vcn_v2_5_disable_clock_gating(adev);
 
@@ -1294,10 +1299,9 @@ static int vcn_v2_5_stop(struct amdgpu_device *adev)
        for (i = 0; i < adev->vcn.num_vcn_inst; ++i) {
                if (adev->vcn.harvest_config & (1 << i))
                        continue;
-
                if (adev->pg_flags & AMD_PG_SUPPORT_VCN_DPG) {
                        r = vcn_v2_5_stop_dpg_mode(adev, i);
-                       goto power_off;
+                       continue;
                }
 
                /* wait for vcn idle */
@@ -1349,7 +1353,6 @@ static int vcn_v2_5_stop(struct amdgpu_device *adev)
                        ~UVD_POWER_STATUS__UVD_POWER_STATUS_MASK);
        }
 
-power_off:
        if (adev->pm.dpm_enabled)
                amdgpu_dpm_enable_uvd(adev, false);
 
@@ -1488,7 +1491,7 @@ static const struct amdgpu_ring_funcs vcn_v2_5_dec_ring_vm_funcs = {
        .emit_ib = vcn_v2_0_dec_ring_emit_ib,
        .emit_fence = vcn_v2_0_dec_ring_emit_fence,
        .emit_vm_flush = vcn_v2_0_dec_ring_emit_vm_flush,
-       .test_ring = amdgpu_vcn_dec_ring_test_ring,
+       .test_ring = vcn_v2_0_dec_ring_test_ring,
        .test_ib = amdgpu_vcn_dec_ring_test_ib,
        .insert_nop = vcn_v2_0_dec_ring_insert_nop,
        .insert_start = vcn_v2_0_dec_ring_insert_start,
@@ -1663,7 +1666,7 @@ static int vcn_v2_5_set_clockgating_state(void *handle,
                                          enum amd_clockgating_state state)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
-       bool enable = (state == AMD_CG_STATE_GATE) ? true : false;
+       bool enable = (state == AMD_CG_STATE_GATE);
 
        if (amdgpu_sriov_vf(adev))
                return 0;
index d9e3310..407c609 100644 (file)
@@ -717,7 +717,7 @@ static int vega10_ih_set_clockgating_state(void *handle,
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
        vega10_ih_update_clockgating_state(adev,
-                               state == AMD_CG_STATE_GATE ? true : false);
+                               state == AMD_CG_STATE_GATE);
        return 0;
 
 }
index 2870553..80d22bf 100644 (file)
@@ -1237,16 +1237,18 @@ static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
 
        list_add(&q->list, &qpd->queues_list);
        qpd->queue_count++;
+
+       if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
+               dqm->sdma_queue_count++;
+       else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
+               dqm->xgmi_sdma_queue_count++;
+
        if (q->properties.is_active) {
                dqm->queue_count++;
                retval = execute_queues_cpsch(dqm,
                                KFD_UNMAP_QUEUES_FILTER_DYNAMIC_QUEUES, 0);
        }
 
-       if (q->properties.type == KFD_QUEUE_TYPE_SDMA)
-               dqm->sdma_queue_count++;
-       else if (q->properties.type == KFD_QUEUE_TYPE_SDMA_XGMI)
-               dqm->xgmi_sdma_queue_count++;
        /*
         * Unconditionally increment this counter, regardless of the queue's
         * type or whether the queue is active.
index 9402374..2795415 100644 (file)
@@ -940,14 +940,14 @@ static int amdgpu_dm_init(struct amdgpu_device *adev)
                goto error;
        }
 
-       dc_hardware_init(adev->dm.dc);
-
        r = dm_dmub_hw_init(adev);
        if (r) {
                DRM_ERROR("DMUB interface failed to initialize: status=%d\n", r);
                goto error;
        }
 
+       dc_hardware_init(adev->dm.dc);
+
        adev->dm.freesync_module = mod_freesync_create(adev->dm.dc);
        if (!adev->dm.freesync_module) {
                DRM_ERROR(
@@ -7759,24 +7759,27 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
        struct drm_crtc_state *new_crtc_state, *old_crtc_state;
        struct dm_crtc_state *new_dm_crtc_state, *old_dm_crtc_state;
        struct dc_stream_status *status = NULL;
-
-       struct dc_surface_update *updates;
        enum surface_update_type update_type = UPDATE_TYPE_FAST;
+       struct surface_info_bundle {
+               struct dc_surface_update surface_updates[MAX_SURFACES];
+               struct dc_plane_info plane_infos[MAX_SURFACES];
+               struct dc_scaling_info scaling_infos[MAX_SURFACES];
+               struct dc_flip_addrs flip_addrs[MAX_SURFACES];
+               struct dc_stream_update stream_update;
+       } *bundle;
 
-       updates = kcalloc(MAX_SURFACES, sizeof(*updates), GFP_KERNEL);
+       bundle = kzalloc(sizeof(*bundle), GFP_KERNEL);
 
-       if (!updates) {
-               DRM_ERROR("Failed to allocate plane updates\n");
+       if (!bundle) {
+               DRM_ERROR("Failed to allocate update bundle\n");
                /* Set type to FULL to avoid crashing in DC*/
                update_type = UPDATE_TYPE_FULL;
                goto cleanup;
        }
 
        for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
-               struct dc_scaling_info scaling_info;
-               struct dc_stream_update stream_update;
 
-               memset(&stream_update, 0, sizeof(stream_update));
+               memset(bundle, 0, sizeof(struct surface_info_bundle));
 
                new_dm_crtc_state = to_dm_crtc_state(new_crtc_state);
                old_dm_crtc_state = to_dm_crtc_state(old_crtc_state);
@@ -7793,8 +7796,9 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
                for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, j) {
                        const struct amdgpu_framebuffer *amdgpu_fb =
                                to_amdgpu_framebuffer(new_plane_state->fb);
-                       struct dc_plane_info plane_info;
-                       struct dc_flip_addrs flip_addr;
+                       struct dc_plane_info *plane_info = &bundle->plane_infos[num_plane];
+                       struct dc_flip_addrs *flip_addr = &bundle->flip_addrs[num_plane];
+                       struct dc_scaling_info *scaling_info = &bundle->scaling_infos[num_plane];
                        uint64_t tiling_flags;
 
                        new_plane_crtc = new_plane_state->crtc;
@@ -7812,49 +7816,48 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
                        if (crtc != new_plane_crtc)
                                continue;
 
-                       updates[num_plane].surface = new_dm_plane_state->dc_state;
+                       bundle->surface_updates[num_plane].surface =
+                                       new_dm_plane_state->dc_state;
 
                        if (new_crtc_state->mode_changed) {
-                               stream_update.dst = new_dm_crtc_state->stream->dst;
-                               stream_update.src = new_dm_crtc_state->stream->src;
+                               bundle->stream_update.dst = new_dm_crtc_state->stream->dst;
+                               bundle->stream_update.src = new_dm_crtc_state->stream->src;
                        }
 
                        if (new_crtc_state->color_mgmt_changed) {
-                               updates[num_plane].gamma =
+                               bundle->surface_updates[num_plane].gamma =
                                                new_dm_plane_state->dc_state->gamma_correction;
-                               updates[num_plane].in_transfer_func =
+                               bundle->surface_updates[num_plane].in_transfer_func =
                                                new_dm_plane_state->dc_state->in_transfer_func;
-                               stream_update.gamut_remap =
+                               bundle->stream_update.gamut_remap =
                                                &new_dm_crtc_state->stream->gamut_remap_matrix;
-                               stream_update.output_csc_transform =
+                               bundle->stream_update.output_csc_transform =
                                                &new_dm_crtc_state->stream->csc_color_matrix;
-                               stream_update.out_transfer_func =
+                               bundle->stream_update.out_transfer_func =
                                                new_dm_crtc_state->stream->out_transfer_func;
                        }
 
                        ret = fill_dc_scaling_info(new_plane_state,
-                                                  &scaling_info);
+                                                  scaling_info);
                        if (ret)
                                goto cleanup;
 
-                       updates[num_plane].scaling_info = &scaling_info;
+                       bundle->surface_updates[num_plane].scaling_info = scaling_info;
 
                        if (amdgpu_fb) {
                                ret = get_fb_info(amdgpu_fb, &tiling_flags);
                                if (ret)
                                        goto cleanup;
 
-                               memset(&flip_addr, 0, sizeof(flip_addr));
-
                                ret = fill_dc_plane_info_and_addr(
                                        dm->adev, new_plane_state, tiling_flags,
-                                       &plane_info,
-                                       &flip_addr.address);
+                                       plane_info,
+                                       &flip_addr->address);
                                if (ret)
                                        goto cleanup;
 
-                               updates[num_plane].plane_info = &plane_info;
-                               updates[num_plane].flip_addr = &flip_addr;
+                               bundle->surface_updates[num_plane].plane_info = plane_info;
+                               bundle->surface_updates[num_plane].flip_addr = flip_addr;
                        }
 
                        num_plane++;
@@ -7875,14 +7878,15 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
 
                status = dc_stream_get_status_from_state(old_dm_state->context,
                                                         new_dm_crtc_state->stream);
-               stream_update.stream = new_dm_crtc_state->stream;
+               bundle->stream_update.stream = new_dm_crtc_state->stream;
                /*
                 * TODO: DC modifies the surface during this call so we need
                 * to lock here - find a way to do this without locking.
                 */
                mutex_lock(&dm->dc_lock);
-               update_type = dc_check_update_surfaces_for_stream(dc, updates, num_plane,
-                                                                 &stream_update, status);
+               update_type = dc_check_update_surfaces_for_stream(
+                               dc,     bundle->surface_updates, num_plane,
+                               &bundle->stream_update, status);
                mutex_unlock(&dm->dc_lock);
 
                if (update_type > UPDATE_TYPE_MED) {
@@ -7892,7 +7896,7 @@ dm_determine_update_type_for_commit(struct amdgpu_display_manager *dm,
        }
 
 cleanup:
-       kfree(updates);
+       kfree(bundle);
 
        *out_type = update_type;
        return ret;
@@ -8163,6 +8167,16 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                        goto fail;
 #endif
 
+               /*
+                * Perform validation of MST topology in the state:
+                * We need to perform MST atomic check before calling
+                * dc_validate_global_state(), or there is a chance
+                * to get stuck in an infinite loop and hang eventually.
+                */
+               ret = drm_dp_mst_atomic_check(state);
+               if (ret)
+                       goto fail;
+
                if (dc_validate_global_state(dc, dm_state->context, false) != DC_OK) {
                        ret = -EINVAL;
                        goto fail;
@@ -8191,10 +8205,6 @@ static int amdgpu_dm_atomic_check(struct drm_device *dev,
                                dc_retain_state(old_dm_state->context);
                }
        }
-       /* Perform validation of MST topology in the state*/
-       ret = drm_dp_mst_atomic_check(state);
-       if (ret)
-               goto fail;
 
        /* Store the overall update type for use later in atomic check. */
        for_each_new_crtc_in_state (state, crtc, new_crtc_state, i) {
index ae32933..0acd340 100644 (file)
@@ -135,6 +135,20 @@ void hdcp_update_display(struct hdcp_workqueue *hdcp_work,
        mutex_unlock(&hdcp_w->mutex);
 }
 
+static void hdcp_remove_display(struct hdcp_workqueue *hdcp_work,
+                        unsigned int link_index,
+                        struct amdgpu_dm_connector *aconnector)
+{
+       struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
+
+       mutex_lock(&hdcp_w->mutex);
+       hdcp_w->aconnector = aconnector;
+
+       mod_hdcp_remove_display(&hdcp_w->hdcp, aconnector->base.index, &hdcp_w->output);
+
+       process_output(hdcp_w);
+       mutex_unlock(&hdcp_w->mutex);
+}
 void hdcp_reset_display(struct hdcp_workqueue *hdcp_work, unsigned int link_index)
 {
        struct hdcp_workqueue *hdcp_w = &hdcp_work[link_index];
@@ -303,6 +317,11 @@ static void update_config(void *handle, struct cp_psp_stream_config *config)
        memset(link, 0, sizeof(*link));
 
        display->index = aconnector->base.index;
+
+       if (config->dpms_off) {
+               hdcp_remove_display(hdcp_work, link_index, aconnector);
+               return;
+       }
        display->state = MOD_HDCP_DISPLAY_ACTIVE;
 
        if (aconnector->dc_sink != NULL)
index 069b7a6..318b474 100644 (file)
@@ -216,7 +216,8 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
                drm_dp_mst_reset_vcpi_slots(mst_mgr, mst_port);
        }
 
-       ret = drm_dp_update_payload_part1(mst_mgr);
+       /* It's OK for this to fail */
+       drm_dp_update_payload_part1(mst_mgr);
 
        /* mst_mgr->->payloads are VC payload notify MST branch using DPCD or
         * AUX message. The sequence is slot 1-63 allocated sequence for each
@@ -225,9 +226,6 @@ bool dm_helpers_dp_mst_write_payload_allocation_table(
 
        get_payload_table(aconnector, proposed_table);
 
-       if (ret)
-               return false;
-
        return true;
 }
 
@@ -285,7 +283,6 @@ bool dm_helpers_dp_mst_send_payload_allocation(
        struct amdgpu_dm_connector *aconnector;
        struct drm_dp_mst_topology_mgr *mst_mgr;
        struct drm_dp_mst_port *mst_port;
-       int ret;
 
        aconnector = (struct amdgpu_dm_connector *)stream->dm_stream_context;
 
@@ -299,10 +296,8 @@ bool dm_helpers_dp_mst_send_payload_allocation(
        if (!mst_mgr->mst_state)
                return false;
 
-       ret = drm_dp_update_payload_part2(mst_mgr);
-
-       if (ret)
-               return false;
+       /* It's OK for this to fail */
+       drm_dp_update_payload_part2(mst_mgr);
 
        if (!enable)
                drm_dp_mst_deallocate_vcpi(mst_mgr, mst_port);
index 96b391e..5672f77 100644 (file)
@@ -632,7 +632,7 @@ static void increase_dsc_bpp(struct drm_atomic_state *state,
                        if (drm_dp_atomic_find_vcpi_slots(state,
                                                          params[next_index].port->mgr,
                                                          params[next_index].port,
-                                                         vars[next_index].pbn,\
+                                                         vars[next_index].pbn,
                                                          dm_mst_get_pbn_divider(dc_link)) < 0)
                                return;
                        if (!drm_dp_mst_atomic_check(state)) {
index 2cb7a42..629a07a 100644 (file)
@@ -89,6 +89,10 @@ static enum bp_result encoder_control_digx_v1_5(
        struct bios_parser *bp,
        struct bp_encoder_control *cntl);
 
+static enum bp_result encoder_control_fallback(
+       struct bios_parser *bp,
+       struct bp_encoder_control *cntl);
+
 static void init_dig_encoder_control(struct bios_parser *bp)
 {
        uint32_t version =
@@ -100,7 +104,7 @@ static void init_dig_encoder_control(struct bios_parser *bp)
                break;
        default:
                dm_output_to_console("Don't have dig_encoder_control for v%d\n", version);
-               bp->cmd_tbl.dig_encoder_control = NULL;
+               bp->cmd_tbl.dig_encoder_control = encoder_control_fallback;
                break;
        }
 }
@@ -184,6 +188,18 @@ static enum bp_result encoder_control_digx_v1_5(
        return result;
 }
 
+static enum bp_result encoder_control_fallback(
+       struct bios_parser *bp,
+       struct bp_encoder_control *cntl)
+{
+       if (bp->base.ctx->dc->ctx->dmub_srv &&
+           bp->base.ctx->dc->debug.dmub_command_table) {
+               return encoder_control_digx_v1_5(bp, cntl);
+       }
+
+       return BP_RESULT_FAILURE;
+}
+
 /*****************************************************************************
  ******************************************************************************
  **
@@ -196,6 +212,10 @@ static enum bp_result transmitter_control_v1_6(
        struct bios_parser *bp,
        struct bp_transmitter_control *cntl);
 
+static enum bp_result transmitter_control_fallback(
+       struct bios_parser *bp,
+       struct bp_transmitter_control *cntl);
+
 static void init_transmitter_control(struct bios_parser *bp)
 {
        uint8_t frev;
@@ -209,7 +229,7 @@ static void init_transmitter_control(struct bios_parser *bp)
                break;
        default:
                dm_output_to_console("Don't have transmitter_control for v%d\n", crev);
-               bp->cmd_tbl.transmitter_control = NULL;
+               bp->cmd_tbl.transmitter_control = transmitter_control_fallback;
                break;
        }
 }
@@ -273,6 +293,18 @@ static enum bp_result transmitter_control_v1_6(
        return result;
 }
 
+static enum bp_result transmitter_control_fallback(
+       struct bios_parser *bp,
+       struct bp_transmitter_control *cntl)
+{
+       if (bp->base.ctx->dc->ctx->dmub_srv &&
+           bp->base.ctx->dc->debug.dmub_command_table) {
+               return transmitter_control_v1_6(bp, cntl);
+       }
+
+       return BP_RESULT_FAILURE;
+}
+
 /******************************************************************************
  ******************************************************************************
  **
@@ -285,6 +317,10 @@ static enum bp_result set_pixel_clock_v7(
        struct bios_parser *bp,
        struct bp_pixel_clock_parameters *bp_params);
 
+static enum bp_result set_pixel_clock_fallback(
+       struct bios_parser *bp,
+       struct bp_pixel_clock_parameters *bp_params);
+
 static void init_set_pixel_clock(struct bios_parser *bp)
 {
        switch (BIOS_CMD_TABLE_PARA_REVISION(setpixelclock)) {
@@ -294,7 +330,7 @@ static void init_set_pixel_clock(struct bios_parser *bp)
        default:
                dm_output_to_console("Don't have set_pixel_clock for v%d\n",
                         BIOS_CMD_TABLE_PARA_REVISION(setpixelclock));
-               bp->cmd_tbl.set_pixel_clock = NULL;
+               bp->cmd_tbl.set_pixel_clock = set_pixel_clock_fallback;
                break;
        }
 }
@@ -400,6 +436,18 @@ static enum bp_result set_pixel_clock_v7(
        return result;
 }
 
+static enum bp_result set_pixel_clock_fallback(
+       struct bios_parser *bp,
+       struct bp_pixel_clock_parameters *bp_params)
+{
+       if (bp->base.ctx->dc->ctx->dmub_srv &&
+           bp->base.ctx->dc->debug.dmub_command_table) {
+               return set_pixel_clock_v7(bp, bp_params);
+       }
+
+       return BP_RESULT_FAILURE;
+}
+
 /******************************************************************************
  ******************************************************************************
  **
@@ -632,6 +680,11 @@ static enum bp_result enable_disp_power_gating_v2_1(
        enum controller_id crtc_id,
        enum bp_pipe_control_action action);
 
+static enum bp_result enable_disp_power_gating_fallback(
+       struct bios_parser *bp,
+       enum controller_id crtc_id,
+       enum bp_pipe_control_action action);
+
 static void init_enable_disp_power_gating(
        struct bios_parser *bp)
 {
@@ -643,7 +696,7 @@ static void init_enable_disp_power_gating(
        default:
                dm_output_to_console("Don't enable_disp_power_gating enable_crtc for v%d\n",
                         BIOS_CMD_TABLE_PARA_REVISION(enabledisppowergating));
-               bp->cmd_tbl.enable_disp_power_gating = NULL;
+               bp->cmd_tbl.enable_disp_power_gating = enable_disp_power_gating_fallback;
                break;
        }
 }
@@ -658,6 +711,10 @@ static void enable_disp_power_gating_dmcub(
        power_gating.header.sub_type = DMUB_CMD__VBIOS_ENABLE_DISP_POWER_GATING;
        power_gating.power_gating.pwr = *pwr;
 
+       /* ATOM_ENABLE is old API in DMUB */
+       if (power_gating.power_gating.pwr.enable == ATOM_ENABLE)
+               power_gating.power_gating.pwr.enable = ATOM_INIT;
+
        dc_dmub_srv_cmd_queue(dmcub, &power_gating.header);
        dc_dmub_srv_cmd_execute(dmcub);
        dc_dmub_srv_wait_idle(dmcub);
@@ -695,6 +752,19 @@ static enum bp_result enable_disp_power_gating_v2_1(
        return result;
 }
 
+static enum bp_result enable_disp_power_gating_fallback(
+       struct bios_parser *bp,
+       enum controller_id crtc_id,
+       enum bp_pipe_control_action action)
+{
+       if (bp->base.ctx->dc->ctx->dmub_srv &&
+           bp->base.ctx->dc->debug.dmub_command_table) {
+               return enable_disp_power_gating_v2_1(bp, crtc_id, action);
+       }
+
+       return BP_RESULT_FAILURE;
+}
+
 /******************************************************************************
 *******************************************************************************
  **
index a27d84c..1a37550 100644 (file)
@@ -1435,6 +1435,7 @@ void dcn_bw_update_from_pplib(struct dc *dc)
        struct dc_context *ctx = dc->ctx;
        struct dm_pp_clock_levels_with_voltage fclks = {0}, dcfclks = {0};
        bool res;
+       unsigned vmin0p65_idx, vmid0p72_idx, vnom0p8_idx, vmax0p9_idx;
 
        /* TODO: This is not the proper way to obtain fabric_and_dram_bandwidth, should be min(fclk, memclk) */
        res = dm_pp_get_clock_levels_by_type_with_voltage(
@@ -1446,17 +1447,28 @@ void dcn_bw_update_from_pplib(struct dc *dc)
                res = verify_clock_values(&fclks);
 
        if (res) {
-               ASSERT(fclks.num_levels >= 3);
-               dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 = 32 * (fclks.data[0].clocks_in_khz / 1000.0) / 1000.0;
-               dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc->number_of_channels *
-                               (fclks.data[fclks.num_levels - (fclks.num_levels > 2 ? 3 : 2)].clocks_in_khz / 1000.0)
-                               * ddr4_dram_factor_single_Channel / 1000.0;
-               dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc->number_of_channels *
-                               (fclks.data[fclks.num_levels - 2].clocks_in_khz / 1000.0)
-                               * ddr4_dram_factor_single_Channel / 1000.0;
-               dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc->number_of_channels *
-                               (fclks.data[fclks.num_levels - 1].clocks_in_khz / 1000.0)
-                               * ddr4_dram_factor_single_Channel / 1000.0;
+               ASSERT(fclks.num_levels);
+
+               vmin0p65_idx = 0;
+               vmid0p72_idx = fclks.num_levels -
+                       (fclks.num_levels > 2 ? 3 : (fclks.num_levels > 1 ? 2 : 1));
+               vnom0p8_idx = fclks.num_levels - (fclks.num_levels > 1 ? 2 : 1);
+               vmax0p9_idx = fclks.num_levels - 1;
+
+               dc->dcn_soc->fabric_and_dram_bandwidth_vmin0p65 =
+                       32 * (fclks.data[vmin0p65_idx].clocks_in_khz / 1000.0) / 1000.0;
+               dc->dcn_soc->fabric_and_dram_bandwidth_vmid0p72 =
+                       dc->dcn_soc->number_of_channels *
+                       (fclks.data[vmid0p72_idx].clocks_in_khz / 1000.0)
+                       * ddr4_dram_factor_single_Channel / 1000.0;
+               dc->dcn_soc->fabric_and_dram_bandwidth_vnom0p8 =
+                       dc->dcn_soc->number_of_channels *
+                       (fclks.data[vnom0p8_idx].clocks_in_khz / 1000.0)
+                       * ddr4_dram_factor_single_Channel / 1000.0;
+               dc->dcn_soc->fabric_and_dram_bandwidth_vmax0p9 =
+                       dc->dcn_soc->number_of_channels *
+                       (fclks.data[vmax0p9_idx].clocks_in_khz / 1000.0)
+                       * ddr4_dram_factor_single_Channel / 1000.0;
        } else
                BREAK_TO_DEBUGGER();
 
index 6c797fa..04441db 100644 (file)
@@ -2462,12 +2462,7 @@ void dc_set_power_state(
        enum dc_acpi_cm_power_state power_state)
 {
        struct kref refcount;
-       struct display_mode_lib *dml = kzalloc(sizeof(struct display_mode_lib),
-                                               GFP_KERNEL);
-
-       ASSERT(dml);
-       if (!dml)
-               return;
+       struct display_mode_lib *dml;
 
        switch (power_state) {
        case DC_ACPI_CM_POWER_STATE_D0:
@@ -2490,6 +2485,12 @@ void dc_set_power_state(
                 * clean state, and dc hw programming optimizations will not
                 * cause any trouble.
                 */
+               dml = kzalloc(sizeof(struct display_mode_lib),
+                               GFP_KERNEL);
+
+               ASSERT(dml);
+               if (!dml)
+                       return;
 
                /* Preserve refcount */
                refcount = dc->current_state->refcount;
@@ -2503,10 +2504,10 @@ void dc_set_power_state(
                dc->current_state->refcount = refcount;
                dc->current_state->bw_ctx.dml = *dml;
 
+               kfree(dml);
+
                break;
        }
-
-       kfree(dml);
 }
 
 void dc_resume(struct dc *dc)
index 260c0b6..a09119c 100644 (file)
@@ -851,18 +851,12 @@ static bool dc_link_detect_helper(struct dc_link *link,
                                if (memcmp(&link->dpcd_caps, &prev_dpcd_caps, sizeof(struct dpcd_caps)))
                                        same_dpcd = false;
                        }
-                       /* Active dongle plug in without display or downstream unplug*/
+                       /* Active dongle downstream unplug*/
                        if (link->type == dc_connection_active_dongle &&
                                link->dpcd_caps.sink_count.bits.SINK_COUNT == 0) {
-                               if (prev_sink != NULL) {
+                               if (prev_sink != NULL)
                                        /* Downstream unplug */
                                        dc_sink_release(prev_sink);
-                               } else {
-                                       /* Empty dongle plug in */
-                                       dp_verify_link_cap_with_retries(link,
-                                                       &link->reported_link_cap,
-                                                       LINK_TRAINING_MAX_VERIFY_RETRY);
-                               }
                                return true;
                        }
 
@@ -969,8 +963,7 @@ static bool dc_link_detect_helper(struct dc_link *link,
                        same_edid = is_same_edid(&prev_sink->dc_edid, &sink->dc_edid);
 
                if (link->connector_signal == SIGNAL_TYPE_DISPLAY_PORT &&
-                       sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX &&
-                       reason != DETECT_REASON_HPDRX) {
+                       sink_caps.transaction_type == DDC_TRANSACTION_TYPE_I2C_OVER_AUX) {
                        /*
                         * TODO debug why Dell 2413 doesn't like
                         *  two link trainings
@@ -2882,7 +2875,16 @@ enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link)
        // Clear all of MST payload then reallocate
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
-               if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link &&
+
+               /* driver enable split pipe for external monitors
+                * we have to check pipe_ctx is split pipe or not
+                * If it's split pipe, driver using top pipe to
+                * reaallocate.
+                */
+               if (!pipe_ctx || pipe_ctx->top_pipe)
+                       continue;
+
+               if (pipe_ctx->stream && pipe_ctx->stream->link == link &&
                                pipe_ctx->stream->dpms_off == false &&
                                pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
                        deallocate_mst_payload(pipe_ctx);
@@ -2891,7 +2893,11 @@ enum dc_status dc_link_reallocate_mst_payload(struct dc_link *link)
 
        for (i = 0; i < MAX_PIPES; i++) {
                pipe_ctx = &link->dc->current_state->res_ctx.pipe_ctx[i];
-               if (pipe_ctx && pipe_ctx->stream && pipe_ctx->stream->link == link &&
+
+               if (!pipe_ctx || pipe_ctx->top_pipe)
+                       continue;
+
+               if (pipe_ctx->stream && pipe_ctx->stream->link == link &&
                                pipe_ctx->stream->dpms_off == false &&
                                pipe_ctx->stream->signal == SIGNAL_TYPE_DISPLAY_PORT_MST) {
                        /* enable/disable PHY will clear connection between BE and FE
index 6ab298c..cb731c1 100644 (file)
@@ -983,7 +983,7 @@ static enum link_training_result perform_clock_recovery_sequence(
                                offset);
 
                /* 2. update DPCD of the receiver*/
-               if (!retries_cr)
+               if (!retry_count)
                        /* EPR #361076 - write as a 5-byte burst,
                         * but only for the 1-st iteration.*/
                        dpcd_set_lt_pattern_and_lane_settings(
@@ -3680,7 +3680,7 @@ static void set_crtc_test_pattern(struct dc_link *link,
                        struct pipe_ctx *odm_pipe;
                        enum controller_dp_color_space controller_color_space;
                        int opp_cnt = 1;
-                       uint8_t count = 0;
+                       int count;
 
                        switch (test_pattern_color_space) {
                        case DP_TEST_PATTERN_COLOR_SPACE_RGB:
@@ -3725,11 +3725,11 @@ static void set_crtc_test_pattern(struct dc_link *link,
                                width,
                                height);
                        /* wait for dpg to blank pixel data with test pattern */
-                       for (count = 0; count < 1000; count++)
+                       for (count = 0; count < 1000; count++) {
                                if (opp->funcs->dpg_is_blanked(opp))
                                        break;
-                               else
-                                       udelay(100);
+                               udelay(100);
+                       }
                }
        }
        break;
@@ -3925,8 +3925,38 @@ bool dc_link_dp_set_test_pattern(
                                             sizeof(training_pattern));
                }
        } else {
-       /* CRTC Patterns */
+               enum dc_color_space color_space = COLOR_SPACE_UNKNOWN;
+
+               switch (test_pattern_color_space) {
+               case DP_TEST_PATTERN_COLOR_SPACE_RGB:
+                       color_space = COLOR_SPACE_SRGB;
+                       if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
+                               color_space = COLOR_SPACE_SRGB_LIMITED;
+                       break;
+
+               case DP_TEST_PATTERN_COLOR_SPACE_YCBCR601:
+                       color_space = COLOR_SPACE_YCBCR601;
+                       if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
+                               color_space = COLOR_SPACE_YCBCR601_LIMITED;
+                       break;
+               case DP_TEST_PATTERN_COLOR_SPACE_YCBCR709:
+                       color_space = COLOR_SPACE_YCBCR709;
+                       if (test_pattern == DP_TEST_PATTERN_COLOR_SQUARES_CEA)
+                               color_space = COLOR_SPACE_YCBCR709_LIMITED;
+                       break;
+               default:
+                       break;
+               }
+               /* update MSA to requested color space */
+               pipe_ctx->stream_res.stream_enc->funcs->dp_set_stream_attribute(pipe_ctx->stream_res.stream_enc,
+                               &pipe_ctx->stream->timing,
+                               color_space,
+                               pipe_ctx->stream->use_vsc_sdp_for_colorimetry,
+                               link->dpcd_caps.dprx_feature.bits.SST_SPLIT_SDP_CAP);
+
+               /* CRTC Patterns */
                set_crtc_test_pattern(link, pipe_ctx, test_pattern, test_pattern_color_space);
+
                /* Set Test Pattern state */
                link->test_pattern_enabled = true;
        }
index 3fa85a5..8ff25b5 100644 (file)
@@ -39,7 +39,7 @@
 #include "inc/hw/dmcu.h"
 #include "dml/display_mode_lib.h"
 
-#define DC_VER "3.2.68"
+#define DC_VER "3.2.69"
 
 #define MAX_SURFACES 3
 #define MAX_PLANES 6
@@ -425,6 +425,7 @@ struct dc_debug_options {
        bool validate_dml_output;
        bool enable_dmcub_surface_flip;
        bool usbc_combo_phy_reset_wa;
+       bool disable_dsc;
 };
 
 struct dc_debug_data {
index 1cd4d8f..066188b 100644 (file)
@@ -100,20 +100,6 @@ static uint32_t get_hw_buffer_available_size(
                        dce_i2c_hw->buffer_used_bytes;
 }
 
-static uint32_t get_speed(
-       const struct dce_i2c_hw *dce_i2c_hw)
-{
-       uint32_t pre_scale = 0;
-
-       REG_GET(SPEED, DC_I2C_DDC1_PRESCALE, &pre_scale);
-
-       /* [anaumov] it seems following is unnecessary */
-       /*ASSERT(value.bits.DC_I2C_DDC1_PRESCALE);*/
-       return pre_scale ?
-               dce_i2c_hw->reference_frequency / pre_scale :
-               dce_i2c_hw->default_speed;
-}
-
 static void process_channel_reply(
        struct dce_i2c_hw *dce_i2c_hw,
        struct i2c_payload *reply)
@@ -278,16 +264,25 @@ static void set_speed(
        struct dce_i2c_hw *dce_i2c_hw,
        uint32_t speed)
 {
+       uint32_t xtal_ref_div = 0;
+       uint32_t prescale = 0;
+
+       REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div);
+
+       if (xtal_ref_div == 0)
+               xtal_ref_div = 2;
+
+       prescale = ((dce_i2c_hw->reference_frequency * 2) / xtal_ref_div) / speed;
 
        if (speed) {
                if (dce_i2c_hw->masks->DC_I2C_DDC1_START_STOP_TIMING_CNTL)
                        REG_UPDATE_N(SPEED, 3,
-                                    FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), dce_i2c_hw->reference_frequency / speed,
+                                    FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), prescale,
                                     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2,
                                     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_START_STOP_TIMING_CNTL), speed > 50 ? 2:1);
                else
                        REG_UPDATE_N(SPEED, 2,
-                                    FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), dce_i2c_hw->reference_frequency / speed,
+                                    FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_PRESCALE), prescale,
                                     FN(DC_I2C_DDC1_SPEED, DC_I2C_DDC1_THRESHOLD), 2);
        }
 }
@@ -344,9 +339,7 @@ static void release_engine(
        bool safe_to_reset;
 
        /* Restore original HW engine speed */
-
-       set_speed(dce_i2c_hw, dce_i2c_hw->original_speed);
-
+       set_speed(dce_i2c_hw, dce_i2c_hw->default_speed);
 
        /* Reset HW engine */
        {
@@ -378,7 +371,6 @@ struct dce_i2c_hw *acquire_i2c_hw_engine(
 {
        uint32_t counter = 0;
        enum gpio_result result;
-       uint32_t current_speed;
        struct dce_i2c_hw *dce_i2c_hw = NULL;
 
        if (!ddc)
@@ -416,11 +408,6 @@ struct dce_i2c_hw *acquire_i2c_hw_engine(
 
        dce_i2c_hw->ddc = ddc;
 
-       current_speed = get_speed(dce_i2c_hw);
-
-       if (current_speed)
-               dce_i2c_hw->original_speed = current_speed;
-
        if (!setup_engine(dce_i2c_hw)) {
                release_engine(dce_i2c_hw);
                return NULL;
@@ -478,13 +465,9 @@ static void submit_channel_request_hw(
 
 static uint32_t get_transaction_timeout_hw(
        const struct dce_i2c_hw *dce_i2c_hw,
-       uint32_t length)
+       uint32_t length,
+       uint32_t speed)
 {
-
-       uint32_t speed = get_speed(dce_i2c_hw);
-
-
-
        uint32_t period_timeout;
        uint32_t num_of_clock_stretches;
 
@@ -504,7 +487,8 @@ static uint32_t get_transaction_timeout_hw(
 bool dce_i2c_hw_engine_submit_payload(
        struct dce_i2c_hw *dce_i2c_hw,
        struct i2c_payload *payload,
-       bool middle_of_transaction)
+       bool middle_of_transaction,
+       uint32_t speed)
 {
 
        struct i2c_request_transaction_data request;
@@ -542,7 +526,7 @@ bool dce_i2c_hw_engine_submit_payload(
        /* obtain timeout value before submitting request */
 
        transaction_timeout = get_transaction_timeout_hw(
-               dce_i2c_hw, payload->length + 1);
+               dce_i2c_hw, payload->length + 1, speed);
 
        submit_channel_request_hw(
                dce_i2c_hw, &request);
@@ -588,13 +572,11 @@ bool dce_i2c_submit_command_hw(
                struct i2c_payload *payload = cmd->payloads + index_of_payload;
 
                if (!dce_i2c_hw_engine_submit_payload(
-                               dce_i2c_hw, payload, mot)) {
+                               dce_i2c_hw, payload, mot, cmd->speed)) {
                        result = false;
                        break;
                }
 
-
-
                ++index_of_payload;
        }
 
@@ -625,7 +607,6 @@ void dce_i2c_hw_construct(
        dce_i2c_hw->buffer_used_bytes = 0;
        dce_i2c_hw->transaction_count = 0;
        dce_i2c_hw->engine_keep_power_up_count = 1;
-       dce_i2c_hw->original_speed = DEFAULT_I2C_HW_SPEED;
        dce_i2c_hw->default_speed = DEFAULT_I2C_HW_SPEED;
        dce_i2c_hw->send_reset_length = 0;
        dce_i2c_hw->setup_limit = I2C_SETUP_TIME_LIMIT_DCE;
@@ -640,9 +621,6 @@ void dce100_i2c_hw_construct(
        const struct dce_i2c_shift *shifts,
        const struct dce_i2c_mask *masks)
 {
-
-       uint32_t xtal_ref_div = 0;
-
        dce_i2c_hw_construct(dce_i2c_hw,
                        ctx,
                        engine_id,
@@ -650,21 +628,6 @@ void dce100_i2c_hw_construct(
                        shifts,
                        masks);
        dce_i2c_hw->buffer_size = I2C_HW_BUFFER_SIZE_DCE100;
-
-       REG_GET(MICROSECOND_TIME_BASE_DIV, XTAL_REF_DIV, &xtal_ref_div);
-
-       if (xtal_ref_div == 0)
-               xtal_ref_div = 2;
-
-       /*Calculating Reference Clock by divding original frequency by
-        * XTAL_REF_DIV.
-        * At upper level, uint32_t reference_frequency =
-        *  dal_dce_i2c_get_reference_clock(as) >> 1
-        *  which already divided by 2. So we need x2 to get original
-        *  reference clock from ppll_info
-        */
-       dce_i2c_hw->reference_frequency =
-               (dce_i2c_hw->reference_frequency * 2) / xtal_ref_div;
 }
 
 void dce112_i2c_hw_construct(
index d4b2037..fb055e6 100644 (file)
@@ -256,7 +256,6 @@ struct i2c_request_transaction_data {
 
 struct dce_i2c_hw {
        struct ddc *ddc;
-       uint32_t original_speed;
        uint32_t engine_keep_power_up_count;
        uint32_t transaction_count;
        uint32_t buffer_used_bytes;
index f2127af..1008ac8 100644 (file)
@@ -2911,6 +2911,33 @@ void dcn10_update_dchub(struct dce_hwseq *hws, struct dchub_init_data *dh_data)
        hubbub->funcs->update_dchub(hubbub, dh_data);
 }
 
+static bool dcn10_can_pipe_disable_cursor(struct pipe_ctx *pipe_ctx)
+{
+       struct pipe_ctx *test_pipe;
+       const struct rect *r1 = &pipe_ctx->plane_res.scl_data.recout, *r2;
+       int r1_r = r1->x + r1->width, r1_b = r1->y + r1->height, r2_r, r2_b;
+
+       /**
+        * Disable the cursor if there's another pipe above this with a
+        * plane that contains this pipe's viewport to prevent double cursor
+        * and incorrect scaling artifacts.
+        */
+       for (test_pipe = pipe_ctx->top_pipe; test_pipe;
+            test_pipe = test_pipe->top_pipe) {
+               if (!test_pipe->plane_state->visible)
+                       continue;
+
+               r2 = &test_pipe->plane_res.scl_data.recout;
+               r2_r = r2->x + r2->width;
+               r2_b = r2->y + r2->height;
+
+               if (r1->x >= r2->x && r1->y >= r2->y && r1_r <= r2_r && r1_b <= r2_b)
+                       return true;
+       }
+
+       return false;
+}
+
 void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
 {
        struct dc_cursor_position pos_cpy = pipe_ctx->stream->cursor_position;
@@ -2956,6 +2983,9 @@ void dcn10_set_cursor_position(struct pipe_ctx *pipe_ctx)
                        == PLN_ADDR_TYPE_VIDEO_PROGRESSIVE)
                pos_cpy.enable = false;
 
+       if (pos_cpy.enable && dcn10_can_pipe_disable_cursor(pipe_ctx))
+               pos_cpy.enable = false;
+
        // Swap axis and mirror horizontally
        if (param.rotation == ROTATION_ANGLE_90) {
                uint32_t temp_x = pos_cpy.x;
index da63fc5..cf09b93 100644 (file)
@@ -261,28 +261,28 @@ static void hubp21_apply_PLAT_54186_wa(
                        address->video_progressive.luma_addr.high_part == 0xf4)
                return;
 
-       if ((rotation_angle == 0 || rotation_angle == 180)
+       if ((rotation_angle == ROTATION_ANGLE_0 || rotation_angle == ROTATION_ANGLE_180)
                        && viewport_c_height <= 512)
                return;
 
-       if ((rotation_angle == 90 || rotation_angle == 270)
+       if ((rotation_angle == ROTATION_ANGLE_90 || rotation_angle == ROTATION_ANGLE_270)
                                && viewport_c_width <= 512)
                return;
 
        switch (rotation_angle) {
-       case 0: /* 0 degree rotation */
+       case ROTATION_ANGLE_0: /* 0 degree rotation */
                row_height = 128;
                patched_viewport_height = (viewport_c_height / row_height + 1) * row_height + 1;
                patched_viewport_width = viewport_c_width;
                hubp21->PLAT_54186_wa_chroma_addr_offset = 0;
                break;
-       case 2: /* 180 degree rotation */
+       case ROTATION_ANGLE_180: /* 180 degree rotation */
                row_height = 128;
                patched_viewport_height = viewport_c_height + row_height;
                patched_viewport_width = viewport_c_width;
                hubp21->PLAT_54186_wa_chroma_addr_offset = 0 - chroma_pitch * row_height * chroma_bpe;
                break;
-       case 1: /* 90 degree rotation */
+       case ROTATION_ANGLE_90: /* 90 degree rotation */
                row_height = 256;
                if (h_mirror_en) {
                        patched_viewport_height = viewport_c_height;
@@ -294,7 +294,7 @@ static void hubp21_apply_PLAT_54186_wa(
                        hubp21->PLAT_54186_wa_chroma_addr_offset = 0 - tile_blk_size;
                }
                break;
-       case 3: /* 270 degree rotation */
+       case ROTATION_ANGLE_270: /* 270 degree rotation */
                row_height = 256;
                if (h_mirror_en) {
                        patched_viewport_height = viewport_c_height;
index 1d741bc..0d506d3 100644 (file)
@@ -830,7 +830,7 @@ static const struct dc_debug_options debug_defaults_drv = {
                .disable_dcc = DCC_ENABLE,
                .vsr_support = true,
                .performance_trace = false,
-               .max_downscale_src_width = 3840,
+               .max_downscale_src_width = 4096,
                .disable_pplib_wm_range = false,
                .scl_reset_length10 = true,
                .sanity_checks = true,
index e7a8ac7..45f0289 100644 (file)
@@ -38,6 +38,7 @@
 
 #define BPP_INVALID 0
 #define BPP_BLENDED_PIPE 0xffffffff
+#define DCN20_MAX_420_IMAGE_WIDTH 4096
 
 static double adjust_ReturnBW(
                struct display_mode_lib *mode_lib,
@@ -3894,13 +3895,19 @@ void dml20_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
                                                && i == mode_lib->vba.soc.num_states)
                                        mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
                                                        * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
-                               if (mode_lib->vba.ODMCapability == false || mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine <= mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
-                                       locals->ODMCombineEnablePerState[i][k] = false;
-                                       mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
-                               } else {
-                                       locals->ODMCombineEnablePerState[i][k] = true;
-                                       mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+
+                               locals->ODMCombineEnablePerState[i][k] = false;
+                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+                               if (mode_lib->vba.ODMCapability) {
+                                       if (locals->PlaneRequiredDISPCLKWithoutODMCombine > mode_lib->vba.MaxDispclkRoundedDownToDFSGranularity) {
+                                               locals->ODMCombineEnablePerState[i][k] = true;
+                                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+                                       } else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
+                                               locals->ODMCombineEnablePerState[i][k] = true;
+                                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+                                       }
                                }
+
                                if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
                                                && locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
                                                && locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
index 22f3b5a..485a9c6 100644 (file)
@@ -39,6 +39,7 @@
 #define BPP_INVALID 0
 #define BPP_BLENDED_PIPE 0xffffffff
 #define DCN20_MAX_DSC_IMAGE_WIDTH 5184
+#define DCN20_MAX_420_IMAGE_WIDTH 4096
 
 static double adjust_ReturnBW(
                struct display_mode_lib *mode_lib,
@@ -3935,15 +3936,22 @@ void dml20v2_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode
                                                && i == mode_lib->vba.soc.num_states)
                                        mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
                                                        * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
-                               if (mode_lib->vba.ODMCapability == false ||
-                                               (locals->PlaneRequiredDISPCLKWithoutODMCombine <= MaxMaxDispclkRoundedDown
-                                                       && (!locals->DSCEnabled[k] || locals->HActive[k] <= DCN20_MAX_DSC_IMAGE_WIDTH))) {
-                                       locals->ODMCombineEnablePerState[i][k] = false;
-                                       mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
-                               } else {
-                                       locals->ODMCombineEnablePerState[i][k] = true;
-                                       mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+
+                               locals->ODMCombineEnablePerState[i][k] = false;
+                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+                               if (mode_lib->vba.ODMCapability) {
+                                       if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
+                                               locals->ODMCombineEnablePerState[i][k] = true;
+                                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+                                       } else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN20_MAX_DSC_IMAGE_WIDTH)) {
+                                               locals->ODMCombineEnablePerState[i][k] = true;
+                                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+                                       } else if (locals->HActive[k] > DCN20_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
+                                               locals->ODMCombineEnablePerState[i][k] = true;
+                                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+                                       }
                                }
+
                                if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
                                                && locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
                                                && locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
index af35b3b..e6617c9 100644 (file)
@@ -65,6 +65,7 @@ typedef struct {
 #define BPP_INVALID 0
 #define BPP_BLENDED_PIPE 0xffffffff
 #define DCN21_MAX_DSC_IMAGE_WIDTH 5184
+#define DCN21_MAX_420_IMAGE_WIDTH 4096
 
 static void DisplayPipeConfiguration(struct display_mode_lib *mode_lib);
 static void DISPCLKDPPCLKDCFCLKDeepSleepPrefetchParametersWatermarksAndPerformanceCalculation(
@@ -3971,15 +3972,22 @@ void dml21_ModeSupportAndSystemConfigurationFull(struct display_mode_lib *mode_l
                                                && i == mode_lib->vba.soc.num_states)
                                        mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine = mode_lib->vba.PixelClock[k] / 2
                                                        * (1 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0);
-                               if (mode_lib->vba.ODMCapability == false ||
-                                               (locals->PlaneRequiredDISPCLKWithoutODMCombine <= MaxMaxDispclkRoundedDown
-                                                       && (!locals->DSCEnabled[k] || locals->HActive[k] <= DCN21_MAX_DSC_IMAGE_WIDTH))) {
-                                       locals->ODMCombineEnablePerState[i][k] = false;
-                                       mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
-                               } else {
-                                       locals->ODMCombineEnablePerState[i][k] = true;
-                                       mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+
+                               locals->ODMCombineEnablePerState[i][k] = false;
+                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithoutODMCombine;
+                               if (mode_lib->vba.ODMCapability) {
+                                       if (locals->PlaneRequiredDISPCLKWithoutODMCombine > MaxMaxDispclkRoundedDown) {
+                                               locals->ODMCombineEnablePerState[i][k] = true;
+                                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+                                       } else if (locals->DSCEnabled[k] && (locals->HActive[k] > DCN21_MAX_DSC_IMAGE_WIDTH)) {
+                                               locals->ODMCombineEnablePerState[i][k] = true;
+                                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+                                       } else if (locals->HActive[k] > DCN21_MAX_420_IMAGE_WIDTH && locals->OutputFormat[k] == dm_420) {
+                                               locals->ODMCombineEnablePerState[i][k] = true;
+                                               mode_lib->vba.PlaneRequiredDISPCLK = mode_lib->vba.PlaneRequiredDISPCLKWithODMCombine;
+                                       }
                                }
+
                                if (locals->MinDPPCLKUsingSingleDPP[k] * (1.0 + mode_lib->vba.DISPCLKDPPCLKDSCCLKDownSpreading / 100.0) <= mode_lib->vba.MaxDppclkRoundedDownToDFSGranularity
                                                && locals->SwathWidthYSingleDPP[k] <= locals->MaximumSwathWidth[k]
                                                && locals->ODMCombineEnablePerState[i][k] == dm_odm_combine_mode_disabled) {
index e7a44df..2875efd 100644 (file)
@@ -763,8 +763,8 @@ struct vba_vars_st {
        double SwathWidthC[DC__NUM_DPP__MAX];
        unsigned int BytePerPixelY[DC__NUM_DPP__MAX];
        unsigned int BytePerPixelC[DC__NUM_DPP__MAX];
-       long dummyinteger1;
-       long dummyinteger2;
+       unsigned int dummyinteger1;
+       unsigned int dummyinteger2;
        double FinalDRAMClockChangeLatency;
        double Tdmdl_vm[DC__NUM_DPP__MAX];
        double Tdmdl[DC__NUM_DPP__MAX];
index 8b78fcb..87d682d 100644 (file)
@@ -224,7 +224,8 @@ static void get_dsc_enc_caps(
 
        memset(dsc_enc_caps, 0, sizeof(struct dsc_enc_caps));
        if (dsc) {
-               dsc->funcs->dsc_get_enc_caps(dsc_enc_caps, pixel_clock_100Hz);
+               if (!dsc->ctx->dc->debug.disable_dsc)
+                       dsc->funcs->dsc_get_enc_caps(dsc_enc_caps, pixel_clock_100Hz);
                if (dsc->ctx->dc->debug.native422_support)
                        dsc_enc_caps->color_formats.bits.YCBCR_NATIVE_422 = 1;
        }
index 8e23a70..f891759 100644 (file)
@@ -231,6 +231,8 @@ struct dmub_srv_base_funcs {
 struct dmub_srv_hw_funcs {
        /* private: internal use only */
 
+       void (*init)(struct dmub_srv *dmub);
+
        void (*reset)(struct dmub_srv *dmub);
 
        void (*reset_release)(struct dmub_srv *dmub);
@@ -417,6 +419,21 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
                                  const struct dmub_srv_hw_params *params);
 
 /**
+ * dmub_srv_hw_reset() - puts the DMUB hardware in reset state if initialized
+ * @dmub: the dmub service
+ *
+ * Before destroying the DMUB service or releasing the backing framebuffer
+ * memory we'll need to put the DMCUB into reset first.
+ *
+ * A subsequent call to dmub_srv_hw_init() will re-enable the DMCUB.
+ *
+ * Return:
+ *   DMUB_STATUS_OK - success
+ *   DMUB_STATUS_INVALID - unspecified error
+ */
+enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub);
+
+/**
  * dmub_srv_cmd_queue() - queues a command to the DMUB
  * @dmub: the dmub service
  * @cmd: the command to queue
index cd51c61..b2ca8e0 100644 (file)
@@ -54,6 +54,19 @@ const struct dmub_srv_common_regs dmub_srv_dcn20_regs = {
 
 /* Shared functions. */
 
+static void dmub_dcn20_get_fb_base_offset(struct dmub_srv *dmub,
+                                         uint64_t *fb_base,
+                                         uint64_t *fb_offset)
+{
+       uint32_t tmp;
+
+       REG_GET(DCN_VM_FB_LOCATION_BASE, FB_BASE, &tmp);
+       *fb_base = (uint64_t)tmp << 24;
+
+       REG_GET(DCN_VM_FB_OFFSET, FB_OFFSET, &tmp);
+       *fb_offset = (uint64_t)tmp << 24;
+}
+
 static inline void dmub_dcn20_translate_addr(const union dmub_addr *addr_in,
                                             uint64_t fb_base,
                                             uint64_t fb_offset,
@@ -67,6 +80,8 @@ void dmub_dcn20_reset(struct dmub_srv *dmub)
        REG_UPDATE(DMCUB_CNTL, DMCUB_SOFT_RESET, 1);
        REG_UPDATE(DMCUB_CNTL, DMCUB_ENABLE, 0);
        REG_UPDATE(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET, 1);
+       REG_WRITE(DMCUB_INBOX1_RPTR, 0);
+       REG_WRITE(DMCUB_INBOX1_WPTR, 0);
 }
 
 void dmub_dcn20_reset_release(struct dmub_srv *dmub)
@@ -82,7 +97,9 @@ void dmub_dcn20_backdoor_load(struct dmub_srv *dmub,
                              const struct dmub_window *cw1)
 {
        union dmub_addr offset;
-       uint64_t fb_base = dmub->fb_base, fb_offset = dmub->fb_offset;
+       uint64_t fb_base, fb_offset;
+
+       dmub_dcn20_get_fb_base_offset(dmub, &fb_base, &fb_offset);
 
        REG_UPDATE(DMCUB_SEC_CNTL, DMCUB_SEC_RESET, 1);
        REG_UPDATE_2(DMCUB_MEM_CNTL, DMCUB_MEM_READ_SPACE, 0x3,
@@ -118,7 +135,9 @@ void dmub_dcn20_setup_windows(struct dmub_srv *dmub,
                              const struct dmub_window *cw6)
 {
        union dmub_addr offset;
-       uint64_t fb_base = dmub->fb_base, fb_offset = dmub->fb_offset;
+       uint64_t fb_base, fb_offset;
+
+       dmub_dcn20_get_fb_base_offset(dmub, &fb_base, &fb_offset);
 
        dmub_dcn20_translate_addr(&cw2->offset, fb_base, fb_offset, &offset);
 
@@ -173,8 +192,6 @@ void dmub_dcn20_setup_mailbox(struct dmub_srv *dmub,
 
        REG_WRITE(DMCUB_INBOX1_BASE_ADDRESS, 0x80000000);
        REG_WRITE(DMCUB_INBOX1_SIZE, inbox1->top - inbox1->base);
-       REG_WRITE(DMCUB_INBOX1_RPTR, 0);
-       REG_WRITE(DMCUB_INBOX1_WPTR, 0);
 }
 
 uint32_t dmub_dcn20_get_inbox1_rptr(struct dmub_srv *dmub)
index 53bfd4d..04b0fa1 100644 (file)
@@ -92,7 +92,9 @@ struct dmub_srv;
        DMUB_SR(DMCUB_SCRATCH14) \
        DMUB_SR(DMCUB_SCRATCH15) \
        DMUB_SR(CC_DC_PIPE_DIS) \
-       DMUB_SR(MMHUBBUB_SOFT_RESET)
+       DMUB_SR(MMHUBBUB_SOFT_RESET) \
+       DMUB_SR(DCN_VM_FB_LOCATION_BASE) \
+       DMUB_SR(DCN_VM_FB_OFFSET)
 
 #define DMUB_COMMON_FIELDS() \
        DMUB_SF(DMCUB_CNTL, DMCUB_ENABLE) \
@@ -121,7 +123,9 @@ struct dmub_srv;
        DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_TOP_ADDRESS) \
        DMUB_SF(DMCUB_REGION4_TOP_ADDRESS, DMCUB_REGION4_ENABLE) \
        DMUB_SF(CC_DC_PIPE_DIS, DC_DMCUB_ENABLE) \
-       DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET)
+       DMUB_SF(MMHUBBUB_SOFT_RESET, DMUIF_SOFT_RESET) \
+       DMUB_SF(DCN_VM_FB_LOCATION_BASE, FB_BASE) \
+       DMUB_SF(DCN_VM_FB_OFFSET, FB_OFFSET)
 
 struct dmub_srv_common_reg_offset {
 #define DMUB_SR(reg) uint32_t reg;
index dee6763..85a518b 100644 (file)
@@ -312,6 +312,9 @@ enum dmub_status dmub_srv_is_hw_init(struct dmub_srv *dmub, bool *is_hw_init)
        if (!dmub->sw_init)
                return DMUB_STATUS_INVALID;
 
+       if (!dmub->hw_init)
+               return DMUB_STATUS_OK;
+
        if (dmub->hw_funcs.is_hw_init)
                *is_hw_init = dmub->hw_funcs.is_hw_init(dmub);
 
@@ -415,6 +418,22 @@ enum dmub_status dmub_srv_hw_init(struct dmub_srv *dmub,
        return DMUB_STATUS_OK;
 }
 
+enum dmub_status dmub_srv_hw_reset(struct dmub_srv *dmub)
+{
+       if (!dmub->sw_init)
+               return DMUB_STATUS_INVALID;
+
+       if (dmub->hw_init == false)
+               return DMUB_STATUS_OK;
+
+       if (dmub->hw_funcs.reset)
+               dmub->hw_funcs.reset(dmub);
+
+       dmub->hw_init = false;
+
+       return DMUB_STATUS_OK;
+}
+
 enum dmub_status dmub_srv_cmd_queue(struct dmub_srv *dmub,
                                    const struct dmub_cmd_header *cmd)
 {
index 1b278c4..cac09d5 100644 (file)
@@ -1673,129 +1673,6 @@ static bool map_regamma_hw_to_x_user(
 
 #define _EXTRA_POINTS 3
 
-bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
-               const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed,
-               const struct freesync_hdr_tf_params *fs_params)
-{
-       struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
-       struct dividers dividers;
-
-       struct pwl_float_data *rgb_user = NULL;
-       struct pwl_float_data_ex *rgb_regamma = NULL;
-       struct gamma_pixel *axis_x = NULL;
-       struct pixel_gamma_point *coeff = NULL;
-       enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
-       bool ret = false;
-
-       if (output_tf->type == TF_TYPE_BYPASS)
-               return false;
-
-       /* we can use hardcoded curve for plain SRGB TF */
-       if (output_tf->type == TF_TYPE_PREDEFINED && canRomBeUsed == true &&
-                       output_tf->tf == TRANSFER_FUNCTION_SRGB) {
-               if (ramp == NULL)
-                       return true;
-               if ((ramp->is_identity && ramp->type != GAMMA_CS_TFM_1D) ||
-                               (!mapUserRamp && ramp->type == GAMMA_RGB_256))
-                       return true;
-       }
-
-       output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
-
-       if (ramp && ramp->type != GAMMA_CS_TFM_1D &&
-                       (mapUserRamp || ramp->type != GAMMA_RGB_256)) {
-               rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
-                           sizeof(*rgb_user),
-                           GFP_KERNEL);
-               if (!rgb_user)
-                       goto rgb_user_alloc_fail;
-
-               axis_x = kvcalloc(ramp->num_entries + 3, sizeof(*axis_x),
-                               GFP_KERNEL);
-               if (!axis_x)
-                       goto axis_x_alloc_fail;
-
-               dividers.divider1 = dc_fixpt_from_fraction(3, 2);
-               dividers.divider2 = dc_fixpt_from_int(2);
-               dividers.divider3 = dc_fixpt_from_fraction(5, 2);
-
-               build_evenly_distributed_points(
-                               axis_x,
-                               ramp->num_entries,
-                               dividers);
-
-               if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
-                       scale_gamma(rgb_user, ramp, dividers);
-               else if (ramp->type == GAMMA_RGB_FLOAT_1024)
-                       scale_gamma_dx(rgb_user, ramp, dividers);
-       }
-
-       rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
-                              sizeof(*rgb_regamma),
-                              GFP_KERNEL);
-       if (!rgb_regamma)
-               goto rgb_regamma_alloc_fail;
-
-       coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
-                        GFP_KERNEL);
-       if (!coeff)
-               goto coeff_alloc_fail;
-
-       tf = output_tf->tf;
-       if (tf == TRANSFER_FUNCTION_PQ) {
-               tf_pts->end_exponent = 7;
-               tf_pts->x_point_at_y1_red = 125;
-               tf_pts->x_point_at_y1_green = 125;
-               tf_pts->x_point_at_y1_blue = 125;
-
-               build_pq(rgb_regamma,
-                               MAX_HW_POINTS,
-                               coordinates_x,
-                               output_tf->sdr_ref_white_level);
-       } else if (tf == TRANSFER_FUNCTION_GAMMA22 &&
-                       fs_params != NULL && fs_params->skip_tm == 0) {
-               build_freesync_hdr(rgb_regamma,
-                               MAX_HW_POINTS,
-                               coordinates_x,
-                               fs_params);
-       } else if (tf == TRANSFER_FUNCTION_HLG) {
-               build_freesync_hdr(rgb_regamma,
-                               MAX_HW_POINTS,
-                               coordinates_x,
-                               fs_params);
-
-       } else {
-               tf_pts->end_exponent = 0;
-               tf_pts->x_point_at_y1_red = 1;
-               tf_pts->x_point_at_y1_green = 1;
-               tf_pts->x_point_at_y1_blue = 1;
-
-               build_regamma(rgb_regamma,
-                               MAX_HW_POINTS,
-                               coordinates_x, tf);
-       }
-       map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
-                       coordinates_x, axis_x, rgb_regamma,
-                       MAX_HW_POINTS, tf_pts,
-                       (mapUserRamp || (ramp && ramp->type != GAMMA_RGB_256)) &&
-                       (ramp && ramp->type != GAMMA_CS_TFM_1D));
-
-       if (ramp && ramp->type == GAMMA_CS_TFM_1D)
-               apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
-
-       ret = true;
-
-       kvfree(coeff);
-coeff_alloc_fail:
-       kvfree(rgb_regamma);
-rgb_regamma_alloc_fail:
-       kvfree(axis_x);
-axis_x_alloc_fail:
-       kvfree(rgb_user);
-rgb_user_alloc_fail:
-       return ret;
-}
-
 bool calculate_user_regamma_coeff(struct dc_transfer_func *output_tf,
                const struct regamma_lut *regamma)
 {
@@ -2043,14 +1920,14 @@ rgb_user_alloc_fail:
        return ret;
 }
 
-
-bool  mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
+static bool calculate_curve(enum dc_transfer_func_predefined trans,
                                struct dc_transfer_func_distributed_points *points,
+                               struct pwl_float_data_ex *rgb_regamma,
+                               const struct freesync_hdr_tf_params *fs_params,
                                uint32_t sdr_ref_white_level)
 {
        uint32_t i;
        bool ret = false;
-       struct pwl_float_data_ex *rgb_regamma = NULL;
 
        if (trans == TRANSFER_FUNCTION_UNITY ||
                trans == TRANSFER_FUNCTION_LINEAR) {
@@ -2060,68 +1937,33 @@ bool  mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
                points->x_point_at_y1_blue = 1;
 
                for (i = 0; i <= MAX_HW_POINTS ; i++) {
-                       points->red[i]    = coordinates_x[i].x;
-                       points->green[i]  = coordinates_x[i].x;
-                       points->blue[i]   = coordinates_x[i].x;
+                       rgb_regamma[i].r = coordinates_x[i].x;
+                       rgb_regamma[i].g = coordinates_x[i].x;
+                       rgb_regamma[i].b = coordinates_x[i].x;
                }
+
                ret = true;
        } else if (trans == TRANSFER_FUNCTION_PQ) {
-               rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
-                                      sizeof(*rgb_regamma),
-                                      GFP_KERNEL);
-               if (!rgb_regamma)
-                       goto rgb_regamma_alloc_fail;
                points->end_exponent = 7;
                points->x_point_at_y1_red = 125;
                points->x_point_at_y1_green = 125;
                points->x_point_at_y1_blue = 125;
 
-
                build_pq(rgb_regamma,
                                MAX_HW_POINTS,
                                coordinates_x,
                                sdr_ref_white_level);
-               for (i = 0; i <= MAX_HW_POINTS ; i++) {
-                       points->red[i]    = rgb_regamma[i].r;
-                       points->green[i]  = rgb_regamma[i].g;
-                       points->blue[i]   = rgb_regamma[i].b;
-               }
-               ret = true;
-
-               kvfree(rgb_regamma);
-       } else if (trans == TRANSFER_FUNCTION_SRGB ||
-               trans == TRANSFER_FUNCTION_BT709 ||
-               trans == TRANSFER_FUNCTION_GAMMA22 ||
-               trans == TRANSFER_FUNCTION_GAMMA24 ||
-               trans == TRANSFER_FUNCTION_GAMMA26) {
-               rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
-                                      sizeof(*rgb_regamma),
-                                      GFP_KERNEL);
-               if (!rgb_regamma)
-                       goto rgb_regamma_alloc_fail;
-               points->end_exponent = 0;
-               points->x_point_at_y1_red = 1;
-               points->x_point_at_y1_green = 1;
-               points->x_point_at_y1_blue = 1;
 
-               build_regamma(rgb_regamma,
+               ret = true;
+       } else if (trans == TRANSFER_FUNCTION_GAMMA22 &&
+                       fs_params != NULL && fs_params->skip_tm == 0) {
+               build_freesync_hdr(rgb_regamma,
                                MAX_HW_POINTS,
                                coordinates_x,
-                               trans);
-               for (i = 0; i <= MAX_HW_POINTS ; i++) {
-                       points->red[i]    = rgb_regamma[i].r;
-                       points->green[i]  = rgb_regamma[i].g;
-                       points->blue[i]   = rgb_regamma[i].b;
-               }
-               ret = true;
+                               fs_params);
 
-               kvfree(rgb_regamma);
+               ret = true;
        } else if (trans == TRANSFER_FUNCTION_HLG) {
-               rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
-                                      sizeof(*rgb_regamma),
-                                      GFP_KERNEL);
-               if (!rgb_regamma)
-                       goto rgb_regamma_alloc_fail;
                points->end_exponent = 4;
                points->x_point_at_y1_red = 12;
                points->x_point_at_y1_green = 12;
@@ -2131,18 +1973,127 @@ bool  mod_color_calculate_curve(enum dc_transfer_func_predefined trans,
                                MAX_HW_POINTS,
                                coordinates_x,
                                80, 1000);
-               for (i = 0; i <= MAX_HW_POINTS ; i++) {
-                       points->red[i]    = rgb_regamma[i].r;
-                       points->green[i]  = rgb_regamma[i].g;
-                       points->blue[i]   = rgb_regamma[i].b;
-               }
+
+               ret = true;
+       } else {
+               // trans == TRANSFER_FUNCTION_SRGB
+               // trans == TRANSFER_FUNCTION_BT709
+               // trans == TRANSFER_FUNCTION_GAMMA22
+               // trans == TRANSFER_FUNCTION_GAMMA24
+               // trans == TRANSFER_FUNCTION_GAMMA26
+               points->end_exponent = 0;
+               points->x_point_at_y1_red = 1;
+               points->x_point_at_y1_green = 1;
+               points->x_point_at_y1_blue = 1;
+
+               build_regamma(rgb_regamma,
+                               MAX_HW_POINTS,
+                               coordinates_x,
+                               trans);
+
                ret = true;
-               kvfree(rgb_regamma);
        }
-rgb_regamma_alloc_fail:
+
        return ret;
 }
 
+bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
+               const struct dc_gamma *ramp, bool mapUserRamp, bool canRomBeUsed,
+               const struct freesync_hdr_tf_params *fs_params)
+{
+       struct dc_transfer_func_distributed_points *tf_pts = &output_tf->tf_pts;
+       struct dividers dividers;
+
+       struct pwl_float_data *rgb_user = NULL;
+       struct pwl_float_data_ex *rgb_regamma = NULL;
+       struct gamma_pixel *axis_x = NULL;
+       struct pixel_gamma_point *coeff = NULL;
+       enum dc_transfer_func_predefined tf = TRANSFER_FUNCTION_SRGB;
+       bool ret = false;
+
+       if (output_tf->type == TF_TYPE_BYPASS)
+               return false;
+
+       /* we can use hardcoded curve for plain SRGB TF */
+       if (output_tf->type == TF_TYPE_PREDEFINED && canRomBeUsed == true &&
+                       output_tf->tf == TRANSFER_FUNCTION_SRGB) {
+               if (ramp == NULL)
+                       return true;
+               if ((ramp->is_identity && ramp->type != GAMMA_CS_TFM_1D) ||
+                               (!mapUserRamp && ramp->type == GAMMA_RGB_256))
+                       return true;
+       }
+
+       output_tf->type = TF_TYPE_DISTRIBUTED_POINTS;
+
+       if (ramp && ramp->type != GAMMA_CS_TFM_1D &&
+                       (mapUserRamp || ramp->type != GAMMA_RGB_256)) {
+               rgb_user = kvcalloc(ramp->num_entries + _EXTRA_POINTS,
+                           sizeof(*rgb_user),
+                           GFP_KERNEL);
+               if (!rgb_user)
+                       goto rgb_user_alloc_fail;
+
+               axis_x = kvcalloc(ramp->num_entries + 3, sizeof(*axis_x),
+                               GFP_KERNEL);
+               if (!axis_x)
+                       goto axis_x_alloc_fail;
+
+               dividers.divider1 = dc_fixpt_from_fraction(3, 2);
+               dividers.divider2 = dc_fixpt_from_int(2);
+               dividers.divider3 = dc_fixpt_from_fraction(5, 2);
+
+               build_evenly_distributed_points(
+                               axis_x,
+                               ramp->num_entries,
+                               dividers);
+
+               if (ramp->type == GAMMA_RGB_256 && mapUserRamp)
+                       scale_gamma(rgb_user, ramp, dividers);
+               else if (ramp->type == GAMMA_RGB_FLOAT_1024)
+                       scale_gamma_dx(rgb_user, ramp, dividers);
+       }
+
+       rgb_regamma = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS,
+                              sizeof(*rgb_regamma),
+                              GFP_KERNEL);
+       if (!rgb_regamma)
+               goto rgb_regamma_alloc_fail;
+
+       coeff = kvcalloc(MAX_HW_POINTS + _EXTRA_POINTS, sizeof(*coeff),
+                        GFP_KERNEL);
+       if (!coeff)
+               goto coeff_alloc_fail;
+
+       tf = output_tf->tf;
+
+       ret = calculate_curve(tf,
+                       tf_pts,
+                       rgb_regamma,
+                       fs_params,
+                       output_tf->sdr_ref_white_level);
+
+       if (ret) {
+               map_regamma_hw_to_x_user(ramp, coeff, rgb_user,
+                               coordinates_x, axis_x, rgb_regamma,
+                               MAX_HW_POINTS, tf_pts,
+                               (mapUserRamp || (ramp && ramp->type != GAMMA_RGB_256)) &&
+                               (ramp && ramp->type != GAMMA_CS_TFM_1D));
+
+               if (ramp && ramp->type == GAMMA_CS_TFM_1D)
+                       apply_lut_1d(ramp, MAX_HW_POINTS, tf_pts);
+       }
+
+       kvfree(coeff);
+coeff_alloc_fail:
+       kvfree(rgb_regamma);
+rgb_regamma_alloc_fail:
+       kvfree(axis_x);
+axis_x_alloc_fail:
+       kvfree(rgb_user);
+rgb_user_alloc_fail:
+       return ret;
+}
 
 bool  mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
                                struct dc_transfer_func_distributed_points *points)
index 44ddea5..9994817 100644 (file)
@@ -103,10 +103,6 @@ bool mod_color_calculate_regamma_params(struct dc_transfer_func *output_tf,
 bool mod_color_calculate_degamma_params(struct dc_transfer_func *output_tf,
                const struct dc_gamma *ramp, bool mapUserRamp);
 
-bool mod_color_calculate_curve(enum dc_transfer_func_predefined  trans,
-               struct dc_transfer_func_distributed_points *points,
-               uint32_t sdr_ref_white_level);
-
 bool mod_color_calculate_degamma_curve(enum dc_transfer_func_predefined trans,
                                struct dc_transfer_func_distributed_points *points);
 
index 6e5ecef..b9992eb 100644 (file)
@@ -381,7 +381,7 @@ static void apply_fixed_refresh(struct core_freesync *core_freesync,
        bool update = false;
        unsigned int max_render_time_in_us = in_out_vrr->max_duration_in_us;
 
-       //Compute the exit refresh rate and exit frame duration
+       /* Compute the exit refresh rate and exit frame duration */
        unsigned int exit_refresh_rate_in_milli_hz = ((1000000000/max_render_time_in_us)
                        + (1000*FIXED_REFRESH_EXIT_MARGIN_IN_HZ));
        unsigned int exit_frame_duration_in_us = 1000000000/exit_refresh_rate_in_milli_hz;
index f98d3d9..af78e4f 100644 (file)
@@ -63,7 +63,7 @@ struct mod_hdcp_transition_input_hdcp1 {
        uint8_t hdcp_capable_dp;
        uint8_t binfo_read_dp;
        uint8_t r0p_available_dp;
-       uint8_t link_integiry_check;
+       uint8_t link_integrity_check;
        uint8_t reauth_request_check;
        uint8_t stream_encryption_dp;
 };
index 04845e4..37670db 100644 (file)
@@ -283,8 +283,8 @@ static enum mod_hdcp_status wait_for_ready(struct mod_hdcp *hdcp,
                                hdcp, "bstatus_read"))
                        goto out;
                if (!mod_hdcp_execute_and_set(check_link_integrity_dp,
-                               &input->link_integiry_check, &status,
-                               hdcp, "link_integiry_check"))
+                               &input->link_integrity_check, &status,
+                               hdcp, "link_integrity_check"))
                        goto out;
                if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
                                &input->reauth_request_check, &status,
@@ -431,8 +431,8 @@ static enum mod_hdcp_status authenticated_dp(struct mod_hdcp *hdcp,
                        hdcp, "bstatus_read"))
                goto out;
        if (!mod_hdcp_execute_and_set(check_link_integrity_dp,
-                       &input->link_integiry_check, &status,
-                       hdcp, "link_integiry_check"))
+                       &input->link_integrity_check, &status,
+                       hdcp, "link_integrity_check"))
                goto out;
        if (!mod_hdcp_execute_and_set(check_no_reauthentication_request_dp,
                        &input->reauth_request_check, &status,
index 21ebc62..76edcbe 100644 (file)
@@ -241,7 +241,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp,
                }
                break;
        case D1_A4_AUTHENTICATED:
-               if (input->link_integiry_check != PASS ||
+               if (input->link_integrity_check != PASS ||
                                input->reauth_request_check != PASS) {
                        /* 1A-07: restart hdcp on a link integrity failure */
                        fail_and_restart_in_ms(0, &status, output);
@@ -249,7 +249,7 @@ enum mod_hdcp_status mod_hdcp_hdcp1_dp_transition(struct mod_hdcp *hdcp,
                }
                break;
        case D1_A6_WAIT_FOR_READY:
-               if (input->link_integiry_check == FAIL ||
+               if (input->link_integrity_check == FAIL ||
                                input->reauth_request_check == FAIL) {
                        fail_and_restart_in_ms(0, &status, output);
                        break;
index 87c8469..bb2c9c7 100644 (file)
@@ -71,4 +71,7 @@
 #define smnDF_PIE_AON_FabricIndirectConfigAccessDataLo3                0x1d098UL
 #define smnDF_PIE_AON_FabricIndirectConfigAccessDataHi3                0x1d09cUL
 
+#define smnDF_CS_UMC_AON0_DramBaseAddress0     0x1c110UL
+#define smnDF_CS_UMC_AON0_DramLimitAddress0    0x1c114UL
+
 #endif
index 65e9f75..7afa87c 100644 (file)
 #define DF_CS_UMC_AON0_DramBaseAddress0__IntLvAddrSel_MASK                                             0x00000E00L
 #define DF_CS_UMC_AON0_DramBaseAddress0__DramBaseAddr_MASK                                             0xFFFFF000L
 
+//DF_CS_UMC_AON0_DramLimitAddress0
+#define DF_CS_UMC_AON0_DramLimitAddress0__DstFabricID__SHIFT                                                  0x0
+#define DF_CS_UMC_AON0_DramLimitAddress0__AllowReqIO__SHIFT                                                   0xa
+#define DF_CS_UMC_AON0_DramLimitAddress0__DramLimitAddr__SHIFT                                                0xc
+#define DF_CS_UMC_AON0_DramLimitAddress0__DstFabricID_MASK                                                    0x000003FFL
+#define DF_CS_UMC_AON0_DramLimitAddress0__AllowReqIO_MASK                                                     0x00000400L
+#define DF_CS_UMC_AON0_DramLimitAddress0__DramLimitAddr_MASK                                                  0xFFFFF000L
+
 #endif
index c9e3f6d..ea316d8 100644 (file)
 
 // addressBlock: gc_sqdec
 //SQ_CONFIG
-#define SQ_CONFIG__UNUSED__SHIFT                                                                              0x0
+#define SQ_CONFIG__DISABLE_BARRIER_WAITCNT__SHIFT                                                             0x0
+#define SQ_CONFIG__UNUSED__SHIFT                                                                              0x1
 #define SQ_CONFIG__OVERRIDE_ALU_BUSY__SHIFT                                                                   0x7
 #define SQ_CONFIG__DEBUG_EN__SHIFT                                                                            0x8
 #define SQ_CONFIG__DEBUG_SINGLE_MEMOP__SHIFT                                                                  0x9
 #define SQ_CONFIG__DISABLE_SP_REDUNDANT_THREAD_GATING__SHIFT                                                  0x1d
 #define SQ_CONFIG__DISABLE_FLAT_SOFT_CLAUSE__SHIFT                                                            0x1e
 #define SQ_CONFIG__DISABLE_MIMG_SOFT_CLAUSE__SHIFT                                                            0x1f
-#define SQ_CONFIG__UNUSED_MASK                                                                                0x0000007FL
+#define SQ_CONFIG__DISABLE_BARRIER_WAITCNT_MASK                                                               0x00000001L
+#define SQ_CONFIG__UNUSED_MASK                                                                                0x0000007EL
 #define SQ_CONFIG__OVERRIDE_ALU_BUSY_MASK                                                                     0x00000080L
 #define SQ_CONFIG__DEBUG_EN_MASK                                                                              0x00000100L
 #define SQ_CONFIG__DEBUG_SINGLE_MEMOP_MASK                                                                    0x00000200L
diff --git a/drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_4_1_offset.h b/drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_4_1_offset.h
new file mode 100644 (file)
index 0000000..f41556a
--- /dev/null
@@ -0,0 +1,264 @@
+/*
+ * Copyright (C) 2020  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _gc_9_4_1_OFFSET_HEADER
+#define _gc_9_4_1_OFFSET_HEADER
+
+// addressBlock: gc_grbmdec
+// base address: 0x8000
+#define mmGRBM_CNTL                                                                                    0x0000
+#define mmGRBM_CNTL_BASE_IDX                                                                           0
+#define mmGRBM_SKEW_CNTL                                                                               0x0001
+#define mmGRBM_SKEW_CNTL_BASE_IDX                                                                      0
+#define mmGRBM_STATUS2                                                                                 0x0002
+#define mmGRBM_STATUS2_BASE_IDX                                                                        0
+#define mmGRBM_PWR_CNTL                                                                                0x0003
+#define mmGRBM_PWR_CNTL_BASE_IDX                                                                       0
+#define mmGRBM_STATUS                                                                                  0x0004
+#define mmGRBM_STATUS_BASE_IDX                                                                         0
+#define mmGRBM_STATUS_SE0                                                                              0x0005
+#define mmGRBM_STATUS_SE0_BASE_IDX                                                                     0
+#define mmGRBM_STATUS_SE1                                                                              0x0006
+#define mmGRBM_STATUS_SE1_BASE_IDX                                                                     0
+#define mmGRBM_SOFT_RESET                                                                              0x0008
+#define mmGRBM_SOFT_RESET_BASE_IDX                                                                     0
+#define mmGRBM_GFX_CLKEN_CNTL                                                                          0x000c
+#define mmGRBM_GFX_CLKEN_CNTL_BASE_IDX                                                                 0
+#define mmGRBM_WAIT_IDLE_CLOCKS                                                                        0x000d
+#define mmGRBM_WAIT_IDLE_CLOCKS_BASE_IDX                                                               0
+#define mmGRBM_STATUS_SE2                                                                              0x000e
+#define mmGRBM_STATUS_SE2_BASE_IDX                                                                     0
+#define mmGRBM_STATUS_SE3                                                                              0x000f
+#define mmGRBM_STATUS_SE3_BASE_IDX                                                                     0
+#define mmGRBM_READ_ERROR                                                                              0x0016
+#define mmGRBM_READ_ERROR_BASE_IDX                                                                     0
+#define mmGRBM_READ_ERROR2                                                                             0x0017
+#define mmGRBM_READ_ERROR2_BASE_IDX                                                                    0
+#define mmGRBM_INT_CNTL                                                                                0x0018
+#define mmGRBM_INT_CNTL_BASE_IDX                                                                       0
+#define mmGRBM_TRAP_OP                                                                                 0x0019
+#define mmGRBM_TRAP_OP_BASE_IDX                                                                        0
+#define mmGRBM_TRAP_ADDR                                                                               0x001a
+#define mmGRBM_TRAP_ADDR_BASE_IDX                                                                      0
+#define mmGRBM_TRAP_ADDR_MSK                                                                           0x001b
+#define mmGRBM_TRAP_ADDR_MSK_BASE_IDX                                                                  0
+#define mmGRBM_TRAP_WD                                                                                 0x001c
+#define mmGRBM_TRAP_WD_BASE_IDX                                                                        0
+#define mmGRBM_TRAP_WD_MSK                                                                             0x001d
+#define mmGRBM_TRAP_WD_MSK_BASE_IDX                                                                    0
+#define mmGRBM_DSM_BYPASS                                                                              0x001e
+#define mmGRBM_DSM_BYPASS_BASE_IDX                                                                     0
+#define mmGRBM_WRITE_ERROR                                                                             0x001f
+#define mmGRBM_WRITE_ERROR_BASE_IDX                                                                    0
+#define mmGRBM_IOV_ERROR                                                                               0x0020
+#define mmGRBM_IOV_ERROR_BASE_IDX                                                                      0
+#define mmGRBM_CHIP_REVISION                                                                           0x0021
+#define mmGRBM_CHIP_REVISION_BASE_IDX                                                                  0
+#define mmGRBM_GFX_CNTL                                                                                0x0022
+#define mmGRBM_GFX_CNTL_BASE_IDX                                                                       0
+#define mmGRBM_RSMU_CFG                                                                                0x0023
+#define mmGRBM_RSMU_CFG_BASE_IDX                                                                       0
+#define mmGRBM_IH_CREDIT                                                                               0x0024
+#define mmGRBM_IH_CREDIT_BASE_IDX                                                                      0
+#define mmGRBM_PWR_CNTL2                                                                               0x0025
+#define mmGRBM_PWR_CNTL2_BASE_IDX                                                                      0
+#define mmGRBM_UTCL2_INVAL_RANGE_START                                                                 0x0026
+#define mmGRBM_UTCL2_INVAL_RANGE_START_BASE_IDX                                                        0
+#define mmGRBM_UTCL2_INVAL_RANGE_END                                                                   0x0027
+#define mmGRBM_UTCL2_INVAL_RANGE_END_BASE_IDX                                                          0
+#define mmGRBM_RSMU_READ_ERROR                                                                         0x0028
+#define mmGRBM_RSMU_READ_ERROR_BASE_IDX                                                                0
+#define mmGRBM_CHICKEN_BITS                                                                            0x0029
+#define mmGRBM_CHICKEN_BITS_BASE_IDX                                                                   0
+#define mmGRBM_FENCE_RANGE0                                                                            0x002a
+#define mmGRBM_FENCE_RANGE0_BASE_IDX                                                                   0
+#define mmGRBM_FENCE_RANGE1                                                                            0x002b
+#define mmGRBM_FENCE_RANGE1_BASE_IDX                                                                   0
+#define mmGRBM_NOWHERE                                                                                 0x003f
+#define mmGRBM_NOWHERE_BASE_IDX                                                                        0
+#define mmGRBM_SCRATCH_REG0                                                                            0x0040
+#define mmGRBM_SCRATCH_REG0_BASE_IDX                                                                   0
+#define mmGRBM_SCRATCH_REG1                                                                            0x0041
+#define mmGRBM_SCRATCH_REG1_BASE_IDX                                                                   0
+#define mmGRBM_SCRATCH_REG2                                                                            0x0042
+#define mmGRBM_SCRATCH_REG2_BASE_IDX                                                                   0
+#define mmGRBM_SCRATCH_REG3                                                                            0x0043
+#define mmGRBM_SCRATCH_REG3_BASE_IDX                                                                   0
+#define mmGRBM_SCRATCH_REG4                                                                            0x0044
+#define mmGRBM_SCRATCH_REG4_BASE_IDX                                                                   0
+#define mmGRBM_SCRATCH_REG5                                                                            0x0045
+#define mmGRBM_SCRATCH_REG5_BASE_IDX                                                                   0
+#define mmGRBM_SCRATCH_REG6                                                                            0x0046
+#define mmGRBM_SCRATCH_REG6_BASE_IDX                                                                   0
+#define mmGRBM_SCRATCH_REG7                                                                            0x0047
+#define mmGRBM_SCRATCH_REG7_BASE_IDX                                                                   0
+
+// addressBlock: gc_cppdec2
+// base address: 0xc600
+#define mmCPF_EDC_TAG_CNT                                                                              0x1189
+#define mmCPF_EDC_TAG_CNT_BASE_IDX                                                                     0
+#define mmCPF_EDC_ROQ_CNT                                                                              0x118a
+#define mmCPF_EDC_ROQ_CNT_BASE_IDX                                                                     0
+#define mmCPG_EDC_TAG_CNT                                                                              0x118b
+#define mmCPG_EDC_TAG_CNT_BASE_IDX                                                                     0
+#define mmCPG_EDC_DMA_CNT                                                                              0x118d
+#define mmCPG_EDC_DMA_CNT_BASE_IDX                                                                     0
+#define mmCPC_EDC_SCRATCH_CNT                                                                          0x118e
+#define mmCPC_EDC_SCRATCH_CNT_BASE_IDX                                                                 0
+#define mmCPC_EDC_UCODE_CNT                                                                            0x118f
+#define mmCPC_EDC_UCODE_CNT_BASE_IDX                                                                   0
+#define mmDC_EDC_STATE_CNT                                                                             0x1191
+#define mmDC_EDC_STATE_CNT_BASE_IDX                                                                    0
+#define mmDC_EDC_CSINVOC_CNT                                                                           0x1192
+#define mmDC_EDC_CSINVOC_CNT_BASE_IDX                                                                  0
+#define mmDC_EDC_RESTORE_CNT                                                                           0x1193
+#define mmDC_EDC_RESTORE_CNT_BASE_IDX                                                                  0
+
+// addressBlock: gc_gdsdec
+// base address: 0x9700
+#define mmGDS_EDC_CNT                                                                                  0x05c5
+#define mmGDS_EDC_CNT_BASE_IDX                                                                         0
+#define mmGDS_EDC_GRBM_CNT                                                                             0x05c6
+#define mmGDS_EDC_GRBM_CNT_BASE_IDX                                                                    0
+#define mmGDS_EDC_OA_DED                                                                               0x05c7
+#define mmGDS_EDC_OA_DED_BASE_IDX                                                                      0
+#define mmGDS_EDC_OA_PHY_CNT                                                                           0x05cb
+#define mmGDS_EDC_OA_PHY_CNT_BASE_IDX                                                                  0
+#define mmGDS_EDC_OA_PIPE_CNT                                                                          0x05cc
+#define mmGDS_EDC_OA_PIPE_CNT_BASE_IDX                                                                 0
+
+// addressBlock: gc_shsdec
+// base address: 0x9000
+#define mmSPI_EDC_CNT                                                                                  0x0445
+#define mmSPI_EDC_CNT_BASE_IDX                                                                         0
+
+// addressBlock: gc_sqdec
+// base address: 0x8c00
+#define mmSQC_EDC_CNT2                                                                                 0x032c
+#define mmSQC_EDC_CNT2_BASE_IDX                                                                        0
+#define mmSQC_EDC_CNT3                                                                                 0x032d
+#define mmSQC_EDC_CNT3_BASE_IDX                                                                        0
+#define mmSQC_EDC_PARITY_CNT3                                                                          0x032e
+#define mmSQC_EDC_PARITY_CNT3_BASE_IDX                                                                 0
+#define mmSQC_EDC_CNT                                                                                  0x03a2
+#define mmSQC_EDC_CNT_BASE_IDX                                                                         0
+#define mmSQ_EDC_SEC_CNT                                                                               0x03a3
+#define mmSQ_EDC_SEC_CNT_BASE_IDX                                                                      0
+#define mmSQ_EDC_DED_CNT                                                                               0x03a4
+#define mmSQ_EDC_DED_CNT_BASE_IDX                                                                      0
+#define mmSQ_EDC_INFO                                                                                  0x03a5
+#define mmSQ_EDC_INFO_BASE_IDX                                                                         0
+#define mmSQ_EDC_CNT                                                                                   0x03a6
+#define mmSQ_EDC_CNT_BASE_IDX                                                                          0
+
+// addressBlock: gc_tpdec
+// base address: 0x9400
+#define mmTA_EDC_CNT                                                                                   0x0586
+#define mmTA_EDC_CNT_BASE_IDX                                                                          0
+
+// addressBlock: gc_tcdec
+// base address: 0xac00
+#define mmTCP_EDC_CNT                                                                                  0x0b17
+#define mmTCP_EDC_CNT_BASE_IDX                                                                         0
+#define mmTCP_EDC_CNT_NEW                                                                              0x0b18
+#define mmTCP_EDC_CNT_NEW_BASE_IDX                                                                     0
+#define mmTCP_ATC_EDC_GATCL1_CNT                                                                       0x12b1
+#define mmTCP_ATC_EDC_GATCL1_CNT_BASE_IDX                                                              0
+#define mmTCI_EDC_CNT                                                                                  0x0b60
+#define mmTCI_EDC_CNT_BASE_IDX                                                                         0
+#define mmTCC_EDC_CNT                                                                                  0x0b82
+#define mmTCC_EDC_CNT_BASE_IDX                                                                         0
+#define mmTCC_EDC_CNT2                                                                                 0x0b83
+#define mmTCC_EDC_CNT2_BASE_IDX                                                                        0
+#define mmTCA_EDC_CNT                                                                                  0x0bc5
+#define mmTCA_EDC_CNT_BASE_IDX                                                                         0
+
+// addressBlock: gc_tpdec
+// base address: 0x9400
+#define mmTD_EDC_CNT                                                                                   0x052e
+#define mmTD_EDC_CNT_BASE_IDX                                                                          0
+#define mmTA_EDC_CNT                                                                                   0x0586
+#define mmTA_EDC_CNT_BASE_IDX                                                                          0
+
+// addressBlock: gc_ea_gceadec2
+// base address: 0x9c00
+#define mmGCEA_EDC_CNT                                                                                 0x0706
+#define mmGCEA_EDC_CNT_BASE_IDX                                                                        0
+#define mmGCEA_EDC_CNT2                                                                                0x0707
+#define mmGCEA_EDC_CNT2_BASE_IDX                                                                       0
+#define mmGCEA_EDC_CNT3                                                                                0x071b
+#define mmGCEA_EDC_CNT3_BASE_IDX                                                                       0
+
+// addressBlock: gc_gfxudec
+// base address: 0x30000
+#define mmSCRATCH_REG0                                                                                 0x2040
+#define mmSCRATCH_REG0_BASE_IDX                                                                        1
+#define mmSCRATCH_REG1                                                                                 0x2041
+#define mmSCRATCH_REG1_BASE_IDX                                                                        1
+#define mmSCRATCH_REG2                                                                                 0x2042
+#define mmSCRATCH_REG2_BASE_IDX                                                                        1
+#define mmSCRATCH_REG3                                                                                 0x2043
+#define mmSCRATCH_REG3_BASE_IDX                                                                        1
+#define mmSCRATCH_REG4                                                                                 0x2044
+#define mmSCRATCH_REG4_BASE_IDX                                                                        1
+#define mmSCRATCH_REG5                                                                                 0x2045
+#define mmSCRATCH_REG5_BASE_IDX                                                                        1
+#define mmSCRATCH_REG6                                                                                 0x2046
+#define mmSCRATCH_REG6_BASE_IDX                                                                        1
+#define mmSCRATCH_REG7                                                                                 0x2047
+#define mmSCRATCH_REG7_BASE_IDX                                                                        1
+#define mmGRBM_GFX_INDEX                                                                               0x2200
+#define mmGRBM_GFX_INDEX_BASE_IDX                                                                      1
+
+// addressBlock: gc_utcl2_atcl2dec
+// base address: 0xa000
+#define mmATC_L2_CACHE_4K_DSM_INDEX                                                                    0x080e
+#define mmATC_L2_CACHE_4K_DSM_INDEX_BASE_IDX                                                           0
+#define mmATC_L2_CACHE_2M_DSM_INDEX                                                                    0x080f
+#define mmATC_L2_CACHE_2M_DSM_INDEX_BASE_IDX                                                           0
+#define mmATC_L2_CACHE_4K_DSM_CNTL                                                                     0x0810
+#define mmATC_L2_CACHE_4K_DSM_CNTL_BASE_IDX                                                            0
+#define mmATC_L2_CACHE_2M_DSM_CNTL                                                                     0x0811
+#define mmATC_L2_CACHE_2M_DSM_CNTL_BASE_IDX                                                            0
+
+// addressBlock: gc_utcl2_vml2pfdec
+// base address: 0xa100
+#define mmVML2_MEM_ECC_INDEX                                                                           0x0860
+#define mmVML2_MEM_ECC_INDEX_BASE_IDX                                                                  0
+#define mmVML2_WALKER_MEM_ECC_INDEX                                                                    0x0861
+#define mmVML2_WALKER_MEM_ECC_INDEX_BASE_IDX                                                           0
+#define mmUTCL2_MEM_ECC_INDEX                                                                          0x0862
+#define mmUTCL2_MEM_ECC_INDEX_BASE_IDX                                                                 0
+
+#define mmVML2_MEM_ECC_CNTL                                                                            0x0863
+#define mmVML2_MEM_ECC_CNTL_BASE_IDX                                                                   0
+#define mmVML2_WALKER_MEM_ECC_CNTL                                                                     0x0864
+#define mmVML2_WALKER_MEM_ECC_CNTL_BASE_IDX                                                            0
+#define mmUTCL2_MEM_ECC_CNTL                                                                           0x0865
+#define mmUTCL2_MEM_ECC_CNTL_BASE_IDX                                                                  0
+
+// addressBlock: gc_rlcpdec
+// base address: 0x3b000
+#define mmRLC_EDC_CNT                                                                                  0x4d40
+#define mmRLC_EDC_CNT_BASE_IDX                                                                         1
+#define mmRLC_EDC_CNT2                                                                                 0x4d41
+#define mmRLC_EDC_CNT2_BASE_IDX                                                                        1
+
+#endif
\ No newline at end of file
diff --git a/drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_4_1_sh_mask.h b/drivers/gpu/drm/amd/include/asic_reg/gc/gc_9_4_1_sh_mask.h
new file mode 100644 (file)
index 0000000..f26246a
--- /dev/null
@@ -0,0 +1,748 @@
+/*
+ * Copyright (C) 2020  Advanced Micro Devices, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef _gc_9_4_1_SH_MASK_HEADER
+#define _gc_9_4_1_SH_MASK_HEADER
+
+// addressBlock: gc_cppdec2
+//CPF_EDC_TAG_CNT
+#define CPF_EDC_TAG_CNT__DED_COUNT__SHIFT                                                                     0x0
+#define CPF_EDC_TAG_CNT__SEC_COUNT__SHIFT                                                                     0x2
+#define CPF_EDC_TAG_CNT__DED_COUNT_MASK                                                                       0x00000003L
+#define CPF_EDC_TAG_CNT__SEC_COUNT_MASK                                                                       0x0000000CL
+//CPF_EDC_ROQ_CNT
+#define CPF_EDC_ROQ_CNT__DED_COUNT_ME1__SHIFT                                                                 0x0
+#define CPF_EDC_ROQ_CNT__SEC_COUNT_ME1__SHIFT                                                                 0x2
+#define CPF_EDC_ROQ_CNT__DED_COUNT_ME2__SHIFT                                                                 0x4
+#define CPF_EDC_ROQ_CNT__SEC_COUNT_ME2__SHIFT                                                                 0x6
+#define CPF_EDC_ROQ_CNT__DED_COUNT_ME1_MASK                                                                   0x00000003L
+#define CPF_EDC_ROQ_CNT__SEC_COUNT_ME1_MASK                                                                   0x0000000CL
+#define CPF_EDC_ROQ_CNT__DED_COUNT_ME2_MASK                                                                   0x00000030L
+#define CPF_EDC_ROQ_CNT__SEC_COUNT_ME2_MASK                                                                   0x000000C0L
+//CPG_EDC_TAG_CNT
+#define CPG_EDC_TAG_CNT__DED_COUNT__SHIFT                                                                     0x0
+#define CPG_EDC_TAG_CNT__SEC_COUNT__SHIFT                                                                     0x2
+#define CPG_EDC_TAG_CNT__DED_COUNT_MASK                                                                       0x00000003L
+#define CPG_EDC_TAG_CNT__SEC_COUNT_MASK                                                                       0x0000000CL
+//CPG_EDC_DMA_CNT
+#define CPG_EDC_DMA_CNT__ROQ_DED_COUNT__SHIFT                                                                 0x0
+#define CPG_EDC_DMA_CNT__ROQ_SEC_COUNT__SHIFT                                                                 0x2
+#define CPG_EDC_DMA_CNT__TAG_DED_COUNT__SHIFT                                                                 0x4
+#define CPG_EDC_DMA_CNT__TAG_SEC_COUNT__SHIFT                                                                 0x6
+#define CPG_EDC_DMA_CNT__ROQ_DED_COUNT_MASK                                                                   0x00000003L
+#define CPG_EDC_DMA_CNT__ROQ_SEC_COUNT_MASK                                                                   0x0000000CL
+#define CPG_EDC_DMA_CNT__TAG_DED_COUNT_MASK                                                                   0x00000030L
+#define CPG_EDC_DMA_CNT__TAG_SEC_COUNT_MASK                                                                   0x000000C0L
+//CPC_EDC_SCRATCH_CNT
+#define CPC_EDC_SCRATCH_CNT__DED_COUNT__SHIFT                                                                 0x0
+#define CPC_EDC_SCRATCH_CNT__SEC_COUNT__SHIFT                                                                 0x2
+#define CPC_EDC_SCRATCH_CNT__DED_COUNT_MASK                                                                   0x00000003L
+#define CPC_EDC_SCRATCH_CNT__SEC_COUNT_MASK                                                                   0x0000000CL
+//CPC_EDC_UCODE_CNT
+#define CPC_EDC_UCODE_CNT__DED_COUNT__SHIFT                                                                   0x0
+#define CPC_EDC_UCODE_CNT__SEC_COUNT__SHIFT                                                                   0x2
+#define CPC_EDC_UCODE_CNT__DED_COUNT_MASK                                                                     0x00000003L
+#define CPC_EDC_UCODE_CNT__SEC_COUNT_MASK                                                                     0x0000000CL
+//DC_EDC_STATE_CNT
+#define DC_EDC_STATE_CNT__DED_COUNT_ME1__SHIFT                                                                0x0
+#define DC_EDC_STATE_CNT__SEC_COUNT_ME1__SHIFT                                                                0x2
+#define DC_EDC_STATE_CNT__DED_COUNT_ME1_MASK                                                                  0x00000003L
+#define DC_EDC_STATE_CNT__SEC_COUNT_ME1_MASK                                                                  0x0000000CL
+//DC_EDC_CSINVOC_CNT
+#define DC_EDC_CSINVOC_CNT__DED_COUNT_ME1__SHIFT                                                              0x0
+#define DC_EDC_CSINVOC_CNT__SEC_COUNT_ME1__SHIFT                                                              0x2
+#define DC_EDC_CSINVOC_CNT__DED_COUNT1_ME1__SHIFT                                                             0x4
+#define DC_EDC_CSINVOC_CNT__SEC_COUNT1_ME1__SHIFT                                                             0x6
+#define DC_EDC_CSINVOC_CNT__DED_COUNT_ME1_MASK                                                                0x00000003L
+#define DC_EDC_CSINVOC_CNT__SEC_COUNT_ME1_MASK                                                                0x0000000CL
+#define DC_EDC_CSINVOC_CNT__DED_COUNT1_ME1_MASK                                                               0x00000030L
+#define DC_EDC_CSINVOC_CNT__SEC_COUNT1_ME1_MASK                                                               0x000000C0L
+//DC_EDC_RESTORE_CNT
+#define DC_EDC_RESTORE_CNT__DED_COUNT_ME1__SHIFT                                                              0x0
+#define DC_EDC_RESTORE_CNT__SEC_COUNT_ME1__SHIFT                                                              0x2
+#define DC_EDC_RESTORE_CNT__DED_COUNT1_ME1__SHIFT                                                             0x4
+#define DC_EDC_RESTORE_CNT__SEC_COUNT1_ME1__SHIFT                                                             0x6
+#define DC_EDC_RESTORE_CNT__DED_COUNT_ME1_MASK                                                                0x00000003L
+#define DC_EDC_RESTORE_CNT__SEC_COUNT_ME1_MASK                                                                0x0000000CL
+#define DC_EDC_RESTORE_CNT__DED_COUNT1_ME1_MASK                                                               0x00000030L
+#define DC_EDC_RESTORE_CNT__SEC_COUNT1_ME1_MASK                                                               0x000000C0L
+
+// addressBlock: gc_gdsdec
+//GDS_EDC_CNT
+#define GDS_EDC_CNT__GDS_MEM_DED__SHIFT                                                                       0x0
+#define GDS_EDC_CNT__GDS_MEM_SEC__SHIFT                                                                       0x4
+#define GDS_EDC_CNT__UNUSED__SHIFT                                                                            0x6
+#define GDS_EDC_CNT__GDS_MEM_DED_MASK                                                                         0x00000003L
+#define GDS_EDC_CNT__GDS_MEM_SEC_MASK                                                                         0x00000030L
+#define GDS_EDC_CNT__UNUSED_MASK                                                                              0xFFFFFFC0L
+//GDS_EDC_GRBM_CNT
+#define GDS_EDC_GRBM_CNT__DED__SHIFT                                                                          0x0
+#define GDS_EDC_GRBM_CNT__SEC__SHIFT                                                                          0x2
+#define GDS_EDC_GRBM_CNT__UNUSED__SHIFT                                                                       0x4
+#define GDS_EDC_GRBM_CNT__DED_MASK                                                                            0x00000003L
+#define GDS_EDC_GRBM_CNT__SEC_MASK                                                                            0x0000000CL
+#define GDS_EDC_GRBM_CNT__UNUSED_MASK                                                                         0xFFFFFFF0L
+//GDS_EDC_OA_DED
+#define GDS_EDC_OA_DED__ME0_GFXHP3D_PIX_DED__SHIFT                                                            0x0
+#define GDS_EDC_OA_DED__ME0_GFXHP3D_VTX_DED__SHIFT                                                            0x1
+#define GDS_EDC_OA_DED__ME0_CS_DED__SHIFT                                                                     0x2
+#define GDS_EDC_OA_DED__ME0_GFXHP3D_GS_DED__SHIFT                                                             0x3
+#define GDS_EDC_OA_DED__ME1_PIPE0_DED__SHIFT                                                                  0x4
+#define GDS_EDC_OA_DED__ME1_PIPE1_DED__SHIFT                                                                  0x5
+#define GDS_EDC_OA_DED__ME1_PIPE2_DED__SHIFT                                                                  0x6
+#define GDS_EDC_OA_DED__ME1_PIPE3_DED__SHIFT                                                                  0x7
+#define GDS_EDC_OA_DED__ME2_PIPE0_DED__SHIFT                                                                  0x8
+#define GDS_EDC_OA_DED__ME2_PIPE1_DED__SHIFT                                                                  0x9
+#define GDS_EDC_OA_DED__ME2_PIPE2_DED__SHIFT                                                                  0xa
+#define GDS_EDC_OA_DED__ME2_PIPE3_DED__SHIFT                                                                  0xb
+#define GDS_EDC_OA_DED__UNUSED1__SHIFT                                                                        0xc
+#define GDS_EDC_OA_DED__ME0_GFXHP3D_PIX_DED_MASK                                                              0x00000001L
+#define GDS_EDC_OA_DED__ME0_GFXHP3D_VTX_DED_MASK                                                              0x00000002L
+#define GDS_EDC_OA_DED__ME0_CS_DED_MASK                                                                       0x00000004L
+#define GDS_EDC_OA_DED__ME0_GFXHP3D_GS_DED_MASK                                                               0x00000008L
+#define GDS_EDC_OA_DED__ME1_PIPE0_DED_MASK                                                                    0x00000010L
+#define GDS_EDC_OA_DED__ME1_PIPE1_DED_MASK                                                                    0x00000020L
+#define GDS_EDC_OA_DED__ME1_PIPE2_DED_MASK                                                                    0x00000040L
+#define GDS_EDC_OA_DED__ME1_PIPE3_DED_MASK                                                                    0x00000080L
+#define GDS_EDC_OA_DED__ME2_PIPE0_DED_MASK                                                                    0x00000100L
+#define GDS_EDC_OA_DED__ME2_PIPE1_DED_MASK                                                                    0x00000200L
+#define GDS_EDC_OA_DED__ME2_PIPE2_DED_MASK                                                                    0x00000400L
+#define GDS_EDC_OA_DED__ME2_PIPE3_DED_MASK                                                                    0x00000800L
+#define GDS_EDC_OA_DED__UNUSED1_MASK                                                                          0xFFFFF000L
+//GDS_EDC_OA_PHY_CNT
+#define GDS_EDC_OA_PHY_CNT__ME0_CS_PIPE_MEM_SEC__SHIFT                                                        0x0
+#define GDS_EDC_OA_PHY_CNT__ME0_CS_PIPE_MEM_DED__SHIFT                                                        0x2
+#define GDS_EDC_OA_PHY_CNT__PHY_CMD_RAM_MEM_SEC__SHIFT                                                        0x4
+#define GDS_EDC_OA_PHY_CNT__PHY_CMD_RAM_MEM_DED__SHIFT                                                        0x6
+#define GDS_EDC_OA_PHY_CNT__PHY_DATA_RAM_MEM_SEC__SHIFT                                                       0x8
+#define GDS_EDC_OA_PHY_CNT__PHY_DATA_RAM_MEM_DED__SHIFT                                                       0xa
+#define GDS_EDC_OA_PHY_CNT__UNUSED1__SHIFT                                                                    0xc
+#define GDS_EDC_OA_PHY_CNT__ME0_CS_PIPE_MEM_SEC_MASK                                                          0x00000003L
+#define GDS_EDC_OA_PHY_CNT__ME0_CS_PIPE_MEM_DED_MASK                                                          0x0000000CL
+#define GDS_EDC_OA_PHY_CNT__PHY_CMD_RAM_MEM_SEC_MASK                                                          0x00000030L
+#define GDS_EDC_OA_PHY_CNT__PHY_CMD_RAM_MEM_DED_MASK                                                          0x000000C0L
+#define GDS_EDC_OA_PHY_CNT__PHY_DATA_RAM_MEM_SEC_MASK                                                         0x00000300L
+#define GDS_EDC_OA_PHY_CNT__PHY_DATA_RAM_MEM_DED_MASK                                                         0x00000C00L
+#define GDS_EDC_OA_PHY_CNT__UNUSED1_MASK                                                                      0xFFFFF000L
+//GDS_EDC_OA_PIPE_CNT
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE0_PIPE_MEM_SEC__SHIFT                                                    0x0
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE0_PIPE_MEM_DED__SHIFT                                                    0x2
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE1_PIPE_MEM_SEC__SHIFT                                                    0x4
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE1_PIPE_MEM_DED__SHIFT                                                    0x6
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE2_PIPE_MEM_SEC__SHIFT                                                    0x8
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE2_PIPE_MEM_DED__SHIFT                                                    0xa
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE3_PIPE_MEM_SEC__SHIFT                                                    0xc
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE3_PIPE_MEM_DED__SHIFT                                                    0xe
+#define GDS_EDC_OA_PIPE_CNT__UNUSED__SHIFT                                                                    0x10
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE0_PIPE_MEM_SEC_MASK                                                      0x00000003L
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE0_PIPE_MEM_DED_MASK                                                      0x0000000CL
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE1_PIPE_MEM_SEC_MASK                                                      0x00000030L
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE1_PIPE_MEM_DED_MASK                                                      0x000000C0L
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE2_PIPE_MEM_SEC_MASK                                                      0x00000300L
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE2_PIPE_MEM_DED_MASK                                                      0x00000C00L
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE3_PIPE_MEM_SEC_MASK                                                      0x00003000L
+#define GDS_EDC_OA_PIPE_CNT__ME1_PIPE3_PIPE_MEM_DED_MASK                                                      0x0000C000L
+#define GDS_EDC_OA_PIPE_CNT__UNUSED_MASK                                                                      0xFFFF0000L
+
+// addressBlock: gc_shsdec
+//SPI_EDC_CNT
+#define SPI_EDC_CNT__SPI_SR_MEM_SEC_COUNT__SHIFT                                                              0x0
+#define SPI_EDC_CNT__SPI_SR_MEM_DED_COUNT__SHIFT                                                              0x2
+#define SPI_EDC_CNT__SPI_GDS_EXPREQ_SEC_COUNT__SHIFT                                                          0x4
+#define SPI_EDC_CNT__SPI_GDS_EXPREQ_DED_COUNT__SHIFT                                                          0x6
+#define SPI_EDC_CNT__SPI_WB_GRANT_30_SEC_COUNT__SHIFT                                                         0x8
+#define SPI_EDC_CNT__SPI_WB_GRANT_30_DED_COUNT__SHIFT                                                         0xa
+#define SPI_EDC_CNT__SPI_WB_GRANT_61_SEC_COUNT__SHIFT                                                         0xc
+#define SPI_EDC_CNT__SPI_WB_GRANT_61_DED_COUNT__SHIFT                                                         0xe
+#define SPI_EDC_CNT__SPI_LIFE_CNT_SEC_COUNT__SHIFT                                                            0x10
+#define SPI_EDC_CNT__SPI_LIFE_CNT_DED_COUNT__SHIFT                                                            0x12
+#define SPI_EDC_CNT__SPI_SR_MEM_SEC_COUNT_MASK                                                                0x00000003L
+#define SPI_EDC_CNT__SPI_SR_MEM_DED_COUNT_MASK                                                                0x0000000CL
+#define SPI_EDC_CNT__SPI_GDS_EXPREQ_SEC_COUNT_MASK                                                            0x00000030L
+#define SPI_EDC_CNT__SPI_GDS_EXPREQ_DED_COUNT_MASK                                                            0x000000C0L
+#define SPI_EDC_CNT__SPI_WB_GRANT_30_SEC_COUNT_MASK                                                           0x00000300L
+#define SPI_EDC_CNT__SPI_WB_GRANT_30_DED_COUNT_MASK                                                           0x00000C00L
+#define SPI_EDC_CNT__SPI_WB_GRANT_61_SEC_COUNT_MASK                                                           0x00003000L
+#define SPI_EDC_CNT__SPI_WB_GRANT_61_DED_COUNT_MASK                                                           0x0000C000L
+#define SPI_EDC_CNT__SPI_LIFE_CNT_SEC_COUNT_MASK                                                              0x00030000L
+#define SPI_EDC_CNT__SPI_LIFE_CNT_DED_COUNT_MASK                                                              0x000C0000L
+
+// addressBlock: gc_sqdec
+//SQC_EDC_CNT2
+#define SQC_EDC_CNT2__INST_BANKA_TAG_RAM_SEC_COUNT__SHIFT                                                     0x0
+#define SQC_EDC_CNT2__INST_BANKA_TAG_RAM_DED_COUNT__SHIFT                                                     0x2
+#define SQC_EDC_CNT2__INST_BANKA_BANK_RAM_SEC_COUNT__SHIFT                                                    0x4
+#define SQC_EDC_CNT2__INST_BANKA_BANK_RAM_DED_COUNT__SHIFT                                                    0x6
+#define SQC_EDC_CNT2__DATA_BANKA_TAG_RAM_SEC_COUNT__SHIFT                                                     0x8
+#define SQC_EDC_CNT2__DATA_BANKA_TAG_RAM_DED_COUNT__SHIFT                                                     0xa
+#define SQC_EDC_CNT2__DATA_BANKA_BANK_RAM_SEC_COUNT__SHIFT                                                    0xc
+#define SQC_EDC_CNT2__DATA_BANKA_BANK_RAM_DED_COUNT__SHIFT                                                    0xe
+#define SQC_EDC_CNT2__INST_UTCL1_LFIFO_SEC_COUNT__SHIFT                                                       0x10
+#define SQC_EDC_CNT2__INST_UTCL1_LFIFO_DED_COUNT__SHIFT                                                       0x12
+#define SQC_EDC_CNT2__INST_BANKA_TAG_RAM_SEC_COUNT_MASK                                                       0x00000003L
+#define SQC_EDC_CNT2__INST_BANKA_TAG_RAM_DED_COUNT_MASK                                                       0x0000000CL
+#define SQC_EDC_CNT2__INST_BANKA_BANK_RAM_SEC_COUNT_MASK                                                      0x00000030L
+#define SQC_EDC_CNT2__INST_BANKA_BANK_RAM_DED_COUNT_MASK                                                      0x000000C0L
+#define SQC_EDC_CNT2__DATA_BANKA_TAG_RAM_SEC_COUNT_MASK                                                       0x00000300L
+#define SQC_EDC_CNT2__DATA_BANKA_TAG_RAM_DED_COUNT_MASK                                                       0x00000C00L
+#define SQC_EDC_CNT2__DATA_BANKA_BANK_RAM_SEC_COUNT_MASK                                                      0x00003000L
+#define SQC_EDC_CNT2__DATA_BANKA_BANK_RAM_DED_COUNT_MASK                                                      0x0000C000L
+#define SQC_EDC_CNT2__INST_UTCL1_LFIFO_SEC_COUNT_MASK                                                         0x00030000L
+#define SQC_EDC_CNT2__INST_UTCL1_LFIFO_DED_COUNT_MASK                                                         0x000C0000L
+//SQC_EDC_CNT3
+#define SQC_EDC_CNT3__INST_BANKB_TAG_RAM_SEC_COUNT__SHIFT                                                     0x0
+#define SQC_EDC_CNT3__INST_BANKB_TAG_RAM_DED_COUNT__SHIFT                                                     0x2
+#define SQC_EDC_CNT3__INST_BANKB_BANK_RAM_SEC_COUNT__SHIFT                                                    0x4
+#define SQC_EDC_CNT3__INST_BANKB_BANK_RAM_DED_COUNT__SHIFT                                                    0x6
+#define SQC_EDC_CNT3__DATA_BANKB_TAG_RAM_SEC_COUNT__SHIFT                                                     0x8
+#define SQC_EDC_CNT3__DATA_BANKB_TAG_RAM_DED_COUNT__SHIFT                                                     0xa
+#define SQC_EDC_CNT3__DATA_BANKB_BANK_RAM_SEC_COUNT__SHIFT                                                    0xc
+#define SQC_EDC_CNT3__DATA_BANKB_BANK_RAM_DED_COUNT__SHIFT                                                    0xe
+#define SQC_EDC_CNT3__INST_BANKB_TAG_RAM_SEC_COUNT_MASK                                                       0x00000003L
+#define SQC_EDC_CNT3__INST_BANKB_TAG_RAM_DED_COUNT_MASK                                                       0x0000000CL
+#define SQC_EDC_CNT3__INST_BANKB_BANK_RAM_SEC_COUNT_MASK                                                      0x00000030L
+#define SQC_EDC_CNT3__INST_BANKB_BANK_RAM_DED_COUNT_MASK                                                      0x000000C0L
+#define SQC_EDC_CNT3__DATA_BANKB_TAG_RAM_SEC_COUNT_MASK                                                       0x00000300L
+#define SQC_EDC_CNT3__DATA_BANKB_TAG_RAM_DED_COUNT_MASK                                                       0x00000C00L
+#define SQC_EDC_CNT3__DATA_BANKB_BANK_RAM_SEC_COUNT_MASK                                                      0x00003000L
+#define SQC_EDC_CNT3__DATA_BANKB_BANK_RAM_DED_COUNT_MASK                                                      0x0000C000L
+//SQC_EDC_PARITY_CNT3
+#define SQC_EDC_PARITY_CNT3__INST_BANKA_UTCL1_MISS_FIFO_SEC_COUNT__SHIFT                                      0x0
+#define SQC_EDC_PARITY_CNT3__INST_BANKA_UTCL1_MISS_FIFO_DED_COUNT__SHIFT                                      0x2
+#define SQC_EDC_PARITY_CNT3__INST_BANKA_MISS_FIFO_SEC_COUNT__SHIFT                                            0x4
+#define SQC_EDC_PARITY_CNT3__INST_BANKA_MISS_FIFO_DED_COUNT__SHIFT                                            0x6
+#define SQC_EDC_PARITY_CNT3__DATA_BANKA_HIT_FIFO_SEC_COUNT__SHIFT                                             0x8
+#define SQC_EDC_PARITY_CNT3__DATA_BANKA_HIT_FIFO_DED_COUNT__SHIFT                                             0xa
+#define SQC_EDC_PARITY_CNT3__DATA_BANKA_MISS_FIFO_SEC_COUNT__SHIFT                                            0xc
+#define SQC_EDC_PARITY_CNT3__DATA_BANKA_MISS_FIFO_DED_COUNT__SHIFT                                            0xe
+#define SQC_EDC_PARITY_CNT3__INST_BANKB_UTCL1_MISS_FIFO_SEC_COUNT__SHIFT                                      0x10
+#define SQC_EDC_PARITY_CNT3__INST_BANKB_UTCL1_MISS_FIFO_DED_COUNT__SHIFT                                      0x12
+#define SQC_EDC_PARITY_CNT3__INST_BANKB_MISS_FIFO_SEC_COUNT__SHIFT                                            0x14
+#define SQC_EDC_PARITY_CNT3__INST_BANKB_MISS_FIFO_DED_COUNT__SHIFT                                            0x16
+#define SQC_EDC_PARITY_CNT3__DATA_BANKB_HIT_FIFO_SEC_COUNT__SHIFT                                             0x18
+#define SQC_EDC_PARITY_CNT3__DATA_BANKB_HIT_FIFO_DED_COUNT__SHIFT                                             0x1a
+#define SQC_EDC_PARITY_CNT3__DATA_BANKB_MISS_FIFO_SEC_COUNT__SHIFT                                            0x1c
+#define SQC_EDC_PARITY_CNT3__DATA_BANKB_MISS_FIFO_DED_COUNT__SHIFT                                            0x1e
+#define SQC_EDC_PARITY_CNT3__INST_BANKA_UTCL1_MISS_FIFO_SEC_COUNT_MASK                                        0x00000003L
+#define SQC_EDC_PARITY_CNT3__INST_BANKA_UTCL1_MISS_FIFO_DED_COUNT_MASK                                        0x0000000CL
+#define SQC_EDC_PARITY_CNT3__INST_BANKA_MISS_FIFO_SEC_COUNT_MASK                                              0x00000030L
+#define SQC_EDC_PARITY_CNT3__INST_BANKA_MISS_FIFO_DED_COUNT_MASK                                              0x000000C0L
+#define SQC_EDC_PARITY_CNT3__DATA_BANKA_HIT_FIFO_SEC_COUNT_MASK                                               0x00000300L
+#define SQC_EDC_PARITY_CNT3__DATA_BANKA_HIT_FIFO_DED_COUNT_MASK                                               0x00000C00L
+#define SQC_EDC_PARITY_CNT3__DATA_BANKA_MISS_FIFO_SEC_COUNT_MASK                                              0x00003000L
+#define SQC_EDC_PARITY_CNT3__DATA_BANKA_MISS_FIFO_DED_COUNT_MASK                                              0x0000C000L
+#define SQC_EDC_PARITY_CNT3__INST_BANKB_UTCL1_MISS_FIFO_SEC_COUNT_MASK                                        0x00030000L
+#define SQC_EDC_PARITY_CNT3__INST_BANKB_UTCL1_MISS_FIFO_DED_COUNT_MASK                                        0x000C0000L
+#define SQC_EDC_PARITY_CNT3__INST_BANKB_MISS_FIFO_SEC_COUNT_MASK                                              0x00300000L
+#define SQC_EDC_PARITY_CNT3__INST_BANKB_MISS_FIFO_DED_COUNT_MASK                                              0x00C00000L
+#define SQC_EDC_PARITY_CNT3__DATA_BANKB_HIT_FIFO_SEC_COUNT_MASK                                               0x03000000L
+#define SQC_EDC_PARITY_CNT3__DATA_BANKB_HIT_FIFO_DED_COUNT_MASK                                               0x0C000000L
+#define SQC_EDC_PARITY_CNT3__DATA_BANKB_MISS_FIFO_SEC_COUNT_MASK                                              0x30000000L
+#define SQC_EDC_PARITY_CNT3__DATA_BANKB_MISS_FIFO_DED_COUNT_MASK                                              0xC0000000L
+//SQC_EDC_CNT
+#define SQC_EDC_CNT__DATA_CU0_WRITE_DATA_BUF_SEC_COUNT__SHIFT                                                 0x0
+#define SQC_EDC_CNT__DATA_CU0_WRITE_DATA_BUF_DED_COUNT__SHIFT                                                 0x2
+#define SQC_EDC_CNT__DATA_CU0_UTCL1_LFIFO_SEC_COUNT__SHIFT                                                    0x4
+#define SQC_EDC_CNT__DATA_CU0_UTCL1_LFIFO_DED_COUNT__SHIFT                                                    0x6
+#define SQC_EDC_CNT__DATA_CU1_WRITE_DATA_BUF_SEC_COUNT__SHIFT                                                 0x8
+#define SQC_EDC_CNT__DATA_CU1_WRITE_DATA_BUF_DED_COUNT__SHIFT                                                 0xa
+#define SQC_EDC_CNT__DATA_CU1_UTCL1_LFIFO_SEC_COUNT__SHIFT                                                    0xc
+#define SQC_EDC_CNT__DATA_CU1_UTCL1_LFIFO_DED_COUNT__SHIFT                                                    0xe
+#define SQC_EDC_CNT__DATA_CU2_WRITE_DATA_BUF_SEC_COUNT__SHIFT                                                 0x10
+#define SQC_EDC_CNT__DATA_CU2_WRITE_DATA_BUF_DED_COUNT__SHIFT                                                 0x12
+#define SQC_EDC_CNT__DATA_CU2_UTCL1_LFIFO_SEC_COUNT__SHIFT                                                    0x14
+#define SQC_EDC_CNT__DATA_CU2_UTCL1_LFIFO_DED_COUNT__SHIFT                                                    0x16
+#define SQC_EDC_CNT__DATA_CU3_WRITE_DATA_BUF_SEC_COUNT__SHIFT                                                 0x18
+#define SQC_EDC_CNT__DATA_CU3_WRITE_DATA_BUF_DED_COUNT__SHIFT                                                 0x1a
+#define SQC_EDC_CNT__DATA_CU3_UTCL1_LFIFO_SEC_COUNT__SHIFT                                                    0x1c
+#define SQC_EDC_CNT__DATA_CU3_UTCL1_LFIFO_DED_COUNT__SHIFT                                                    0x1e
+#define SQC_EDC_CNT__DATA_CU0_WRITE_DATA_BUF_SEC_COUNT_MASK                                                   0x00000003L
+#define SQC_EDC_CNT__DATA_CU0_WRITE_DATA_BUF_DED_COUNT_MASK                                                   0x0000000CL
+#define SQC_EDC_CNT__DATA_CU0_UTCL1_LFIFO_SEC_COUNT_MASK                                                      0x00000030L
+#define SQC_EDC_CNT__DATA_CU0_UTCL1_LFIFO_DED_COUNT_MASK                                                      0x000000C0L
+#define SQC_EDC_CNT__DATA_CU1_WRITE_DATA_BUF_SEC_COUNT_MASK                                                   0x00000300L
+#define SQC_EDC_CNT__DATA_CU1_WRITE_DATA_BUF_DED_COUNT_MASK                                                   0x00000C00L
+#define SQC_EDC_CNT__DATA_CU1_UTCL1_LFIFO_SEC_COUNT_MASK                                                      0x00003000L
+#define SQC_EDC_CNT__DATA_CU1_UTCL1_LFIFO_DED_COUNT_MASK                                                      0x0000C000L
+#define SQC_EDC_CNT__DATA_CU2_WRITE_DATA_BUF_SEC_COUNT_MASK                                                   0x00030000L
+#define SQC_EDC_CNT__DATA_CU2_WRITE_DATA_BUF_DED_COUNT_MASK                                                   0x000C0000L
+#define SQC_EDC_CNT__DATA_CU2_UTCL1_LFIFO_SEC_COUNT_MASK                                                      0x00300000L
+#define SQC_EDC_CNT__DATA_CU2_UTCL1_LFIFO_DED_COUNT_MASK                                                      0x00C00000L
+#define SQC_EDC_CNT__DATA_CU3_WRITE_DATA_BUF_SEC_COUNT_MASK                                                   0x03000000L
+#define SQC_EDC_CNT__DATA_CU3_WRITE_DATA_BUF_DED_COUNT_MASK                                                   0x0C000000L
+#define SQC_EDC_CNT__DATA_CU3_UTCL1_LFIFO_SEC_COUNT_MASK                                                      0x30000000L
+#define SQC_EDC_CNT__DATA_CU3_UTCL1_LFIFO_DED_COUNT_MASK                                                      0xC0000000L
+//SQ_EDC_SEC_CNT
+#define SQ_EDC_SEC_CNT__LDS_SEC__SHIFT                                                                        0x0
+#define SQ_EDC_SEC_CNT__SGPR_SEC__SHIFT                                                                       0x8
+#define SQ_EDC_SEC_CNT__VGPR_SEC__SHIFT                                                                       0x10
+#define SQ_EDC_SEC_CNT__LDS_SEC_MASK                                                                          0x000000FFL
+#define SQ_EDC_SEC_CNT__SGPR_SEC_MASK                                                                         0x0000FF00L
+#define SQ_EDC_SEC_CNT__VGPR_SEC_MASK                                                                         0x00FF0000L
+//SQ_EDC_DED_CNT
+#define SQ_EDC_DED_CNT__LDS_DED__SHIFT                                                                        0x0
+#define SQ_EDC_DED_CNT__SGPR_DED__SHIFT                                                                       0x8
+#define SQ_EDC_DED_CNT__VGPR_DED__SHIFT                                                                       0x10
+#define SQ_EDC_DED_CNT__LDS_DED_MASK                                                                          0x000000FFL
+#define SQ_EDC_DED_CNT__SGPR_DED_MASK                                                                         0x0000FF00L
+#define SQ_EDC_DED_CNT__VGPR_DED_MASK                                                                         0x00FF0000L
+//SQ_EDC_INFO
+#define SQ_EDC_INFO__WAVE_ID__SHIFT                                                                           0x0
+#define SQ_EDC_INFO__SIMD_ID__SHIFT                                                                           0x4
+#define SQ_EDC_INFO__SOURCE__SHIFT                                                                            0x6
+#define SQ_EDC_INFO__VM_ID__SHIFT                                                                             0x9
+#define SQ_EDC_INFO__WAVE_ID_MASK                                                                             0x0000000FL
+#define SQ_EDC_INFO__SIMD_ID_MASK                                                                             0x00000030L
+#define SQ_EDC_INFO__SOURCE_MASK                                                                              0x000001C0L
+#define SQ_EDC_INFO__VM_ID_MASK                                                                               0x00001E00L
+//SQ_EDC_CNT
+#define SQ_EDC_CNT__LDS_D_SEC_COUNT__SHIFT                                                                    0x0
+#define SQ_EDC_CNT__LDS_D_DED_COUNT__SHIFT                                                                    0x2
+#define SQ_EDC_CNT__LDS_I_SEC_COUNT__SHIFT                                                                    0x4
+#define SQ_EDC_CNT__LDS_I_DED_COUNT__SHIFT                                                                    0x6
+#define SQ_EDC_CNT__SGPR_SEC_COUNT__SHIFT                                                                     0x8
+#define SQ_EDC_CNT__SGPR_DED_COUNT__SHIFT                                                                     0xa
+#define SQ_EDC_CNT__VGPR0_SEC_COUNT__SHIFT                                                                    0xc
+#define SQ_EDC_CNT__VGPR0_DED_COUNT__SHIFT                                                                    0xe
+#define SQ_EDC_CNT__VGPR1_SEC_COUNT__SHIFT                                                                    0x10
+#define SQ_EDC_CNT__VGPR1_DED_COUNT__SHIFT                                                                    0x12
+#define SQ_EDC_CNT__VGPR2_SEC_COUNT__SHIFT                                                                    0x14
+#define SQ_EDC_CNT__VGPR2_DED_COUNT__SHIFT                                                                    0x16
+#define SQ_EDC_CNT__VGPR3_SEC_COUNT__SHIFT                                                                    0x18
+#define SQ_EDC_CNT__VGPR3_DED_COUNT__SHIFT                                                                    0x1a
+#define SQ_EDC_CNT__LDS_D_SEC_COUNT_MASK                                                                      0x00000003L
+#define SQ_EDC_CNT__LDS_D_DED_COUNT_MASK                                                                      0x0000000CL
+#define SQ_EDC_CNT__LDS_I_SEC_COUNT_MASK                                                                      0x00000030L
+#define SQ_EDC_CNT__LDS_I_DED_COUNT_MASK                                                                      0x000000C0L
+#define SQ_EDC_CNT__SGPR_SEC_COUNT_MASK                                                                       0x00000300L
+#define SQ_EDC_CNT__SGPR_DED_COUNT_MASK                                                                       0x00000C00L
+#define SQ_EDC_CNT__VGPR0_SEC_COUNT_MASK                                                                      0x00003000L
+#define SQ_EDC_CNT__VGPR0_DED_COUNT_MASK                                                                      0x0000C000L
+#define SQ_EDC_CNT__VGPR1_SEC_COUNT_MASK                                                                      0x00030000L
+#define SQ_EDC_CNT__VGPR1_DED_COUNT_MASK                                                                      0x000C0000L
+#define SQ_EDC_CNT__VGPR2_SEC_COUNT_MASK                                                                      0x00300000L
+#define SQ_EDC_CNT__VGPR2_DED_COUNT_MASK                                                                      0x00C00000L
+#define SQ_EDC_CNT__VGPR3_SEC_COUNT_MASK                                                                      0x03000000L
+#define SQ_EDC_CNT__VGPR3_DED_COUNT_MASK                                                                      0x0C000000L
+
+// addressBlock: gc_tpdec
+//TA_EDC_CNT
+#define TA_EDC_CNT__TA_FS_DFIFO_SEC_COUNT__SHIFT                                                              0x0
+#define TA_EDC_CNT__TA_FS_DFIFO_DED_COUNT__SHIFT                                                              0x2
+#define TA_EDC_CNT__TA_FS_AFIFO_SEC_COUNT__SHIFT                                                              0x4
+#define TA_EDC_CNT__TA_FS_AFIFO_DED_COUNT__SHIFT                                                              0x6
+#define TA_EDC_CNT__TA_FL_LFIFO_SEC_COUNT__SHIFT                                                              0x8
+#define TA_EDC_CNT__TA_FL_LFIFO_DED_COUNT__SHIFT                                                              0xa
+#define TA_EDC_CNT__TA_FX_LFIFO_SEC_COUNT__SHIFT                                                              0xc
+#define TA_EDC_CNT__TA_FX_LFIFO_DED_COUNT__SHIFT                                                              0xe
+#define TA_EDC_CNT__TA_FS_CFIFO_SEC_COUNT__SHIFT                                                              0x10
+#define TA_EDC_CNT__TA_FS_CFIFO_DED_COUNT__SHIFT                                                              0x12
+#define TA_EDC_CNT__TA_FS_DFIFO_SEC_COUNT_MASK                                                                0x00000003L
+#define TA_EDC_CNT__TA_FS_DFIFO_DED_COUNT_MASK                                                                0x0000000CL
+#define TA_EDC_CNT__TA_FS_AFIFO_SEC_COUNT_MASK                                                                0x00000030L
+#define TA_EDC_CNT__TA_FS_AFIFO_DED_COUNT_MASK                                                                0x000000C0L
+#define TA_EDC_CNT__TA_FL_LFIFO_SEC_COUNT_MASK                                                                0x00000300L
+#define TA_EDC_CNT__TA_FL_LFIFO_DED_COUNT_MASK                                                                0x00000C00L
+#define TA_EDC_CNT__TA_FX_LFIFO_SEC_COUNT_MASK                                                                0x00003000L
+#define TA_EDC_CNT__TA_FX_LFIFO_DED_COUNT_MASK                                                                0x0000C000L
+#define TA_EDC_CNT__TA_FS_CFIFO_SEC_COUNT_MASK                                                                0x00030000L
+#define TA_EDC_CNT__TA_FS_CFIFO_DED_COUNT_MASK                                                                0x000C0000L
+
+// addressBlock: gc_tcdec
+//TCP_EDC_CNT
+#define TCP_EDC_CNT__SEC_COUNT__SHIFT                                                                         0x0
+#define TCP_EDC_CNT__LFIFO_SED_COUNT__SHIFT                                                                   0x8
+#define TCP_EDC_CNT__DED_COUNT__SHIFT                                                                         0x10
+#define TCP_EDC_CNT__SEC_COUNT_MASK                                                                           0x000000FFL
+#define TCP_EDC_CNT__LFIFO_SED_COUNT_MASK                                                                     0x0000FF00L
+#define TCP_EDC_CNT__DED_COUNT_MASK                                                                           0x00FF0000L
+//TCP_EDC_CNT_NEW
+#define TCP_EDC_CNT_NEW__CACHE_RAM_SEC_COUNT__SHIFT                                                           0x0
+#define TCP_EDC_CNT_NEW__CACHE_RAM_DED_COUNT__SHIFT                                                           0x2
+#define TCP_EDC_CNT_NEW__LFIFO_RAM_SEC_COUNT__SHIFT                                                           0x4
+#define TCP_EDC_CNT_NEW__LFIFO_RAM_DED_COUNT__SHIFT                                                           0x6
+#define TCP_EDC_CNT_NEW__CMD_FIFO_SEC_COUNT__SHIFT                                                            0x8
+#define TCP_EDC_CNT_NEW__CMD_FIFO_DED_COUNT__SHIFT                                                            0xa
+#define TCP_EDC_CNT_NEW__VM_FIFO_SEC_COUNT__SHIFT                                                             0xc
+#define TCP_EDC_CNT_NEW__VM_FIFO_DED_COUNT__SHIFT                                                             0xe
+#define TCP_EDC_CNT_NEW__DB_RAM_SED_COUNT__SHIFT                                                              0x10
+#define TCP_EDC_CNT_NEW__UTCL1_LFIFO0_SEC_COUNT__SHIFT                                                        0x12
+#define TCP_EDC_CNT_NEW__UTCL1_LFIFO0_DED_COUNT__SHIFT                                                        0x14
+#define TCP_EDC_CNT_NEW__UTCL1_LFIFO1_SEC_COUNT__SHIFT                                                        0x16
+#define TCP_EDC_CNT_NEW__UTCL1_LFIFO1_DED_COUNT__SHIFT                                                        0x18
+#define TCP_EDC_CNT_NEW__CACHE_RAM_SEC_COUNT_MASK                                                             0x00000003L
+#define TCP_EDC_CNT_NEW__CACHE_RAM_DED_COUNT_MASK                                                             0x0000000CL
+#define TCP_EDC_CNT_NEW__LFIFO_RAM_SEC_COUNT_MASK                                                             0x00000030L
+#define TCP_EDC_CNT_NEW__LFIFO_RAM_DED_COUNT_MASK                                                             0x000000C0L
+#define TCP_EDC_CNT_NEW__CMD_FIFO_SEC_COUNT_MASK                                                              0x00000300L
+#define TCP_EDC_CNT_NEW__CMD_FIFO_DED_COUNT_MASK                                                              0x00000C00L
+#define TCP_EDC_CNT_NEW__VM_FIFO_SEC_COUNT_MASK                                                               0x00003000L
+#define TCP_EDC_CNT_NEW__VM_FIFO_DED_COUNT_MASK                                                               0x0000C000L
+#define TCP_EDC_CNT_NEW__DB_RAM_SED_COUNT_MASK                                                                0x00030000L
+#define TCP_EDC_CNT_NEW__UTCL1_LFIFO0_SEC_COUNT_MASK                                                          0x000C0000L
+#define TCP_EDC_CNT_NEW__UTCL1_LFIFO0_DED_COUNT_MASK                                                          0x00300000L
+#define TCP_EDC_CNT_NEW__UTCL1_LFIFO1_SEC_COUNT_MASK                                                          0x00C00000L
+#define TCP_EDC_CNT_NEW__UTCL1_LFIFO1_DED_COUNT_MASK                                                          0x03000000L
+//TCP_ATC_EDC_GATCL1_CNT
+#define TCP_ATC_EDC_GATCL1_CNT__DATA_SEC__SHIFT                                                               0x0
+#define TCP_ATC_EDC_GATCL1_CNT__DATA_SEC_MASK                                                                 0x000000FFL
+//TCI_EDC_CNT
+#define TCI_EDC_CNT__WRITE_RAM_SEC_COUNT__SHIFT                                                               0x0
+#define TCI_EDC_CNT__WRITE_RAM_DED_COUNT__SHIFT                                                               0x2
+#define TCI_EDC_CNT__WRITE_RAM_SEC_COUNT_MASK                                                                 0x00000003L
+#define TCI_EDC_CNT__WRITE_RAM_DED_COUNT_MASK                                                                 0x0000000CL
+//TCA_EDC_CNT
+#define TCA_EDC_CNT__HOLE_FIFO_SEC_COUNT__SHIFT                                                               0x0
+#define TCA_EDC_CNT__HOLE_FIFO_DED_COUNT__SHIFT                                                               0x2
+#define TCA_EDC_CNT__REQ_FIFO_SEC_COUNT__SHIFT                                                                0x4
+#define TCA_EDC_CNT__REQ_FIFO_DED_COUNT__SHIFT                                                                0x6
+#define TCA_EDC_CNT__HOLE_FIFO_SEC_COUNT_MASK                                                                 0x00000003L
+#define TCA_EDC_CNT__HOLE_FIFO_DED_COUNT_MASK                                                                 0x0000000CL
+#define TCA_EDC_CNT__REQ_FIFO_SEC_COUNT_MASK                                                                  0x00000030L
+#define TCA_EDC_CNT__REQ_FIFO_DED_COUNT_MASK                                                                  0x000000C0L
+//TCC_EDC_CNT
+#define TCC_EDC_CNT__CACHE_DATA_SEC_COUNT__SHIFT                                                              0x0
+#define TCC_EDC_CNT__CACHE_DATA_DED_COUNT__SHIFT                                                              0x2
+#define TCC_EDC_CNT__CACHE_DIRTY_SEC_COUNT__SHIFT                                                             0x4
+#define TCC_EDC_CNT__CACHE_DIRTY_DED_COUNT__SHIFT                                                             0x6
+#define TCC_EDC_CNT__HIGH_RATE_TAG_SEC_COUNT__SHIFT                                                           0x8
+#define TCC_EDC_CNT__HIGH_RATE_TAG_DED_COUNT__SHIFT                                                           0xa
+#define TCC_EDC_CNT__LOW_RATE_TAG_SEC_COUNT__SHIFT                                                            0xc
+#define TCC_EDC_CNT__LOW_RATE_TAG_DED_COUNT__SHIFT                                                            0xe
+#define TCC_EDC_CNT__SRC_FIFO_SEC_COUNT__SHIFT                                                                0x10
+#define TCC_EDC_CNT__SRC_FIFO_DED_COUNT__SHIFT                                                                0x12
+#define TCC_EDC_CNT__LATENCY_FIFO_SEC_COUNT__SHIFT                                                            0x14
+#define TCC_EDC_CNT__LATENCY_FIFO_DED_COUNT__SHIFT                                                            0x16
+#define TCC_EDC_CNT__LATENCY_FIFO_NEXT_RAM_SEC_COUNT__SHIFT                                                   0x18
+#define TCC_EDC_CNT__LATENCY_FIFO_NEXT_RAM_DED_COUNT__SHIFT                                                   0x1a
+#define TCC_EDC_CNT__CACHE_DATA_SEC_COUNT_MASK                                                                0x00000003L
+#define TCC_EDC_CNT__CACHE_DATA_DED_COUNT_MASK                                                                0x0000000CL
+#define TCC_EDC_CNT__CACHE_DIRTY_SEC_COUNT_MASK                                                               0x00000030L
+#define TCC_EDC_CNT__CACHE_DIRTY_DED_COUNT_MASK                                                               0x000000C0L
+#define TCC_EDC_CNT__HIGH_RATE_TAG_SEC_COUNT_MASK                                                             0x00000300L
+#define TCC_EDC_CNT__HIGH_RATE_TAG_DED_COUNT_MASK                                                             0x00000C00L
+#define TCC_EDC_CNT__LOW_RATE_TAG_SEC_COUNT_MASK                                                              0x00003000L
+#define TCC_EDC_CNT__LOW_RATE_TAG_DED_COUNT_MASK                                                              0x0000C000L
+#define TCC_EDC_CNT__SRC_FIFO_SEC_COUNT_MASK                                                                  0x00030000L
+#define TCC_EDC_CNT__SRC_FIFO_DED_COUNT_MASK                                                                  0x000C0000L
+#define TCC_EDC_CNT__LATENCY_FIFO_SEC_COUNT_MASK                                                              0x00300000L
+#define TCC_EDC_CNT__LATENCY_FIFO_DED_COUNT_MASK                                                              0x00C00000L
+#define TCC_EDC_CNT__LATENCY_FIFO_NEXT_RAM_SEC_COUNT_MASK                                                     0x03000000L
+#define TCC_EDC_CNT__LATENCY_FIFO_NEXT_RAM_DED_COUNT_MASK                                                     0x0C000000L
+//TCC_EDC_CNT2
+#define TCC_EDC_CNT2__CACHE_TAG_PROBE_FIFO_SEC_COUNT__SHIFT                                                   0x0
+#define TCC_EDC_CNT2__CACHE_TAG_PROBE_FIFO_DED_COUNT__SHIFT                                                   0x2
+#define TCC_EDC_CNT2__UC_ATOMIC_FIFO_SEC_COUNT__SHIFT                                                         0x4
+#define TCC_EDC_CNT2__UC_ATOMIC_FIFO_DED_COUNT__SHIFT                                                         0x6
+#define TCC_EDC_CNT2__WRITE_CACHE_READ_SEC_COUNT__SHIFT                                                       0x8
+#define TCC_EDC_CNT2__WRITE_CACHE_READ_DED_COUNT__SHIFT                                                       0xa
+#define TCC_EDC_CNT2__RETURN_CONTROL_SEC_COUNT__SHIFT                                                         0xc
+#define TCC_EDC_CNT2__RETURN_CONTROL_DED_COUNT__SHIFT                                                         0xe
+#define TCC_EDC_CNT2__IN_USE_TRANSFER_SEC_COUNT__SHIFT                                                        0x10
+#define TCC_EDC_CNT2__IN_USE_TRANSFER_DED_COUNT__SHIFT                                                        0x12
+#define TCC_EDC_CNT2__IN_USE_DEC_SEC_COUNT__SHIFT                                                             0x14
+#define TCC_EDC_CNT2__IN_USE_DEC_DED_COUNT__SHIFT                                                             0x16
+#define TCC_EDC_CNT2__WRITE_RETURN_SEC_COUNT__SHIFT                                                           0x18
+#define TCC_EDC_CNT2__WRITE_RETURN_DED_COUNT__SHIFT                                                           0x1a
+#define TCC_EDC_CNT2__RETURN_DATA_SEC_COUNT__SHIFT                                                            0x1c
+#define TCC_EDC_CNT2__RETURN_DATA_DED_COUNT__SHIFT                                                            0x1e
+#define TCC_EDC_CNT2__CACHE_TAG_PROBE_FIFO_SEC_COUNT_MASK                                                     0x00000003L
+#define TCC_EDC_CNT2__CACHE_TAG_PROBE_FIFO_DED_COUNT_MASK                                                     0x0000000CL
+#define TCC_EDC_CNT2__UC_ATOMIC_FIFO_SEC_COUNT_MASK                                                           0x00000030L
+#define TCC_EDC_CNT2__UC_ATOMIC_FIFO_DED_COUNT_MASK                                                           0x000000C0L
+#define TCC_EDC_CNT2__WRITE_CACHE_READ_SEC_COUNT_MASK                                                         0x00000300L
+#define TCC_EDC_CNT2__WRITE_CACHE_READ_DED_COUNT_MASK                                                         0x00000C00L
+#define TCC_EDC_CNT2__RETURN_CONTROL_SEC_COUNT_MASK                                                           0x00003000L
+#define TCC_EDC_CNT2__RETURN_CONTROL_DED_COUNT_MASK                                                           0x0000C000L
+#define TCC_EDC_CNT2__IN_USE_TRANSFER_SEC_COUNT_MASK                                                          0x00030000L
+#define TCC_EDC_CNT2__IN_USE_TRANSFER_DED_COUNT_MASK                                                          0x000C0000L
+#define TCC_EDC_CNT2__IN_USE_DEC_SEC_COUNT_MASK                                                               0x00300000L
+#define TCC_EDC_CNT2__IN_USE_DEC_DED_COUNT_MASK                                                               0x00C00000L
+#define TCC_EDC_CNT2__WRITE_RETURN_SEC_COUNT_MASK                                                             0x03000000L
+#define TCC_EDC_CNT2__WRITE_RETURN_DED_COUNT_MASK                                                             0x0C000000L
+#define TCC_EDC_CNT2__RETURN_DATA_SEC_COUNT_MASK                                                              0x30000000L
+#define TCC_EDC_CNT2__RETURN_DATA_DED_COUNT_MASK                                                              0xC0000000L
+
+// addressBlock: gc_tpdec
+//TD_EDC_CNT
+#define TD_EDC_CNT__SS_FIFO_LO_SEC_COUNT__SHIFT                                                               0x0
+#define TD_EDC_CNT__SS_FIFO_LO_DED_COUNT__SHIFT                                                               0x2
+#define TD_EDC_CNT__SS_FIFO_HI_SEC_COUNT__SHIFT                                                               0x4
+#define TD_EDC_CNT__SS_FIFO_HI_DED_COUNT__SHIFT                                                               0x6
+#define TD_EDC_CNT__CS_FIFO_SEC_COUNT__SHIFT                                                                  0x8
+#define TD_EDC_CNT__CS_FIFO_DED_COUNT__SHIFT                                                                  0xa
+#define TD_EDC_CNT__SS_FIFO_LO_SEC_COUNT_MASK                                                                 0x00000003L
+#define TD_EDC_CNT__SS_FIFO_LO_DED_COUNT_MASK                                                                 0x0000000CL
+#define TD_EDC_CNT__SS_FIFO_HI_SEC_COUNT_MASK                                                                 0x00000030L
+#define TD_EDC_CNT__SS_FIFO_HI_DED_COUNT_MASK                                                                 0x000000C0L
+#define TD_EDC_CNT__CS_FIFO_SEC_COUNT_MASK                                                                    0x00000300L
+#define TD_EDC_CNT__CS_FIFO_DED_COUNT_MASK                                                                    0x00000C00L
+//TA_EDC_CNT
+#define TA_EDC_CNT__TA_FS_DFIFO_SEC_COUNT__SHIFT                                                              0x0
+#define TA_EDC_CNT__TA_FS_DFIFO_DED_COUNT__SHIFT                                                              0x2
+#define TA_EDC_CNT__TA_FS_AFIFO_SEC_COUNT__SHIFT                                                              0x4
+#define TA_EDC_CNT__TA_FS_AFIFO_DED_COUNT__SHIFT                                                              0x6
+#define TA_EDC_CNT__TA_FL_LFIFO_SEC_COUNT__SHIFT                                                              0x8
+#define TA_EDC_CNT__TA_FL_LFIFO_DED_COUNT__SHIFT                                                              0xa
+#define TA_EDC_CNT__TA_FX_LFIFO_SEC_COUNT__SHIFT                                                              0xc
+#define TA_EDC_CNT__TA_FX_LFIFO_DED_COUNT__SHIFT                                                              0xe
+#define TA_EDC_CNT__TA_FS_CFIFO_SEC_COUNT__SHIFT                                                              0x10
+#define TA_EDC_CNT__TA_FS_CFIFO_DED_COUNT__SHIFT                                                              0x12
+#define TA_EDC_CNT__TA_FS_DFIFO_SEC_COUNT_MASK                                                                0x00000003L
+#define TA_EDC_CNT__TA_FS_DFIFO_DED_COUNT_MASK                                                                0x0000000CL
+#define TA_EDC_CNT__TA_FS_AFIFO_SEC_COUNT_MASK                                                                0x00000030L
+#define TA_EDC_CNT__TA_FS_AFIFO_DED_COUNT_MASK                                                                0x000000C0L
+#define TA_EDC_CNT__TA_FL_LFIFO_SEC_COUNT_MASK                                                                0x00000300L
+#define TA_EDC_CNT__TA_FL_LFIFO_DED_COUNT_MASK                                                                0x00000C00L
+#define TA_EDC_CNT__TA_FX_LFIFO_SEC_COUNT_MASK                                                                0x00003000L
+#define TA_EDC_CNT__TA_FX_LFIFO_DED_COUNT_MASK                                                                0x0000C000L
+#define TA_EDC_CNT__TA_FS_CFIFO_SEC_COUNT_MASK                                                                0x00030000L
+#define TA_EDC_CNT__TA_FS_CFIFO_DED_COUNT_MASK                                                                0x000C0000L
+
+// addressBlock: gc_ea_gceadec2
+//GCEA_EDC_CNT
+#define GCEA_EDC_CNT__DRAMRD_CMDMEM_SEC_COUNT__SHIFT                                                          0x0
+#define GCEA_EDC_CNT__DRAMRD_CMDMEM_DED_COUNT__SHIFT                                                          0x2
+#define GCEA_EDC_CNT__DRAMWR_CMDMEM_SEC_COUNT__SHIFT                                                          0x4
+#define GCEA_EDC_CNT__DRAMWR_CMDMEM_DED_COUNT__SHIFT                                                          0x6
+#define GCEA_EDC_CNT__DRAMWR_DATAMEM_SEC_COUNT__SHIFT                                                         0x8
+#define GCEA_EDC_CNT__DRAMWR_DATAMEM_DED_COUNT__SHIFT                                                         0xa
+#define GCEA_EDC_CNT__RRET_TAGMEM_SEC_COUNT__SHIFT                                                            0xc
+#define GCEA_EDC_CNT__RRET_TAGMEM_DED_COUNT__SHIFT                                                            0xe
+#define GCEA_EDC_CNT__WRET_TAGMEM_SEC_COUNT__SHIFT                                                            0x10
+#define GCEA_EDC_CNT__WRET_TAGMEM_DED_COUNT__SHIFT                                                            0x12
+#define GCEA_EDC_CNT__DRAMRD_PAGEMEM_SED_COUNT__SHIFT                                                         0x14
+#define GCEA_EDC_CNT__DRAMWR_PAGEMEM_SED_COUNT__SHIFT                                                         0x16
+#define GCEA_EDC_CNT__IORD_CMDMEM_SED_COUNT__SHIFT                                                            0x18
+#define GCEA_EDC_CNT__IOWR_CMDMEM_SED_COUNT__SHIFT                                                            0x1a
+#define GCEA_EDC_CNT__IOWR_DATAMEM_SED_COUNT__SHIFT                                                           0x1c
+#define GCEA_EDC_CNT__MAM_AFMEM_SEC_COUNT__SHIFT                                                              0x1e
+#define GCEA_EDC_CNT__DRAMRD_CMDMEM_SEC_COUNT_MASK                                                            0x00000003L
+#define GCEA_EDC_CNT__DRAMRD_CMDMEM_DED_COUNT_MASK                                                            0x0000000CL
+#define GCEA_EDC_CNT__DRAMWR_CMDMEM_SEC_COUNT_MASK                                                            0x00000030L
+#define GCEA_EDC_CNT__DRAMWR_CMDMEM_DED_COUNT_MASK                                                            0x000000C0L
+#define GCEA_EDC_CNT__DRAMWR_DATAMEM_SEC_COUNT_MASK                                                           0x00000300L
+#define GCEA_EDC_CNT__DRAMWR_DATAMEM_DED_COUNT_MASK                                                           0x00000C00L
+#define GCEA_EDC_CNT__RRET_TAGMEM_SEC_COUNT_MASK                                                              0x00003000L
+#define GCEA_EDC_CNT__RRET_TAGMEM_DED_COUNT_MASK                                                              0x0000C000L
+#define GCEA_EDC_CNT__WRET_TAGMEM_SEC_COUNT_MASK                                                              0x00030000L
+#define GCEA_EDC_CNT__WRET_TAGMEM_DED_COUNT_MASK                                                              0x000C0000L
+#define GCEA_EDC_CNT__DRAMRD_PAGEMEM_SED_COUNT_MASK                                                           0x00300000L
+#define GCEA_EDC_CNT__DRAMWR_PAGEMEM_SED_COUNT_MASK                                                           0x00C00000L
+#define GCEA_EDC_CNT__IORD_CMDMEM_SED_COUNT_MASK                                                              0x03000000L
+#define GCEA_EDC_CNT__IOWR_CMDMEM_SED_COUNT_MASK                                                              0x0C000000L
+#define GCEA_EDC_CNT__IOWR_DATAMEM_SED_COUNT_MASK                                                             0x30000000L
+#define GCEA_EDC_CNT__MAM_AFMEM_SEC_COUNT_MASK                                                                0xC0000000L
+//GCEA_EDC_CNT2
+#define GCEA_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT__SHIFT                                                          0x0
+#define GCEA_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT__SHIFT                                                          0x2
+#define GCEA_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT__SHIFT                                                          0x4
+#define GCEA_EDC_CNT2__GMIWR_CMDMEM_DED_COUNT__SHIFT                                                          0x6
+#define GCEA_EDC_CNT2__GMIWR_DATAMEM_SEC_COUNT__SHIFT                                                         0x8
+#define GCEA_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                         0xa
+#define GCEA_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                         0xc
+#define GCEA_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                         0xe
+#define GCEA_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                             0x10
+#define GCEA_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                             0x12
+#define GCEA_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                             0x14
+#define GCEA_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                             0x16
+#define GCEA_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                             0x18
+#define GCEA_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                             0x1a
+#define GCEA_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                             0x1c
+#define GCEA_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                             0x1e
+#define GCEA_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                            0x00000003L
+#define GCEA_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                            0x0000000CL
+#define GCEA_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                            0x00000030L
+#define GCEA_EDC_CNT2__GMIWR_CMDMEM_DED_COUNT_MASK                                                            0x000000C0L
+#define GCEA_EDC_CNT2__GMIWR_DATAMEM_SEC_COUNT_MASK                                                           0x00000300L
+#define GCEA_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                           0x00000C00L
+#define GCEA_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                           0x00003000L
+#define GCEA_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                           0x0000C000L
+#define GCEA_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                               0x00030000L
+#define GCEA_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                               0x000C0000L
+#define GCEA_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                               0x00300000L
+#define GCEA_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                               0x00C00000L
+#define GCEA_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                               0x03000000L
+#define GCEA_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                               0x0C000000L
+#define GCEA_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                               0x30000000L
+#define GCEA_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                               0xC0000000L
+//GCEA_EDC_CNT3
+#define GCEA_EDC_CNT3__DRAMRD_PAGEMEM_DED_COUNT__SHIFT                                                        0x0
+#define GCEA_EDC_CNT3__DRAMWR_PAGEMEM_DED_COUNT__SHIFT                                                        0x2
+#define GCEA_EDC_CNT3__IORD_CMDMEM_DED_COUNT__SHIFT                                                           0x4
+#define GCEA_EDC_CNT3__IOWR_CMDMEM_DED_COUNT__SHIFT                                                           0x6
+#define GCEA_EDC_CNT3__IOWR_DATAMEM_DED_COUNT__SHIFT                                                          0x8
+#define GCEA_EDC_CNT3__GMIRD_PAGEMEM_DED_COUNT__SHIFT                                                         0xa
+#define GCEA_EDC_CNT3__GMIWR_PAGEMEM_DED_COUNT__SHIFT                                                         0xc
+#define GCEA_EDC_CNT3__MAM_AFMEM_DED_COUNT__SHIFT                                                             0xe
+#define GCEA_EDC_CNT3__MAM_A0MEM_SEC_COUNT__SHIFT                                                             0x10
+#define GCEA_EDC_CNT3__MAM_A0MEM_DED_COUNT__SHIFT                                                             0x12
+#define GCEA_EDC_CNT3__MAM_A1MEM_SEC_COUNT__SHIFT                                                             0x14
+#define GCEA_EDC_CNT3__MAM_A1MEM_DED_COUNT__SHIFT                                                             0x16
+#define GCEA_EDC_CNT3__MAM_A2MEM_SEC_COUNT__SHIFT                                                             0x18
+#define GCEA_EDC_CNT3__MAM_A2MEM_DED_COUNT__SHIFT                                                             0x1a
+#define GCEA_EDC_CNT3__MAM_A3MEM_SEC_COUNT__SHIFT                                                             0x1c
+#define GCEA_EDC_CNT3__MAM_A3MEM_DED_COUNT__SHIFT                                                             0x1e
+#define GCEA_EDC_CNT3__DRAMRD_PAGEMEM_DED_COUNT_MASK                                                          0x00000003L
+#define GCEA_EDC_CNT3__DRAMWR_PAGEMEM_DED_COUNT_MASK                                                          0x0000000CL
+#define GCEA_EDC_CNT3__IORD_CMDMEM_DED_COUNT_MASK                                                             0x00000030L
+#define GCEA_EDC_CNT3__IOWR_CMDMEM_DED_COUNT_MASK                                                             0x000000C0L
+#define GCEA_EDC_CNT3__IOWR_DATAMEM_DED_COUNT_MASK                                                            0x00000300L
+#define GCEA_EDC_CNT3__GMIRD_PAGEMEM_DED_COUNT_MASK                                                           0x00000C00L
+#define GCEA_EDC_CNT3__GMIWR_PAGEMEM_DED_COUNT_MASK                                                           0x00003000L
+#define GCEA_EDC_CNT3__MAM_AFMEM_DED_COUNT_MASK                                                               0x0000C000L
+#define GCEA_EDC_CNT3__MAM_A0MEM_SEC_COUNT_MASK                                                               0x00030000L
+#define GCEA_EDC_CNT3__MAM_A0MEM_DED_COUNT_MASK                                                               0x000C0000L
+#define GCEA_EDC_CNT3__MAM_A1MEM_SEC_COUNT_MASK                                                               0x00300000L
+#define GCEA_EDC_CNT3__MAM_A1MEM_DED_COUNT_MASK                                                               0x00C00000L
+#define GCEA_EDC_CNT3__MAM_A2MEM_SEC_COUNT_MASK                                                               0x03000000L
+#define GCEA_EDC_CNT3__MAM_A2MEM_DED_COUNT_MASK                                                               0x0C000000L
+#define GCEA_EDC_CNT3__MAM_A3MEM_SEC_COUNT_MASK                                                               0x30000000L
+#define GCEA_EDC_CNT3__MAM_A3MEM_DED_COUNT_MASK                                                               0xC0000000L
+
+// addressBlock: gc_gfxudec
+//GRBM_GFX_INDEX
+#define GRBM_GFX_INDEX__INSTANCE_INDEX__SHIFT                                                                 0x0
+#define GRBM_GFX_INDEX__SH_INDEX__SHIFT                                                                       0x8
+#define GRBM_GFX_INDEX__SE_INDEX__SHIFT                                                                       0x10
+#define GRBM_GFX_INDEX__SH_BROADCAST_WRITES__SHIFT                                                            0x1d
+#define GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES__SHIFT                                                      0x1e
+#define GRBM_GFX_INDEX__SE_BROADCAST_WRITES__SHIFT                                                            0x1f
+#define GRBM_GFX_INDEX__INSTANCE_INDEX_MASK                                                                   0x000000FFL
+#define GRBM_GFX_INDEX__SH_INDEX_MASK                                                                         0x0000FF00L
+#define GRBM_GFX_INDEX__SE_INDEX_MASK                                                                         0x00FF0000L
+#define GRBM_GFX_INDEX__SH_BROADCAST_WRITES_MASK                                                              0x20000000L
+#define GRBM_GFX_INDEX__INSTANCE_BROADCAST_WRITES_MASK                                                        0x40000000L
+#define GRBM_GFX_INDEX__SE_BROADCAST_WRITES_MASK                                                              0x80000000L
+
+// addressBlock: gc_utcl2_atcl2dec
+//ATC_L2_CNTL
+//ATC_L2_CACHE_4K_DSM_INDEX
+#define ATC_L2_CACHE_4K_DSM_INDEX__INDEX__SHIFT                                                               0x0
+#define ATC_L2_CACHE_4K_DSM_INDEX__INDEX_MASK                                                                 0x000000FFL
+//ATC_L2_CACHE_2M_DSM_INDEX
+#define ATC_L2_CACHE_2M_DSM_INDEX__INDEX__SHIFT                                                               0x0
+#define ATC_L2_CACHE_2M_DSM_INDEX__INDEX_MASK                                                                 0x000000FFL
+//ATC_L2_CACHE_4K_DSM_CNTL
+#define ATC_L2_CACHE_4K_DSM_CNTL__SEC_COUNT__SHIFT                                                            0xd
+#define ATC_L2_CACHE_4K_DSM_CNTL__DED_COUNT__SHIFT                                                            0xf
+#define ATC_L2_CACHE_4K_DSM_CNTL__SEC_COUNT_MASK                                                              0x00006000L
+#define ATC_L2_CACHE_4K_DSM_CNTL__DED_COUNT_MASK                                                              0x00018000L
+//ATC_L2_CACHE_2M_DSM_CNTL
+#define ATC_L2_CACHE_2M_DSM_CNTL__SEC_COUNT__SHIFT                                                            0xd
+#define ATC_L2_CACHE_2M_DSM_CNTL__DED_COUNT__SHIFT                                                            0xf
+#define ATC_L2_CACHE_2M_DSM_CNTL__SEC_COUNT_MASK                                                              0x00006000L
+#define ATC_L2_CACHE_2M_DSM_CNTL__DED_COUNT_MASK                                                              0x00018000L
+
+// addressBlock: gc_utcl2_vml2pfdec
+//VML2_MEM_ECC_INDEX
+#define VML2_MEM_ECC_INDEX__INDEX__SHIFT                                                                      0x0
+#define VML2_MEM_ECC_INDEX__INDEX_MASK                                                                        0x000000FFL
+//VML2_WALKER_MEM_ECC_INDEX
+#define VML2_WALKER_MEM_ECC_INDEX__INDEX__SHIFT                                                               0x0
+#define VML2_WALKER_MEM_ECC_INDEX__INDEX_MASK                                                                 0x000000FFL
+//UTCL2_MEM_ECC_INDEX
+#define UTCL2_MEM_ECC_INDEX__INDEX__SHIFT                                                                     0x0
+#define UTCL2_MEM_ECC_INDEX__INDEX_MASK                                                                       0x000000FFL
+//VML2_MEM_ECC_CNTL
+#define VML2_MEM_ECC_CNTL__SEC_COUNT__SHIFT                                                                   0xc
+#define VML2_MEM_ECC_CNTL__DED_COUNT__SHIFT                                                                   0xe
+#define VML2_MEM_ECC_CNTL__SEC_COUNT_MASK                                                                     0x00003000L
+#define VML2_MEM_ECC_CNTL__DED_COUNT_MASK                                                                     0x0000C000L
+//VML2_WALKER_MEM_ECC_CNTL
+#define VML2_WALKER_MEM_ECC_CNTL__SEC_COUNT__SHIFT                                                            0xc
+#define VML2_WALKER_MEM_ECC_CNTL__DED_COUNT__SHIFT                                                            0xe
+#define VML2_WALKER_MEM_ECC_CNTL__SEC_COUNT_MASK                                                              0x00003000L
+#define VML2_WALKER_MEM_ECC_CNTL__DED_COUNT_MASK                                                              0x0000C000L
+//UTCL2_MEM_ECC_CNTL
+#define UTCL2_MEM_ECC_CNTL__SEC_COUNT__SHIFT                                                                  0xc
+#define UTCL2_MEM_ECC_CNTL__DED_COUNT__SHIFT                                                                  0xe
+#define UTCL2_MEM_ECC_CNTL__SEC_COUNT_MASK                                                                    0x00003000L
+#define UTCL2_MEM_ECC_CNTL__DED_COUNT_MASK                                                                    0x0000C000L
+
+// addressBlock: gc_rlcpdec
+//RLC_EDC_CNT
+#define RLC_EDC_CNT__RLCG_INSTR_RAM_SEC_COUNT__SHIFT                                                          0x0
+#define RLC_EDC_CNT__RLCG_INSTR_RAM_DED_COUNT__SHIFT                                                          0x2
+#define RLC_EDC_CNT__RLCG_SCRATCH_RAM_SEC_COUNT__SHIFT                                                        0x4
+#define RLC_EDC_CNT__RLCG_SCRATCH_RAM_DED_COUNT__SHIFT                                                        0x6
+#define RLC_EDC_CNT__RLCV_INSTR_RAM_SEC_COUNT__SHIFT                                                          0x8
+#define RLC_EDC_CNT__RLCV_INSTR_RAM_DED_COUNT__SHIFT                                                          0xa
+#define RLC_EDC_CNT__RLCV_SCRATCH_RAM_SEC_COUNT__SHIFT                                                        0xc
+#define RLC_EDC_CNT__RLCV_SCRATCH_RAM_DED_COUNT__SHIFT                                                        0xe
+#define RLC_EDC_CNT__RLC_TCTAG_RAM_SEC_COUNT__SHIFT                                                           0x10
+#define RLC_EDC_CNT__RLC_TCTAG_RAM_DED_COUNT__SHIFT                                                           0x12
+#define RLC_EDC_CNT__RLC_SPM_SCRATCH_RAM_SEC_COUNT__SHIFT                                                     0x14
+#define RLC_EDC_CNT__RLC_SPM_SCRATCH_RAM_DED_COUNT__SHIFT                                                      0x16
+#define RLC_EDC_CNT__RLC_SRM_DATA_RAM_SEC_COUNT__SHIFT                                                        0x18
+#define RLC_EDC_CNT__RLC_SRM_DATA_RAM_DED_COUNT__SHIFT                                                        0x1a
+#define RLC_EDC_CNT__RLC_SRM_ADDR_RAM_SEC_COUNT__SHIFT                                                        0x1c
+#define RLC_EDC_CNT__RLC_SRM_ADDR_RAM_DED_COUNT__SHIFT                                                        0x1e
+#define RLC_EDC_CNT__RLCG_INSTR_RAM_SEC_COUNT_MASK                                                            0x00000003L
+#define RLC_EDC_CNT__RLCG_INSTR_RAM_DED_COUNT_MASK                                                            0x0000000CL
+#define RLC_EDC_CNT__RLCG_SCRATCH_RAM_SEC_COUNT_MASK                                                          0x00000030L
+#define RLC_EDC_CNT__RLCG_SCRATCH_RAM_DED_COUNT_MASK                                                          0x000000C0L
+#define RLC_EDC_CNT__RLCV_INSTR_RAM_SEC_COUNT_MASK                                                            0x00000300L
+#define RLC_EDC_CNT__RLCV_INSTR_RAM_DED_COUNT_MASK                                                            0x00000C00L
+#define RLC_EDC_CNT__RLCV_SCRATCH_RAM_SEC_COUNT_MASK                                                          0x00003000L
+#define RLC_EDC_CNT__RLCV_SCRATCH_RAM_DED_COUNT_MASK                                                          0x0000C000L
+#define RLC_EDC_CNT__RLC_TCTAG_RAM_SEC_COUNT_MASK                                                             0x00030000L
+#define RLC_EDC_CNT__RLC_TCTAG_RAM_DED_COUNT_MASK                                                             0x000C0000L
+#define RLC_EDC_CNT__RLC_SPM_SCRATCH_RAM_SEC_COUNT_MASK                                                       0x00300000L
+#define RLC_EDC_CNT__RLC_SPM_SCRATCH_RAM_DED_COUNT_MASK                                                        0x00C00000L
+#define RLC_EDC_CNT__RLC_SRM_DATA_RAM_SEC_COUNT_MASK                                                          0x03000000L
+#define RLC_EDC_CNT__RLC_SRM_DATA_RAM_DED_COUNT_MASK                                                          0x0C000000L
+#define RLC_EDC_CNT__RLC_SRM_ADDR_RAM_SEC_COUNT_MASK                                                          0x30000000L
+#define RLC_EDC_CNT__RLC_SRM_ADDR_RAM_DED_COUNT_MASK                                                          0xC0000000L
+//RLC_EDC_CNT2
+#define RLC_EDC_CNT2__RLC_SPM_SE0_SCRATCH_RAM_SEC_COUNT__SHIFT                                                0x0
+#define RLC_EDC_CNT2__RLC_SPM_SE0_SCRATCH_RAM_DED_COUNT__SHIFT                                                0x2
+#define RLC_EDC_CNT2__RLC_SPM_SE1_SCRATCH_RAM_SEC_COUNT__SHIFT                                                0x4
+#define RLC_EDC_CNT2__RLC_SPM_SE1_SCRATCH_RAM_DED_COUNT__SHIFT                                                0x6
+#define RLC_EDC_CNT2__RLC_SPM_SE2_SCRATCH_RAM_SEC_COUNT__SHIFT                                                0x8
+#define RLC_EDC_CNT2__RLC_SPM_SE2_SCRATCH_RAM_DED_COUNT__SHIFT                                                0xa
+#define RLC_EDC_CNT2__RLC_SPM_SE3_SCRATCH_RAM_SEC_COUNT__SHIFT                                                0xc
+#define RLC_EDC_CNT2__RLC_SPM_SE3_SCRATCH_RAM_DED_COUNT__SHIFT                                                0xe
+#define RLC_EDC_CNT2__RLC_SPM_SE4_SCRATCH_RAM_SEC_COUNT__SHIFT                                                0x10
+#define RLC_EDC_CNT2__RLC_SPM_SE4_SCRATCH_RAM_DED_COUNT__SHIFT                                                0x12
+#define RLC_EDC_CNT2__RLC_SPM_SE5_SCRATCH_RAM_SEC_COUNT__SHIFT                                                0x14
+#define RLC_EDC_CNT2__RLC_SPM_SE5_SCRATCH_RAM_DED_COUNT__SHIFT                                                0x16
+#define RLC_EDC_CNT2__RLC_SPM_SE6_SCRATCH_RAM_SEC_COUNT__SHIFT                                                0x18
+#define RLC_EDC_CNT2__RLC_SPM_SE6_SCRATCH_RAM_DED_COUNT__SHIFT                                                0x1a
+#define RLC_EDC_CNT2__RLC_SPM_SE7_SCRATCH_RAM_SEC_COUNT__SHIFT                                                0x1c
+#define RLC_EDC_CNT2__RLC_SPM_SE7_SCRATCH_RAM_DED_COUNT__SHIFT                                                0x1e
+#define RLC_EDC_CNT2__RLC_SPM_SE0_SCRATCH_RAM_SEC_COUNT_MASK                                                  0x00000003L
+#define RLC_EDC_CNT2__RLC_SPM_SE0_SCRATCH_RAM_DED_COUNT_MASK                                                  0x0000000CL
+#define RLC_EDC_CNT2__RLC_SPM_SE1_SCRATCH_RAM_SEC_COUNT_MASK                                                  0x00000030L
+#define RLC_EDC_CNT2__RLC_SPM_SE1_SCRATCH_RAM_DED_COUNT_MASK                                                  0x000000C0L
+#define RLC_EDC_CNT2__RLC_SPM_SE2_SCRATCH_RAM_SEC_COUNT_MASK                                                  0x00000300L
+#define RLC_EDC_CNT2__RLC_SPM_SE2_SCRATCH_RAM_DED_COUNT_MASK                                                  0x00000C00L
+#define RLC_EDC_CNT2__RLC_SPM_SE3_SCRATCH_RAM_SEC_COUNT_MASK                                                  0x00003000L
+#define RLC_EDC_CNT2__RLC_SPM_SE3_SCRATCH_RAM_DED_COUNT_MASK                                                  0x0000C000L
+#define RLC_EDC_CNT2__RLC_SPM_SE4_SCRATCH_RAM_SEC_COUNT_MASK                                                  0x00030000L
+#define RLC_EDC_CNT2__RLC_SPM_SE4_SCRATCH_RAM_DED_COUNT_MASK                                                  0x000C0000L
+#define RLC_EDC_CNT2__RLC_SPM_SE5_SCRATCH_RAM_SEC_COUNT_MASK                                                  0x00300000L
+#define RLC_EDC_CNT2__RLC_SPM_SE5_SCRATCH_RAM_DED_COUNT_MASK                                                  0x00C00000L
+#define RLC_EDC_CNT2__RLC_SPM_SE6_SCRATCH_RAM_SEC_COUNT_MASK                                                  0x03000000L
+#define RLC_EDC_CNT2__RLC_SPM_SE6_SCRATCH_RAM_DED_COUNT_MASK                                                  0x0C000000L
+#define RLC_EDC_CNT2__RLC_SPM_SE7_SCRATCH_RAM_SEC_COUNT_MASK                                                  0x30000000L
+#define RLC_EDC_CNT2__RLC_SPM_SE7_SCRATCH_RAM_DED_COUNT_MASK                                                  0xC0000000L
+
+#endif
\ No newline at end of file
index 40dfbf1..111a71b 100644 (file)
 #define MMEA0_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                        0xa
 #define MMEA0_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                        0xc
 #define MMEA0_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                        0xe
+#define MMEA0_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                            0x10
+#define MMEA0_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                            0x12
+#define MMEA0_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                            0x14
+#define MMEA0_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                            0x16
+#define MMEA0_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                            0x18
+#define MMEA0_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                            0x1a
+#define MMEA0_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                            0x1c
+#define MMEA0_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                            0x1e
 #define MMEA0_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                           0x00000003L
 #define MMEA0_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                           0x0000000CL
 #define MMEA0_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                           0x00000030L
 #define MMEA0_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                          0x00000C00L
 #define MMEA0_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                          0x00003000L
 #define MMEA0_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                          0x0000C000L
+#define MMEA0_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                              0x00030000L
+#define MMEA0_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                              0x000C0000L
+#define MMEA0_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                              0x00300000L
+#define MMEA0_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                              0x00C00000L
+#define MMEA0_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                              0x03000000L
+#define MMEA0_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                              0x0C000000L
+#define MMEA0_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                              0x30000000L
+#define MMEA0_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                              0xC0000000L
 //MMEA0_DSM_CNTL
 #define MMEA0_DSM_CNTL__DRAMRD_CMDMEM_DSM_IRRITATOR_DATA__SHIFT                                               0x0
 #define MMEA0_DSM_CNTL__DRAMRD_CMDMEM_ENABLE_SINGLE_WRITE__SHIFT                                              0x2
 #define MMEA1_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                        0xa
 #define MMEA1_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                        0xc
 #define MMEA1_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                        0xe
+#define MMEA1_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                            0x10
+#define MMEA1_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                            0x12
+#define MMEA1_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                            0x14
+#define MMEA1_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                            0x16
+#define MMEA1_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                            0x18
+#define MMEA1_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                            0x1a
+#define MMEA1_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                            0x1c
+#define MMEA1_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                            0x1e
 #define MMEA1_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                           0x00000003L
 #define MMEA1_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                           0x0000000CL
 #define MMEA1_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                           0x00000030L
 #define MMEA1_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                          0x00000C00L
 #define MMEA1_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                          0x00003000L
 #define MMEA1_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                          0x0000C000L
+#define MMEA1_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                              0x00030000L
+#define MMEA1_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                              0x000C0000L
+#define MMEA1_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                              0x00300000L
+#define MMEA1_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                              0x00C00000L
+#define MMEA1_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                              0x03000000L
+#define MMEA1_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                              0x0C000000L
+#define MMEA1_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                              0x30000000L
+#define MMEA1_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                              0xC0000000L
 //MMEA1_DSM_CNTL
 #define MMEA1_DSM_CNTL__DRAMRD_CMDMEM_DSM_IRRITATOR_DATA__SHIFT                                               0x0
 #define MMEA1_DSM_CNTL__DRAMRD_CMDMEM_ENABLE_SINGLE_WRITE__SHIFT                                              0x2
 #define MMEA2_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                        0xa
 #define MMEA2_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                        0xc
 #define MMEA2_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                        0xe
+#define MMEA2_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                            0x10
+#define MMEA2_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                            0x12
+#define MMEA2_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                            0x14
+#define MMEA2_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                            0x16
+#define MMEA2_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                            0x18
+#define MMEA2_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                            0x1a
+#define MMEA2_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                            0x1c
+#define MMEA2_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                            0x1e
 #define MMEA2_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                           0x00000003L
 #define MMEA2_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                           0x0000000CL
 #define MMEA2_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                           0x00000030L
 #define MMEA2_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                          0x00000C00L
 #define MMEA2_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                          0x00003000L
 #define MMEA2_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                          0x0000C000L
+#define MMEA2_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                              0x00030000L
+#define MMEA2_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                              0x000C0000L
+#define MMEA2_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                              0x00300000L
+#define MMEA2_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                              0x00C00000L
+#define MMEA2_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                              0x03000000L
+#define MMEA2_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                              0x0C000000L
+#define MMEA2_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                              0x30000000L
+#define MMEA2_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                              0xC0000000L
 //MMEA2_DSM_CNTL
 #define MMEA2_DSM_CNTL__DRAMRD_CMDMEM_DSM_IRRITATOR_DATA__SHIFT                                               0x0
 #define MMEA2_DSM_CNTL__DRAMRD_CMDMEM_ENABLE_SINGLE_WRITE__SHIFT                                              0x2
 #define MMEA3_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                        0xa
 #define MMEA3_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                        0xc
 #define MMEA3_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                        0xe
+#define MMEA3_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                            0x10
+#define MMEA3_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                            0x12
+#define MMEA3_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                            0x14
+#define MMEA3_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                            0x16
+#define MMEA3_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                            0x18
+#define MMEA3_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                            0x1a
+#define MMEA3_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                            0x1c
+#define MMEA3_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                            0x1e
 #define MMEA3_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                           0x00000003L
 #define MMEA3_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                           0x0000000CL
 #define MMEA3_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                           0x00000030L
 #define MMEA3_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                          0x00000C00L
 #define MMEA3_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                          0x00003000L
 #define MMEA3_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                          0x0000C000L
+#define MMEA3_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                              0x00030000L
+#define MMEA3_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                              0x000C0000L
+#define MMEA3_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                              0x00300000L
+#define MMEA3_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                              0x00C00000L
+#define MMEA3_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                              0x03000000L
+#define MMEA3_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                              0x0C000000L
+#define MMEA3_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                              0x30000000L
+#define MMEA3_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                              0xC0000000L
 //MMEA3_DSM_CNTL
 #define MMEA3_DSM_CNTL__DRAMRD_CMDMEM_DSM_IRRITATOR_DATA__SHIFT                                               0x0
 #define MMEA3_DSM_CNTL__DRAMRD_CMDMEM_ENABLE_SINGLE_WRITE__SHIFT                                              0x2
 #define MMEA4_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                        0xa
 #define MMEA4_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                        0xc
 #define MMEA4_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                        0xe
+#define MMEA4_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                            0x10
+#define MMEA4_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                            0x12
+#define MMEA4_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                            0x14
+#define MMEA4_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                            0x16
+#define MMEA4_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                            0x18
+#define MMEA4_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                            0x1a
+#define MMEA4_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                            0x1c
+#define MMEA4_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                            0x1e
 #define MMEA4_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                           0x00000003L
 #define MMEA4_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                           0x0000000CL
 #define MMEA4_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                           0x00000030L
 #define MMEA4_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                          0x00000C00L
 #define MMEA4_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                          0x00003000L
 #define MMEA4_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                          0x0000C000L
+#define MMEA4_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                              0x00030000L
+#define MMEA4_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                              0x000C0000L
+#define MMEA4_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                              0x00300000L
+#define MMEA4_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                              0x00C00000L
+#define MMEA4_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                              0x03000000L
+#define MMEA4_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                              0x0C000000L
+#define MMEA4_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                              0x30000000L
+#define MMEA4_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                              0xC0000000L
 //MMEA4_DSM_CNTL
 #define MMEA4_DSM_CNTL__DRAMRD_CMDMEM_DSM_IRRITATOR_DATA__SHIFT                                               0x0
 #define MMEA4_DSM_CNTL__DRAMRD_CMDMEM_ENABLE_SINGLE_WRITE__SHIFT                                              0x2
 #define MMEA5_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                        0xa
 #define MMEA5_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                        0xc
 #define MMEA5_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                        0xe
+#define MMEA5_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                            0x10
+#define MMEA5_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                            0x12
+#define MMEA5_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                            0x14
+#define MMEA5_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                            0x16
+#define MMEA5_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                            0x18
+#define MMEA5_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                            0x1a
+#define MMEA5_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                            0x1c
+#define MMEA5_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                            0x1e
 #define MMEA5_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                           0x00000003L
 #define MMEA5_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                           0x0000000CL
 #define MMEA5_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                           0x00000030L
 #define MMEA5_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                          0x00000C00L
 #define MMEA5_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                          0x00003000L
 #define MMEA5_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                          0x0000C000L
+#define MMEA5_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                              0x00030000L
+#define MMEA5_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                              0x000C0000L
+#define MMEA5_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                              0x00300000L
+#define MMEA5_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                              0x00C00000L
+#define MMEA5_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                              0x03000000L
+#define MMEA5_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                              0x0C000000L
+#define MMEA5_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                              0x30000000L
+#define MMEA5_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                              0xC0000000L
 //MMEA5_DSM_CNTL
 #define MMEA5_DSM_CNTL__DRAMRD_CMDMEM_DSM_IRRITATOR_DATA__SHIFT                                               0x0
 #define MMEA5_DSM_CNTL__DRAMRD_CMDMEM_ENABLE_SINGLE_WRITE__SHIFT                                              0x2
 #define MMEA6_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                        0xa
 #define MMEA6_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                        0xc
 #define MMEA6_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                        0xe
+#define MMEA6_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                            0x10
+#define MMEA6_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                            0x12
+#define MMEA6_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                            0x14
+#define MMEA6_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                            0x16
+#define MMEA6_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                            0x18
+#define MMEA6_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                            0x1a
+#define MMEA6_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                            0x1c
+#define MMEA6_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                            0x1e
 #define MMEA6_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                           0x00000003L
 #define MMEA6_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                           0x0000000CL
 #define MMEA6_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                           0x00000030L
 #define MMEA6_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                          0x00000C00L
 #define MMEA6_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                          0x00003000L
 #define MMEA6_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                          0x0000C000L
+#define MMEA6_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                              0x00030000L
+#define MMEA6_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                              0x000C0000L
+#define MMEA6_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                              0x00300000L
+#define MMEA6_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                              0x00C00000L
+#define MMEA6_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                              0x03000000L
+#define MMEA6_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                              0x0C000000L
+#define MMEA6_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                              0x30000000L
+#define MMEA6_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                              0xC0000000L
 //MMEA6_DSM_CNTL
 #define MMEA6_DSM_CNTL__DRAMRD_CMDMEM_DSM_IRRITATOR_DATA__SHIFT                                               0x0
 #define MMEA6_DSM_CNTL__DRAMRD_CMDMEM_ENABLE_SINGLE_WRITE__SHIFT                                              0x2
 #define MMEA7_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT__SHIFT                                                        0xa
 #define MMEA7_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT__SHIFT                                                        0xc
 #define MMEA7_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT__SHIFT                                                        0xe
+#define MMEA7_EDC_CNT2__MAM_D0MEM_SED_COUNT__SHIFT                                                            0x10
+#define MMEA7_EDC_CNT2__MAM_D1MEM_SED_COUNT__SHIFT                                                            0x12
+#define MMEA7_EDC_CNT2__MAM_D2MEM_SED_COUNT__SHIFT                                                            0x14
+#define MMEA7_EDC_CNT2__MAM_D3MEM_SED_COUNT__SHIFT                                                            0x16
+#define MMEA7_EDC_CNT2__MAM_D0MEM_DED_COUNT__SHIFT                                                            0x18
+#define MMEA7_EDC_CNT2__MAM_D1MEM_DED_COUNT__SHIFT                                                            0x1a
+#define MMEA7_EDC_CNT2__MAM_D2MEM_DED_COUNT__SHIFT                                                            0x1c
+#define MMEA7_EDC_CNT2__MAM_D3MEM_DED_COUNT__SHIFT                                                            0x1e
 #define MMEA7_EDC_CNT2__GMIRD_CMDMEM_SEC_COUNT_MASK                                                           0x00000003L
 #define MMEA7_EDC_CNT2__GMIRD_CMDMEM_DED_COUNT_MASK                                                           0x0000000CL
 #define MMEA7_EDC_CNT2__GMIWR_CMDMEM_SEC_COUNT_MASK                                                           0x00000030L
 #define MMEA7_EDC_CNT2__GMIWR_DATAMEM_DED_COUNT_MASK                                                          0x00000C00L
 #define MMEA7_EDC_CNT2__GMIRD_PAGEMEM_SED_COUNT_MASK                                                          0x00003000L
 #define MMEA7_EDC_CNT2__GMIWR_PAGEMEM_SED_COUNT_MASK                                                          0x0000C000L
+#define MMEA7_EDC_CNT2__MAM_D0MEM_SED_COUNT_MASK                                                              0x00030000L
+#define MMEA7_EDC_CNT2__MAM_D1MEM_SED_COUNT_MASK                                                              0x000C0000L
+#define MMEA7_EDC_CNT2__MAM_D2MEM_SED_COUNT_MASK                                                              0x00300000L
+#define MMEA7_EDC_CNT2__MAM_D3MEM_SED_COUNT_MASK                                                              0x00C00000L
+#define MMEA7_EDC_CNT2__MAM_D0MEM_DED_COUNT_MASK                                                              0x03000000L
+#define MMEA7_EDC_CNT2__MAM_D1MEM_DED_COUNT_MASK                                                              0x0C000000L
+#define MMEA7_EDC_CNT2__MAM_D2MEM_DED_COUNT_MASK                                                              0x30000000L
+#define MMEA7_EDC_CNT2__MAM_D3MEM_DED_COUNT_MASK                                                              0xC0000000L
 //MMEA7_DSM_CNTL
 #define MMEA7_DSM_CNTL__DRAMRD_CMDMEM_DSM_IRRITATOR_DATA__SHIFT                                               0x0
 #define MMEA7_DSM_CNTL__DRAMRD_CMDMEM_ENABLE_SINGLE_WRITE__SHIFT                                              0x2
index 9946947..99ad4dd 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/pci.h>
 
 #include "pp_debug.h"
 #include "amdgpu.h"
@@ -1137,6 +1138,23 @@ static int smu_smc_table_hw_init(struct smu_context *smu,
                ret = smu_system_features_control(smu, true);
                if (ret)
                        return ret;
+
+               if (adev->asic_type == CHIP_NAVI10) {
+                       if ((adev->pdev->device == 0x731f && (adev->pdev->revision == 0xc2 ||
+                                                             adev->pdev->revision == 0xc3 ||
+                                                             adev->pdev->revision == 0xca ||
+                                                             adev->pdev->revision == 0xcb)) ||
+                           (adev->pdev->device == 0x66af && (adev->pdev->revision == 0xf3 ||
+                                                             adev->pdev->revision == 0xf4 ||
+                                                             adev->pdev->revision == 0xf5 ||
+                                                             adev->pdev->revision == 0xf6))) {
+                               ret = smu_disable_umc_cdr_12gbps_workaround(smu);
+                               if (ret) {
+                                       pr_err("Workaround failed to disable UMC CDR feature on 12Gbps SKU!\n");
+                                       return ret;
+                               }
+                       }
+               }
        }
        if (adev->asic_type != CHIP_ARCTURUS) {
                ret = smu_notify_display_change(smu);
index 4e8ab13..689072a 100644 (file)
@@ -1026,12 +1026,15 @@ static int smu10_get_clock_by_type_with_latency(struct pp_hwmgr *hwmgr,
 
        clocks->num_levels = 0;
        for (i = 0; i < pclk_vol_table->count; i++) {
-               clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk * 10;
-               clocks->data[i].latency_in_us = latency_required ?
-                                               smu10_get_mem_latency(hwmgr,
-                                               pclk_vol_table->entries[i].clk) :
-                                               0;
-               clocks->num_levels++;
+               if (pclk_vol_table->entries[i].clk) {
+                       clocks->data[clocks->num_levels].clocks_in_khz =
+                               pclk_vol_table->entries[i].clk * 10;
+                       clocks->data[clocks->num_levels].latency_in_us = latency_required ?
+                               smu10_get_mem_latency(hwmgr,
+                                                     pclk_vol_table->entries[i].clk) :
+                               0;
+                       clocks->num_levels++;
+               }
        }
 
        return 0;
@@ -1077,9 +1080,11 @@ static int smu10_get_clock_by_type_with_voltage(struct pp_hwmgr *hwmgr,
 
        clocks->num_levels = 0;
        for (i = 0; i < pclk_vol_table->count; i++) {
-               clocks->data[i].clocks_in_khz = pclk_vol_table->entries[i].clk  * 10;
-               clocks->data[i].voltage_in_mv = pclk_vol_table->entries[i].vol;
-               clocks->num_levels++;
+               if (pclk_vol_table->entries[i].clk) {
+                       clocks->data[clocks->num_levels].clocks_in_khz = pclk_vol_table->entries[i].clk  * 10;
+                       clocks->data[clocks->num_levels].voltage_in_mv = pclk_vol_table->entries[i].vol;
+                       clocks->num_levels++;
+               }
        }
 
        return 0;
index d70abad..bf04cfe 100644 (file)
@@ -720,7 +720,7 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr)
                data->dpm_table.vddc_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].v;
                data->dpm_table.vddc_table.dpm_levels[i].param1 = std_voltage_table->entries[i].Leakage;
                /* param1 is for corresponding std voltage */
-               data->dpm_table.vddc_table.dpm_levels[i].enabled = 1;
+               data->dpm_table.vddc_table.dpm_levels[i].enabled = true;
        }
 
        data->dpm_table.vddc_table.count = allowed_vdd_sclk_table->count;
@@ -730,7 +730,7 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr)
                /* Initialize Vddci DPM table based on allow Mclk values */
                for (i = 0; i < allowed_vdd_mclk_table->count; i++) {
                        data->dpm_table.vddci_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].v;
-                       data->dpm_table.vddci_table.dpm_levels[i].enabled = 1;
+                       data->dpm_table.vddci_table.dpm_levels[i].enabled = true;
                }
                data->dpm_table.vddci_table.count = allowed_vdd_mclk_table->count;
        }
@@ -744,7 +744,7 @@ static int smu7_setup_dpm_tables_v0(struct pp_hwmgr *hwmgr)
                 */
                for (i = 0; i < allowed_vdd_mclk_table->count; i++) {
                        data->dpm_table.mvdd_table.dpm_levels[i].value = allowed_vdd_mclk_table->entries[i].v;
-                       data->dpm_table.mvdd_table.dpm_levels[i].enabled = 1;
+                       data->dpm_table.mvdd_table.dpm_levels[i].enabled = true;
                }
                data->dpm_table.mvdd_table.count = allowed_vdd_mclk_table->count;
        }
index b0591a8..97b6714 100644 (file)
@@ -273,6 +273,7 @@ struct smu_table_context
        uint8_t                         thermal_controller_type;
 
        void                            *overdrive_table;
+       void                            *boot_overdrive_table;
 };
 
 struct smu_dpm_context {
@@ -565,6 +566,7 @@ struct pptable_funcs {
        int (*set_soft_freq_limited_range)(struct smu_context *smu, enum smu_clk_type clk_type, uint32_t min, uint32_t max);
        int (*override_pcie_parameters)(struct smu_context *smu);
        uint32_t (*get_pptable_power_limit)(struct smu_context *smu);
+       int (*disable_umc_cdr_12gbps_workaround)(struct smu_context *smu);
 };
 
 int smu_load_microcode(struct smu_context *smu);
index d8c9b7f..a5b4df1 100644 (file)
        __SMU_DUMMY_MAP(SetSoftMinJpeg),              \
        __SMU_DUMMY_MAP(SetHardMinFclkByFreq),        \
        __SMU_DUMMY_MAP(DFCstateControl), \
+       __SMU_DUMMY_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE), \
+       __SMU_DUMMY_MAP(DAL_ENABLE_DUMMY_PSTATE_CHANGE), \
 
 #undef __SMU_DUMMY_MAP
 #define __SMU_DUMMY_MAP(type)  SMU_MSG_##type
index 373861d..406bfd1 100644 (file)
 #define PPSMC_MSG_GetVoltageByDpmOverdrive       0x45
 #define PPSMC_MSG_BacoAudioD3PME                 0x48
 
-#define PPSMC_Message_Count                      0x49
+#define PPSMC_MSG_DALDisableDummyPstateChange    0x49
+#define PPSMC_MSG_DALEnableDummyPstateChange     0x4A
+
+#define PPSMC_Message_Count                      0x4B
 
 typedef uint32_t PPSMC_Result;
 typedef uint32_t PPSMC_Msg;
index 93c66c6..19a9846 100644 (file)
@@ -119,6 +119,10 @@ static struct smu_11_0_cmn2aisc_mapping navi10_message_map[SMU_MSG_MAX_COUNT] =
        MSG_MAP(PowerDownJpeg,          PPSMC_MSG_PowerDownJpeg),
        MSG_MAP(BacoAudioD3PME,         PPSMC_MSG_BacoAudioD3PME),
        MSG_MAP(ArmD3,                  PPSMC_MSG_ArmD3),
+       MSG_MAP(DAL_DISABLE_DUMMY_PSTATE_CHANGE,PPSMC_MSG_DALDisableDummyPstateChange),
+       MSG_MAP(DAL_ENABLE_DUMMY_PSTATE_CHANGE, PPSMC_MSG_DALEnableDummyPstateChange),
+       MSG_MAP(GetVoltageByDpm,                     PPSMC_MSG_GetVoltageByDpm),
+       MSG_MAP(GetVoltageByDpmOverdrive,            PPSMC_MSG_GetVoltageByDpmOverdrive),
 };
 
 static struct smu_11_0_cmn2aisc_mapping navi10_clk_map[SMU_CLK_COUNT] = {
@@ -737,6 +741,15 @@ static inline bool navi10_od_feature_is_supported(struct smu_11_0_overdrive_tabl
        return od_table->cap[feature];
 }
 
+static void navi10_od_setting_get_range(struct smu_11_0_overdrive_table *od_table,
+                                       enum SMU_11_0_ODSETTING_ID setting,
+                                       uint32_t *min, uint32_t *max)
+{
+       if (min)
+               *min = od_table->min[setting];
+       if (max)
+               *max = od_table->max[setting];
+}
 
 static int navi10_print_clk_levels(struct smu_context *smu,
                        enum smu_clk_type clk_type, char *buf)
@@ -755,6 +768,7 @@ static int navi10_print_clk_levels(struct smu_context *smu,
        OverDriveTable_t *od_table =
                (OverDriveTable_t *)table_context->overdrive_table;
        struct smu_11_0_overdrive_table *od_settings = smu->od_settings;
+       uint32_t min_value, max_value;
 
        switch (clk_type) {
        case SMU_GFXCLK:
@@ -843,7 +857,7 @@ static int navi10_print_clk_levels(struct smu_context *smu,
                if (!navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX))
                        break;
                size += sprintf(buf + size, "OD_MCLK:\n");
-               size += sprintf(buf + size, "0: %uMHz\n", od_table->UclkFmax);
+               size += sprintf(buf + size, "1: %uMHz\n", od_table->UclkFmax);
                break;
        case SMU_OD_VDDC_CURVE:
                if (!smu->od_enabled || !od_table || !od_settings)
@@ -868,6 +882,55 @@ static int navi10_print_clk_levels(struct smu_context *smu,
                        size += sprintf(buf + size, "%d: %uMHz @ %umV\n", i, curve_settings[0], curve_settings[1] / NAVI10_VOLTAGE_SCALE);
                }
                break;
+       case SMU_OD_RANGE:
+               if (!smu->od_enabled || !od_table || !od_settings)
+                       break;
+               size = sprintf(buf, "%s:\n", "OD_RANGE");
+
+               if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_LIMITS)) {
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMIN,
+                                                   &min_value, NULL);
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_GFXCLKFMAX,
+                                                   NULL, &max_value);
+                       size += sprintf(buf + size, "SCLK: %7uMhz %10uMhz\n",
+                                       min_value, max_value);
+               }
+
+               if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_UCLK_MAX)) {
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_UCLKFMAX,
+                                                   &min_value, &max_value);
+                       size += sprintf(buf + size, "MCLK: %7uMhz %10uMhz\n",
+                                       min_value, max_value);
+               }
+
+               if (navi10_od_feature_is_supported(od_settings, SMU_11_0_ODFEATURE_GFXCLK_CURVE)) {
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P1,
+                                                   &min_value, &max_value);
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[0]: %7uMhz %10uMhz\n",
+                                       min_value, max_value);
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P1,
+                                                   &min_value, &max_value);
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[0]: %7dmV %11dmV\n",
+                                       min_value, max_value);
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P2,
+                                                   &min_value, &max_value);
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[1]: %7uMhz %10uMhz\n",
+                                       min_value, max_value);
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P2,
+                                                   &min_value, &max_value);
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[1]: %7dmV %11dmV\n",
+                                       min_value, max_value);
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEFREQ_P3,
+                                                   &min_value, &max_value);
+                       size += sprintf(buf + size, "VDDC_CURVE_SCLK[2]: %7uMhz %10uMhz\n",
+                                       min_value, max_value);
+                       navi10_od_setting_get_range(od_settings, SMU_11_0_ODSETTING_VDDGFXCURVEVOLTAGE_P3,
+                                                   &min_value, &max_value);
+                       size += sprintf(buf + size, "VDDC_CURVE_VOLT[2]: %7dmV %11dmV\n",
+                                       min_value, max_value);
+               }
+
+               break;
        default:
                break;
        }
@@ -949,6 +1012,8 @@ static int navi10_get_clock_by_type_with_latency(struct smu_context *smu,
        case SMU_GFXCLK:
        case SMU_DCEFCLK:
        case SMU_SOCCLK:
+       case SMU_MCLK:
+       case SMU_UCLK:
                ret = smu_get_dpm_level_count(smu, clk_type, &level_count);
                if (ret)
                        return ret;
@@ -1871,6 +1936,28 @@ static int navi10_od_setting_check_range(struct smu_11_0_overdrive_table *od_tab
        return 0;
 }
 
+static int navi10_overdrive_get_gfx_clk_base_voltage(struct smu_context *smu,
+                                                    uint16_t *voltage,
+                                                    uint32_t freq)
+{
+       uint32_t param = (freq & 0xFFFF) | (PPCLK_GFXCLK << 16);
+       uint32_t value = 0;
+       int ret;
+
+       ret = smu_send_smc_msg_with_param(smu,
+                                         SMU_MSG_GetVoltageByDpm,
+                                         param);
+       if (ret) {
+               pr_err("[GetBaseVoltage] failed to get GFXCLK AVFS voltage from SMU!");
+               return ret;
+       }
+
+       smu_read_smc_arg(smu, &value);
+       *voltage = (uint16_t)value;
+
+       return 0;
+}
+
 static int navi10_setup_od_limits(struct smu_context *smu) {
        struct smu_11_0_overdrive_table *overdrive_table = NULL;
        struct smu_11_0_powerplay_table *powerplay_table = NULL;
@@ -1890,23 +1977,54 @@ static int navi10_setup_od_limits(struct smu_context *smu) {
 }
 
 static int navi10_set_default_od_settings(struct smu_context *smu, bool initialize) {
-       OverDriveTable_t *od_table;
+       OverDriveTable_t *od_table, *boot_od_table;
        int ret = 0;
 
        ret = smu_v11_0_set_default_od_settings(smu, initialize, sizeof(OverDriveTable_t));
        if (ret)
                return ret;
 
+       od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table;
+       boot_od_table = (OverDriveTable_t *)smu->smu_table.boot_overdrive_table;
        if (initialize) {
                ret = navi10_setup_od_limits(smu);
                if (ret) {
                        pr_err("Failed to retrieve board OD limits\n");
                        return ret;
                }
+               if (od_table) {
+                       if (!od_table->GfxclkVolt1) {
+                               ret = navi10_overdrive_get_gfx_clk_base_voltage(smu,
+                                                                               &od_table->GfxclkVolt1,
+                                                                               od_table->GfxclkFreq1);
+                               if (ret)
+                                       od_table->GfxclkVolt1 = 0;
+                               if (boot_od_table)
+                                       boot_od_table->GfxclkVolt1 = od_table->GfxclkVolt1;
+                       }
 
+                       if (!od_table->GfxclkVolt2) {
+                               ret = navi10_overdrive_get_gfx_clk_base_voltage(smu,
+                                                                               &od_table->GfxclkVolt2,
+                                                                               od_table->GfxclkFreq2);
+                               if (ret)
+                                       od_table->GfxclkVolt2 = 0;
+                               if (boot_od_table)
+                                       boot_od_table->GfxclkVolt2 = od_table->GfxclkVolt2;
+                       }
+
+                       if (!od_table->GfxclkVolt3) {
+                               ret = navi10_overdrive_get_gfx_clk_base_voltage(smu,
+                                                                               &od_table->GfxclkVolt3,
+                                                                               od_table->GfxclkFreq3);
+                               if (ret)
+                                       od_table->GfxclkVolt3 = 0;
+                               if (boot_od_table)
+                                       boot_od_table->GfxclkVolt3 = od_table->GfxclkVolt3;
+                       }
+               }
        }
 
-       od_table = (OverDriveTable_t *)smu->smu_table.overdrive_table;
        if (od_table) {
                navi10_dump_od_table(od_table);
        }
@@ -2002,6 +2120,13 @@ static int navi10_od_edit_dpm_table(struct smu_context *smu, enum PP_OD_DPM_TABL
                        return ret;
                od_table->UclkFmax = input[1];
                break;
+       case PP_OD_RESTORE_DEFAULT_TABLE:
+               if (!(table_context->overdrive_table && table_context->boot_overdrive_table)) {
+                       pr_err("Overdrive table was not initialized!\n");
+                       return -EINVAL;
+               }
+               memcpy(table_context->overdrive_table, table_context->boot_overdrive_table, sizeof(OverDriveTable_t));
+               break;
        case PP_OD_COMMIT_DPM_TABLE:
                navi10_dump_od_table(od_table);
                ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, (void *)od_table, true);
@@ -2091,6 +2216,61 @@ static int navi10_run_btc(struct smu_context *smu)
        return ret;
 }
 
+static int navi10_dummy_pstate_control(struct smu_context *smu, bool enable)
+{
+       int result = 0;
+
+       if (!enable)
+               result = smu_send_smc_msg(smu, SMU_MSG_DAL_DISABLE_DUMMY_PSTATE_CHANGE);
+       else
+               result = smu_send_smc_msg(smu, SMU_MSG_DAL_ENABLE_DUMMY_PSTATE_CHANGE);
+
+       return result;
+}
+
+static int navi10_disable_umc_cdr_12gbps_workaround(struct smu_context *smu)
+{
+       uint32_t uclk_count, uclk_min, uclk_max;
+       uint32_t smu_version;
+       int ret = 0;
+
+       ret = smu_get_smc_version(smu, NULL, &smu_version);
+       if (ret)
+               return ret;
+
+       /* This workaround is available only for 42.50 or later SMC firmwares */
+       if (smu_version < 0x2A3200)
+               return 0;
+
+       ret = smu_get_dpm_level_count(smu, SMU_UCLK, &uclk_count);
+       if (ret)
+               return ret;
+
+       ret = smu_get_dpm_freq_by_index(smu, SMU_UCLK, (uint16_t)0, &uclk_min);
+       if (ret)
+               return ret;
+
+       ret = smu_get_dpm_freq_by_index(smu, SMU_UCLK, (uint16_t)(uclk_count - 1), &uclk_max);
+       if (ret)
+               return ret;
+
+       /* Force UCLK out of the highest DPM */
+       ret = smu_set_hard_freq_range(smu, SMU_UCLK, 0, uclk_min);
+       if (ret)
+               return ret;
+
+       /* Revert the UCLK Hardmax */
+       ret = smu_set_hard_freq_range(smu, SMU_UCLK, 0, uclk_max);
+       if (ret)
+               return ret;
+
+       /*
+        * In this case, SMU already disabled dummy pstate during enablement
+        * of UCLK DPM, we have to re-enabled it.
+        * */
+       return navi10_dummy_pstate_control(smu, true);
+}
+
 static const struct pptable_funcs navi10_ppt_funcs = {
        .tables_init = navi10_tables_init,
        .alloc_dpm_context = navi10_allocate_dpm_context,
@@ -2185,6 +2365,7 @@ static const struct pptable_funcs navi10_ppt_funcs = {
        .od_edit_dpm_table = navi10_od_edit_dpm_table,
        .get_pptable_power_limit = navi10_get_pptable_power_limit,
        .run_btc = navi10_run_btc,
+       .disable_umc_cdr_12gbps_workaround = navi10_disable_umc_cdr_12gbps_workaround,
 };
 
 void navi10_set_ppt_funcs(struct smu_context *smu)
index 783319e..7bd200f 100644 (file)
@@ -207,4 +207,7 @@ int smu_send_smc_msg(struct smu_context *smu, enum smu_message_type msg);
 #define smu_update_pcie_parameters(smu, pcie_gen_cap, pcie_width_cap) \
                ((smu)->ppt_funcs->update_pcie_parameters ? (smu)->ppt_funcs->update_pcie_parameters((smu), (pcie_gen_cap), (pcie_width_cap)) : 0)
 
+#define smu_disable_umc_cdr_12gbps_workaround(smu) \
+       ((smu)->ppt_funcs->disable_umc_cdr_12gbps_workaround ? (smu)->ppt_funcs->disable_umc_cdr_12gbps_workaround((smu)) : 0)
+
 #endif
index 02f8c9c..0dc4947 100644 (file)
@@ -1882,6 +1882,12 @@ int smu_v11_0_set_default_od_settings(struct smu_context *smu, bool initialize,
                        pr_err("Failed to export overdrive table!\n");
                        return ret;
                }
+               if (!table_context->boot_overdrive_table) {
+                       table_context->boot_overdrive_table = kmemdup(table_context->overdrive_table, overdrive_table_size, GFP_KERNEL);
+                       if (!table_context->boot_overdrive_table) {
+                               return -ENOMEM;
+                       }
+               }
        }
        ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, true);
        if (ret) {
index a3915bf..275dbf6 100644 (file)
@@ -128,20 +128,20 @@ int vega12_enable_smc_features(struct pp_hwmgr *hwmgr,
        if (enable) {
                PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
                                PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low) == 0,
-                               "[EnableDisableSMCFeatures] Attemp to enable SMU features Low failed!",
+                               "[EnableDisableSMCFeatures] Attempt to enable SMU features Low failed!",
                                return -EINVAL);
                PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
                                PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high) == 0,
-                               "[EnableDisableSMCFeatures] Attemp to enable SMU features High failed!",
+                               "[EnableDisableSMCFeatures] Attempt to enable SMU features High failed!",
                                return -EINVAL);
        } else {
                PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
                                PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low) == 0,
-                               "[EnableDisableSMCFeatures] Attemp to disable SMU features Low failed!",
+                               "[EnableDisableSMCFeatures] Attempt to disable SMU features Low failed!",
                                return -EINVAL);
                PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc_with_parameter(hwmgr,
                                PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high) == 0,
-                               "[EnableDisableSMCFeatures] Attemp to disable SMU features High failed!",
+                               "[EnableDisableSMCFeatures] Attempt to disable SMU features High failed!",
                                return -EINVAL);
        }
 
@@ -158,13 +158,13 @@ int vega12_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
 
        PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc(hwmgr,
                        PPSMC_MSG_GetEnabledSmuFeaturesLow) == 0,
-                       "[GetEnabledSMCFeatures] Attemp to get SMU features Low failed!",
+                       "[GetEnabledSMCFeatures] Attempt to get SMU features Low failed!",
                        return -EINVAL);
        smc_features_low = smu9_get_argument(hwmgr);
 
        PP_ASSERT_WITH_CODE(smu9_send_msg_to_smc(hwmgr,
                        PPSMC_MSG_GetEnabledSmuFeaturesHigh) == 0,
-                       "[GetEnabledSMCFeatures] Attemp to get SMU features High failed!",
+                       "[GetEnabledSMCFeatures] Attempt to get SMU features High failed!",
                        return -EINVAL);
        smc_features_high = smu9_get_argument(hwmgr);
 
index 0db57fb..49e5ef3 100644 (file)
@@ -316,20 +316,20 @@ int vega20_enable_smc_features(struct pp_hwmgr *hwmgr,
        if (enable) {
                PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
                                PPSMC_MSG_EnableSmuFeaturesLow, smu_features_low)) == 0,
-                               "[EnableDisableSMCFeatures] Attemp to enable SMU features Low failed!",
+                               "[EnableDisableSMCFeatures] Attempt to enable SMU features Low failed!",
                                return ret);
                PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
                                PPSMC_MSG_EnableSmuFeaturesHigh, smu_features_high)) == 0,
-                               "[EnableDisableSMCFeatures] Attemp to enable SMU features High failed!",
+                               "[EnableDisableSMCFeatures] Attempt to enable SMU features High failed!",
                                return ret);
        } else {
                PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
                                PPSMC_MSG_DisableSmuFeaturesLow, smu_features_low)) == 0,
-                               "[EnableDisableSMCFeatures] Attemp to disable SMU features Low failed!",
+                               "[EnableDisableSMCFeatures] Attempt to disable SMU features Low failed!",
                                return ret);
                PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc_with_parameter(hwmgr,
                                PPSMC_MSG_DisableSmuFeaturesHigh, smu_features_high)) == 0,
-                               "[EnableDisableSMCFeatures] Attemp to disable SMU features High failed!",
+                               "[EnableDisableSMCFeatures] Attempt to disable SMU features High failed!",
                                return ret);
        }
 
@@ -347,12 +347,12 @@ int vega20_get_enabled_smc_features(struct pp_hwmgr *hwmgr,
 
        PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc(hwmgr,
                        PPSMC_MSG_GetEnabledSmuFeaturesLow)) == 0,
-                       "[GetEnabledSMCFeatures] Attemp to get SMU features Low failed!",
+                       "[GetEnabledSMCFeatures] Attempt to get SMU features Low failed!",
                        return ret);
        smc_features_low = vega20_get_argument(hwmgr);
        PP_ASSERT_WITH_CODE((ret = vega20_send_msg_to_smc(hwmgr,
                        PPSMC_MSG_GetEnabledSmuFeaturesHigh)) == 0,
-                       "[GetEnabledSMCFeatures] Attemp to get SMU features High failed!",
+                       "[GetEnabledSMCFeatures] Attempt to get SMU features High failed!",
                        return ret);
        smc_features_high = vega20_get_argument(hwmgr);
 
index 38febd5..4ad8d6c 100644 (file)
@@ -1706,22 +1706,11 @@ static int vega20_set_default_od_settings(struct smu_context *smu,
        struct smu_table_context *table_context = &smu->smu_table;
        int ret;
 
-       if (initialize) {
-               if (table_context->overdrive_table)
-                       return -EINVAL;
-
-               table_context->overdrive_table = kzalloc(sizeof(OverDriveTable_t), GFP_KERNEL);
-
-               if (!table_context->overdrive_table)
-                       return -ENOMEM;
-
-               ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0,
-                                      table_context->overdrive_table, false);
-               if (ret) {
-                       pr_err("Failed to export over drive table!\n");
-                       return ret;
-               }
+       ret = smu_v11_0_set_default_od_settings(smu, initialize, sizeof(OverDriveTable_t));
+       if (ret)
+               return ret;
 
+       if (initialize) {
                ret = vega20_set_default_od8_setttings(smu);
                if (ret)
                        return ret;
@@ -2778,12 +2767,11 @@ static int vega20_odn_edit_dpm_table(struct smu_context *smu,
                break;
 
        case PP_OD_RESTORE_DEFAULT_TABLE:
-               ret = smu_update_table(smu, SMU_TABLE_OVERDRIVE, 0, table_context->overdrive_table, false);
-               if (ret) {
-                       pr_err("Failed to export over drive table!\n");
-                       return ret;
+               if (!(table_context->overdrive_table && table_context->boot_overdrive_table)) {
+                       pr_err("Overdrive table was not initialized!\n");
+                       return -EINVAL;
                }
-
+               memcpy(table_context->overdrive_table, table_context->boot_overdrive_table, sizeof(OverDriveTable_t));
                break;
 
        case PP_OD_COMMIT_DPM_TABLE:
index 8f6100d..1c89454 100644 (file)
@@ -751,9 +751,9 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm)
        snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id);
 
        hw = clk_hw_register_mux(dev, clk_name,
-                                (const char *[]){
+                                ((const char *[]){
                                 parent, parent2, parent3, parent4
-                                }, 4, 0, pll_10nm->phy_cmn_mmio +
+                                }), 4, 0, pll_10nm->phy_cmn_mmio +
                                 REG_DSI_10nm_PHY_CMN_CLK_CFG1,
                                 0, 2, 0, NULL);
        if (IS_ERR(hw)) {
index 8c99e01..6dffd7f 100644 (file)
@@ -554,9 +554,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm)
        snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id);
        snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id);
        clks[num++] = clk_register_mux(dev, clk_name,
-                       (const char *[]){
+                       ((const char *[]){
                                parent1, parent2
-                       }, 2, CLK_SET_RATE_PARENT, pll_28nm->mmio +
+                       }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio +
                        REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL);
 
        snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id);
index df8336b..ff94f3f 100644 (file)
@@ -6,6 +6,7 @@
 struct nv50_core {
        const struct nv50_core_func *func;
        struct nv50_dmac chan;
+       bool assign_windows;
 };
 
 int nv50_core_new(struct nouveau_drm *, struct nv50_core **);
@@ -18,6 +19,10 @@ struct nv50_core_func {
                              struct nvif_device *);
        void (*update)(struct nv50_core *, u32 *interlock, bool ntfy);
 
+       struct {
+               void (*owner)(struct nv50_core *);
+       } wndw;
+
        const struct nv50_head_func *head;
        const struct nv50_outp_func {
                void (*ctrl)(struct nv50_core *, int or, u32 ctrl,
@@ -48,6 +53,7 @@ int core917d_new(struct nouveau_drm *, s32, struct nv50_core **);
 int corec37d_new(struct nouveau_drm *, s32, struct nv50_core **);
 int corec37d_ntfy_wait_done(struct nouveau_bo *, u32, struct nvif_device *);
 void corec37d_update(struct nv50_core *, u32 *, bool);
+void corec37d_wndw_owner(struct nv50_core *);
 extern const struct nv50_outp_func sorc37d;
 
 int corec57d_new(struct nouveau_drm *, s32, struct nv50_core **);
index 40d9b65..3b36dc8 100644 (file)
 #include <nouveau_bo.h>
 
 void
+corec37d_wndw_owner(struct nv50_core *core)
+{
+       const u32 windows = 8; /*XXX*/
+       u32 *push, i;
+       if ((push = evo_wait(&core->chan, 2 * windows))) {
+               for (i = 0; i < windows; i++) {
+                       evo_mthd(push, 0x1000 + (i * 0x080), 1);
+                       evo_data(push, i >> 1);
+               }
+               evo_kick(push, &core->chan);
+       }
+}
+
+void
 corec37d_update(struct nv50_core *core, u32 *interlock, bool ntfy)
 {
        u32 *push;
@@ -76,20 +90,18 @@ corec37d_init(struct nv50_core *core)
 {
        const u32 windows = 8; /*XXX*/
        u32 *push, i;
-       if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) {
+       if ((push = evo_wait(&core->chan, 2 + 5 * windows))) {
                evo_mthd(push, 0x0208, 1);
                evo_data(push, core->chan.sync.handle);
                for (i = 0; i < windows; i++) {
-                       evo_mthd(push, 0x1000 + (i * 0x080), 3);
-                       evo_data(push, i >> 1);
+                       evo_mthd(push, 0x1004 + (i * 0x080), 2);
                        evo_data(push, 0x0000001f);
                        evo_data(push, 0x00000000);
                        evo_mthd(push, 0x1010 + (i * 0x080), 1);
                        evo_data(push, 0x00127fff);
                }
-               evo_mthd(push, 0x0200, 1);
-               evo_data(push, 0x00000001);
                evo_kick(push, &core->chan);
+               core->assign_windows = true;
        }
 }
 
@@ -99,6 +111,7 @@ corec37d = {
        .ntfy_init = corec37d_ntfy_init,
        .ntfy_wait_done = corec37d_ntfy_wait_done,
        .update = corec37d_update,
+       .wndw.owner = corec37d_wndw_owner,
        .head = &headc37d,
        .sor = &sorc37d,
 };
index b606d68..147adcd 100644 (file)
@@ -27,20 +27,18 @@ corec57d_init(struct nv50_core *core)
 {
        const u32 windows = 8; /*XXX*/
        u32 *push, i;
-       if ((push = evo_wait(&core->chan, 2 + 6 * windows + 2))) {
+       if ((push = evo_wait(&core->chan, 2 + 5 * windows))) {
                evo_mthd(push, 0x0208, 1);
                evo_data(push, core->chan.sync.handle);
                for (i = 0; i < windows; i++) {
-                       evo_mthd(push, 0x1000 + (i * 0x080), 3);
-                       evo_data(push, i >> 1);
+                       evo_mthd(push, 0x1004 + (i * 0x080), 2);
                        evo_data(push, 0x0000000f);
                        evo_data(push, 0x00000000);
                        evo_mthd(push, 0x1010 + (i * 0x080), 1);
                        evo_data(push, 0x00117fff);
                }
-               evo_mthd(push, 0x0200, 1);
-               evo_data(push, 0x00000001);
                evo_kick(push, &core->chan);
+               core->assign_windows = true;
        }
 }
 
@@ -50,6 +48,7 @@ corec57d = {
        .ntfy_init = corec37d_ntfy_init,
        .ntfy_wait_done = corec37d_ntfy_wait_done,
        .update = corec37d_update,
+       .wndw.owner = corec37d_wndw_owner,
        .head = &headc57d,
        .sor = &sorc37d,
 };
index 2f12308..a3dc2ba 100644 (file)
@@ -1933,6 +1933,7 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
        struct nouveau_drm *drm = nouveau_drm(dev);
        struct nv50_disp *disp = nv50_disp(dev);
        struct nv50_atom *atom = nv50_atom(state);
+       struct nv50_core *core = disp->core;
        struct nv50_outp_atom *outp, *outt;
        u32 interlock[NV50_DISP_INTERLOCK__SIZE] = {};
        int i;
@@ -2051,6 +2052,21 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
                }
        }
 
+       /* Update window->head assignment.
+        *
+        * This has to happen in an update that's not interlocked with
+        * any window channels to avoid hitting HW error checks.
+        *
+        *TODO: Proper handling of window ownership (Turing apparently
+        *      supports non-fixed mappings).
+        */
+       if (core->assign_windows) {
+               core->func->wndw.owner(core);
+               core->func->update(core, interlock, false);
+               core->assign_windows = false;
+               interlock[NV50_DISP_INTERLOCK_CORE] = 0;
+       }
+
        /* Update plane(s). */
        for_each_new_plane_in_state(state, plane, new_plane_state, i) {
                struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);
index 3aa2cc3..c103252 100644 (file)
@@ -155,6 +155,12 @@ gv100_disp_intr_ctrl_disp(struct nv50_disp *disp)
        if (stat & 0x00000008)
                stat &= ~0x00000008;
 
+       if (stat & 0x00000080) {
+               u32 error = nvkm_mask(device, 0x611848, 0x00000000, 0x00000000);
+               nvkm_warn(subdev, "error %08x\n", error);
+               stat &= ~0x00000080;
+       }
+
        if (stat & 0x00000100) {
                unsigned long wndws = nvkm_rd32(device, 0x611858);
                unsigned long other = nvkm_rd32(device, 0x61185c);
index 856526c..d07c7db 100644 (file)
@@ -127,6 +127,8 @@ static void dce5_crtc_load_lut(struct drm_crtc *crtc)
 
        DRM_DEBUG_KMS("%d\n", radeon_crtc->crtc_id);
 
+       msleep(10);
+
        WREG32(NI_INPUT_CSC_CONTROL + radeon_crtc->crtc_offset,
               (NI_INPUT_CSC_GRPH_MODE(NI_INPUT_CSC_BYPASS) |
                NI_INPUT_CSC_OVL_MODE(NI_INPUT_CSC_BYPASS)));
@@ -672,7 +674,6 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
 {
        struct radeon_device *rdev = dev->dev_private;
        struct radeon_crtc *radeon_crtc;
-       int i;
 
        radeon_crtc = kzalloc(sizeof(struct radeon_crtc) + (RADEONFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL);
        if (radeon_crtc == NULL)
@@ -701,12 +702,6 @@ static void radeon_crtc_init(struct drm_device *dev, int index)
        radeon_crtc->mode_set.num_connectors = 0;
 #endif
 
-       for (i = 0; i < 256; i++) {
-               radeon_crtc->lut_r[i] = i << 2;
-               radeon_crtc->lut_g[i] = i << 2;
-               radeon_crtc->lut_b[i] = i << 2;
-       }
-
        if (rdev->is_atom_bios && (ASIC_IS_AVIVO(rdev) || radeon_r4xx_atom))
                radeon_atombios_init_crtc(dev, radeon_crtc);
        else
index fd470d6..9656517 100644 (file)
@@ -327,7 +327,6 @@ enum radeon_flip_status {
 struct radeon_crtc {
        struct drm_crtc base;
        int crtc_id;
-       u16 lut_r[256], lut_g[256], lut_b[256];
        bool enabled;
        bool can_tile;
        bool cursor_out_of_bounds;
index ec79e8e..63bccd2 100644 (file)
@@ -45,7 +45,7 @@
  * @guilty: atomic_t set to 1 when a job on this queue
  *          is found to be guilty causing a timeout
  *
- * Note: the sched_list should have atleast one element to schedule
+ * Note: the sched_list should have at least one element to schedule
  *       the entity
  *
  * Returns 0 on success or a negative error code on failure.
index aa9e49f..bd26802 100644 (file)
@@ -1037,23 +1037,9 @@ void tegra_drm_free(struct tegra_drm *tegra, size_t size, void *virt,
        free_pages((unsigned long)virt, get_order(size));
 }
 
-static int host1x_drm_probe(struct host1x_device *dev)
+static bool host1x_drm_wants_iommu(struct host1x_device *dev)
 {
-       struct drm_driver *driver = &tegra_drm_driver;
        struct iommu_domain *domain;
-       struct tegra_drm *tegra;
-       struct drm_device *drm;
-       int err;
-
-       drm = drm_dev_alloc(driver, &dev->dev);
-       if (IS_ERR(drm))
-               return PTR_ERR(drm);
-
-       tegra = kzalloc(sizeof(*tegra), GFP_KERNEL);
-       if (!tegra) {
-               err = -ENOMEM;
-               goto put;
-       }
 
        /*
         * If the Tegra DRM clients are backed by an IOMMU, push buffers are
@@ -1082,9 +1068,38 @@ static int host1x_drm_probe(struct host1x_device *dev)
         * up the device tree appropriately. This is considered an problem
         * of integration, so care must be taken for the DT to be consistent.
         */
-       domain = iommu_get_domain_for_dev(drm->dev->parent);
+       domain = iommu_get_domain_for_dev(dev->dev.parent);
+
+       /*
+        * Tegra20 and Tegra30 don't support addressing memory beyond the
+        * 32-bit boundary, so the regular GATHER opcodes will always be
+        * sufficient and whether or not the host1x is attached to an IOMMU
+        * doesn't matter.
+        */
+       if (!domain && dma_get_mask(dev->dev.parent) <= DMA_BIT_MASK(32))
+               return true;
+
+       return domain != NULL;
+}
+
+static int host1x_drm_probe(struct host1x_device *dev)
+{
+       struct drm_driver *driver = &tegra_drm_driver;
+       struct tegra_drm *tegra;
+       struct drm_device *drm;
+       int err;
+
+       drm = drm_dev_alloc(driver, &dev->dev);
+       if (IS_ERR(drm))
+               return PTR_ERR(drm);
+
+       tegra = kzalloc(sizeof(*tegra), GFP_KERNEL);
+       if (!tegra) {
+               err = -ENOMEM;
+               goto put;
+       }
 
-       if (domain && iommu_present(&platform_bus_type)) {
+       if (host1x_drm_wants_iommu(dev) && iommu_present(&platform_bus_type)) {
                tegra->domain = iommu_domain_alloc(&platform_bus_type);
                if (!tegra->domain) {
                        err = -ENOMEM;
index 1237df1..6237681 100644 (file)
@@ -60,8 +60,16 @@ static struct sg_table *tegra_bo_pin(struct device *dev, struct host1x_bo *bo,
        /*
         * If we've manually mapped the buffer object through the IOMMU, make
         * sure to return the IOVA address of our mapping.
+        *
+        * Similarly, for buffers that have been allocated by the DMA API the
+        * physical address can be used for devices that are not attached to
+        * an IOMMU. For these devices, callers must pass a valid pointer via
+        * the @phys argument.
+        *
+        * Imported buffers were also already mapped at import time, so the
+        * existing mapping can be reused.
         */
-       if (phys && obj->mm) {
+       if (phys) {
                *phys = obj->iova;
                return NULL;
        }
index cadcdd9..9ccfb56 100644 (file)
@@ -3,6 +3,8 @@
  * Copyright (C) 2017 NVIDIA CORPORATION.  All rights reserved.
  */
 
+#include <linux/iommu.h>
+
 #include <drm/drm_atomic.h>
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_fourcc.h>
@@ -107,21 +109,27 @@ const struct drm_plane_funcs tegra_plane_funcs = {
 
 static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
 {
+       struct iommu_domain *domain = iommu_get_domain_for_dev(dc->dev);
        unsigned int i;
        int err;
 
        for (i = 0; i < state->base.fb->format->num_planes; i++) {
                struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i);
+               dma_addr_t phys_addr, *phys;
+               struct sg_table *sgt;
 
-               if (!dc->client.group) {
-                       struct sg_table *sgt;
+               if (!domain || dc->client.group)
+                       phys = &phys_addr;
+               else
+                       phys = NULL;
 
-                       sgt = host1x_bo_pin(dc->dev, &bo->base, NULL);
-                       if (IS_ERR(sgt)) {
-                               err = PTR_ERR(sgt);
-                               goto unpin;
-                       }
+               sgt = host1x_bo_pin(dc->dev, &bo->base, phys);
+               if (IS_ERR(sgt)) {
+                       err = PTR_ERR(sgt);
+                       goto unpin;
+               }
 
+               if (sgt) {
                        err = dma_map_sg(dc->dev, sgt->sgl, sgt->nents,
                                         DMA_TO_DEVICE);
                        if (err == 0) {
@@ -143,7 +151,7 @@ static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
                        state->iova[i] = sg_dma_address(sgt->sgl);
                        state->sgt[i] = sgt;
                } else {
-                       state->iova[i] = bo->iova;
+                       state->iova[i] = phys_addr;
                }
        }
 
@@ -156,9 +164,11 @@ unpin:
                struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i);
                struct sg_table *sgt = state->sgt[i];
 
-               dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents, DMA_TO_DEVICE);
-               host1x_bo_unpin(dc->dev, &bo->base, sgt);
+               if (sgt)
+                       dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+                                    DMA_TO_DEVICE);
 
+               host1x_bo_unpin(dc->dev, &bo->base, sgt);
                state->iova[i] = DMA_MAPPING_ERROR;
                state->sgt[i] = NULL;
        }
@@ -172,17 +182,13 @@ static void tegra_dc_unpin(struct tegra_dc *dc, struct tegra_plane_state *state)
 
        for (i = 0; i < state->base.fb->format->num_planes; i++) {
                struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i);
+               struct sg_table *sgt = state->sgt[i];
 
-               if (!dc->client.group) {
-                       struct sg_table *sgt = state->sgt[i];
-
-                       if (sgt) {
-                               dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
-                                            DMA_TO_DEVICE);
-                               host1x_bo_unpin(dc->dev, &bo->base, sgt);
-                       }
-               }
+               if (sgt)
+                       dma_unmap_sg(dc->dev, sgt->sgl, sgt->nents,
+                                    DMA_TO_DEVICE);
 
+               host1x_bo_unpin(dc->dev, &bo->base, sgt);
                state->iova[i] = DMA_MAPPING_ERROR;
                state->sgt[i] = NULL;
        }
index 41d2494..81226a4 100644 (file)
@@ -3915,6 +3915,17 @@ static int tegra_sor_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, sor);
        pm_runtime_enable(&pdev->dev);
 
+       INIT_LIST_HEAD(&sor->client.list);
+       sor->client.ops = &sor_client_ops;
+       sor->client.dev = &pdev->dev;
+
+       err = host1x_client_register(&sor->client);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to register host1x client: %d\n",
+                       err);
+               goto rpm_disable;
+       }
+
        /*
         * On Tegra210 and earlier, provide our own implementation for the
         * pad output clock.
@@ -3922,16 +3933,17 @@ static int tegra_sor_probe(struct platform_device *pdev)
        if (!sor->clk_pad) {
                char *name;
 
+               name = devm_kasprintf(sor->dev, GFP_KERNEL, "sor%u_pad_clkout",
+                                     sor->index);
+               if (!name) {
+                       err = -ENOMEM;
+                       goto unregister;
+               }
+
                err = host1x_client_resume(&sor->client);
                if (err < 0) {
                        dev_err(sor->dev, "failed to resume: %d\n", err);
-                       goto remove;
-               }
-
-               name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "sor%u_pad_clkout", sor->index);
-               if (!name) {
-                       err = -ENOMEM;
-                       goto remove;
+                       goto unregister;
                }
 
                sor->clk_pad = tegra_clk_sor_pad_register(sor, name);
@@ -3940,24 +3952,17 @@ static int tegra_sor_probe(struct platform_device *pdev)
 
        if (IS_ERR(sor->clk_pad)) {
                err = PTR_ERR(sor->clk_pad);
-               dev_err(&pdev->dev, "failed to register SOR pad clock: %d\n",
-                       err);
-               goto remove;
-       }
-
-       INIT_LIST_HEAD(&sor->client.list);
-       sor->client.ops = &sor_client_ops;
-       sor->client.dev = &pdev->dev;
-
-       err = host1x_client_register(&sor->client);
-       if (err < 0) {
-               dev_err(&pdev->dev, "failed to register host1x client: %d\n",
+               dev_err(sor->dev, "failed to register SOR pad clock: %d\n",
                        err);
-               goto remove;
+               goto unregister;
        }
 
        return 0;
 
+unregister:
+       host1x_client_unregister(&sor->client);
+rpm_disable:
+       pm_runtime_disable(&pdev->dev);
 remove:
        if (sor->ops && sor->ops->remove)
                sor->ops->remove(sor);
@@ -3971,8 +3976,6 @@ static int tegra_sor_remove(struct platform_device *pdev)
        struct tegra_sor *sor = platform_get_drvdata(pdev);
        int err;
 
-       pm_runtime_disable(&pdev->dev);
-
        err = host1x_client_unregister(&sor->client);
        if (err < 0) {
                dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
@@ -3980,6 +3983,8 @@ static int tegra_sor_remove(struct platform_device *pdev)
                return err;
        }
 
+       pm_runtime_disable(&pdev->dev);
+
        if (sor->ops && sor->ops->remove) {
                err = sor->ops->remove(sor);
                if (err < 0)
index eebb4c0..389128b 100644 (file)
@@ -179,7 +179,6 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
                                    pgoff_t num_prefault)
 {
        struct vm_area_struct *vma = vmf->vma;
-       struct vm_area_struct cvma = *vma;
        struct ttm_buffer_object *bo = vma->vm_private_data;
        struct ttm_bo_device *bdev = bo->bdev;
        unsigned long page_offset;
@@ -250,7 +249,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
                goto out_io_unlock;
        }
 
-       cvma.vm_page_prot = ttm_io_prot(bo->mem.placement, prot);
+       prot = ttm_io_prot(bo->mem.placement, prot);
        if (!bo->mem.bus.is_iomem) {
                struct ttm_operation_ctx ctx = {
                        .interruptible = false,
@@ -266,7 +265,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
                }
        } else {
                /* Iomem should not be marked encrypted */
-               cvma.vm_page_prot = pgprot_decrypted(cvma.vm_page_prot);
+               prot = pgprot_decrypted(prot);
        }
 
        /*
@@ -289,11 +288,20 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf,
                        pfn = page_to_pfn(page);
                }
 
+               /*
+                * Note that the value of @prot at this point may differ from
+                * the value of @vma->vm_page_prot in the caching- and
+                * encryption bits. This is because the exact location of the
+                * data may not be known at mmap() time and may also change
+                * at arbitrary times while the data is mmap'ed.
+                * See vmf_insert_mixed_prot() for a discussion.
+                */
                if (vma->vm_flags & VM_MIXEDMAP)
-                       ret = vmf_insert_mixed(&cvma, address,
-                                       __pfn_to_pfn_t(pfn, PFN_DEV));
+                       ret = vmf_insert_mixed_prot(vma, address,
+                                                   __pfn_to_pfn_t(pfn, PFN_DEV),
+                                                   prot);
                else
-                       ret = vmf_insert_pfn(&cvma, address, pfn);
+                       ret = vmf_insert_pfn_prot(vma, address, pfn, prot);
 
                /* Never error on prefaulted PTEs */
                if (unlikely((ret & VM_FAULT_ERROR))) {
@@ -325,7 +333,7 @@ vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf)
        if (ret)
                return ret;
 
-       prot = vm_get_page_prot(vma->vm_flags);
+       prot = vma->vm_page_prot;
        ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT);
        if (ret == VM_FAULT_RETRY && !(vmf->flags & FAULT_FLAG_RETRY_NOWAIT))
                return ret;
index 60b2fed..a10643a 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
 #include <linux/host1x.h>
+#include <linux/iommu.h>
 #include <linux/kref.h>
 #include <linux/module.h>
 #include <linux/scatterlist.h>
@@ -101,9 +102,11 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 {
        struct host1x_client *client = job->client;
        struct device *dev = client->dev;
+       struct iommu_domain *domain;
        unsigned int i;
        int err;
 
+       domain = iommu_get_domain_for_dev(dev);
        job->num_unpins = 0;
 
        for (i = 0; i < job->num_relocs; i++) {
@@ -117,7 +120,19 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
                        goto unpin;
                }
 
-               if (client->group)
+               /*
+                * If the client device is not attached to an IOMMU, the
+                * physical address of the buffer object can be used.
+                *
+                * Similarly, when an IOMMU domain is shared between all
+                * host1x clients, the IOVA is already available, so no
+                * need to map the buffer object again.
+                *
+                * XXX Note that this isn't always safe to do because it
+                * relies on an assumption that no cache maintenance is
+                * needed on the buffer objects.
+                */
+               if (!domain || client->group)
                        phys = &phys_addr;
                else
                        phys = NULL;
@@ -176,6 +191,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
                dma_addr_t phys_addr;
                unsigned long shift;
                struct iova *alloc;
+               dma_addr_t *phys;
                unsigned int j;
 
                g->bo = host1x_bo_get(g->bo);
@@ -184,7 +200,17 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
                        goto unpin;
                }
 
-               sgt = host1x_bo_pin(host->dev, g->bo, NULL);
+               /**
+                * If the host1x is not attached to an IOMMU, there is no need
+                * to map the buffer object for the host1x, since the physical
+                * address can simply be used.
+                */
+               if (!iommu_get_domain_for_dev(host->dev))
+                       phys = &phys_addr;
+               else
+                       phys = NULL;
+
+               sgt = host1x_bo_pin(host->dev, g->bo, phys);
                if (IS_ERR(sgt)) {
                        err = PTR_ERR(sgt);
                        goto unpin;
@@ -214,7 +240,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
 
                        job->unpins[job->num_unpins].size = gather_size;
                        phys_addr = iova_dma_addr(&host->iova, alloc);
-               } else {
+               } else if (sgt) {
                        err = dma_map_sg(host->dev, sgt->sgl, sgt->nents,
                                         DMA_TO_DEVICE);
                        if (!err) {
@@ -222,6 +248,7 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
                                goto unpin;
                        }
 
+                       job->unpins[job->num_unpins].dir = DMA_TO_DEVICE;
                        job->unpins[job->num_unpins].dev = host->dev;
                        phys_addr = sg_dma_address(sgt->sgl);
                }
@@ -229,7 +256,6 @@ static unsigned int pin_job(struct host1x *host, struct host1x_job *job)
                job->addr_phys[job->num_unpins] = phys_addr;
                job->gather_addr_phys[i] = phys_addr;
 
-               job->unpins[job->num_unpins].dir = DMA_TO_DEVICE;
                job->unpins[job->num_unpins].bo = g->bo;
                job->unpins[job->num_unpins].sgt = sgt;
                job->num_unpins++;
index 8eb1675..0370364 100644 (file)
@@ -1351,6 +1351,8 @@ channel_message_table[CHANNELMSG_COUNT] = {
        { CHANNELMSG_19,                        0, NULL },
        { CHANNELMSG_20,                        0, NULL },
        { CHANNELMSG_TL_CONNECT_REQUEST,        0, NULL },
+       { CHANNELMSG_22,                        0, NULL },
+       { CHANNELMSG_TL_CONNECT_RESULT,         0, NULL },
 };
 
 /*
@@ -1362,25 +1364,16 @@ void vmbus_onmessage(void *context)
 {
        struct hv_message *msg = context;
        struct vmbus_channel_message_header *hdr;
-       int size;
 
        hdr = (struct vmbus_channel_message_header *)msg->u.payload;
-       size = msg->header.payload_size;
 
        trace_vmbus_on_message(hdr);
 
-       if (hdr->msgtype >= CHANNELMSG_COUNT) {
-               pr_err("Received invalid channel message type %d size %d\n",
-                          hdr->msgtype, size);
-               print_hex_dump_bytes("", DUMP_PREFIX_NONE,
-                                    (unsigned char *)msg->u.payload, size);
-               return;
-       }
-
-       if (channel_message_table[hdr->msgtype].message_handler)
-               channel_message_table[hdr->msgtype].message_handler(hdr);
-       else
-               pr_err("Unhandled channel message type %d\n", hdr->msgtype);
+       /*
+        * vmbus_on_msg_dpc() makes sure the hdr->msgtype here can not go
+        * out of bound and the message_handler pointer can not be NULL.
+        */
+       channel_message_table[hdr->msgtype].message_handler(hdr);
 }
 
 /*
index b155d00..a02ce43 100644 (file)
@@ -1217,10 +1217,7 @@ static unsigned int alloc_balloon_pages(struct hv_dynmem_device *dm,
        unsigned int i, j;
        struct page *pg;
 
-       if (num_pages < alloc_unit)
-               return 0;
-
-       for (i = 0; (i * alloc_unit) < num_pages; i++) {
+       for (i = 0; i < num_pages / alloc_unit; i++) {
                if (bl_resp->hdr.size + sizeof(union dm_mem_page_range) >
                        HV_HYP_PAGE_SIZE)
                        return i * alloc_unit;
@@ -1258,7 +1255,7 @@ static unsigned int alloc_balloon_pages(struct hv_dynmem_device *dm,
 
        }
 
-       return num_pages;
+       return i * alloc_unit;
 }
 
 static void balloon_up(struct work_struct *dummy)
@@ -1273,9 +1270,6 @@ static void balloon_up(struct work_struct *dummy)
        long avail_pages;
        unsigned long floor;
 
-       /* The host balloons pages in 2M granularity. */
-       WARN_ON_ONCE(num_pages % PAGES_IN_2M != 0);
-
        /*
         * We will attempt 2M allocations. However, if we fail to
         * allocate 2M chunks, we will go back to PAGE_SIZE allocations.
@@ -1285,14 +1279,13 @@ static void balloon_up(struct work_struct *dummy)
        avail_pages = si_mem_available();
        floor = compute_balloon_floor();
 
-       /* Refuse to balloon below the floor, keep the 2M granularity. */
+       /* Refuse to balloon below the floor. */
        if (avail_pages < num_pages || avail_pages - num_pages < floor) {
                pr_warn("Balloon request will be partially fulfilled. %s\n",
                        avail_pages < num_pages ? "Not enough memory." :
                        "Balloon floor reached.");
 
                num_pages = avail_pages > floor ? (avail_pages - floor) : 0;
-               num_pages -= num_pages % PAGES_IN_2M;
        }
 
        while (!done) {
index 08fa4a5..bb9ba3f 100644 (file)
@@ -346,9 +346,61 @@ int hv_fcopy_init(struct hv_util_service *srv)
        return 0;
 }
 
+static void hv_fcopy_cancel_work(void)
+{
+       cancel_delayed_work_sync(&fcopy_timeout_work);
+       cancel_work_sync(&fcopy_send_work);
+}
+
+int hv_fcopy_pre_suspend(void)
+{
+       struct vmbus_channel *channel = fcopy_transaction.recv_channel;
+       struct hv_fcopy_hdr *fcopy_msg;
+
+       /*
+        * Fake a CANCEL_FCOPY message for the user space daemon in case the
+        * daemon is in the middle of copying some file. It doesn't matter if
+        * there is already a message pending to be delivered to the user
+        * space since we force fcopy_transaction.state to be HVUTIL_READY, so
+        * the user space daemon's write() will fail with EINVAL (see
+        * fcopy_on_msg()), and the daemon will reset the device by closing
+        * and re-opening it.
+        */
+       fcopy_msg = kzalloc(sizeof(*fcopy_msg), GFP_KERNEL);
+       if (!fcopy_msg)
+               return -ENOMEM;
+
+       tasklet_disable(&channel->callback_event);
+
+       fcopy_msg->operation = CANCEL_FCOPY;
+
+       hv_fcopy_cancel_work();
+
+       /* We don't care about the return value. */
+       hvutil_transport_send(hvt, fcopy_msg, sizeof(*fcopy_msg), NULL);
+
+       kfree(fcopy_msg);
+
+       fcopy_transaction.state = HVUTIL_READY;
+
+       /* tasklet_enable() will be called in hv_fcopy_pre_resume(). */
+       return 0;
+}
+
+int hv_fcopy_pre_resume(void)
+{
+       struct vmbus_channel *channel = fcopy_transaction.recv_channel;
+
+       tasklet_enable(&channel->callback_event);
+
+       return 0;
+}
+
 void hv_fcopy_deinit(void)
 {
        fcopy_transaction.state = HVUTIL_DEVICE_DYING;
-       cancel_delayed_work_sync(&fcopy_timeout_work);
+
+       hv_fcopy_cancel_work();
+
        hvutil_transport_destroy(hvt);
 }
index ae7c028..e74b144 100644 (file)
@@ -758,11 +758,50 @@ hv_kvp_init(struct hv_util_service *srv)
        return 0;
 }
 
-void hv_kvp_deinit(void)
+static void hv_kvp_cancel_work(void)
 {
-       kvp_transaction.state = HVUTIL_DEVICE_DYING;
        cancel_delayed_work_sync(&kvp_host_handshake_work);
        cancel_delayed_work_sync(&kvp_timeout_work);
        cancel_work_sync(&kvp_sendkey_work);
+}
+
+int hv_kvp_pre_suspend(void)
+{
+       struct vmbus_channel *channel = kvp_transaction.recv_channel;
+
+       tasklet_disable(&channel->callback_event);
+
+       /*
+        * If there is a pending transtion, it's unnecessary to tell the host
+        * that the transaction will fail, because that is implied when
+        * util_suspend() calls vmbus_close() later.
+        */
+       hv_kvp_cancel_work();
+
+       /*
+        * Forece the state to READY to handle the ICMSGTYPE_NEGOTIATE message
+        * later. The user space daemon may go out of order and its write()
+        * may fail with EINVAL: this doesn't matter since the daemon will
+        * reset the device by closing and re-opening it.
+        */
+       kvp_transaction.state = HVUTIL_READY;
+       return 0;
+}
+
+int hv_kvp_pre_resume(void)
+{
+       struct vmbus_channel *channel = kvp_transaction.recv_channel;
+
+       tasklet_enable(&channel->callback_event);
+
+       return 0;
+}
+
+void hv_kvp_deinit(void)
+{
+       kvp_transaction.state = HVUTIL_DEVICE_DYING;
+
+       hv_kvp_cancel_work();
+
        hvutil_transport_destroy(hvt);
 }
index 03b6454..1c75b38 100644 (file)
@@ -379,10 +379,61 @@ hv_vss_init(struct hv_util_service *srv)
        return 0;
 }
 
-void hv_vss_deinit(void)
+static void hv_vss_cancel_work(void)
 {
-       vss_transaction.state = HVUTIL_DEVICE_DYING;
        cancel_delayed_work_sync(&vss_timeout_work);
        cancel_work_sync(&vss_handle_request_work);
+}
+
+int hv_vss_pre_suspend(void)
+{
+       struct vmbus_channel *channel = vss_transaction.recv_channel;
+       struct hv_vss_msg *vss_msg;
+
+       /*
+        * Fake a THAW message for the user space daemon in case the daemon
+        * has frozen the file systems. It doesn't matter if there is already
+        * a message pending to be delivered to the user space since we force
+        * vss_transaction.state to be HVUTIL_READY, so the user space daemon's
+        * write() will fail with EINVAL (see vss_on_msg()), and the daemon
+        * will reset the device by closing and re-opening it.
+        */
+       vss_msg = kzalloc(sizeof(*vss_msg), GFP_KERNEL);
+       if (!vss_msg)
+               return -ENOMEM;
+
+       tasklet_disable(&channel->callback_event);
+
+       vss_msg->vss_hdr.operation = VSS_OP_THAW;
+
+       /* Cancel any possible pending work. */
+       hv_vss_cancel_work();
+
+       /* We don't care about the return value. */
+       hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg), NULL);
+
+       kfree(vss_msg);
+
+       vss_transaction.state = HVUTIL_READY;
+
+       /* tasklet_enable() will be called in hv_vss_pre_resume(). */
+       return 0;
+}
+
+int hv_vss_pre_resume(void)
+{
+       struct vmbus_channel *channel = vss_transaction.recv_channel;
+
+       tasklet_enable(&channel->callback_event);
+
+       return 0;
+}
+
+void hv_vss_deinit(void)
+{
+       vss_transaction.state = HVUTIL_DEVICE_DYING;
+
+       hv_vss_cancel_work();
+
        hvutil_transport_destroy(hvt);
 }
index 296f909..92ee0fe 100644 (file)
 
 #define SD_MAJOR       3
 #define SD_MINOR       0
+#define SD_MINOR_1     1
+#define SD_MINOR_2     2
+#define SD_VERSION_3_1 (SD_MAJOR << 16 | SD_MINOR_1)
+#define SD_VERSION_3_2 (SD_MAJOR << 16 | SD_MINOR_2)
 #define SD_VERSION     (SD_MAJOR << 16 | SD_MINOR)
 
 #define SD_MAJOR_1     1
@@ -50,8 +54,10 @@ static int sd_srv_version;
 static int ts_srv_version;
 static int hb_srv_version;
 
-#define SD_VER_COUNT 2
+#define SD_VER_COUNT 4
 static const int sd_versions[] = {
+       SD_VERSION_3_2,
+       SD_VERSION_3_1,
        SD_VERSION,
        SD_VERSION_1
 };
@@ -75,18 +81,56 @@ static const int fw_versions[] = {
        UTIL_WS2K8_FW_VERSION
 };
 
+/*
+ * Send the "hibernate" udev event in a thread context.
+ */
+struct hibernate_work_context {
+       struct work_struct work;
+       struct hv_device *dev;
+};
+
+static struct hibernate_work_context hibernate_context;
+static bool hibernation_supported;
+
+static void send_hibernate_uevent(struct work_struct *work)
+{
+       char *uevent_env[2] = { "EVENT=hibernate", NULL };
+       struct hibernate_work_context *ctx;
+
+       ctx = container_of(work, struct hibernate_work_context, work);
+
+       kobject_uevent_env(&ctx->dev->device.kobj, KOBJ_CHANGE, uevent_env);
+
+       pr_info("Sent hibernation uevent\n");
+}
+
+static int hv_shutdown_init(struct hv_util_service *srv)
+{
+       struct vmbus_channel *channel = srv->channel;
+
+       INIT_WORK(&hibernate_context.work, send_hibernate_uevent);
+       hibernate_context.dev = channel->device_obj;
+
+       hibernation_supported = hv_is_hibernation_supported();
+
+       return 0;
+}
+
 static void shutdown_onchannelcallback(void *context);
 static struct hv_util_service util_shutdown = {
        .util_cb = shutdown_onchannelcallback,
+       .util_init = hv_shutdown_init,
 };
 
 static int hv_timesync_init(struct hv_util_service *srv);
+static int hv_timesync_pre_suspend(void);
 static void hv_timesync_deinit(void);
 
 static void timesync_onchannelcallback(void *context);
 static struct hv_util_service util_timesynch = {
        .util_cb = timesync_onchannelcallback,
        .util_init = hv_timesync_init,
+       .util_pre_suspend = hv_timesync_pre_suspend,
        .util_deinit = hv_timesync_deinit,
 };
 
@@ -98,18 +142,24 @@ static struct hv_util_service util_heartbeat = {
 static struct hv_util_service util_kvp = {
        .util_cb = hv_kvp_onchannelcallback,
        .util_init = hv_kvp_init,
+       .util_pre_suspend = hv_kvp_pre_suspend,
+       .util_pre_resume = hv_kvp_pre_resume,
        .util_deinit = hv_kvp_deinit,
 };
 
 static struct hv_util_service util_vss = {
        .util_cb = hv_vss_onchannelcallback,
        .util_init = hv_vss_init,
+       .util_pre_suspend = hv_vss_pre_suspend,
+       .util_pre_resume = hv_vss_pre_resume,
        .util_deinit = hv_vss_deinit,
 };
 
 static struct hv_util_service util_fcopy = {
        .util_cb = hv_fcopy_onchannelcallback,
        .util_init = hv_fcopy_init,
+       .util_pre_suspend = hv_fcopy_pre_suspend,
+       .util_pre_resume = hv_fcopy_pre_resume,
        .util_deinit = hv_fcopy_deinit,
 };
 
@@ -118,17 +168,27 @@ static void perform_shutdown(struct work_struct *dummy)
        orderly_poweroff(true);
 }
 
+static void perform_restart(struct work_struct *dummy)
+{
+       orderly_reboot();
+}
+
 /*
  * Perform the shutdown operation in a thread context.
  */
 static DECLARE_WORK(shutdown_work, perform_shutdown);
 
+/*
+ * Perform the restart operation in a thread context.
+ */
+static DECLARE_WORK(restart_work, perform_restart);
+
 static void shutdown_onchannelcallback(void *context)
 {
        struct vmbus_channel *channel = context;
+       struct work_struct *work = NULL;
        u32 recvlen;
        u64 requestid;
-       bool execute_shutdown = false;
        u8  *shut_txf_buf = util_shutdown.recv_buffer;
 
        struct shutdown_msg_data *shutdown_msg;
@@ -157,19 +217,37 @@ static void shutdown_onchannelcallback(void *context)
                                        sizeof(struct vmbuspipe_hdr) +
                                        sizeof(struct icmsg_hdr)];
 
+                       /*
+                        * shutdown_msg->flags can be 0(shut down), 2(reboot),
+                        * or 4(hibernate). It may bitwise-OR 1, which means
+                        * performing the request by force. Linux always tries
+                        * to perform the request by force.
+                        */
                        switch (shutdown_msg->flags) {
                        case 0:
                        case 1:
                                icmsghdrp->status = HV_S_OK;
-                               execute_shutdown = true;
-
+                               work = &shutdown_work;
                                pr_info("Shutdown request received -"
                                            " graceful shutdown initiated\n");
                                break;
+                       case 2:
+                       case 3:
+                               icmsghdrp->status = HV_S_OK;
+                               work = &restart_work;
+                               pr_info("Restart request received -"
+                                           " graceful restart initiated\n");
+                               break;
+                       case 4:
+                       case 5:
+                               pr_info("Hibernation request received\n");
+                               icmsghdrp->status = hibernation_supported ?
+                                       HV_S_OK : HV_E_FAIL;
+                               if (hibernation_supported)
+                                       work = &hibernate_context.work;
+                               break;
                        default:
                                icmsghdrp->status = HV_E_FAIL;
-                               execute_shutdown = false;
-
                                pr_info("Shutdown request received -"
                                            " Invalid request\n");
                                break;
@@ -184,8 +262,8 @@ static void shutdown_onchannelcallback(void *context)
                                       VM_PKT_DATA_INBAND, 0);
        }
 
-       if (execute_shutdown == true)
-               schedule_work(&shutdown_work);
+       if (work)
+               schedule_work(work);
 }
 
 /*
@@ -441,6 +519,44 @@ static int util_remove(struct hv_device *dev)
        return 0;
 }
 
+/*
+ * When we're in util_suspend(), all the userspace processes have been frozen
+ * (refer to hibernate() -> freeze_processes()). The userspace is thawed only
+ * after the whole resume procedure, including util_resume(), finishes.
+ */
+static int util_suspend(struct hv_device *dev)
+{
+       struct hv_util_service *srv = hv_get_drvdata(dev);
+       int ret = 0;
+
+       if (srv->util_pre_suspend) {
+               ret = srv->util_pre_suspend();
+               if (ret)
+                       return ret;
+       }
+
+       vmbus_close(dev->channel);
+
+       return 0;
+}
+
+static int util_resume(struct hv_device *dev)
+{
+       struct hv_util_service *srv = hv_get_drvdata(dev);
+       int ret = 0;
+
+       if (srv->util_pre_resume) {
+               ret = srv->util_pre_resume();
+               if (ret)
+                       return ret;
+       }
+
+       ret = vmbus_open(dev->channel, 4 * HV_HYP_PAGE_SIZE,
+                        4 * HV_HYP_PAGE_SIZE, NULL, 0, srv->util_cb,
+                        dev->channel);
+       return ret;
+}
+
 static const struct hv_vmbus_device_id id_table[] = {
        /* Shutdown guid */
        { HV_SHUTDOWN_GUID,
@@ -477,6 +593,8 @@ static  struct hv_driver util_drv = {
        .id_table = id_table,
        .probe =  util_probe,
        .remove =  util_remove,
+       .suspend = util_suspend,
+       .resume =  util_resume,
        .driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
@@ -546,11 +664,23 @@ static int hv_timesync_init(struct hv_util_service *srv)
        return 0;
 }
 
+static void hv_timesync_cancel_work(void)
+{
+       cancel_work_sync(&adj_time_work);
+}
+
+static int hv_timesync_pre_suspend(void)
+{
+       hv_timesync_cancel_work();
+       return 0;
+}
+
 static void hv_timesync_deinit(void)
 {
        if (hv_ptp_clock)
                ptp_clock_unregister(hv_ptp_clock);
-       cancel_work_sync(&adj_time_work);
+
+       hv_timesync_cancel_work();
 }
 
 static int __init init_hyperv_utils(void)
index 20edcfd..f5fa3b3 100644 (file)
@@ -352,14 +352,20 @@ void vmbus_on_msg_dpc(unsigned long data);
 
 int hv_kvp_init(struct hv_util_service *srv);
 void hv_kvp_deinit(void);
+int hv_kvp_pre_suspend(void);
+int hv_kvp_pre_resume(void);
 void hv_kvp_onchannelcallback(void *context);
 
 int hv_vss_init(struct hv_util_service *srv);
 void hv_vss_deinit(void);
+int hv_vss_pre_suspend(void);
+int hv_vss_pre_resume(void);
 void hv_vss_onchannelcallback(void *context);
 
 int hv_fcopy_init(struct hv_util_service *srv);
 void hv_fcopy_deinit(void);
+int hv_fcopy_pre_suspend(void);
+int hv_fcopy_pre_resume(void);
 void hv_fcopy_onchannelcallback(void *context);
 void vmbus_initiate_unload(bool crash);
 
index 4ef5a66..029378c 100644 (file)
@@ -1033,6 +1033,10 @@ void vmbus_on_msg_dpc(unsigned long data)
        }
 
        entry = &channel_message_table[hdr->msgtype];
+
+       if (!entry->message_handler)
+               goto msg_handled;
+
        if (entry->handler_type == VMHT_BLOCKING) {
                ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC);
                if (ctx == NULL)
index 17583bf..d4c8300 100644 (file)
@@ -595,19 +595,18 @@ static int i8k_open_fs(struct inode *inode, struct file *file)
        return single_open(file, i8k_proc_show, NULL);
 }
 
-static const struct file_operations i8k_fops = {
-       .owner          = THIS_MODULE,
-       .open           = i8k_open_fs,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .unlocked_ioctl = i8k_ioctl,
+static const struct proc_ops i8k_proc_ops = {
+       .proc_open      = i8k_open_fs,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_ioctl     = i8k_ioctl,
 };
 
 static void __init i8k_init_procfs(void)
 {
        /* Register the proc entry */
-       proc_create("i8k", 0, NULL, &i8k_fops);
+       proc_create("i8k", 0, NULL, &i8k_proc_ops);
 }
 
 static void __exit i8k_exit_procfs(void)
index 8a7732c..286d3cf 100644 (file)
@@ -259,7 +259,7 @@ static int scmi_hwmon_probe(struct scmi_device *sdev)
 }
 
 static const struct scmi_device_id scmi_id_table[] = {
-       { SCMI_PROTOCOL_SENSOR },
+       { SCMI_PROTOCOL_SENSOR, "hwmon" },
        { },
 };
 MODULE_DEVICE_TABLE(scmi, scmi_id_table);
index 14e1a53..3b05560 100644 (file)
@@ -76,7 +76,6 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
        struct device_node *node = pdev->dev.of_node;
        struct hwspinlock_device *bank;
        struct hwspinlock *hwlock;
-       struct resource *res;
        void __iomem *io_base;
        int num_locks, i, ret;
        /* Only a single hwspinlock block device is supported */
@@ -85,13 +84,9 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
        if (!node)
                return -ENODEV;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!res)
-               return -ENODEV;
-
-       io_base = ioremap(res->start, resource_size(res));
-       if (!io_base)
-               return -ENOMEM;
+       io_base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(io_base))
+               return PTR_ERR(io_base);
 
        /*
         * make sure the module is enabled and clocked before reading
@@ -101,7 +96,7 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
        ret = pm_runtime_get_sync(&pdev->dev);
        if (ret < 0) {
                pm_runtime_put_noidle(&pdev->dev);
-               goto iounmap_base;
+               goto runtime_err;
        }
 
        /* Determine number of locks */
@@ -114,20 +109,21 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
         */
        ret = pm_runtime_put(&pdev->dev);
        if (ret < 0)
-               goto iounmap_base;
+               goto runtime_err;
 
        /* one of the four lsb's must be set, and nothing else */
        if (hweight_long(i & 0xf) != 1 || i > 8) {
                ret = -EINVAL;
-               goto iounmap_base;
+               goto runtime_err;
        }
 
        num_locks = i * 32; /* actual number of locks in this device */
 
-       bank = kzalloc(struct_size(bank, lock, num_locks), GFP_KERNEL);
+       bank = devm_kzalloc(&pdev->dev, struct_size(bank, lock, num_locks),
+                           GFP_KERNEL);
        if (!bank) {
                ret = -ENOMEM;
-               goto iounmap_base;
+               goto runtime_err;
        }
 
        platform_set_drvdata(pdev, bank);
@@ -138,25 +134,21 @@ static int omap_hwspinlock_probe(struct platform_device *pdev)
        ret = hwspin_lock_register(bank, &pdev->dev, &omap_hwspinlock_ops,
                                                base_id, num_locks);
        if (ret)
-               goto reg_fail;
+               goto runtime_err;
 
        dev_dbg(&pdev->dev, "Registered %d locks with HwSpinlock core\n",
                num_locks);
 
        return 0;
 
-reg_fail:
-       kfree(bank);
-iounmap_base:
+runtime_err:
        pm_runtime_disable(&pdev->dev);
-       iounmap(io_base);
        return ret;
 }
 
 static int omap_hwspinlock_remove(struct platform_device *pdev)
 {
        struct hwspinlock_device *bank = platform_get_drvdata(pdev);
-       void __iomem *io_base = bank->lock[0].priv - LOCK_BASE_OFFSET;
        int ret;
 
        ret = hwspin_lock_unregister(bank);
@@ -166,8 +158,6 @@ static int omap_hwspinlock_remove(struct platform_device *pdev)
        }
 
        pm_runtime_disable(&pdev->dev);
-       iounmap(io_base);
-       kfree(bank);
 
        return 0;
 }
index 6da7447..f0da544 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
-#include <linux/pm_runtime.h>
 #include <linux/regmap.h>
 
 #include "hwspinlock_internal.h"
@@ -122,35 +121,12 @@ static int qcom_hwspinlock_probe(struct platform_device *pdev)
                                                             regmap, field);
        }
 
-       pm_runtime_enable(&pdev->dev);
-
-       ret = hwspin_lock_register(bank, &pdev->dev, &qcom_hwspinlock_ops,
-                                  0, QCOM_MUTEX_NUM_LOCKS);
-       if (ret)
-               pm_runtime_disable(&pdev->dev);
-
-       return ret;
-}
-
-static int qcom_hwspinlock_remove(struct platform_device *pdev)
-{
-       struct hwspinlock_device *bank = platform_get_drvdata(pdev);
-       int ret;
-
-       ret = hwspin_lock_unregister(bank);
-       if (ret) {
-               dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
-               return ret;
-       }
-
-       pm_runtime_disable(&pdev->dev);
-
-       return 0;
+       return devm_hwspin_lock_register(&pdev->dev, bank, &qcom_hwspinlock_ops,
+                                        0, QCOM_MUTEX_NUM_LOCKS);
 }
 
 static struct platform_driver qcom_hwspinlock_driver = {
        .probe          = qcom_hwspinlock_probe,
-       .remove         = qcom_hwspinlock_remove,
        .driver         = {
                .name   = "qcom_hwspinlock",
                .of_match_table = qcom_hwspinlock_of_match,
index 1f625cd..823d3c4 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/module.h>
 #include <linux/device.h>
 #include <linux/io.h>
-#include <linux/pm_runtime.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/hwspinlock.h>
@@ -56,7 +55,7 @@ static int sirf_hwspinlock_probe(struct platform_device *pdev)
 {
        struct sirf_hwspinlock *hwspin;
        struct hwspinlock *hwlock;
-       int idx, ret;
+       int idx;
 
        if (!pdev->dev.of_node)
                return -ENODEV;
@@ -69,9 +68,9 @@ static int sirf_hwspinlock_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        /* retrieve io base */
-       hwspin->io_base = of_iomap(pdev->dev.of_node, 0);
-       if (!hwspin->io_base)
-               return -ENOMEM;
+       hwspin->io_base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(hwspin->io_base))
+               return PTR_ERR(hwspin->io_base);
 
        for (idx = 0; idx < HW_SPINLOCK_NUMBER; idx++) {
                hwlock = &hwspin->bank.lock[idx];
@@ -80,39 +79,9 @@ static int sirf_hwspinlock_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, hwspin);
 
-       pm_runtime_enable(&pdev->dev);
-
-       ret = hwspin_lock_register(&hwspin->bank, &pdev->dev,
-                                  &sirf_hwspinlock_ops, 0,
-                                  HW_SPINLOCK_NUMBER);
-       if (ret)
-               goto reg_failed;
-
-       return 0;
-
-reg_failed:
-       pm_runtime_disable(&pdev->dev);
-       iounmap(hwspin->io_base);
-
-       return ret;
-}
-
-static int sirf_hwspinlock_remove(struct platform_device *pdev)
-{
-       struct sirf_hwspinlock *hwspin = platform_get_drvdata(pdev);
-       int ret;
-
-       ret = hwspin_lock_unregister(&hwspin->bank);
-       if (ret) {
-               dev_err(&pdev->dev, "%s failed: %d\n", __func__, ret);
-               return ret;
-       }
-
-       pm_runtime_disable(&pdev->dev);
-
-       iounmap(hwspin->io_base);
-
-       return 0;
+       return devm_hwspin_lock_register(&pdev->dev, &hwspin->bank,
+                                        &sirf_hwspinlock_ops, 0,
+                                        HW_SPINLOCK_NUMBER);
 }
 
 static const struct of_device_id sirf_hwpinlock_ids[] = {
@@ -123,7 +92,6 @@ MODULE_DEVICE_TABLE(of, sirf_hwpinlock_ids);
 
 static struct platform_driver sirf_hwspinlock_driver = {
        .probe = sirf_hwspinlock_probe,
-       .remove = sirf_hwspinlock_remove,
        .driver = {
                .name = "atlas7_hwspinlock",
                .of_match_table = of_match_ptr(sirf_hwpinlock_ids),
index c8eacf4..3ad0ce0 100644 (file)
@@ -58,12 +58,10 @@ static int stm32_hwspinlock_probe(struct platform_device *pdev)
 {
        struct stm32_hwspinlock *hw;
        void __iomem *io_base;
-       struct resource *res;
        size_t array_size;
        int i, ret;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       io_base = devm_ioremap_resource(&pdev->dev, res);
+       io_base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(io_base))
                return PTR_ERR(io_base);
 
index 6a0aa76..2ddca08 100644 (file)
@@ -367,7 +367,8 @@ comment "I2C system bus drivers (mostly embedded / system-on-chip)"
 
 config I2C_ALTERA
        tristate "Altera Soft IP I2C"
-       depends on (ARCH_SOCFPGA || NIOS2) && OF
+       depends on ARCH_SOCFPGA || NIOS2 || COMPILE_TEST
+       depends on OF
        help
          If you say yes to this option, support will be included for the
          Altera Soft IP I2C interfaces on SoCFPGA and Nios2 architectures.
@@ -387,7 +388,7 @@ config I2C_ASPEED
 
 config I2C_AT91
        tristate "Atmel AT91 I2C Two-Wire interface (TWI)"
-       depends on ARCH_AT91
+       depends on ARCH_AT91 || COMPILE_TEST
        help
          This supports the use of the I2C interface on Atmel AT91
          processors.
@@ -440,7 +441,8 @@ config I2C_AXXIA
 
 config I2C_BCM2835
        tristate "Broadcom BCM2835 I2C controller"
-       depends on ARCH_BCM2835 || ARCH_BRCMSTB
+       depends on ARCH_BCM2835 || ARCH_BRCMSTB || COMPILE_TEST
+       depends on COMMON_CLK
        help
          If you say yes to this option, support will be included for the
          BCM2835 I2C controller.
@@ -463,8 +465,8 @@ config I2C_BCM_IPROC
 
 config I2C_BCM_KONA
        tristate "BCM Kona I2C adapter"
-       depends on ARCH_BCM_MOBILE
-       default y
+       depends on ARCH_BCM_MOBILE || COMPILE_TEST
+       default y if ARCH_BCM_MOBILE
        help
          If you say yes to this option, support will be included for the
          I2C interface on the Broadcom Kona family of processors.
@@ -511,7 +513,7 @@ config I2C_CPM
 
 config I2C_DAVINCI
        tristate "DaVinci I2C driver"
-       depends on ARCH_DAVINCI || ARCH_KEYSTONE
+       depends on ARCH_DAVINCI || ARCH_KEYSTONE || COMPILE_TEST
        help
          Support for TI DaVinci I2C controller driver.
 
@@ -572,7 +574,7 @@ config I2C_DESIGNWARE_BAYTRAIL
 
 config I2C_DIGICOLOR
        tristate "Conexant Digicolor I2C driver"
-       depends on ARCH_DIGICOLOR
+       depends on ARCH_DIGICOLOR || COMPILE_TEST
        help
          Support for Conexant Digicolor SoCs (CX92755) I2C controller driver.
 
@@ -610,11 +612,12 @@ config I2C_EMEV2
          I2C interface on the Renesas Electronics EM/EV family of processors.
 
 config I2C_EXYNOS5
-       tristate "Exynos5 high-speed I2C driver"
-       depends on ARCH_EXYNOS && OF
-       default y
+       tristate "Exynos high-speed I2C driver"
+       depends on OF
+       depends on ARCH_EXYNOS || COMPILE_TEST
+       default y if ARCH_EXYNOS
        help
-         High-speed I2C controller on Exynos5 based Samsung SoCs.
+         High-speed I2C controller on Exynos5 and newer Samsung SoCs.
 
 config I2C_GPIO
        tristate "GPIO-based bitbanging I2C"
@@ -634,7 +637,7 @@ config I2C_GPIO_FAULT_INJECTOR
 
 config I2C_HIGHLANDER
        tristate "Highlander FPGA SMBus interface"
-       depends on SH_HIGHLANDER
+       depends on SH_HIGHLANDER || COMPILE_TEST
        help
          If you say yes to this option, support will be included for
          the SMBus interface located in the FPGA on various Highlander
@@ -686,7 +689,7 @@ config I2C_IMX_LPI2C
 
 config I2C_IOP3XX
        tristate "Intel IOPx3xx and IXP4xx on-chip I2C interface"
-       depends on ARCH_IOP32X || ARCH_IXP4XX
+       depends on ARCH_IOP32X || ARCH_IXP4XX || COMPILE_TEST
        help
          Say Y here if you want to use the IIC bus controller on
          the Intel IOPx3xx I/O Processors or IXP4xx Network Processors.
@@ -726,6 +729,7 @@ config I2C_LPC2K
 config I2C_MESON
        tristate "Amlogic Meson I2C controller"
        depends on ARCH_MESON || COMPILE_TEST
+       depends on COMMON_CLK
        help
          If you say yes to this option, support will be included for the
          I2C interface on the Amlogic Meson family of SoCs.
@@ -759,7 +763,7 @@ config I2C_MT7621
 
 config I2C_MV64XXX
        tristate "Marvell mv64xxx I2C Controller"
-       depends on MV64X60 || PLAT_ORION || ARCH_SUNXI || ARCH_MVEBU
+       depends on MV64X60 || PLAT_ORION || ARCH_SUNXI || ARCH_MVEBU || COMPILE_TEST
        help
          If you say yes to this option, support will be included for the
          built-in I2C interface on the Marvell 64xxx line of host bridges.
@@ -770,7 +774,7 @@ config I2C_MV64XXX
 
 config I2C_MXS
        tristate "Freescale i.MX28 I2C interface"
-       depends on SOC_IMX28
+       depends on SOC_IMX28 || COMPILE_TEST
        select STMP_DEVICE
        help
          Say Y here if you want to use the I2C bus controller on
@@ -799,7 +803,7 @@ config I2C_OCORES
 
 config I2C_OMAP
        tristate "OMAP I2C adapter"
-       depends on ARCH_OMAP || ARCH_K3
+       depends on ARCH_OMAP || ARCH_K3 || COMPILE_TEST
        default y if MACH_OMAP_H3 || MACH_OMAP_OSK
        help
          If you say yes to this option, support will be included for the
@@ -833,7 +837,7 @@ config I2C_PCA_PLATFORM
 
 config I2C_PMCMSP
        tristate "PMC MSP I2C TWI Controller"
-       depends on PMC_MSP
+       depends on PMC_MSP || COMPILE_TEST
        help
          This driver supports the PMC TWI controller on MSP devices.
 
@@ -842,7 +846,7 @@ config I2C_PMCMSP
 
 config I2C_PNX
        tristate "I2C bus support for Philips PNX and NXP LPC targets"
-       depends on ARCH_LPC32XX
+       depends on ARCH_LPC32XX || COMPILE_TEST
        help
          This driver supports the Philips IP3204 I2C IP block master and/or
          slave controller
@@ -863,7 +867,7 @@ config I2C_PUV3
 
 config I2C_PXA
        tristate "Intel PXA2XX I2C adapter"
-       depends on ARCH_PXA || ARCH_MMP || ARCH_MVEBU || (X86_32 && PCI && OF)
+       depends on ARCH_PXA || ARCH_MMP || ARCH_MVEBU || (X86_32 && PCI && OF) || COMPILE_TEST
        help
          If you have devices in the PXA I2C bus, say yes to this option.
          This driver can also be built as a module.  If so, the module
@@ -932,11 +936,11 @@ config HAVE_S3C2410_I2C
          respective Kconfig file.
 
 config I2C_S3C2410
-       tristate "S3C2410 I2C Driver"
-       depends on HAVE_S3C2410_I2C
+       tristate "S3C/Exynos I2C Driver"
+       depends on HAVE_S3C2410_I2C || COMPILE_TEST
        help
          Say Y here to include support for I2C controller in the
-         Samsung SoCs.
+         Samsung SoCs (S3C, S5Pv210, Exynos).
 
 config I2C_SH7760
        tristate "Renesas SH7760 I2C Controller"
@@ -971,7 +975,7 @@ config I2C_SIMTEC
 
 config I2C_SIRF
        tristate "CSR SiRFprimaII I2C interface"
-       depends on ARCH_SIRF
+       depends on ARCH_SIRF || COMPILE_TEST
        help
          If you say yes to this option, support will be included for the
          CSR SiRFprimaII I2C interface.
@@ -981,14 +985,14 @@ config I2C_SIRF
 
 config I2C_SPRD
        tristate "Spreadtrum I2C interface"
-       depends on I2C=y && ARCH_SPRD
+       depends on I2C=y && (ARCH_SPRD || COMPILE_TEST)
        help
          If you say yes to this option, support will be included for the
          Spreadtrum I2C interface.
 
 config I2C_ST
        tristate "STMicroelectronics SSC I2C support"
-       depends on ARCH_STI
+       depends on ARCH_STI || COMPILE_TEST
        help
          Enable this option to add support for STMicroelectronics SoCs
          hardware SSC (Synchronous Serial Controller) as an I2C controller.
@@ -1019,7 +1023,7 @@ config I2C_STM32F7
 
 config I2C_STU300
        tristate "ST Microelectronics DDC I2C interface"
-       depends on MACH_U300
+       depends on MACH_U300 || COMPILE_TEST
        default y if MACH_U300
        help
          If you say yes to this option, support will be included for the
@@ -1055,15 +1059,16 @@ config I2C_SYNQUACER
 
 config I2C_TEGRA
        tristate "NVIDIA Tegra internal I2C controller"
-       depends on ARCH_TEGRA
+       depends on ARCH_TEGRA || (COMPILE_TEST && (ARC || ARM || ARM64 || M68K || RISCV || SUPERH || SPARC))
+       # COMPILE_TEST needs architectures with readsX()/writesX() primitives
        help
          If you say yes to this option, support will be included for the
          I2C controller embedded in NVIDIA Tegra SOCs
 
 config I2C_TEGRA_BPMP
        tristate "NVIDIA Tegra BPMP I2C controller"
-       depends on TEGRA_BPMP
-       default y
+       depends on TEGRA_BPMP || COMPILE_TEST
+       default y if TEGRA_BPMP
        help
          If you say yes to this option, support will be included for the I2C
          controller embedded in NVIDIA Tegra SoCs accessed via the BPMP.
@@ -1101,7 +1106,7 @@ config I2C_VERSATILE
 
 config I2C_WMT
        tristate "Wondermedia WM8xxx SoC I2C bus support"
-       depends on ARCH_VT8500
+       depends on ARCH_VT8500 || COMPILE_TEST
        help
          Say yes if you want to support the I2C bus on Wondermedia 8xxx-series
          SoCs.
@@ -1142,7 +1147,7 @@ config I2C_XILINX
 
 config I2C_XLR
        tristate "Netlogic XLR and Sigma Designs I2C support"
-       depends on CPU_XLR || ARCH_TANGO
+       depends on CPU_XLR || ARCH_TANGO || COMPILE_TEST
        help
          This driver enables support for the on-chip I2C interface of
          the Netlogic XLR/XLS MIPS processors and Sigma Designs SOCs.
@@ -1202,46 +1207,12 @@ config I2C_PARPORT
          This supports parallel port I2C adapters such as the ones made by
          Philips or Velleman, Analog Devices evaluation boards, and more.
          Basically any adapter using the parallel port as an I2C bus with
-         no extra chipset is supported by this driver, or could be.
-
-         This driver is a replacement for (and was inspired by) an older
-         driver named i2c-philips-par.  The new driver supports more devices,
-         and makes it easier to add support for new devices.
-
-         An adapter type parameter is now mandatory.  Please read the file
-         Documentation/i2c/busses/i2c-parport.rst for details.
-
-         Another driver exists, named i2c-parport-light, which doesn't depend
-         on the parport driver.  This is meant for embedded systems. Don't say
-         Y here if you intend to say Y or M there.
+         no extra chipset is supported by this driver, or could be. Please
+         read the file Documentation/i2c/busses/i2c-parport.rst for details.
 
          This support is also available as a module.  If so, the module
          will be called i2c-parport.
 
-config I2C_PARPORT_LIGHT
-       tristate "Parallel port adapter (light)"
-       select I2C_ALGOBIT
-       select I2C_SMBUS
-       help
-         This supports parallel port I2C adapters such as the ones made by
-         Philips or Velleman, Analog Devices evaluation boards, and more.
-         Basically any adapter using the parallel port as an I2C bus with
-         no extra chipset is supported by this driver, or could be.
-
-         This driver is a light version of i2c-parport.  It doesn't depend
-         on the parport driver, and uses direct I/O access instead.  This
-         might be preferred on embedded systems where wasting memory for
-         the clean but heavy parport handling is not an option.  The
-         drawback is a reduced portability and the impossibility to
-         daisy-chain other parallel port devices.
-
-         Don't say Y here if you said Y or M to i2c-parport.  Saying M to
-         both is possible but both modules should not be loaded at the same
-         time.
-
-         This support is also available as a module.  If so, the module
-         will be called i2c-parport-light.
-
 config I2C_ROBOTFUZZ_OSIF
        tristate "RobotFuzz Open Source InterFace USB adapter"
        depends on USB
@@ -1328,7 +1299,7 @@ config I2C_ICY
 
 config I2C_MLXCPLD
        tristate "Mellanox I2C driver"
-       depends on X86_64
+       depends on X86_64 || COMPILE_TEST
        help
          This exposes the Mellanox platform I2C busses to the linux I2C layer
          for X86 based systems.
index 3ab8aeb..25d6088 100644 (file)
@@ -128,7 +128,6 @@ obj-$(CONFIG_I2C_ZX2967)    += i2c-zx2967.o
 obj-$(CONFIG_I2C_DIOLAN_U2C)   += i2c-diolan-u2c.o
 obj-$(CONFIG_I2C_DLN2)         += i2c-dln2.o
 obj-$(CONFIG_I2C_PARPORT)      += i2c-parport.o
-obj-$(CONFIG_I2C_PARPORT_LIGHT)        += i2c-parport-light.o
 obj-$(CONFIG_I2C_ROBOTFUZZ_OSIF)       += i2c-robotfuzz-osif.o
 obj-$(CONFIG_I2C_TAOS_EVM)     += i2c-taos-evm.o
 obj-$(CONFIG_I2C_TINY_USB)     += i2c-tiny-usb.o
index 5137e62..3da1a8a 100644 (file)
@@ -66,55 +66,26 @@ static struct at91_twi_pdata at91rm9200_config = {
        .clk_max_div = 5,
        .clk_offset = 3,
        .has_unre_flag = true,
-       .has_alt_cmd = false,
-       .has_hold_field = false,
-       .has_dig_filtr = false,
-       .has_adv_dig_filtr = false,
-       .has_ana_filtr = false,
 };
 
 static struct at91_twi_pdata at91sam9261_config = {
        .clk_max_div = 5,
        .clk_offset = 4,
-       .has_unre_flag = false,
-       .has_alt_cmd = false,
-       .has_hold_field = false,
-       .has_dig_filtr = false,
-       .has_adv_dig_filtr = false,
-       .has_ana_filtr = false,
 };
 
 static struct at91_twi_pdata at91sam9260_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
-       .has_unre_flag = false,
-       .has_alt_cmd = false,
-       .has_hold_field = false,
-       .has_dig_filtr = false,
-       .has_adv_dig_filtr = false,
-       .has_ana_filtr = false,
 };
 
 static struct at91_twi_pdata at91sam9g20_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
-       .has_unre_flag = false,
-       .has_alt_cmd = false,
-       .has_hold_field = false,
-       .has_dig_filtr = false,
-       .has_adv_dig_filtr = false,
-       .has_ana_filtr = false,
 };
 
 static struct at91_twi_pdata at91sam9g10_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
-       .has_unre_flag = false,
-       .has_alt_cmd = false,
-       .has_hold_field = false,
-       .has_dig_filtr = false,
-       .has_adv_dig_filtr = false,
-       .has_ana_filtr = false,
 };
 
 static const struct platform_device_id at91_twi_devtypes[] = {
@@ -142,23 +113,13 @@ static const struct platform_device_id at91_twi_devtypes[] = {
 static struct at91_twi_pdata at91sam9x5_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
-       .has_unre_flag = false,
-       .has_alt_cmd = false,
-       .has_hold_field = false,
-       .has_dig_filtr = false,
-       .has_adv_dig_filtr = false,
-       .has_ana_filtr = false,
 };
 
 static struct at91_twi_pdata sama5d4_config = {
        .clk_max_div = 7,
        .clk_offset = 4,
-       .has_unre_flag = false,
-       .has_alt_cmd = false,
        .has_hold_field = true,
        .has_dig_filtr = true,
-       .has_adv_dig_filtr = false,
-       .has_ana_filtr = false,
 };
 
 static struct at91_twi_pdata sama5d2_config = {
index 9d71ce1..1105aee 100644 (file)
@@ -208,6 +208,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
 
        isr_status = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET);
        cdns_i2c_writereg(isr_status, CDNS_I2C_ISR_OFFSET);
+       id->err_status = 0;
 
        /* Handling nack and arbitration lost interrupt */
        if (isr_status & (CDNS_I2C_IXR_NACK | CDNS_I2C_IXR_ARB_LOST)) {
@@ -241,10 +242,17 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
                            !id->bus_hold_flag)
                                cdns_i2c_clear_bus_hold(id);
 
-                       *(id->p_recv_buf)++ =
-                               cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET);
-                       id->recv_count--;
-                       id->curr_recv_count--;
+                       if (id->recv_count > 0) {
+                               *(id->p_recv_buf)++ =
+                                       cdns_i2c_readreg(CDNS_I2C_DATA_OFFSET);
+                               id->recv_count--;
+                               id->curr_recv_count--;
+                       } else {
+                               dev_err(id->adap.dev.parent,
+                                       "xfer_size reg rollover. xfer aborted!\n");
+                               id->err_status |= CDNS_I2C_IXR_TO;
+                               break;
+                       }
 
                        if (cdns_is_holdquirk(id, hold_quirk))
                                break;
@@ -342,7 +350,7 @@ static irqreturn_t cdns_i2c_isr(int irq, void *ptr)
        }
 
        /* Update the status for errors */
-       id->err_status = isr_status & CDNS_I2C_IXR_ERR_INTR_MASK;
+       id->err_status |= isr_status & CDNS_I2C_IXR_ERR_INTR_MASK;
        if (id->err_status)
                status = IRQ_HANDLED;
 
@@ -500,7 +508,7 @@ static void cdns_i2c_master_reset(struct i2c_adapter *adap)
        cdns_i2c_writereg(regval, CDNS_I2C_CR_OFFSET);
        /* Update the transfercount register to zero */
        cdns_i2c_writereg(0, CDNS_I2C_XFER_SIZE_OFFSET);
-       /* Clear the interupt status register */
+       /* Clear the interrupt status register */
        regval = cdns_i2c_readreg(CDNS_I2C_ISR_OFFSET);
        cdns_i2c_writereg(regval, CDNS_I2C_ISR_OFFSET);
        /* Clear the status register */
@@ -921,17 +929,18 @@ static int cdns_i2c_probe(struct platform_device *pdev)
 
        id->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(id->clk)) {
-               dev_err(&pdev->dev, "input clock not found.\n");
+               if (PTR_ERR(id->clk) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "input clock not found.\n");
                return PTR_ERR(id->clk);
        }
        ret = clk_prepare_enable(id->clk);
        if (ret)
                dev_err(&pdev->dev, "Unable to enable clock.\n");
 
-       pm_runtime_enable(id->dev);
        pm_runtime_set_autosuspend_delay(id->dev, CNDS_I2C_PM_TIMEOUT);
        pm_runtime_use_autosuspend(id->dev);
        pm_runtime_set_active(id->dev);
+       pm_runtime_enable(id->dev);
 
        id->clk_rate_change_nb.notifier_call = cdns_i2c_clk_notifier_cb;
        if (clk_notifier_register(id->clk, &id->clk_rate_change_nb))
@@ -980,8 +989,8 @@ static int cdns_i2c_probe(struct platform_device *pdev)
 
 err_clk_dis:
        clk_disable_unprepare(id->clk);
-       pm_runtime_set_suspended(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
        return ret;
 }
 
@@ -997,10 +1006,13 @@ static int cdns_i2c_remove(struct platform_device *pdev)
 {
        struct cdns_i2c *id = platform_get_drvdata(pdev);
 
+       pm_runtime_disable(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
+
        i2c_del_adapter(&id->adap);
        clk_notifier_unregister(id->clk, &id->clk_rate_change_nb);
        clk_disable_unprepare(id->clk);
-       pm_runtime_disable(&pdev->dev);
 
        return 0;
 }
index b8fde61..35e55fe 100644 (file)
@@ -388,9 +388,9 @@ static int cht_wc_i2c_adap_i2c_probe(struct platform_device *pdev)
         */
        if (acpi_dev_present("INT33FE", NULL, -1)) {
                board_info.irq = adap->client_irq;
-               adap->client = i2c_new_device(&adap->adapter, &board_info);
-               if (!adap->client) {
-                       ret = -ENOMEM;
+               adap->client = i2c_new_client_device(&adap->adapter, &board_info);
+               if (IS_ERR(adap->client)) {
+                       ret = PTR_ERR(adap->client);
                        goto del_adapter;
                }
        }
index 958161c..790ea3f 100644 (file)
@@ -273,6 +273,7 @@ static int ec_i2c_probe(struct platform_device *pdev)
        bus->adap.dev.parent = &pdev->dev;
        bus->adap.dev.of_node = pdev->dev.of_node;
        bus->adap.retries = I2C_MAX_RETRIES;
+       ACPI_COMPANION_SET(&bus->adap.dev, ACPI_COMPANION(&pdev->dev));
 
        err = i2c_add_adapter(&bus->adap);
        if (err)
@@ -298,7 +299,7 @@ static const struct of_device_id cros_ec_i2c_of_match[] = {
 MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match);
 
 static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] = {
-       { "GOOG001A", 0 },
+       { "GOOG0012", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_tunnel_acpi_id);
index 16dd338..3b7d58c 100644 (file)
@@ -130,6 +130,7 @@ static const struct acpi_device_id dw_i2c_acpi_match[] = {
        { "APMC0D0F", 0 },
        { "HISI02A1", 0 },
        { "HISI02A2", 0 },
+       { "HISI02A3", 0 },
        { }
 };
 MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
index abfe309..803dad7 100644 (file)
@@ -322,7 +322,7 @@ static int highlander_i2c_smbus_xfer(struct i2c_adapter *adap, u16 addr,
                tmp |= (SMMR_MODE0 | SMMR_MODE1);
                break;
        default:
-               dev_err(dev->dev, "unsupported xfer size %d\n", dev->buf_len);
+               dev_err(dev->dev, "unsupported xfer size %zu\n", dev->buf_len);
                return -EINVAL;
        }
 
index f5e69fe..ca4f096 100644 (file)
@@ -68,6 +68,7 @@
  * Elkhart Lake (PCH)          0x4b23  32      hard    yes     yes     yes
  * Tiger Lake-LP (PCH)         0xa0a3  32      hard    yes     yes     yes
  * Jasper Lake (SOC)           0x4da3  32      hard    yes     yes     yes
+ * Comet Lake-V (PCH)          0xa3a3  32      hard    yes     yes     yes
  *
  * Features supported by this driver:
  * Software PEC                                no
 #define PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS       0xa223
 #define PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS       0xa2a3
 #define PCI_DEVICE_ID_INTEL_CANNONLAKE_H_SMBUS         0xa323
+#define PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS          0xa3a3
 
 struct i801_mux_config {
        char *gpio_chip;
@@ -1074,6 +1076,7 @@ static const struct pci_device_id i801_ids[] = {
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICELAKE_LP_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_H_SMBUS) },
+       { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ELKHART_LAKE_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_TIGERLAKE_LP_SMBUS) },
        { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_JASPER_LAKE_SMBUS) },
@@ -1142,7 +1145,7 @@ static void dmi_check_onboard_device(u8 type, const char *name,
                memset(&info, 0, sizeof(struct i2c_board_info));
                info.addr = dmi_devices[i].i2c_addr;
                strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
-               i2c_new_device(adap, &info);
+               i2c_new_client_device(adap, &info);
                break;
        }
 }
@@ -1296,7 +1299,7 @@ static void register_dell_lis3lv02d_i2c_device(struct i801_priv *priv)
        memset(&info, 0, sizeof(struct i2c_board_info));
        info.addr = dell_lis3lv02d_devices[i].i2c_addr;
        strlcpy(info.type, "lis3lv02d", I2C_NAME_SIZE);
-       i2c_new_device(&priv->adapter, &info);
+       i2c_new_client_device(&priv->adapter, &info);
 }
 
 /* Register optional slaves */
@@ -1312,7 +1315,7 @@ static void i801_probe_optional_slaves(struct i801_priv *priv)
                memset(&info, 0, sizeof(struct i2c_board_info));
                info.addr = apanel_addr;
                strlcpy(info.type, "fujitsu_apanel", I2C_NAME_SIZE);
-               i2c_new_device(&priv->adapter, &info);
+               i2c_new_client_device(&priv->adapter, &info);
        }
 
        if (dmi_name_in_vendors("FUJITSU"))
@@ -1742,6 +1745,7 @@ static int i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
        case PCI_DEVICE_ID_INTEL_LEWISBURG_SSKU_SMBUS:
        case PCI_DEVICE_ID_INTEL_DNV_SMBUS:
        case PCI_DEVICE_ID_INTEL_KABYLAKE_PCH_H_SMBUS:
+       case PCI_DEVICE_ID_INTEL_COMETLAKE_V_SMBUS:
                priv->features |= FEATURE_BLOCK_PROC;
                priv->features |= FEATURE_I2C_BLOCK_READ;
                priv->features |= FEATURE_IRQ;
index 25dcd73..16a67a6 100644 (file)
@@ -4,6 +4,7 @@
  *
  * Copyright (C) 2006 - 2009 Ingenic Semiconductor Inc.
  * Copyright (C) 2015 Imagination Technologies
+ * Copyright (C) 2019 周琰杰 (Zhou Yanjie) <zhouyanjie@wanyeetech.com>
  */
 
 #include <linux/bitops.h>
@@ -17,6 +18,7 @@
 #include <linux/io.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -55,6 +57,7 @@
 #define JZ4780_I2C_ACKGC       0x98
 #define JZ4780_I2C_ENSTA       0x9C
 #define JZ4780_I2C_SDAHD       0xD0
+#define X1000_I2C_SDAHD                0x7C
 
 #define JZ4780_I2C_CTRL_STPHLD         BIT(7)
 #define JZ4780_I2C_CTRL_SLVDIS         BIT(6)
@@ -73,6 +76,8 @@
 #define JZ4780_I2C_STA_TFNF            BIT(1)
 #define JZ4780_I2C_STA_ACT             BIT(0)
 
+#define X1000_I2C_DC_STOP              BIT(9)
+
 static const char * const jz4780_i2c_abrt_src[] = {
        "ABRT_7B_ADDR_NOACK",
        "ABRT_10ADDR1_NOACK",
@@ -130,18 +135,33 @@ static const char * const jz4780_i2c_abrt_src[] = {
 #define JZ4780_I2CFLCNT_ADJUST(n)      (((n) - 1) < 8 ? 8 : ((n) - 1))
 
 #define JZ4780_I2C_FIFO_LEN    16
-#define TX_LEVEL               3
-#define RX_LEVEL               (JZ4780_I2C_FIFO_LEN - TX_LEVEL - 1)
+
+#define X1000_I2C_FIFO_LEN     64
 
 #define JZ4780_I2C_TIMEOUT     300
 
 #define BUFSIZE 200
 
+enum ingenic_i2c_version {
+       ID_JZ4780,
+       ID_X1000,
+};
+
+/* ingenic_i2c_config: SoC specific config data. */
+struct ingenic_i2c_config {
+       enum ingenic_i2c_version version;
+
+       int fifosize;
+       int tx_level;
+       int rx_level;
+};
+
 struct jz4780_i2c {
        void __iomem            *iomem;
        int                      irq;
        struct clk              *clk;
        struct i2c_adapter       adap;
+       const struct ingenic_i2c_config *cdata;
 
        /* lock to protect rbuf and wbuf between xfer_rd/wr and irq handler */
        spinlock_t              lock;
@@ -340,11 +360,18 @@ static int jz4780_i2c_set_speed(struct jz4780_i2c *i2c)
 
        if (hold_time >= 0) {
                /*i2c hold time enable */
-               hold_time |= JZ4780_I2C_SDAHD_HDENB;
-               jz4780_i2c_writew(i2c, JZ4780_I2C_SDAHD, hold_time);
+               if (i2c->cdata->version >= ID_X1000) {
+                       jz4780_i2c_writew(i2c, X1000_I2C_SDAHD, hold_time);
+               } else {
+                       hold_time |= JZ4780_I2C_SDAHD_HDENB;
+                       jz4780_i2c_writew(i2c, JZ4780_I2C_SDAHD, hold_time);
+               }
        } else {
                /* disable hold time */
-               jz4780_i2c_writew(i2c, JZ4780_I2C_SDAHD, 0);
+               if (i2c->cdata->version >= ID_X1000)
+                       jz4780_i2c_writew(i2c, X1000_I2C_SDAHD, 0);
+               else
+                       jz4780_i2c_writew(i2c, JZ4780_I2C_SDAHD, 0);
        }
 
        return 0;
@@ -359,9 +386,11 @@ static int jz4780_i2c_cleanup(struct jz4780_i2c *i2c)
        spin_lock_irqsave(&i2c->lock, flags);
 
        /* can send stop now if need */
-       tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
-       tmp &= ~JZ4780_I2C_CTRL_STPHLD;
-       jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+       if (i2c->cdata->version < ID_X1000) {
+               tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
+               tmp &= ~JZ4780_I2C_CTRL_STPHLD;
+               jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+       }
 
        /* disable all interrupts first */
        jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0);
@@ -399,11 +428,19 @@ static int jz4780_i2c_prepare(struct jz4780_i2c *i2c)
        return jz4780_i2c_enable(i2c);
 }
 
-static void jz4780_i2c_send_rcmd(struct jz4780_i2c *i2c, int cmd_count)
+static void jz4780_i2c_send_rcmd(struct jz4780_i2c *i2c,
+                                                                int cmd_count,
+                                                                int cmd_left)
 {
        int i;
 
-       for (i = 0; i < cmd_count; i++)
+       for (i = 0; i < cmd_count - 1; i++)
+               jz4780_i2c_writew(i2c, JZ4780_I2C_DC, JZ4780_I2C_DC_READ);
+
+       if ((cmd_left == 0) && (i2c->cdata->version >= ID_X1000))
+               jz4780_i2c_writew(i2c, JZ4780_I2C_DC,
+                               JZ4780_I2C_DC_READ | X1000_I2C_DC_STOP);
+       else
                jz4780_i2c_writew(i2c, JZ4780_I2C_DC, JZ4780_I2C_DC_READ);
 }
 
@@ -458,37 +495,44 @@ static irqreturn_t jz4780_i2c_irq(int irqno, void *dev_id)
 
                rd_left = i2c->rd_total_len - i2c->rd_data_xfered;
 
-               if (rd_left <= JZ4780_I2C_FIFO_LEN)
+               if (rd_left <= i2c->cdata->fifosize)
                        jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, rd_left - 1);
        }
 
        if (intst & JZ4780_I2C_INTST_TXEMP) {
                if (i2c->is_write == 0) {
                        int cmd_left = i2c->rd_total_len - i2c->rd_cmd_xfered;
-                       int max_send = (JZ4780_I2C_FIFO_LEN - 1)
+                       int max_send = (i2c->cdata->fifosize - 1)
                                         - (i2c->rd_cmd_xfered
                                         - i2c->rd_data_xfered);
                        int cmd_to_send = min(cmd_left, max_send);
 
                        if (i2c->rd_cmd_xfered != 0)
                                cmd_to_send = min(cmd_to_send,
-                                                 JZ4780_I2C_FIFO_LEN
-                                                 - TX_LEVEL - 1);
+                                                 i2c->cdata->fifosize
+                                                 - i2c->cdata->tx_level - 1);
 
                        if (cmd_to_send) {
-                               jz4780_i2c_send_rcmd(i2c, cmd_to_send);
                                i2c->rd_cmd_xfered += cmd_to_send;
+                               cmd_left = i2c->rd_total_len -
+                                               i2c->rd_cmd_xfered;
+                               jz4780_i2c_send_rcmd(i2c,
+                                               cmd_to_send, cmd_left);
+
                        }
 
-                       cmd_left = i2c->rd_total_len - i2c->rd_cmd_xfered;
                        if (cmd_left == 0) {
                                intmsk = jz4780_i2c_readw(i2c, JZ4780_I2C_INTM);
                                intmsk &= ~JZ4780_I2C_INTM_MTXEMP;
                                jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, intmsk);
 
-                               tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
-                               tmp &= ~JZ4780_I2C_CTRL_STPHLD;
-                               jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+                               if (i2c->cdata->version < ID_X1000) {
+                                       tmp = jz4780_i2c_readw(i2c,
+                                                       JZ4780_I2C_CTRL);
+                                       tmp &= ~JZ4780_I2C_CTRL_STPHLD;
+                                       jz4780_i2c_writew(i2c,
+                                                       JZ4780_I2C_CTRL, tmp);
+                               }
                        }
                } else {
                        unsigned short data;
@@ -497,23 +541,26 @@ static irqreturn_t jz4780_i2c_irq(int irqno, void *dev_id)
                        i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA);
 
                        while ((i2c_sta & JZ4780_I2C_STA_TFNF) &&
-                              (i2c->wt_len > 0)) {
+                                       (i2c->wt_len > 0)) {
                                i2c_sta = jz4780_i2c_readw(i2c, JZ4780_I2C_STA);
                                data = *i2c->wbuf;
                                data &= ~JZ4780_I2C_DC_READ;
-                               jz4780_i2c_writew(i2c, JZ4780_I2C_DC,
-                                                 data);
+                               if ((!i2c->stop_hold) && (i2c->cdata->version >=
+                                               ID_X1000))
+                                       data |= X1000_I2C_DC_STOP;
+                               jz4780_i2c_writew(i2c, JZ4780_I2C_DC, data);
                                i2c->wbuf++;
                                i2c->wt_len--;
                        }
 
                        if (i2c->wt_len == 0) {
-                               if (!i2c->stop_hold) {
+                               if ((!i2c->stop_hold) && (i2c->cdata->version <
+                                               ID_X1000)) {
                                        tmp = jz4780_i2c_readw(i2c,
-                                                              JZ4780_I2C_CTRL);
+                                                       JZ4780_I2C_CTRL);
                                        tmp &= ~JZ4780_I2C_CTRL_STPHLD;
-                                       jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL,
-                                                         tmp);
+                                       jz4780_i2c_writew(i2c,
+                                                       JZ4780_I2C_CTRL, tmp);
                                }
 
                                jz4780_i2c_trans_done(i2c);
@@ -567,20 +614,22 @@ static inline int jz4780_i2c_xfer_read(struct jz4780_i2c *i2c,
        i2c->rd_data_xfered = 0;
        i2c->rd_cmd_xfered = 0;
 
-       if (len <= JZ4780_I2C_FIFO_LEN)
+       if (len <= i2c->cdata->fifosize)
                jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, len - 1);
        else
-               jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, RX_LEVEL);
+               jz4780_i2c_writew(i2c, JZ4780_I2C_RXTL, i2c->cdata->rx_level);
 
-       jz4780_i2c_writew(i2c, JZ4780_I2C_TXTL, TX_LEVEL);
+       jz4780_i2c_writew(i2c, JZ4780_I2C_TXTL, i2c->cdata->tx_level);
 
        jz4780_i2c_writew(i2c, JZ4780_I2C_INTM,
                          JZ4780_I2C_INTM_MRXFL | JZ4780_I2C_INTM_MTXEMP
                          | JZ4780_I2C_INTM_MTXABT | JZ4780_I2C_INTM_MRXOF);
 
-       tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
-       tmp |= JZ4780_I2C_CTRL_STPHLD;
-       jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+       if (i2c->cdata->version < ID_X1000) {
+               tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
+               tmp |= JZ4780_I2C_CTRL_STPHLD;
+               jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+       }
 
        spin_unlock_irqrestore(&i2c->lock, flags);
 
@@ -626,14 +675,16 @@ static inline int jz4780_i2c_xfer_write(struct jz4780_i2c *i2c,
        i2c->wbuf = buf;
        i2c->wt_len = len;
 
-       jz4780_i2c_writew(i2c, JZ4780_I2C_TXTL, TX_LEVEL);
+       jz4780_i2c_writew(i2c, JZ4780_I2C_TXTL, i2c->cdata->tx_level);
 
        jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, JZ4780_I2C_INTM_MTXEMP
                                        | JZ4780_I2C_INTM_MTXABT);
 
-       tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
-       tmp |= JZ4780_I2C_CTRL_STPHLD;
-       jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+       if (i2c->cdata->version < ID_X1000) {
+               tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
+               tmp |= JZ4780_I2C_CTRL_STPHLD;
+               jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+       }
 
        spin_unlock_irqrestore(&i2c->lock, flags);
 
@@ -716,8 +767,25 @@ static const struct i2c_algorithm jz4780_i2c_algorithm = {
        .functionality  = jz4780_i2c_functionality,
 };
 
+static const struct ingenic_i2c_config jz4780_i2c_config = {
+       .version = ID_JZ4780,
+
+       .fifosize = JZ4780_I2C_FIFO_LEN,
+       .tx_level = JZ4780_I2C_FIFO_LEN / 2,
+       .rx_level = JZ4780_I2C_FIFO_LEN / 2 - 1,
+};
+
+static const struct ingenic_i2c_config x1000_i2c_config = {
+       .version = ID_X1000,
+
+       .fifosize = X1000_I2C_FIFO_LEN,
+       .tx_level = X1000_I2C_FIFO_LEN / 2,
+       .rx_level = X1000_I2C_FIFO_LEN / 2 - 1,
+};
+
 static const struct of_device_id jz4780_i2c_of_matches[] = {
-       { .compatible = "ingenic,jz4780-i2c", },
+       { .compatible = "ingenic,jz4780-i2c", .data = &jz4780_i2c_config },
+       { .compatible = "ingenic,x1000-i2c", .data = &x1000_i2c_config },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, jz4780_i2c_of_matches);
@@ -734,6 +802,12 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
        if (!i2c)
                return -ENOMEM;
 
+       i2c->cdata = device_get_match_data(&pdev->dev);
+       if (!i2c->cdata) {
+               dev_err(&pdev->dev, "Error: No device match found\n");
+               return -ENODEV;
+       }
+
        i2c->adap.owner         = THIS_MODULE;
        i2c->adap.algo          = &jz4780_i2c_algorithm;
        i2c->adap.algo_data     = i2c;
@@ -777,9 +851,11 @@ static int jz4780_i2c_probe(struct platform_device *pdev)
 
        dev_info(&pdev->dev, "Bus frequency is %d KHz\n", i2c->speed);
 
-       tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
-       tmp &= ~JZ4780_I2C_CTRL_STPHLD;
-       jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+       if (i2c->cdata->version < ID_X1000) {
+               tmp = jz4780_i2c_readw(i2c, JZ4780_I2C_CTRL);
+               tmp &= ~JZ4780_I2C_CTRL_STPHLD;
+               jz4780_i2c_writew(i2c, JZ4780_I2C_CTRL, tmp);
+       }
 
        jz4780_i2c_writew(i2c, JZ4780_I2C_INTM, 0x0);
 
index 1e2647f..06b3bed 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/i2c.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
+#include <linux/iopoll.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
@@ -213,6 +214,30 @@ static void meson_i2c_prepare_xfer(struct meson_i2c *i2c)
        writel(i2c->tokens[1], i2c->regs + REG_TOK_LIST1);
 }
 
+static void meson_i2c_transfer_complete(struct meson_i2c *i2c, u32 ctrl)
+{
+       if (ctrl & REG_CTRL_ERROR) {
+               /*
+                * The bit is set when the IGNORE_NAK bit is cleared
+                * and the device didn't respond. In this case, the
+                * I2C controller automatically generates a STOP
+                * condition.
+                */
+               dev_dbg(i2c->dev, "error bit set\n");
+               i2c->error = -ENXIO;
+               i2c->state = STATE_IDLE;
+       } else {
+               if (i2c->state == STATE_READ && i2c->count)
+                       meson_i2c_get_data(i2c, i2c->msg->buf + i2c->pos,
+                                          i2c->count);
+
+               i2c->pos += i2c->count;
+
+               if (i2c->pos >= i2c->msg->len)
+                       i2c->state = STATE_IDLE;
+       }
+}
+
 static irqreturn_t meson_i2c_irq(int irqno, void *dev_id)
 {
        struct meson_i2c *i2c = dev_id;
@@ -232,27 +257,9 @@ static irqreturn_t meson_i2c_irq(int irqno, void *dev_id)
                return IRQ_NONE;
        }
 
-       if (ctrl & REG_CTRL_ERROR) {
-               /*
-                * The bit is set when the IGNORE_NAK bit is cleared
-                * and the device didn't respond. In this case, the
-                * I2C controller automatically generates a STOP
-                * condition.
-                */
-               dev_dbg(i2c->dev, "error bit set\n");
-               i2c->error = -ENXIO;
-               i2c->state = STATE_IDLE;
-               complete(&i2c->done);
-               goto out;
-       }
-
-       if (i2c->state == STATE_READ && i2c->count)
-               meson_i2c_get_data(i2c, i2c->msg->buf + i2c->pos, i2c->count);
+       meson_i2c_transfer_complete(i2c, ctrl);
 
-       i2c->pos += i2c->count;
-
-       if (i2c->pos >= i2c->msg->len) {
-               i2c->state = STATE_IDLE;
+       if (i2c->state == STATE_IDLE) {
                complete(&i2c->done);
                goto out;
        }
@@ -279,10 +286,11 @@ static void meson_i2c_do_start(struct meson_i2c *i2c, struct i2c_msg *msg)
 }
 
 static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg,
-                             int last)
+                             int last, bool atomic)
 {
        unsigned long time_left, flags;
        int ret = 0;
+       u32 ctrl;
 
        i2c->msg = msg;
        i2c->last = last;
@@ -300,13 +308,24 @@ static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg,
 
        i2c->state = (msg->flags & I2C_M_RD) ? STATE_READ : STATE_WRITE;
        meson_i2c_prepare_xfer(i2c);
-       reinit_completion(&i2c->done);
+
+       if (!atomic)
+               reinit_completion(&i2c->done);
 
        /* Start the transfer */
        meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, REG_CTRL_START);
 
-       time_left = msecs_to_jiffies(I2C_TIMEOUT_MS);
-       time_left = wait_for_completion_timeout(&i2c->done, time_left);
+       if (atomic) {
+               ret = readl_poll_timeout_atomic(i2c->regs + REG_CTRL, ctrl,
+                                               !(ctrl & REG_CTRL_STATUS),
+                                               10, I2C_TIMEOUT_MS * 1000);
+       } else {
+               time_left = msecs_to_jiffies(I2C_TIMEOUT_MS);
+               time_left = wait_for_completion_timeout(&i2c->done, time_left);
+
+               if (!time_left)
+                       ret = -ETIMEDOUT;
+       }
 
        /*
         * Protect access to i2c struct and registers from interrupt
@@ -315,13 +334,14 @@ static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg,
         */
        spin_lock_irqsave(&i2c->lock, flags);
 
+       if (atomic && !ret)
+               meson_i2c_transfer_complete(i2c, ctrl);
+
        /* Abort any active operation */
        meson_i2c_set_mask(i2c, REG_CTRL, REG_CTRL_START, 0);
 
-       if (!time_left) {
+       if (ret)
                i2c->state = STATE_IDLE;
-               ret = -ETIMEDOUT;
-       }
 
        if (i2c->error)
                ret = i2c->error;
@@ -331,8 +351,8 @@ static int meson_i2c_xfer_msg(struct meson_i2c *i2c, struct i2c_msg *msg,
        return ret;
 }
 
-static int meson_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
-                         int num)
+static int meson_i2c_xfer_messages(struct i2c_adapter *adap,
+                                  struct i2c_msg *msgs, int num, bool atomic)
 {
        struct meson_i2c *i2c = adap->algo_data;
        int i, ret = 0;
@@ -340,7 +360,7 @@ static int meson_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
        clk_enable(i2c->clk);
 
        for (i = 0; i < num; i++) {
-               ret = meson_i2c_xfer_msg(i2c, msgs + i, i == num - 1);
+               ret = meson_i2c_xfer_msg(i2c, msgs + i, i == num - 1, atomic);
                if (ret)
                        break;
        }
@@ -350,14 +370,27 @@ static int meson_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
        return ret ?: i;
 }
 
+static int meson_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
+                         int num)
+{
+       return meson_i2c_xfer_messages(adap, msgs, num, false);
+}
+
+static int meson_i2c_xfer_atomic(struct i2c_adapter *adap,
+                                struct i2c_msg *msgs, int num)
+{
+       return meson_i2c_xfer_messages(adap, msgs, num, true);
+}
+
 static u32 meson_i2c_func(struct i2c_adapter *adap)
 {
        return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
 }
 
 static const struct i2c_algorithm meson_i2c_algorithm = {
-       .master_xfer    = meson_i2c_xfer,
-       .functionality  = meson_i2c_func,
+       .master_xfer = meson_i2c_xfer,
+       .master_xfer_atomic = meson_i2c_xfer_atomic,
+       .functionality = meson_i2c_func,
 };
 
 static int meson_i2c_probe(struct platform_device *pdev)
index a5a95ea..febb7c7 100644 (file)
@@ -901,14 +901,13 @@ mv64xxx_i2c_probe(struct platform_device *pd)
 
        /* Not all platforms have clocks */
        drv_data->clk = devm_clk_get(&pd->dev, NULL);
-       if (IS_ERR(drv_data->clk) && PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
+       if (PTR_ERR(drv_data->clk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
        if (!IS_ERR(drv_data->clk))
                clk_prepare_enable(drv_data->clk);
 
        drv_data->reg_clk = devm_clk_get(&pd->dev, "reg");
-       if (IS_ERR(drv_data->reg_clk) &&
-           PTR_ERR(drv_data->reg_clk) == -EPROBE_DEFER)
+       if (PTR_ERR(drv_data->reg_clk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
        if (!IS_ERR(drv_data->reg_clk))
                clk_prepare_enable(drv_data->reg_clk);
index 5a1235f..62e18b4 100644 (file)
@@ -280,9 +280,9 @@ static int gpu_populate_client(struct gpu_i2c_dev *i2cd, int irq)
        i2cd->gpu_ccgx_ucsi->addr = 0x8;
        i2cd->gpu_ccgx_ucsi->irq = irq;
        i2cd->gpu_ccgx_ucsi->properties = ccgx_props;
-       i2cd->ccgx_client = i2c_new_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi);
-       if (!i2cd->ccgx_client)
-               return -ENODEV;
+       i2cd->ccgx_client = i2c_new_client_device(&i2cd->adapter, i2cd->gpu_ccgx_ucsi);
+       if (IS_ERR(i2cd->ccgx_client))
+               return PTR_ERR(i2cd->ccgx_client);
 
        return 0;
 }
index ca8b3ec..f5fc75b 100644 (file)
@@ -731,7 +731,7 @@ static int ocores_i2c_probe(struct platform_device *pdev)
        /* add in known devices to the bus */
        if (pdata) {
                for (i = 0; i < pdata->num_devices; i++)
-                       i2c_new_device(&i2c->adap, pdata->devices + i);
+                       i2c_new_client_device(&i2c->adap, pdata->devices + i);
        }
 
        return 0;
diff --git a/drivers/i2c/busses/i2c-parport-light.c b/drivers/i2c/busses/i2c-parport-light.c
deleted file mode 100644 (file)
index 00f6aaf..0000000
+++ /dev/null
@@ -1,267 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0-or-later
-/* ------------------------------------------------------------------------ *
- * i2c-parport-light.c I2C bus over parallel port                           *
- * ------------------------------------------------------------------------ *
-   Copyright (C) 2003-2010 Jean Delvare <jdelvare@suse.de>
-
-   Based on older i2c-velleman.c driver
-   Copyright (C) 1995-2000 Simon G. Vogl
-   With some changes from:
-   Frodo Looijaard <frodol@dds.nl>
-   Kyösti Mälkki <kmalkki@cc.hut.fi>
-
- * ------------------------------------------------------------------------ */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/ioport.h>
-#include <linux/i2c.h>
-#include <linux/i2c-algo-bit.h>
-#include <linux/i2c-smbus.h>
-#include <linux/io.h>
-#include "i2c-parport.h"
-
-#define DEFAULT_BASE 0x378
-#define DRVNAME "i2c-parport-light"
-
-static struct platform_device *pdev;
-
-static u16 base;
-module_param_hw(base, ushort, ioport, 0);
-MODULE_PARM_DESC(base, "Base I/O address");
-
-static int irq;
-module_param_hw(irq, int, irq, 0);
-MODULE_PARM_DESC(irq, "IRQ (optional)");
-
-/* ----- Low-level parallel port access ----------------------------------- */
-
-static inline void port_write(unsigned char p, unsigned char d)
-{
-       outb(d, base+p);
-}
-
-static inline unsigned char port_read(unsigned char p)
-{
-       return inb(base+p);
-}
-
-/* ----- Unified line operation functions --------------------------------- */
-
-static inline void line_set(int state, const struct lineop *op)
-{
-       u8 oldval = port_read(op->port);
-
-       /* Touch only the bit(s) needed */
-       if ((op->inverted && !state) || (!op->inverted && state))
-               port_write(op->port, oldval | op->val);
-       else
-               port_write(op->port, oldval & ~op->val);
-}
-
-static inline int line_get(const struct lineop *op)
-{
-       u8 oldval = port_read(op->port);
-
-       return ((op->inverted && (oldval & op->val) != op->val)
-           || (!op->inverted && (oldval & op->val) == op->val));
-}
-
-/* ----- I2C algorithm call-back functions and structures ----------------- */
-
-static void parport_setscl(void *data, int state)
-{
-       line_set(state, &adapter_parm[type].setscl);
-}
-
-static void parport_setsda(void *data, int state)
-{
-       line_set(state, &adapter_parm[type].setsda);
-}
-
-static int parport_getscl(void *data)
-{
-       return line_get(&adapter_parm[type].getscl);
-}
-
-static int parport_getsda(void *data)
-{
-       return line_get(&adapter_parm[type].getsda);
-}
-
-/* Encapsulate the functions above in the correct structure
-   Note that getscl will be set to NULL by the attaching code for adapters
-   that cannot read SCL back */
-static struct i2c_algo_bit_data parport_algo_data = {
-       .setsda         = parport_setsda,
-       .setscl         = parport_setscl,
-       .getsda         = parport_getsda,
-       .getscl         = parport_getscl,
-       .udelay         = 50,
-       .timeout        = HZ,
-};
-
-/* ----- Driver registration ---------------------------------------------- */
-
-static struct i2c_adapter parport_adapter = {
-       .owner          = THIS_MODULE,
-       .class          = I2C_CLASS_HWMON,
-       .algo_data      = &parport_algo_data,
-       .name           = "Parallel port adapter (light)",
-};
-
-/* SMBus alert support */
-static struct i2c_smbus_alert_setup alert_data = {
-};
-static struct i2c_client *ara;
-static struct lineop parport_ctrl_irq = {
-       .val            = (1 << 4),
-       .port           = PORT_CTRL,
-};
-
-static int i2c_parport_probe(struct platform_device *pdev)
-{
-       int err;
-
-       /* Reset hardware to a sane state (SCL and SDA high) */
-       parport_setsda(NULL, 1);
-       parport_setscl(NULL, 1);
-       /* Other init if needed (power on...) */
-       if (adapter_parm[type].init.val) {
-               line_set(1, &adapter_parm[type].init);
-               /* Give powered devices some time to settle */
-               msleep(100);
-       }
-
-       parport_adapter.dev.parent = &pdev->dev;
-       err = i2c_bit_add_bus(&parport_adapter);
-       if (err) {
-               dev_err(&pdev->dev, "Unable to register with I2C\n");
-               return err;
-       }
-
-       /* Setup SMBus alert if supported */
-       if (adapter_parm[type].smbus_alert && irq) {
-               alert_data.irq = irq;
-               ara = i2c_setup_smbus_alert(&parport_adapter, &alert_data);
-               if (ara)
-                       line_set(1, &parport_ctrl_irq);
-               else
-                       dev_warn(&pdev->dev, "Failed to register ARA client\n");
-       }
-
-       return 0;
-}
-
-static int i2c_parport_remove(struct platform_device *pdev)
-{
-       if (ara) {
-               line_set(0, &parport_ctrl_irq);
-               i2c_unregister_device(ara);
-               ara = NULL;
-       }
-       i2c_del_adapter(&parport_adapter);
-
-       /* Un-init if needed (power off...) */
-       if (adapter_parm[type].init.val)
-               line_set(0, &adapter_parm[type].init);
-
-       return 0;
-}
-
-static struct platform_driver i2c_parport_driver = {
-       .driver = {
-               .name   = DRVNAME,
-       },
-       .probe          = i2c_parport_probe,
-       .remove         = i2c_parport_remove,
-};
-
-static int __init i2c_parport_device_add(u16 address)
-{
-       int err;
-
-       pdev = platform_device_alloc(DRVNAME, -1);
-       if (!pdev) {
-               err = -ENOMEM;
-               printk(KERN_ERR DRVNAME ": Device allocation failed\n");
-               goto exit;
-       }
-
-       err = platform_device_add(pdev);
-       if (err) {
-               printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
-                      err);
-               goto exit_device_put;
-       }
-
-       return 0;
-
-exit_device_put:
-       platform_device_put(pdev);
-exit:
-       return err;
-}
-
-static int __init i2c_parport_init(void)
-{
-       int err;
-
-       if (type < 0) {
-               printk(KERN_ERR DRVNAME ": adapter type unspecified\n");
-               return -ENODEV;
-       }
-
-       if (type >= ARRAY_SIZE(adapter_parm)) {
-               printk(KERN_ERR DRVNAME ": invalid type (%d)\n", type);
-               return -ENODEV;
-       }
-
-       if (base == 0) {
-               pr_info(DRVNAME ": using default base 0x%x\n", DEFAULT_BASE);
-               base = DEFAULT_BASE;
-       }
-
-       if (!request_region(base, 3, DRVNAME))
-               return -EBUSY;
-
-       if (irq != 0)
-               pr_info(DRVNAME ": using irq %d\n", irq);
-
-       if (!adapter_parm[type].getscl.val)
-               parport_algo_data.getscl = NULL;
-
-       /* Sets global pdev as a side effect */
-       err = i2c_parport_device_add(base);
-       if (err)
-               goto exit_release;
-
-       err = platform_driver_register(&i2c_parport_driver);
-       if (err)
-               goto exit_device;
-
-       return 0;
-
-exit_device:
-       platform_device_unregister(pdev);
-exit_release:
-       release_region(base, 3);
-       return err;
-}
-
-static void __exit i2c_parport_exit(void)
-{
-       platform_driver_unregister(&i2c_parport_driver);
-       platform_device_unregister(pdev);
-       release_region(base, 3);
-}
-
-MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
-MODULE_DESCRIPTION("I2C bus over parallel port (light)");
-MODULE_LICENSE("GPL");
-
-module_init(i2c_parport_init);
-module_exit(i2c_parport_exit);
index e8ed882..81eb441 100644 (file)
 #include <linux/slab.h>
 #include <linux/list.h>
 #include <linux/mutex.h>
-#include "i2c-parport.h"
+
+#define PORT_DATA      0
+#define PORT_STAT      1
+#define PORT_CTRL      2
+
+struct lineop {
+       u8 val;
+       u8 port;
+       u8 inverted;
+};
+
+struct adapter_parm {
+       struct lineop setsda;
+       struct lineop setscl;
+       struct lineop getsda;
+       struct lineop getscl;
+       struct lineop init;
+       unsigned int smbus_alert:1;
+};
+
+static const struct adapter_parm adapter_parm[] = {
+       /* type 0: Philips adapter */
+       {
+               .setsda = { 0x80, PORT_DATA, 1 },
+               .setscl = { 0x08, PORT_CTRL, 0 },
+               .getsda = { 0x80, PORT_STAT, 0 },
+               .getscl = { 0x08, PORT_STAT, 0 },
+       },
+       /* type 1: home brew teletext adapter */
+       {
+               .setsda = { 0x02, PORT_DATA, 0 },
+               .setscl = { 0x01, PORT_DATA, 0 },
+               .getsda = { 0x80, PORT_STAT, 1 },
+       },
+       /* type 2: Velleman K8000 adapter */
+       {
+               .setsda = { 0x02, PORT_CTRL, 1 },
+               .setscl = { 0x08, PORT_CTRL, 1 },
+               .getsda = { 0x10, PORT_STAT, 0 },
+       },
+       /* type 3: ELV adapter */
+       {
+               .setsda = { 0x02, PORT_DATA, 1 },
+               .setscl = { 0x01, PORT_DATA, 1 },
+               .getsda = { 0x40, PORT_STAT, 1 },
+               .getscl = { 0x08, PORT_STAT, 1 },
+       },
+       /* type 4: ADM1032 evaluation board */
+       {
+               .setsda = { 0x02, PORT_DATA, 1 },
+               .setscl = { 0x01, PORT_DATA, 1 },
+               .getsda = { 0x10, PORT_STAT, 1 },
+               .init   = { 0xf0, PORT_DATA, 0 },
+               .smbus_alert = 1,
+       },
+       /* type 5: ADM1025, ADM1030 and ADM1031 evaluation boards */
+       {
+               .setsda = { 0x02, PORT_DATA, 1 },
+               .setscl = { 0x01, PORT_DATA, 1 },
+               .getsda = { 0x10, PORT_STAT, 1 },
+       },
+       /* type 6: Barco LPT->DVI (K5800236) adapter */
+       {
+               .setsda = { 0x02, PORT_DATA, 1 },
+               .setscl = { 0x01, PORT_DATA, 1 },
+               .getsda = { 0x20, PORT_STAT, 0 },
+               .getscl = { 0x40, PORT_STAT, 0 },
+               .init   = { 0xfc, PORT_DATA, 0 },
+       },
+       /* type 7: One For All JP1 parallel port adapter */
+       {
+               .setsda = { 0x01, PORT_DATA, 0 },
+               .setscl = { 0x02, PORT_DATA, 0 },
+               .getsda = { 0x80, PORT_STAT, 1 },
+               .init   = { 0x04, PORT_DATA, 1 },
+       },
+       /* type 8: VCT-jig */
+       {
+               .setsda = { 0x04, PORT_DATA, 1 },
+               .setscl = { 0x01, PORT_DATA, 1 },
+               .getsda = { 0x40, PORT_STAT, 0 },
+               .getscl = { 0x80, PORT_STAT, 1 },
+       },
+};
 
 /* ----- Device list ------------------------------------------------------ */
 
@@ -40,9 +123,30 @@ struct i2c_par {
 
 static LIST_HEAD(adapter_list);
 static DEFINE_MUTEX(adapter_list_lock);
+
 #define MAX_DEVICE 4
 static int parport[MAX_DEVICE] = {0, -1, -1, -1};
+module_param_array(parport, int, NULL, 0);
+MODULE_PARM_DESC(parport,
+                "List of parallel ports to bind to, by index.\n"
+                " At most " __stringify(MAX_DEVICE) " devices are supported.\n"
+                " Default is one device connected to parport0.\n"
+);
 
+static int type = -1;
+module_param(type, int, 0);
+MODULE_PARM_DESC(type,
+       "Type of adapter:\n"
+       " 0 = Philips adapter\n"
+       " 1 = home brew teletext adapter\n"
+       " 2 = Velleman K8000 adapter\n"
+       " 3 = ELV adapter\n"
+       " 4 = ADM1032 evaluation board\n"
+       " 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"
+       " 6 = Barco LPT->DVI (K5800236) adapter\n"
+       " 7 = One For All JP1 parallel port adapter\n"
+       " 8 = VCT-jig\n"
+);
 
 /* ----- Low-level parallel port access ----------------------------------- */
 
@@ -311,12 +415,5 @@ MODULE_AUTHOR("Jean Delvare <jdelvare@suse.de>");
 MODULE_DESCRIPTION("I2C bus over parallel port");
 MODULE_LICENSE("GPL");
 
-module_param_array(parport, int, NULL, 0);
-MODULE_PARM_DESC(parport,
-                "List of parallel ports to bind to, by index.\n"
-                " Atmost " __stringify(MAX_DEVICE) " devices are supported.\n"
-                " Default is one device connected to parport0.\n"
-);
-
 module_init(i2c_parport_init);
 module_exit(i2c_parport_exit);
diff --git a/drivers/i2c/busses/i2c-parport.h b/drivers/i2c/busses/i2c-parport.h
deleted file mode 100644 (file)
index 3b32d92..0000000
+++ /dev/null
@@ -1,106 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/* ------------------------------------------------------------------------ *
- * i2c-parport.h I2C bus over parallel port                                 *
- * ------------------------------------------------------------------------ *
-   Copyright (C) 2003-2010 Jean Delvare <jdelvare@suse.de>
-
- * ------------------------------------------------------------------------ */
-
-#define PORT_DATA      0
-#define PORT_STAT      1
-#define PORT_CTRL      2
-
-struct lineop {
-       u8 val;
-       u8 port;
-       u8 inverted;
-};
-
-struct adapter_parm {
-       struct lineop setsda;
-       struct lineop setscl;
-       struct lineop getsda;
-       struct lineop getscl;
-       struct lineop init;
-       unsigned int smbus_alert:1;
-};
-
-static const struct adapter_parm adapter_parm[] = {
-       /* type 0: Philips adapter */
-       {
-               .setsda = { 0x80, PORT_DATA, 1 },
-               .setscl = { 0x08, PORT_CTRL, 0 },
-               .getsda = { 0x80, PORT_STAT, 0 },
-               .getscl = { 0x08, PORT_STAT, 0 },
-       },
-       /* type 1: home brew teletext adapter */
-       {
-               .setsda = { 0x02, PORT_DATA, 0 },
-               .setscl = { 0x01, PORT_DATA, 0 },
-               .getsda = { 0x80, PORT_STAT, 1 },
-       },
-       /* type 2: Velleman K8000 adapter */
-       {
-               .setsda = { 0x02, PORT_CTRL, 1 },
-               .setscl = { 0x08, PORT_CTRL, 1 },
-               .getsda = { 0x10, PORT_STAT, 0 },
-       },
-       /* type 3: ELV adapter */
-       {
-               .setsda = { 0x02, PORT_DATA, 1 },
-               .setscl = { 0x01, PORT_DATA, 1 },
-               .getsda = { 0x40, PORT_STAT, 1 },
-               .getscl = { 0x08, PORT_STAT, 1 },
-       },
-       /* type 4: ADM1032 evaluation board */
-       {
-               .setsda = { 0x02, PORT_DATA, 1 },
-               .setscl = { 0x01, PORT_DATA, 1 },
-               .getsda = { 0x10, PORT_STAT, 1 },
-               .init   = { 0xf0, PORT_DATA, 0 },
-               .smbus_alert = 1,
-       },
-       /* type 5: ADM1025, ADM1030 and ADM1031 evaluation boards */
-       {
-               .setsda = { 0x02, PORT_DATA, 1 },
-               .setscl = { 0x01, PORT_DATA, 1 },
-               .getsda = { 0x10, PORT_STAT, 1 },
-       },
-       /* type 6: Barco LPT->DVI (K5800236) adapter */
-       {
-               .setsda = { 0x02, PORT_DATA, 1 },
-               .setscl = { 0x01, PORT_DATA, 1 },
-               .getsda = { 0x20, PORT_STAT, 0 },
-               .getscl = { 0x40, PORT_STAT, 0 },
-               .init   = { 0xfc, PORT_DATA, 0 },
-       },
-       /* type 7: One For All JP1 parallel port adapter */
-       {
-               .setsda = { 0x01, PORT_DATA, 0 },
-               .setscl = { 0x02, PORT_DATA, 0 },
-               .getsda = { 0x80, PORT_STAT, 1 },
-               .init   = { 0x04, PORT_DATA, 1 },
-       },
-       /* type 8: VCT-jig */
-       {
-               .setsda = { 0x04, PORT_DATA, 1 },
-               .setscl = { 0x01, PORT_DATA, 1 },
-               .getsda = { 0x40, PORT_STAT, 0 },
-               .getscl = { 0x80, PORT_STAT, 1 },
-       },
-};
-
-static int type = -1;
-module_param(type, int, 0);
-MODULE_PARM_DESC(type,
-       "Type of adapter:\n"
-       " 0 = Philips adapter\n"
-       " 1 = home brew teletext adapter\n"
-       " 2 = Velleman K8000 adapter\n"
-       " 3 = ELV adapter\n"
-       " 4 = ADM1032 evaluation board\n"
-       " 5 = ADM1025, ADM1030 and ADM1031 evaluation boards\n"
-       " 6 = Barco LPT->DVI (K5800236) adapter\n"
-       " 7 = One For All JP1 parallel port adapter\n"
-       " 8 = VCT-jig\n"
-);
index 4fde74e..5d89c7c 100644 (file)
@@ -274,8 +274,8 @@ static int pmcmsptwi_probe(struct platform_device *pldev)
        if (!request_mem_region(res->start, resource_size(res),
                                pldev->name)) {
                dev_err(&pldev->dev,
-                       "Unable to get memory/io address region 0x%08x\n",
-                       res->start);
+                       "Unable to get memory/io address region %pap\n",
+                       &res->start);
                rc = -EBUSY;
                goto ret_err;
        }
@@ -285,7 +285,7 @@ static int pmcmsptwi_probe(struct platform_device *pldev)
                                                resource_size(res));
        if (!pmcmsptwi_data.iobase) {
                dev_err(&pldev->dev,
-                       "Unable to ioremap address 0x%08x\n", res->start);
+                       "Unable to ioremap address %pap\n", &res->start);
                rc = -EIO;
                goto ret_unreserve;
        }
index 6e0e546..686c06f 100644 (file)
@@ -734,8 +734,8 @@ static int i2c_pnx_probe(struct platform_device *pdev)
        if (ret < 0)
                goto out_clock;
 
-       dev_dbg(&pdev->dev, "%s: Master at %#8x, irq %d.\n",
-               alg_data->adapter.name, res->start, alg_data->irq);
+       dev_dbg(&pdev->dev, "%s: Master at %pap, irq %d.\n",
+               alg_data->adapter.name, &res->start, alg_data->irq);
 
        return 0;
 
index 504f5bf..973e533 100644 (file)
@@ -240,8 +240,8 @@ static void i2c_powermac_create_one(struct i2c_adapter *adap,
 
        strncpy(info.type, type, sizeof(info.type));
        info.addr = addr;
-       newdev = i2c_new_device(adap, &info);
-       if (!newdev)
+       newdev = i2c_new_client_device(adap, &info);
+       if (IS_ERR(newdev))
                dev_err(&adap->dev,
                        "i2c-powermac: Failure to register missing %s\n",
                        type);
@@ -359,8 +359,8 @@ static void i2c_powermac_register_devices(struct i2c_adapter *adap,
                info.irq = irq_of_parse_and_map(node, 0);
                info.of_node = of_node_get(node);
 
-               newdev = i2c_new_device(adap, &info);
-               if (!newdev) {
+               newdev = i2c_new_client_device(adap, &info);
+               if (IS_ERR(newdev)) {
                        dev_err(&adap->dev, "i2c-powermac: Failure to register"
                                " %pOF\n", node);
                        of_node_put(node);
index b2634af..5c3e8ac 100644 (file)
 #define STM32F7_AUTOSUSPEND_DELAY              (HZ / 100)
 
 /**
+ * struct stm32f7_i2c_regs - i2c f7 registers backup
+ * @cr1: Control register 1
+ * @cr2: Control register 2
+ * @oar1: Own address 1 register
+ * @oar2: Own address 2 register
+ * @pecr: PEC register
+ * @tmgr: Timing register
+ */
+struct stm32f7_i2c_regs {
+       u32 cr1;
+       u32 cr2;
+       u32 oar1;
+       u32 oar2;
+       u32 pecr;
+       u32 tmgr;
+};
+
+/**
  * struct stm32f7_i2c_spec - private i2c specification timing
  * @rate: I2C bus speed (Hz)
  * @rate_min: 80% of I2C bus speed (Hz)
@@ -276,6 +294,7 @@ struct stm32f7_i2c_msg {
  * @timing: I2C computed timings
  * @slave: list of slave devices registered on the I2C bus
  * @slave_running: slave device currently used
+ * @backup_regs: backup of i2c controller registers (for suspend/resume)
  * @slave_dir: transfer direction for the current slave device
  * @master_mode: boolean to know in which mode the I2C is running (master or
  * slave)
@@ -298,6 +317,7 @@ struct stm32f7_i2c_dev {
        struct stm32f7_i2c_timings timing;
        struct i2c_client *slave[STM32F7_I2C_MAX_SLAVE];
        struct i2c_client *slave_running;
+       struct stm32f7_i2c_regs backup_regs;
        u32 slave_dir;
        bool master_mode;
        struct stm32_i2c_dma *dma;
@@ -2027,8 +2047,7 @@ static int stm32f7_i2c_remove(struct platform_device *pdev)
        return 0;
 }
 
-#ifdef CONFIG_PM
-static int stm32f7_i2c_runtime_suspend(struct device *dev)
+static int __maybe_unused stm32f7_i2c_runtime_suspend(struct device *dev)
 {
        struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
 
@@ -2038,7 +2057,7 @@ static int stm32f7_i2c_runtime_suspend(struct device *dev)
        return 0;
 }
 
-static int stm32f7_i2c_runtime_resume(struct device *dev)
+static int __maybe_unused stm32f7_i2c_runtime_resume(struct device *dev)
 {
        struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
        int ret;
@@ -2053,11 +2072,101 @@ static int stm32f7_i2c_runtime_resume(struct device *dev)
 
        return 0;
 }
-#endif
+
+static int __maybe_unused
+stm32f7_i2c_regs_backup(struct stm32f7_i2c_dev *i2c_dev)
+{
+       int ret;
+       struct stm32f7_i2c_regs *backup_regs = &i2c_dev->backup_regs;
+
+       ret = pm_runtime_get_sync(i2c_dev->dev);
+       if (ret < 0)
+               return ret;
+
+       backup_regs->cr1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR1);
+       backup_regs->cr2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR2);
+       backup_regs->oar1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR1);
+       backup_regs->oar2 = readl_relaxed(i2c_dev->base + STM32F7_I2C_OAR2);
+       backup_regs->pecr = readl_relaxed(i2c_dev->base + STM32F7_I2C_PECR);
+       backup_regs->tmgr = readl_relaxed(i2c_dev->base + STM32F7_I2C_TIMINGR);
+
+       pm_runtime_put_sync(i2c_dev->dev);
+
+       return ret;
+}
+
+static int __maybe_unused
+stm32f7_i2c_regs_restore(struct stm32f7_i2c_dev *i2c_dev)
+{
+       u32 cr1;
+       int ret;
+       struct stm32f7_i2c_regs *backup_regs = &i2c_dev->backup_regs;
+
+       ret = pm_runtime_get_sync(i2c_dev->dev);
+       if (ret < 0)
+               return ret;
+
+       cr1 = readl_relaxed(i2c_dev->base + STM32F7_I2C_CR1);
+       if (cr1 & STM32F7_I2C_CR1_PE)
+               stm32f7_i2c_clr_bits(i2c_dev->base + STM32F7_I2C_CR1,
+                                    STM32F7_I2C_CR1_PE);
+
+       writel_relaxed(backup_regs->tmgr, i2c_dev->base + STM32F7_I2C_TIMINGR);
+       writel_relaxed(backup_regs->cr1 & ~STM32F7_I2C_CR1_PE,
+                      i2c_dev->base + STM32F7_I2C_CR1);
+       if (backup_regs->cr1 & STM32F7_I2C_CR1_PE)
+               stm32f7_i2c_set_bits(i2c_dev->base + STM32F7_I2C_CR1,
+                                    STM32F7_I2C_CR1_PE);
+       writel_relaxed(backup_regs->cr2, i2c_dev->base + STM32F7_I2C_CR2);
+       writel_relaxed(backup_regs->oar1, i2c_dev->base + STM32F7_I2C_OAR1);
+       writel_relaxed(backup_regs->oar2, i2c_dev->base + STM32F7_I2C_OAR2);
+       writel_relaxed(backup_regs->pecr, i2c_dev->base + STM32F7_I2C_PECR);
+
+       pm_runtime_put_sync(i2c_dev->dev);
+
+       return ret;
+}
+
+static int __maybe_unused stm32f7_i2c_suspend(struct device *dev)
+{
+       struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+       int ret;
+
+       i2c_mark_adapter_suspended(&i2c_dev->adap);
+       ret = stm32f7_i2c_regs_backup(i2c_dev);
+       if (ret < 0) {
+               i2c_mark_adapter_resumed(&i2c_dev->adap);
+               return ret;
+       }
+
+       pinctrl_pm_select_sleep_state(dev);
+       pm_runtime_force_suspend(dev);
+
+       return 0;
+}
+
+static int __maybe_unused stm32f7_i2c_resume(struct device *dev)
+{
+       struct stm32f7_i2c_dev *i2c_dev = dev_get_drvdata(dev);
+       int ret;
+
+       ret = pm_runtime_force_resume(dev);
+       if (ret < 0)
+               return ret;
+       pinctrl_pm_select_default_state(dev);
+
+       ret = stm32f7_i2c_regs_restore(i2c_dev);
+       if (ret < 0)
+               return ret;
+       i2c_mark_adapter_resumed(&i2c_dev->adap);
+
+       return 0;
+}
 
 static const struct dev_pm_ops stm32f7_i2c_pm_ops = {
        SET_RUNTIME_PM_OPS(stm32f7_i2c_runtime_suspend,
                           stm32f7_i2c_runtime_resume, NULL)
+       SET_SYSTEM_SLEEP_PM_OPS(stm32f7_i2c_suspend, stm32f7_i2c_resume)
 };
 
 static const struct of_device_id stm32f7_i2c_match[] = {
index 8c3e2d4..42e0a53 100644 (file)
@@ -444,7 +444,7 @@ static int stu300_wait_while_busy(struct stu300_dev *dev)
                       "Attempt: %d\n", i+1);
 
                dev_err(&dev->pdev->dev, "base address = "
-                       "0x%08x, reinit hardware\n", (u32) dev->virtbase);
+                       "0x%p, reinit hardware\n", dev->virtbase);
 
                (void) stu300_init_hw(dev);
        }
index 39762f0..8602679 100644 (file)
@@ -553,7 +553,7 @@ static int synquacer_i2c_probe(struct platform_device *pdev)
                                 &i2c->pclkrate);
 
        i2c->pclk = devm_clk_get(&pdev->dev, "pclk");
-       if (IS_ERR(i2c->pclk) && PTR_ERR(i2c->pclk) == -EPROBE_DEFER)
+       if (PTR_ERR(i2c->pclk) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
        if (!IS_ERR_OR_NULL(i2c->pclk)) {
                dev_dbg(&pdev->dev, "clock source %p\n", i2c->pclk);
index 0bff3f3..b4050f5 100644 (file)
@@ -49,10 +49,10 @@ static struct i2c_client *taos_instantiate_device(struct i2c_adapter *adapter)
        if (!strncmp(adapter->name, "TAOS TSL2550 EVM", 16)) {
                dev_info(&adapter->dev, "Instantiating device %s at 0x%02x\n",
                        tsl2550_info.type, tsl2550_info.addr);
-               return i2c_new_device(adapter, &tsl2550_info);
+               return i2c_new_client_device(adapter, &tsl2550_info);
        }
 
-       return NULL;
+       return ERR_PTR(-ENODEV);
 }
 
 static int taos_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
index 61339c6..cbc2ad4 100644 (file)
@@ -16,7 +16,9 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
+#include <linux/ktime.h>
 #include <linux/module.h>
 #include <linux/of_device.h>
 #include <linux/pinctrl/consumer.h>
 #define I2C_PACKET_HEADER_SIZE                 12
 
 /*
- * Upto I2C_PIO_MODE_MAX_LEN bytes, controller will use PIO mode,
- * above this, controller will use DMA to fill FIFO.
- * MAX PIO len is 20 bytes excluding packet header.
+ * I2C Controller will use PIO mode for transfers up to 32 bytes in order to
+ * avoid DMA overhead, otherwise external APB DMA controller will be used.
+ * Note that the actual MAX PIO length is 20 bytes because 32 bytes include
+ * I2C_PACKET_HEADER_SIZE.
  */
-#define I2C_PIO_MODE_MAX_LEN                   32
+#define I2C_PIO_MODE_PREFERRED_LEN             32
 
 /*
  * msg_end_type: The bus control which need to be send at end of transfer.
@@ -230,7 +233,6 @@ struct tegra_i2c_hw_feature {
  * @base_phys: physical base address of the I2C controller
  * @cont_id: I2C controller ID, used for packet header
  * @irq: IRQ number of transfer complete interrupt
- * @irq_disabled: used to track whether or not the interrupt is enabled
  * @is_dvc: identifies the DVC I2C controller, has a different register layout
  * @msg_complete: transfer completion notifier
  * @msg_err: error code for completed message
@@ -240,7 +242,6 @@ struct tegra_i2c_hw_feature {
  * @bus_clk_rate: current I2C bus clock rate
  * @clk_divisor_non_hs_mode: clock divider for non-high-speed modes
  * @is_multimaster_mode: track if I2C controller is in multi-master mode
- * @xfer_lock: lock to serialize transfer submission and processing
  * @tx_dma_chan: DMA transmit channel
  * @rx_dma_chan: DMA receive channel
  * @dma_phys: handle to DMA resources
@@ -248,6 +249,7 @@ struct tegra_i2c_hw_feature {
  * @dma_buf_size: DMA buffer size
  * @is_curr_dma_xfer: indicates active DMA transfer
  * @dma_complete: DMA completion notifier
+ * @is_curr_atomic_xfer: indicates active atomic transfer
  */
 struct tegra_i2c_dev {
        struct device *dev;
@@ -260,7 +262,6 @@ struct tegra_i2c_dev {
        phys_addr_t base_phys;
        int cont_id;
        int irq;
-       bool irq_disabled;
        int is_dvc;
        struct completion msg_complete;
        int msg_err;
@@ -270,8 +271,6 @@ struct tegra_i2c_dev {
        u32 bus_clk_rate;
        u16 clk_divisor_non_hs_mode;
        bool is_multimaster_mode;
-       /* xfer_lock: lock to serialize transfer submission and processing */
-       spinlock_t xfer_lock;
        struct dma_chan *tx_dma_chan;
        struct dma_chan *rx_dma_chan;
        dma_addr_t dma_phys;
@@ -279,17 +278,18 @@ struct tegra_i2c_dev {
        unsigned int dma_buf_size;
        bool is_curr_dma_xfer;
        struct completion dma_complete;
+       bool is_curr_atomic_xfer;
 };
 
 static void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
                       unsigned long reg)
 {
-       writel(val, i2c_dev->base + reg);
+       writel_relaxed(val, i2c_dev->base + reg);
 }
 
 static u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
 {
-       return readl(i2c_dev->base + reg);
+       return readl_relaxed(i2c_dev->base + reg);
 }
 
 /*
@@ -307,16 +307,16 @@ static unsigned long tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev,
 static void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
                       unsigned long reg)
 {
-       writel(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+       writel_relaxed(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
 
        /* Read back register to make sure that register writes completed */
        if (reg != I2C_TX_FIFO)
-               readl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+               readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
 }
 
 static u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned long reg)
 {
-       return readl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
+       return readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
 }
 
 static void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
@@ -687,13 +687,15 @@ static int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
                reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_CONFIG_LOAD);
                addr = i2c_dev->base + reg_offset;
                i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
-               if (in_interrupt())
-                       err = readl_poll_timeout_atomic(addr, val, val == 0,
-                                                       1000,
-                                                       I2C_CONFIG_LOAD_TIMEOUT);
+
+               if (i2c_dev->is_curr_atomic_xfer)
+                       err = readl_relaxed_poll_timeout_atomic(
+                                               addr, val, val == 0, 1000,
+                                               I2C_CONFIG_LOAD_TIMEOUT);
                else
-                       err = readl_poll_timeout(addr, val, val == 0, 1000,
-                                                I2C_CONFIG_LOAD_TIMEOUT);
+                       err = readl_relaxed_poll_timeout(
+                                               addr, val, val == 0, 1000,
+                                               I2C_CONFIG_LOAD_TIMEOUT);
 
                if (err) {
                        dev_warn(i2c_dev->dev,
@@ -790,11 +792,6 @@ static int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev, bool clk_reinit)
        if (err)
                return err;
 
-       if (i2c_dev->irq_disabled) {
-               i2c_dev->irq_disabled = false;
-               enable_irq(i2c_dev->irq);
-       }
-
        return 0;
 }
 
@@ -825,18 +822,12 @@ static irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
 
        status = i2c_readl(i2c_dev, I2C_INT_STATUS);
 
-       spin_lock(&i2c_dev->xfer_lock);
        if (status == 0) {
                dev_warn(i2c_dev->dev, "irq status 0 %08x %08x %08x\n",
                         i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS),
                         i2c_readl(i2c_dev, I2C_STATUS),
                         i2c_readl(i2c_dev, I2C_CNFG));
                i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
-
-               if (!i2c_dev->irq_disabled) {
-                       disable_irq_nosync(i2c_dev->irq);
-                       i2c_dev->irq_disabled = true;
-               }
                goto err;
        }
 
@@ -925,7 +916,6 @@ err:
 
        complete(&i2c_dev->msg_complete);
 done:
-       spin_unlock(&i2c_dev->xfer_lock);
        return IRQ_HANDLED;
 }
 
@@ -999,6 +989,64 @@ out:
        i2c_writel(i2c_dev, val, reg);
 }
 
+static unsigned long
+tegra_i2c_poll_completion_timeout(struct tegra_i2c_dev *i2c_dev,
+                                 struct completion *complete,
+                                 unsigned int timeout_ms)
+{
+       ktime_t ktime = ktime_get();
+       ktime_t ktimeout = ktime_add_ms(ktime, timeout_ms);
+
+       do {
+               u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
+
+               if (status) {
+                       tegra_i2c_isr(i2c_dev->irq, i2c_dev);
+
+                       if (completion_done(complete)) {
+                               s64 delta = ktime_ms_delta(ktimeout, ktime);
+
+                               return msecs_to_jiffies(delta) ?: 1;
+                       }
+               }
+
+               ktime = ktime_get();
+
+       } while (ktime_before(ktime, ktimeout));
+
+       return 0;
+}
+
+static unsigned long
+tegra_i2c_wait_completion_timeout(struct tegra_i2c_dev *i2c_dev,
+                                 struct completion *complete,
+                                 unsigned int timeout_ms)
+{
+       unsigned long ret;
+
+       if (i2c_dev->is_curr_atomic_xfer) {
+               ret = tegra_i2c_poll_completion_timeout(i2c_dev, complete,
+                                                       timeout_ms);
+       } else {
+               enable_irq(i2c_dev->irq);
+               ret = wait_for_completion_timeout(complete,
+                                                 msecs_to_jiffies(timeout_ms));
+               disable_irq(i2c_dev->irq);
+
+               /*
+                * There is a chance that completion may happen after IRQ
+                * synchronization, which is done by disable_irq().
+                */
+               if (ret == 0 && completion_done(complete)) {
+                       dev_warn(i2c_dev->dev,
+                                "completion done after timeout\n");
+                       ret = 1;
+               }
+       }
+
+       return ret;
+}
+
 static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
 {
        struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
@@ -1020,8 +1068,8 @@ static int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
        i2c_writel(i2c_dev, reg, I2C_BUS_CLEAR_CNFG);
        tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
 
-       time_left = wait_for_completion_timeout(&i2c_dev->msg_complete,
-                                               msecs_to_jiffies(50));
+       time_left = tegra_i2c_wait_completion_timeout(
+                       i2c_dev, &i2c_dev->msg_complete, 50);
        if (time_left == 0) {
                dev_err(i2c_dev->dev, "timed out for bus clear\n");
                return -ETIMEDOUT;
@@ -1044,7 +1092,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
        u32 packet_header;
        u32 int_mask;
        unsigned long time_left;
-       unsigned long flags;
        size_t xfer_size;
        u32 *buffer = NULL;
        int err = 0;
@@ -1065,8 +1112,9 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
                xfer_size = msg->len + I2C_PACKET_HEADER_SIZE;
 
        xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
-       i2c_dev->is_curr_dma_xfer = (xfer_size > I2C_PIO_MODE_MAX_LEN) &&
-                                   i2c_dev->dma_buf;
+       i2c_dev->is_curr_dma_xfer = (xfer_size > I2C_PIO_MODE_PREFERRED_LEN) &&
+                                   i2c_dev->dma_buf &&
+                                   !i2c_dev->is_curr_atomic_xfer;
        tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
        dma = i2c_dev->is_curr_dma_xfer;
        /*
@@ -1075,7 +1123,6 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
         */
        xfer_time += DIV_ROUND_CLOSEST(((xfer_size * 9) + 2) * MSEC_PER_SEC,
                                        i2c_dev->bus_clk_rate);
-       spin_lock_irqsave(&i2c_dev->xfer_lock, flags);
 
        int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
        tegra_i2c_unmask_irq(i2c_dev, int_mask);
@@ -1090,7 +1137,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
                                dev_err(i2c_dev->dev,
                                        "starting RX DMA failed, err %d\n",
                                        err);
-                               goto unlock;
+                               return err;
                        }
 
                } else {
@@ -1149,7 +1196,7 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
                                dev_err(i2c_dev->dev,
                                        "starting TX DMA failed, err %d\n",
                                        err);
-                               goto unlock;
+                               return err;
                        }
                } else {
                        tegra_i2c_fill_tx_fifo(i2c_dev);
@@ -1169,20 +1216,16 @@ static int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
        dev_dbg(i2c_dev->dev, "unmasked irq: %02x\n",
                i2c_readl(i2c_dev, I2C_INT_MASK));
 
-unlock:
-       spin_unlock_irqrestore(&i2c_dev->xfer_lock, flags);
-
        if (dma) {
-               if (err)
-                       return err;
+               time_left = tegra_i2c_wait_completion_timeout(
+                               i2c_dev, &i2c_dev->dma_complete, xfer_time);
+
+               dmaengine_terminate_sync(i2c_dev->msg_read ?
+                                        i2c_dev->rx_dma_chan :
+                                        i2c_dev->tx_dma_chan);
 
-               time_left = wait_for_completion_timeout(&i2c_dev->dma_complete,
-                                                       msecs_to_jiffies(xfer_time));
-               if (time_left == 0) {
+               if (!time_left && !completion_done(&i2c_dev->dma_complete)) {
                        dev_err(i2c_dev->dev, "DMA transfer timeout\n");
-                       dmaengine_terminate_sync(i2c_dev->msg_read ?
-                                                i2c_dev->rx_dma_chan :
-                                                i2c_dev->tx_dma_chan);
                        tegra_i2c_init(i2c_dev, true);
                        return -ETIMEDOUT;
                }
@@ -1195,20 +1238,15 @@ unlock:
                        memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf,
                               msg->len);
                }
-
-               if (i2c_dev->msg_err != I2C_ERR_NONE)
-                       dmaengine_synchronize(i2c_dev->msg_read ?
-                                             i2c_dev->rx_dma_chan :
-                                             i2c_dev->tx_dma_chan);
        }
 
-       time_left = wait_for_completion_timeout(&i2c_dev->msg_complete,
-                                               msecs_to_jiffies(xfer_time));
+       time_left = tegra_i2c_wait_completion_timeout(
+                       i2c_dev, &i2c_dev->msg_complete, xfer_time);
+
        tegra_i2c_mask_irq(i2c_dev, int_mask);
 
        if (time_left == 0) {
                dev_err(i2c_dev->dev, "i2c transfer timed out\n");
-
                tegra_i2c_init(i2c_dev, true);
                return -ETIMEDOUT;
        }
@@ -1270,6 +1308,19 @@ static int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
        return ret ?: i;
 }
 
+static int tegra_i2c_xfer_atomic(struct i2c_adapter *adap,
+                                struct i2c_msg msgs[], int num)
+{
+       struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
+       int ret;
+
+       i2c_dev->is_curr_atomic_xfer = true;
+       ret = tegra_i2c_xfer(adap, msgs, num);
+       i2c_dev->is_curr_atomic_xfer = false;
+
+       return ret;
+}
+
 static u32 tegra_i2c_func(struct i2c_adapter *adap)
 {
        struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
@@ -1297,8 +1348,9 @@ static void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
 }
 
 static const struct i2c_algorithm tegra_i2c_algo = {
-       .master_xfer    = tegra_i2c_xfer,
-       .functionality  = tegra_i2c_func,
+       .master_xfer            = tegra_i2c_xfer,
+       .master_xfer_atomic     = tegra_i2c_xfer_atomic,
+       .functionality          = tegra_i2c_func,
 };
 
 /* payload size is only 12 bit */
@@ -1568,7 +1620,6 @@ static int tegra_i2c_probe(struct platform_device *pdev)
                                I2C_PACKET_HEADER_SIZE;
        init_completion(&i2c_dev->msg_complete);
        init_completion(&i2c_dev->dma_complete);
-       spin_lock_init(&i2c_dev->xfer_lock);
 
        if (!i2c_dev->hw->has_single_clk_source) {
                fast_clk = devm_clk_get(&pdev->dev, "fast-clk");
@@ -1607,6 +1658,7 @@ static int tegra_i2c_probe(struct platform_device *pdev)
                goto unprepare_fast_clk;
        }
 
+       pm_runtime_irq_safe(&pdev->dev);
        pm_runtime_enable(&pdev->dev);
        if (!pm_runtime_enabled(&pdev->dev)) {
                ret = tegra_i2c_runtime_resume(&pdev->dev);
@@ -1644,6 +1696,8 @@ static int tegra_i2c_probe(struct platform_device *pdev)
                goto release_dma;
        }
 
+       irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
+
        ret = devm_request_irq(&pdev->dev, i2c_dev->irq,
                               tegra_i2c_isr, 0, dev_name(&pdev->dev), i2c_dev);
        if (ret) {
index 43e3603..7279ca0 100644 (file)
@@ -84,7 +84,7 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
                                     pmsg->buf, pmsg->len) != pmsg->len) {
                                dev_err(&adapter->dev,
                                        "failure reading data\n");
-                               ret = -EREMOTEIO;
+                               ret = -EIO;
                                goto out;
                        }
                } else {
@@ -94,7 +94,7 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
                                      pmsg->buf, pmsg->len) != pmsg->len) {
                                dev_err(&adapter->dev,
                                        "failure writing data\n");
-                               ret = -EREMOTEIO;
+                               ret = -EIO;
                                goto out;
                        }
                }
@@ -102,13 +102,13 @@ static int usb_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs, int num)
                /* read status */
                if (usb_read(adapter, CMD_GET_STATUS, 0, 0, pstatus, 1) != 1) {
                        dev_err(&adapter->dev, "failure reading status\n");
-                       ret = -EREMOTEIO;
+                       ret = -EIO;
                        goto out;
                }
 
                dev_dbg(&adapter->dev, "  status = %d\n", *pstatus);
                if (*pstatus == STATUS_ADDRESS_NAK) {
-                       ret = -EREMOTEIO;
+                       ret = -ENXIO;
                        goto out;
                }
        }
index d8d49f1..90c1c36 100644 (file)
@@ -156,6 +156,8 @@ struct xiic_i2c {
 #define XIIC_RESET_MASK             0xAUL
 
 #define XIIC_PM_TIMEOUT                1000    /* ms */
+/* timeout waiting for the controller to respond */
+#define XIIC_I2C_TIMEOUT       (msecs_to_jiffies(1000))
 /*
  * The following constant is used for the device global interrupt enable
  * register, to enable all interrupts for the device, this is the only bit
@@ -166,7 +168,7 @@ struct xiic_i2c {
 #define xiic_tx_space(i2c) ((i2c)->tx_msg->len - (i2c)->tx_pos)
 #define xiic_rx_space(i2c) ((i2c)->rx_msg->len - (i2c)->rx_pos)
 
-static void xiic_start_xfer(struct xiic_i2c *i2c);
+static int xiic_start_xfer(struct xiic_i2c *i2c);
 static void __xiic_start_xfer(struct xiic_i2c *i2c);
 
 /*
@@ -247,17 +249,29 @@ static inline void xiic_irq_clr_en(struct xiic_i2c *i2c, u32 mask)
        xiic_irq_en(i2c, mask);
 }
 
-static void xiic_clear_rx_fifo(struct xiic_i2c *i2c)
+static int xiic_clear_rx_fifo(struct xiic_i2c *i2c)
 {
        u8 sr;
+       unsigned long timeout;
+
+       timeout = jiffies + XIIC_I2C_TIMEOUT;
        for (sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET);
                !(sr & XIIC_SR_RX_FIFO_EMPTY_MASK);
-               sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET))
+               sr = xiic_getreg8(i2c, XIIC_SR_REG_OFFSET)) {
                xiic_getreg8(i2c, XIIC_DRR_REG_OFFSET);
+               if (time_after(jiffies, timeout)) {
+                       dev_err(i2c->dev, "Failed to clear rx fifo\n");
+                       return -ETIMEDOUT;
+               }
+       }
+
+       return 0;
 }
 
-static void xiic_reinit(struct xiic_i2c *i2c)
+static int xiic_reinit(struct xiic_i2c *i2c)
 {
+       int ret;
+
        xiic_setreg32(i2c, XIIC_RESETR_OFFSET, XIIC_RESET_MASK);
 
        /* Set receive Fifo depth to maximum (zero based). */
@@ -270,12 +284,16 @@ static void xiic_reinit(struct xiic_i2c *i2c)
        xiic_setreg8(i2c, XIIC_CR_REG_OFFSET, XIIC_CR_ENABLE_DEVICE_MASK);
 
        /* make sure RX fifo is empty */
-       xiic_clear_rx_fifo(i2c);
+       ret = xiic_clear_rx_fifo(i2c);
+       if (ret)
+               return ret;
 
        /* Enable interrupts */
        xiic_setreg32(i2c, XIIC_DGIER_OFFSET, XIIC_GINTR_ENABLE_MASK);
 
        xiic_irq_clr_en(i2c, XIIC_INTR_ARB_LOST_MASK);
+
+       return 0;
 }
 
 static void xiic_deinit(struct xiic_i2c *i2c)
@@ -655,12 +673,18 @@ static void __xiic_start_xfer(struct xiic_i2c *i2c)
 
 }
 
-static void xiic_start_xfer(struct xiic_i2c *i2c)
+static int xiic_start_xfer(struct xiic_i2c *i2c)
 {
+       int ret;
        mutex_lock(&i2c->lock);
-       xiic_reinit(i2c);
-       __xiic_start_xfer(i2c);
+
+       ret = xiic_reinit(i2c);
+       if (!ret)
+               __xiic_start_xfer(i2c);
+
        mutex_unlock(&i2c->lock);
+
+       return ret;
 }
 
 static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
@@ -682,7 +706,11 @@ static int xiic_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
        i2c->tx_msg = msgs;
        i2c->nmsgs = num;
 
-       xiic_start_xfer(i2c);
+       err = xiic_start_xfer(i2c);
+       if (err < 0) {
+               dev_err(adap->dev.parent, "Error xiic_start_xfer\n");
+               goto out;
+       }
 
        if (wait_event_timeout(i2c->wait, (i2c->state == STATE_ERROR) ||
                (i2c->state == STATE_DONE), HZ)) {
@@ -760,7 +788,8 @@ static int xiic_i2c_probe(struct platform_device *pdev)
 
        i2c->clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(i2c->clk)) {
-               dev_err(&pdev->dev, "input clock not found.\n");
+               if (PTR_ERR(i2c->clk) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "input clock not found.\n");
                return PTR_ERR(i2c->clk);
        }
        ret = clk_prepare_enable(i2c->clk);
@@ -769,10 +798,10 @@ static int xiic_i2c_probe(struct platform_device *pdev)
                return ret;
        }
        i2c->dev = &pdev->dev;
-       pm_runtime_enable(i2c->dev);
        pm_runtime_set_autosuspend_delay(i2c->dev, XIIC_PM_TIMEOUT);
        pm_runtime_use_autosuspend(i2c->dev);
        pm_runtime_set_active(i2c->dev);
+       pm_runtime_enable(i2c->dev);
        ret = devm_request_threaded_irq(&pdev->dev, irq, xiic_isr,
                                        xiic_process, IRQF_ONESHOT,
                                        pdev->name, i2c);
@@ -794,7 +823,11 @@ static int xiic_i2c_probe(struct platform_device *pdev)
        if (!(sr & XIIC_SR_TX_FIFO_EMPTY_MASK))
                i2c->endianness = BIG;
 
-       xiic_reinit(i2c);
+       ret = xiic_reinit(i2c);
+       if (ret < 0) {
+               dev_err(&pdev->dev, "Cannot xiic_reinit\n");
+               goto err_clk_dis;
+       }
 
        /* add i2c adapter to i2c tree */
        ret = i2c_add_adapter(&i2c->adap);
@@ -806,7 +839,7 @@ static int xiic_i2c_probe(struct platform_device *pdev)
        if (pdata) {
                /* add in known devices to the bus */
                for (i = 0; i < pdata->num_devices; i++)
-                       i2c_new_device(&i2c->adap, pdata->devices + i);
+                       i2c_new_client_device(&i2c->adap, pdata->devices + i);
        }
 
        return 0;
@@ -826,14 +859,16 @@ static int xiic_i2c_remove(struct platform_device *pdev)
        /* remove adapter & data */
        i2c_del_adapter(&i2c->adap);
 
-       ret = clk_prepare_enable(i2c->clk);
-       if (ret) {
-               dev_err(&pdev->dev, "Unable to enable clock.\n");
+       ret = pm_runtime_get_sync(i2c->dev);
+       if (ret < 0)
                return ret;
-       }
+
        xiic_deinit(i2c);
+       pm_runtime_put_sync(i2c->dev);
        clk_disable_unprepare(i2c->clk);
        pm_runtime_disable(&pdev->dev);
+       pm_runtime_set_suspended(&pdev->dev);
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
 
        return 0;
 }
index 62a1c92..8f3dbc9 100644 (file)
@@ -225,7 +225,7 @@ static void i2c_acpi_register_device(struct i2c_adapter *adapter,
        adev->power.flags.ignore_parent = true;
        acpi_device_set_enumerated(adev);
 
-       if (!i2c_new_device(adapter, info)) {
+       if (IS_ERR(i2c_new_client_device(adapter, info))) {
                adev->power.flags.ignore_parent = false;
                dev_err(&adapter->dev,
                        "failed to add I2C device %s from ACPI\n",
@@ -451,7 +451,8 @@ struct notifier_block i2c_acpi_notifier = {
  * resources, in that case this function can be used to create an i2c-client
  * for other I2cSerialBus resources in the Current Resource Settings table.
  *
- * Also see i2c_new_device, which this function calls to create the i2c-client.
+ * Also see i2c_new_client_device, which this function calls to create the
+ * i2c-client.
  *
  * Returns a pointer to the new i2c-client, or error pointer in case of failure.
  * Specifically, -EPROBE_DEFER is returned if the adapter is not found.
@@ -461,7 +462,6 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
 {
        struct i2c_acpi_lookup lookup;
        struct i2c_adapter *adapter;
-       struct i2c_client *client;
        struct acpi_device *adev;
        LIST_HEAD(resource_list);
        int ret;
@@ -489,11 +489,7 @@ struct i2c_client *i2c_acpi_new_device(struct device *dev, int index,
        if (!adapter)
                return ERR_PTR(-EPROBE_DEFER);
 
-       client = i2c_new_device(adapter, info);
-       if (!client)
-               return ERR_PTR(-ENODEV);
-
-       return client;
+       return i2c_new_client_device(adapter, info);
 }
 EXPORT_SYMBOL_GPL(i2c_acpi_new_device);
 
index 35b2097..cefad08 100644 (file)
@@ -456,15 +456,15 @@ static void i2c_client_dev_release(struct device *dev)
 }
 
 static ssize_t
-show_name(struct device *dev, struct device_attribute *attr, char *buf)
+name_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        return sprintf(buf, "%s\n", dev->type == &i2c_client_type ?
                       to_i2c_client(dev)->name : to_i2c_adapter(dev)->name);
 }
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
+static DEVICE_ATTR_RO(name);
 
 static ssize_t
-show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
+modalias_show(struct device *dev, struct device_attribute *attr, char *buf)
 {
        struct i2c_client *client = to_i2c_client(dev);
        int len;
@@ -479,7 +479,7 @@ show_modalias(struct device *dev, struct device_attribute *attr, char *buf)
 
        return sprintf(buf, "%s%s\n", I2C_MODULE_PREFIX, client->name);
 }
-static DEVICE_ATTR(modalias, S_IRUGO, show_modalias, NULL);
+static DEVICE_ATTR_RO(modalias);
 
 static struct attribute *i2c_dev_attrs[] = {
        &dev_attr_name.attr,
@@ -831,8 +831,8 @@ EXPORT_SYMBOL_GPL(i2c_new_device);
 
 
 /**
- * i2c_unregister_device - reverse effect of i2c_new_device()
- * @client: value returned from i2c_new_device()
+ * i2c_unregister_device - reverse effect of i2c_new_*_device()
+ * @client: value returned from i2c_new_*_device()
  * Context: can sleep
  */
 void i2c_unregister_device(struct i2c_client *client)
@@ -1023,8 +1023,8 @@ EXPORT_SYMBOL_GPL(i2c_adapter_depth);
  * the user to provide incorrect parameters.
  */
 static ssize_t
-i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
-                    const char *buf, size_t count)
+new_device_store(struct device *dev, struct device_attribute *attr,
+                const char *buf, size_t count)
 {
        struct i2c_adapter *adap = to_i2c_adapter(dev);
        struct i2c_board_info info;
@@ -1079,7 +1079,7 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
 
        return count;
 }
-static DEVICE_ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device);
+static DEVICE_ATTR_WO(new_device);
 
 /*
  * And of course let the users delete the devices they instantiated, if
@@ -1091,8 +1091,8 @@ static DEVICE_ATTR(new_device, S_IWUSR, NULL, i2c_sysfs_new_device);
  * the user to delete the wrong device.
  */
 static ssize_t
-i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
-                       const char *buf, size_t count)
+delete_device_store(struct device *dev, struct device_attribute *attr,
+                   const char *buf, size_t count)
 {
        struct i2c_adapter *adap = to_i2c_adapter(dev);
        struct i2c_client *client, *next;
@@ -1135,7 +1135,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
        return res;
 }
 static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, S_IWUSR, NULL,
-                                  i2c_sysfs_delete_device);
+                                 delete_device_store);
 
 static struct attribute *i2c_adapter_attrs[] = {
        &dev_attr_name.attr,
@@ -1178,9 +1178,8 @@ static void i2c_scan_static_board_info(struct i2c_adapter *adapter)
 
        down_read(&__i2c_board_lock);
        list_for_each_entry(devinfo, &__i2c_board_list, list) {
-               if (devinfo->busnum == adapter->nr
-                               && !i2c_new_device(adapter,
-                                               &devinfo->board_info))
+               if (devinfo->busnum == adapter->nr &&
+                   IS_ERR(i2c_new_client_device(adapter, &devinfo->board_info)))
                        dev_err(&adapter->dev,
                                "Can't create device at 0x%02x\n",
                                devinfo->board_info.addr);
@@ -2167,8 +2166,8 @@ static int i2c_detect_address(struct i2c_client *temp_client,
 
                dev_dbg(&adapter->dev, "Creating %s at 0x%02x\n",
                        info.type, info.addr);
-               client = i2c_new_device(adapter, &info);
-               if (client)
+               client = i2c_new_client_device(adapter, &info);
+               if (!IS_ERR(client))
                        list_add_tail(&client->detected, &driver->clients);
                else
                        dev_err(&adapter->dev, "Failed creating %s at 0x%02x\n",
index e4d296b..6787c1f 100644 (file)
@@ -75,11 +75,10 @@ static struct i2c_client *of_i2c_register_device(struct i2c_adapter *adap,
        if (ret)
                return ERR_PTR(ret);
 
-       client = i2c_new_device(adap, &info);
-       if (!client) {
+       client = i2c_new_client_device(adap, &info);
+       if (IS_ERR(client))
                dev_err(&adap->dev, "of_i2c: Failure registering %pOF\n", node);
-               return ERR_PTR(-EINVAL);
-       }
+
        return client;
 }
 
index 50e1fb4..6daec8d 100644 (file)
@@ -16,6 +16,7 @@
  * warranty of any kind, whether express or implied.
  */
 
+#include <linux/bitops.h>
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/i2c.h>
 #define PCA9541_CONTROL                0x01
 #define PCA9541_ISTAT          0x02
 
-#define PCA9541_CTL_MYBUS      (1 << 0)
-#define PCA9541_CTL_NMYBUS     (1 << 1)
-#define PCA9541_CTL_BUSON      (1 << 2)
-#define PCA9541_CTL_NBUSON     (1 << 3)
-#define PCA9541_CTL_BUSINIT    (1 << 4)
-#define PCA9541_CTL_TESTON     (1 << 6)
-#define PCA9541_CTL_NTESTON    (1 << 7)
-
-#define PCA9541_ISTAT_INTIN    (1 << 0)
-#define PCA9541_ISTAT_BUSINIT  (1 << 1)
-#define PCA9541_ISTAT_BUSOK    (1 << 2)
-#define PCA9541_ISTAT_BUSLOST  (1 << 3)
-#define PCA9541_ISTAT_MYTEST   (1 << 6)
-#define PCA9541_ISTAT_NMYTEST  (1 << 7)
+#define PCA9541_CTL_MYBUS      BIT(0)
+#define PCA9541_CTL_NMYBUS     BIT(1)
+#define PCA9541_CTL_BUSON      BIT(2)
+#define PCA9541_CTL_NBUSON     BIT(3)
+#define PCA9541_CTL_BUSINIT    BIT(4)
+#define PCA9541_CTL_TESTON     BIT(6)
+#define PCA9541_CTL_NTESTON    BIT(7)
+
+#define PCA9541_ISTAT_INTIN    BIT(0)
+#define PCA9541_ISTAT_BUSINIT  BIT(1)
+#define PCA9541_ISTAT_BUSOK    BIT(2)
+#define PCA9541_ISTAT_BUSLOST  BIT(3)
+#define PCA9541_ISTAT_MYTEST   BIT(6)
+#define PCA9541_ISTAT_NMYTEST  BIT(7)
 
 #define BUSON          (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON)
 #define MYBUS          (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS)
index 923aa3a..a0d926a 100644 (file)
@@ -86,7 +86,7 @@ struct pca954x {
 
        u8 last_chan;           /* last register value */
        /* MUX_IDLE_AS_IS, MUX_IDLE_DISCONNECT or >= 0 for channel */
-       s8 idle_state;
+       s32 idle_state;
 
        struct i2c_client *client;
 
@@ -229,20 +229,23 @@ static int pca954x_reg_write(struct i2c_adapter *adap,
                                I2C_SMBUS_BYTE, &dummy);
 }
 
+static u8 pca954x_regval(struct pca954x *data, u8 chan)
+{
+       /* We make switches look like muxes, not sure how to be smarter. */
+       if (data->chip->muxtype == pca954x_ismux)
+               return chan | data->chip->enable;
+       else
+               return 1 << chan;
+}
+
 static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan)
 {
        struct pca954x *data = i2c_mux_priv(muxc);
        struct i2c_client *client = data->client;
-       const struct chip_desc *chip = data->chip;
        u8 regval;
        int ret = 0;
 
-       /* we make switches look like muxes, not sure how to be smarter */
-       if (chip->muxtype == pca954x_ismux)
-               regval = chan | chip->enable;
-       else
-               regval = 1 << chan;
-
+       regval = pca954x_regval(data, chan);
        /* Only select the channel if its different from the last channel */
        if (data->last_chan != regval) {
                ret = pca954x_reg_write(muxc->parent, client, regval);
@@ -256,7 +259,7 @@ static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan)
 {
        struct pca954x *data = i2c_mux_priv(muxc);
        struct i2c_client *client = data->client;
-       s8 idle_state;
+       s32 idle_state;
 
        idle_state = READ_ONCE(data->idle_state);
        if (idle_state >= 0)
@@ -402,6 +405,22 @@ static void pca954x_cleanup(struct i2c_mux_core *muxc)
        i2c_mux_del_adapters(muxc);
 }
 
+static int pca954x_init(struct i2c_client *client, struct pca954x *data)
+{
+       int ret;
+
+       if (data->idle_state >= 0)
+               data->last_chan = pca954x_regval(data, data->idle_state);
+       else
+               data->last_chan = 0; /* Disconnect multiplexer */
+
+       ret = i2c_smbus_write_byte(client, data->last_chan);
+       if (ret < 0)
+               data->last_chan = 0;
+
+       return ret;
+}
+
 /*
  * I2C init/probing/exit functions
  */
@@ -411,7 +430,6 @@ static int pca954x_probe(struct i2c_client *client,
        struct i2c_adapter *adap = client->adapter;
        struct device *dev = &client->dev;
        struct device_node *np = dev->of_node;
-       bool idle_disconnect_dt;
        struct gpio_desc *gpio;
        struct i2c_mux_core *muxc;
        struct pca954x *data;
@@ -462,23 +480,24 @@ static int pca954x_probe(struct i2c_client *client,
                }
        }
 
-       /* Write the mux register at addr to verify
+       data->idle_state = MUX_IDLE_AS_IS;
+       if (of_property_read_u32(np, "idle-state", &data->idle_state)) {
+               if (np && of_property_read_bool(np, "i2c-mux-idle-disconnect"))
+                       data->idle_state = MUX_IDLE_DISCONNECT;
+       }
+
+       /*
+        * Write the mux register at addr to verify
         * that the mux is in fact present. This also
-        * initializes the mux to disconnected state.
+        * initializes the mux to a channel
+        * or disconnected state.
         */
-       if (i2c_smbus_write_byte(client, 0) < 0) {
+       ret = pca954x_init(client, data);
+       if (ret < 0) {
                dev_warn(dev, "probe failed\n");
                return -ENODEV;
        }
 
-       data->last_chan = 0;               /* force the first selection */
-       data->idle_state = MUX_IDLE_AS_IS;
-
-       idle_disconnect_dt = np &&
-               of_property_read_bool(np, "i2c-mux-idle-disconnect");
-       if (idle_disconnect_dt)
-               data->idle_state = MUX_IDLE_DISCONNECT;
-
        ret = pca954x_irq_setup(muxc);
        if (ret)
                goto fail_cleanup;
@@ -530,9 +549,13 @@ static int pca954x_resume(struct device *dev)
        struct i2c_client *client = to_i2c_client(dev);
        struct i2c_mux_core *muxc = i2c_get_clientdata(client);
        struct pca954x *data = i2c_mux_priv(muxc);
+       int ret;
 
-       data->last_chan = 0;
-       return i2c_smbus_write_byte(client, 0);
+       ret = pca954x_init(client, data);
+       if (ret < 0)
+               dev_err(&client->dev, "failed to verify mux presence\n");
+
+       return ret;
 }
 #endif
 
index e73016c..15c17f3 100644 (file)
@@ -381,13 +381,12 @@ parse_error:
        return -EINVAL;
 }
 
-static const struct file_operations ide_settings_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = ide_settings_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = ide_settings_proc_write,
+static const struct proc_ops ide_settings_proc_ops = {
+       .proc_open      = ide_settings_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = ide_settings_proc_write,
 };
 
 int ide_capacity_proc_show(struct seq_file *m, void *v)
@@ -546,7 +545,7 @@ void ide_proc_port_register_devices(ide_hwif_t *hwif)
                if (drive->proc) {
                        ide_add_proc_entries(drive->proc, generic_drive_entries, drive);
                        proc_create_data("settings", S_IFREG|S_IRUSR|S_IWUSR,
-                                       drive->proc, &ide_settings_proc_fops,
+                                       drive->proc, &ide_settings_proc_ops,
                                        drive);
                }
                sprintf(name, "ide%d/%s", (drive->name[2]-'a')/2, drive->name);
@@ -615,7 +614,7 @@ static int ide_drivers_show(struct seq_file *s, void *p)
        return 0;
 }
 
-DEFINE_SHOW_ATTRIBUTE(ide_drivers);
+DEFINE_PROC_SHOW_ATTRIBUTE(ide_drivers);
 
 void proc_ide_create(void)
 {
@@ -624,7 +623,7 @@ void proc_ide_create(void)
        if (!proc_ide_root)
                return;
 
-       proc_create("drivers", 0, proc_ide_root, &ide_drivers_fops);
+       proc_create("drivers", 0, proc_ide_root, &ide_drivers_proc_ops);
 }
 
 void proc_ide_destroy(void)
index 7833e65..d556066 100644 (file)
@@ -63,6 +63,7 @@ static struct cpuidle_driver intel_idle_driver = {
 };
 /* intel_idle.max_cstate=0 disables driver */
 static int max_cstate = CPUIDLE_STATE_MAX - 1;
+static unsigned int disabled_states_mask;
 
 static unsigned int mwait_substates;
 
@@ -1131,6 +1132,10 @@ static bool no_acpi __read_mostly;
 module_param(no_acpi, bool, 0444);
 MODULE_PARM_DESC(no_acpi, "Do not use ACPI _CST for building the idle states list");
 
+static bool force_use_acpi __read_mostly; /* No effect if no_acpi is set. */
+module_param_named(use_acpi, force_use_acpi, bool, 0444);
+MODULE_PARM_DESC(use_acpi, "Use ACPI _CST for building the idle states list");
+
 static struct acpi_processor_power acpi_state_table __initdata;
 
 /**
@@ -1230,6 +1235,9 @@ static void __init intel_idle_init_cstates_acpi(struct cpuidle_driver *drv)
                if (cx->type > ACPI_STATE_C2)
                        state->flags |= CPUIDLE_FLAG_TLB_FLUSHED;
 
+               if (disabled_states_mask & BIT(cstate))
+                       state->flags |= CPUIDLE_FLAG_OFF;
+
                state->enter = intel_idle;
                state->enter_s2idle = intel_idle_s2idle;
        }
@@ -1258,6 +1266,8 @@ static bool __init intel_idle_off_by_default(u32 mwait_hint)
        return true;
 }
 #else /* !CONFIG_ACPI_PROCESSOR_CSTATE */
+#define force_use_acpi (false)
+
 static inline bool intel_idle_acpi_cst_extract(void) { return false; }
 static inline void intel_idle_init_cstates_acpi(struct cpuidle_driver *drv) { }
 static inline bool intel_idle_off_by_default(u32 mwait_hint) { return false; }
@@ -1460,8 +1470,10 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
                /* Structure copy. */
                drv->states[drv->state_count] = cpuidle_state_table[cstate];
 
-               if (icpu->use_acpi && intel_idle_off_by_default(mwait_hint) &&
-                   !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE))
+               if ((disabled_states_mask & BIT(drv->state_count)) ||
+                   ((icpu->use_acpi || force_use_acpi) &&
+                    intel_idle_off_by_default(mwait_hint) &&
+                    !(cpuidle_state_table[cstate].flags & CPUIDLE_FLAG_ALWAYS_ENABLE)))
                        drv->states[drv->state_count].flags |= CPUIDLE_FLAG_OFF;
 
                drv->state_count++;
@@ -1480,6 +1492,10 @@ static void __init intel_idle_init_cstates_icpu(struct cpuidle_driver *drv)
 static void __init intel_idle_cpuidle_driver_init(struct cpuidle_driver *drv)
 {
        cpuidle_poll_state_init(drv);
+
+       if (disabled_states_mask & BIT(0))
+               drv->states[0].flags |= CPUIDLE_FLAG_OFF;
+
        drv->state_count = 1;
 
        if (icpu)
@@ -1607,7 +1623,7 @@ static int __init intel_idle_init(void)
        icpu = (const struct idle_cpu *)id->driver_data;
        if (icpu) {
                cpuidle_state_table = icpu->state_table;
-               if (icpu->use_acpi)
+               if (icpu->use_acpi || force_use_acpi)
                        intel_idle_acpi_cst_extract();
        } else if (!intel_idle_acpi_cst_extract()) {
                return -ENODEV;
@@ -1660,3 +1676,11 @@ device_initcall(intel_idle_init);
  * is the easiest way (currently) to continue doing that.
  */
 module_param(max_cstate, int, 0444);
+/*
+ * The positions of the bits that are set in this number are the indices of the
+ * idle states to be disabled by default (as reflected by the names of the
+ * corresponding idle state directories in sysfs, "state0", "state1" ...
+ * "state<i>" ..., where <i> is the index of the given state).
+ */
+module_param_named(states_off, disabled_states_mask, uint, 0444);
+MODULE_PARM_DESC(states_off, "Mask of disabled idle states");
index 65f85fa..68e847c 100644 (file)
@@ -18,7 +18,6 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 #include <linux/kernel.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_data/cros_ec_commands.h>
index 7dce044..576e45f 100644 (file)
@@ -16,7 +16,6 @@
 #include <linux/iio/trigger_consumer.h>
 #include <linux/iio/triggered_buffer.h>
 #include <linux/kernel.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
index 81a7f69..d3a3626 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/iio/kfifo_buf.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/kernel.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_data/cros_ec_commands.h>
index d85a391..7a838e2 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/kernel.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
index 52f53f3..b521beb 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/iio/triggered_buffer.h>
 #include <linux/iio/trigger_consumer.h>
 #include <linux/kernel.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/platform_data/cros_ec_commands.h>
index ee6c323..fce43e6 100644 (file)
@@ -1216,13 +1216,12 @@ static int input_proc_devices_open(struct inode *inode, struct file *file)
        return seq_open(file, &input_devices_seq_ops);
 }
 
-static const struct file_operations input_devices_fileops = {
-       .owner          = THIS_MODULE,
-       .open           = input_proc_devices_open,
-       .poll           = input_proc_devices_poll,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops input_devices_proc_ops = {
+       .proc_open      = input_proc_devices_open,
+       .proc_poll      = input_proc_devices_poll,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 static void *input_handlers_seq_start(struct seq_file *seq, loff_t *pos)
@@ -1280,12 +1279,11 @@ static int input_proc_handlers_open(struct inode *inode, struct file *file)
        return seq_open(file, &input_handlers_seq_ops);
 }
 
-static const struct file_operations input_handlers_fileops = {
-       .owner          = THIS_MODULE,
-       .open           = input_proc_handlers_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops input_handlers_proc_ops = {
+       .proc_open      = input_proc_handlers_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 static int __init input_proc_init(void)
@@ -1297,12 +1295,12 @@ static int __init input_proc_init(void)
                return -ENOMEM;
 
        entry = proc_create("devices", 0, proc_bus_input_dir,
-                           &input_devices_fileops);
+                           &input_devices_proc_ops);
        if (!entry)
                goto fail1;
 
        entry = proc_create("handlers", 0, proc_bus_input_dir,
-                           &input_handlers_fileops);
+                           &input_handlers_proc_ops);
        if (!entry)
                goto fail2;
 
index 17c1cca..c8f87df 100644 (file)
@@ -191,9 +191,10 @@ static ssize_t axp20x_store_attr_shutdown(struct device *dev,
                                 axp20x_pek->info->shutdown_mask, buf, count);
 }
 
-DEVICE_ATTR(startup, 0644, axp20x_show_attr_startup, axp20x_store_attr_startup);
-DEVICE_ATTR(shutdown, 0644, axp20x_show_attr_shutdown,
-           axp20x_store_attr_shutdown);
+static DEVICE_ATTR(startup, 0644, axp20x_show_attr_startup,
+                  axp20x_store_attr_startup);
+static DEVICE_ATTR(shutdown, 0644, axp20x_show_attr_shutdown,
+                  axp20x_store_attr_shutdown);
 
 static struct attribute *axp20x_attrs[] = {
        &dev_attr_startup.attr,
@@ -279,8 +280,7 @@ static int axp20x_pek_probe_input_device(struct axp20x_pek *axp20x_pek,
                return error;
        }
 
-       if (axp20x_pek->axp20x->variant == AXP288_ID)
-               enable_irq_wake(axp20x_pek->irq_dbr);
+       device_init_wakeup(&pdev->dev, true);
 
        return 0;
 }
@@ -352,6 +352,40 @@ static int axp20x_pek_probe(struct platform_device *pdev)
        return 0;
 }
 
+static int __maybe_unused axp20x_pek_suspend(struct device *dev)
+{
+       struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
+
+       /*
+        * As nested threaded IRQs are not automatically disabled during
+        * suspend, we must explicitly disable non-wakeup IRQs.
+        */
+       if (device_may_wakeup(dev)) {
+               enable_irq_wake(axp20x_pek->irq_dbf);
+               enable_irq_wake(axp20x_pek->irq_dbr);
+       } else {
+               disable_irq(axp20x_pek->irq_dbf);
+               disable_irq(axp20x_pek->irq_dbr);
+       }
+
+       return 0;
+}
+
+static int __maybe_unused axp20x_pek_resume(struct device *dev)
+{
+       struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
+
+       if (device_may_wakeup(dev)) {
+               disable_irq_wake(axp20x_pek->irq_dbf);
+               disable_irq_wake(axp20x_pek->irq_dbr);
+       } else {
+               enable_irq(axp20x_pek->irq_dbf);
+               enable_irq(axp20x_pek->irq_dbr);
+       }
+
+       return 0;
+}
+
 static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
 {
        struct axp20x_pek *axp20x_pek = dev_get_drvdata(dev);
@@ -371,6 +405,7 @@ static int __maybe_unused axp20x_pek_resume_noirq(struct device *dev)
 }
 
 static const struct dev_pm_ops axp20x_pek_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(axp20x_pek_suspend, axp20x_pek_resume)
 #ifdef CONFIG_PM_SLEEP
        .resume_noirq = axp20x_pek_resume_noirq,
 #endif
index bbf9ae9..6adea8a 100644 (file)
@@ -412,6 +412,10 @@ struct f11_2d_sensor_queries {
 
 /* Defs for Ctrl0. */
 #define RMI_F11_REPORT_MODE_MASK        0x07
+#define RMI_F11_REPORT_MODE_CONTINUOUS  (0 << 0)
+#define RMI_F11_REPORT_MODE_REDUCED     (1 << 0)
+#define RMI_F11_REPORT_MODE_FS_CHANGE   (2 << 0)
+#define RMI_F11_REPORT_MODE_FP_CHANGE   (3 << 0)
 #define RMI_F11_ABS_POS_FILT            (1 << 3)
 #define RMI_F11_REL_POS_FILT            (1 << 4)
 #define RMI_F11_REL_BALLISTICS          (1 << 5)
@@ -1195,6 +1199,16 @@ static int rmi_f11_initialize(struct rmi_function *fn)
                ctrl->ctrl0_11[RMI_F11_DELTA_Y_THRESHOLD] =
                        sensor->axis_align.delta_y_threshold;
 
+       /*
+        * If distance threshold values are set, switch to reduced reporting
+        * mode so they actually get used by the controller.
+        */
+       if (ctrl->ctrl0_11[RMI_F11_DELTA_X_THRESHOLD] ||
+           ctrl->ctrl0_11[RMI_F11_DELTA_Y_THRESHOLD]) {
+               ctrl->ctrl0_11[0] &= ~RMI_F11_REPORT_MODE_MASK;
+               ctrl->ctrl0_11[0] |= RMI_F11_REPORT_MODE_REDUCED;
+       }
+
        if (f11->sens_query.has_dribble) {
                switch (sensor->dribble) {
                case RMI_REG_STATE_OFF:
index f3e18f8..373a164 100644 (file)
@@ -165,6 +165,16 @@ config SERIO_MACEPS2
          To compile this driver as a module, choose M here: the
          module will be called maceps2.
 
+config SERIO_SGI_IOC3
+       tristate "SGI IOC3 PS/2 controller"
+       depends on SGI_MFD_IOC3
+       help
+         Say Y here if you have an SGI Onyx2, SGI Octane or IOC3 PCI card
+         and you want to attach and use a keyboard, mouse, or both.
+
+         To compile this driver as a module, choose M here: the
+         module will be called ioc3kbd.
+
 config SERIO_LIBPS2
        tristate "PS/2 driver library"
        depends on SERIO_I8042 || SERIO_I8042=n
index 67950a5..6d97bad 100644 (file)
@@ -20,6 +20,7 @@ obj-$(CONFIG_HIL_MLC)         += hp_sdc_mlc.o hil_mlc.o
 obj-$(CONFIG_SERIO_PCIPS2)     += pcips2.o
 obj-$(CONFIG_SERIO_PS2MULT)    += ps2mult.o
 obj-$(CONFIG_SERIO_MACEPS2)    += maceps2.o
+obj-$(CONFIG_SERIO_SGI_IOC3)   += ioc3kbd.o
 obj-$(CONFIG_SERIO_LIBPS2)     += libps2.o
 obj-$(CONFIG_SERIO_RAW)                += serio_raw.o
 obj-$(CONFIG_SERIO_AMS_DELTA)  += ams_delta_serio.o
index f290d5d..594ac4e 100644 (file)
@@ -51,7 +51,7 @@ struct apbps2_regs {
 
 struct apbps2_priv {
        struct serio            *io;
-       struct apbps2_regs      *regs;
+       struct apbps2_regs      __iomem *regs;
 };
 
 static int apbps2_idx;
index e486a8a..df4e9f6 100644 (file)
@@ -259,6 +259,8 @@ static int hv_kbd_connect_to_vsp(struct hv_device *hv_dev)
        u32 proto_status;
        int error;
 
+       reinit_completion(&kbd_dev->wait_event);
+
        request = &kbd_dev->protocol_req;
        memset(request, 0, sizeof(struct synth_kbd_protocol_request));
        request->header.type = __cpu_to_le32(SYNTH_KBD_PROTOCOL_REQUEST);
@@ -380,6 +382,29 @@ static int hv_kbd_remove(struct hv_device *hv_dev)
        return 0;
 }
 
+static int hv_kbd_suspend(struct hv_device *hv_dev)
+{
+       vmbus_close(hv_dev->channel);
+
+       return 0;
+}
+
+static int hv_kbd_resume(struct hv_device *hv_dev)
+{
+       int ret;
+
+       ret = vmbus_open(hv_dev->channel,
+                        KBD_VSC_SEND_RING_BUFFER_SIZE,
+                        KBD_VSC_RECV_RING_BUFFER_SIZE,
+                        NULL, 0,
+                        hv_kbd_on_channel_callback,
+                        hv_dev);
+       if (ret == 0)
+               ret = hv_kbd_connect_to_vsp(hv_dev);
+
+       return ret;
+}
+
 static const struct hv_vmbus_device_id id_table[] = {
        /* Keyboard guid */
        { HV_KBD_GUID, },
@@ -393,6 +418,8 @@ static struct  hv_driver hv_kbd_drv = {
        .id_table = id_table,
        .probe = hv_kbd_probe,
        .remove = hv_kbd_remove,
+       .suspend = hv_kbd_suspend,
+       .resume = hv_kbd_resume,
        .driver = {
                .probe_type = PROBE_PREFER_ASYNCHRONOUS,
        },
diff --git a/drivers/input/serio/ioc3kbd.c b/drivers/input/serio/ioc3kbd.c
new file mode 100644 (file)
index 0000000..d51bfe9
--- /dev/null
@@ -0,0 +1,216 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * SGI IOC3 PS/2 controller driver for linux
+ *
+ * Copyright (C) 2019 Thomas Bogendoerfer <tbogendoerfer@suse.de>
+ *
+ * Based on code Copyright (C) 2005 Stanislaw Skowronek <skylark@unaligned.org>
+ *               Copyright (C) 2009 Johannes Dickgreber <tanzy@gmx.de>
+ */
+
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/serio.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include <asm/sn/ioc3.h>
+
+struct ioc3kbd_data {
+       struct ioc3_serioregs __iomem *regs;
+       struct serio *kbd, *aux;
+       bool kbd_exists, aux_exists;
+       int irq;
+};
+
+static int ioc3kbd_wait(struct ioc3_serioregs __iomem *regs, u32 mask)
+{
+       unsigned long timeout = 0;
+
+       while ((readl(&regs->km_csr) & mask) && (timeout < 250)) {
+               udelay(50);
+               timeout++;
+       }
+       return (timeout >= 250) ? -ETIMEDOUT : 0;
+}
+
+static int ioc3kbd_write(struct serio *dev, u8 val)
+{
+       struct ioc3kbd_data *d = dev->port_data;
+       int ret;
+
+       ret = ioc3kbd_wait(d->regs, KM_CSR_K_WRT_PEND);
+       if (ret)
+               return ret;
+
+       writel(val, &d->regs->k_wd);
+
+       return 0;
+}
+
+static int ioc3kbd_start(struct serio *dev)
+{
+       struct ioc3kbd_data *d = dev->port_data;
+
+       d->kbd_exists = true;
+       return 0;
+}
+
+static void ioc3kbd_stop(struct serio *dev)
+{
+       struct ioc3kbd_data *d = dev->port_data;
+
+       d->kbd_exists = false;
+}
+
+static int ioc3aux_write(struct serio *dev, u8 val)
+{
+       struct ioc3kbd_data *d = dev->port_data;
+       int ret;
+
+       ret = ioc3kbd_wait(d->regs, KM_CSR_M_WRT_PEND);
+       if (ret)
+               return ret;
+
+       writel(val, &d->regs->m_wd);
+
+       return 0;
+}
+
+static int ioc3aux_start(struct serio *dev)
+{
+       struct ioc3kbd_data *d = dev->port_data;
+
+       d->aux_exists = true;
+       return 0;
+}
+
+static void ioc3aux_stop(struct serio *dev)
+{
+       struct ioc3kbd_data *d = dev->port_data;
+
+       d->aux_exists = false;
+}
+
+static void ioc3kbd_process_data(struct serio *dev, u32 data)
+{
+       if (data & KM_RD_VALID_0)
+               serio_interrupt(dev, (data >> KM_RD_DATA_0_SHIFT) & 0xff, 0);
+       if (data & KM_RD_VALID_1)
+               serio_interrupt(dev, (data >> KM_RD_DATA_1_SHIFT) & 0xff, 0);
+       if (data & KM_RD_VALID_2)
+               serio_interrupt(dev, (data >> KM_RD_DATA_2_SHIFT) & 0xff, 0);
+}
+
+static irqreturn_t ioc3kbd_intr(int itq, void *dev_id)
+{
+       struct ioc3kbd_data *d = dev_id;
+       u32 data_k, data_m;
+
+       data_k = readl(&d->regs->k_rd);
+       if (d->kbd_exists)
+               ioc3kbd_process_data(d->kbd, data_k);
+
+       data_m = readl(&d->regs->m_rd);
+       if (d->aux_exists)
+               ioc3kbd_process_data(d->aux, data_m);
+
+       return IRQ_HANDLED;
+}
+
+static int ioc3kbd_probe(struct platform_device *pdev)
+{
+       struct ioc3_serioregs __iomem *regs;
+       struct device *dev = &pdev->dev;
+       struct ioc3kbd_data *d;
+       struct serio *sk, *sa;
+       int irq, ret;
+
+       regs = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(regs))
+               return PTR_ERR(regs);
+
+       irq = platform_get_irq(pdev, 0);
+       if (irq < 0)
+               return -ENXIO;
+
+       d = devm_kzalloc(dev, sizeof(*d), GFP_KERNEL);
+       if (!d)
+               return -ENOMEM;
+
+       sk = kzalloc(sizeof(*sk), GFP_KERNEL);
+       if (!sk)
+               return -ENOMEM;
+
+       sa = kzalloc(sizeof(*sa), GFP_KERNEL);
+       if (!sa) {
+               kfree(sk);
+               return -ENOMEM;
+       }
+
+       sk->id.type = SERIO_8042;
+       sk->write = ioc3kbd_write;
+       sk->start = ioc3kbd_start;
+       sk->stop = ioc3kbd_stop;
+       snprintf(sk->name, sizeof(sk->name), "IOC3 keyboard %d", pdev->id);
+       snprintf(sk->phys, sizeof(sk->phys), "ioc3/serio%dkbd", pdev->id);
+       sk->port_data = d;
+       sk->dev.parent = dev;
+
+       sa->id.type = SERIO_8042;
+       sa->write = ioc3aux_write;
+       sa->start = ioc3aux_start;
+       sa->stop = ioc3aux_stop;
+       snprintf(sa->name, sizeof(sa->name), "IOC3 auxiliary %d", pdev->id);
+       snprintf(sa->phys, sizeof(sa->phys), "ioc3/serio%daux", pdev->id);
+       sa->port_data = d;
+       sa->dev.parent = dev;
+
+       d->regs = regs;
+       d->kbd = sk;
+       d->aux = sa;
+       d->irq = irq;
+
+       platform_set_drvdata(pdev, d);
+       serio_register_port(d->kbd);
+       serio_register_port(d->aux);
+
+       ret = request_irq(irq, ioc3kbd_intr, IRQF_SHARED, "ioc3-kbd", d);
+       if (ret) {
+               dev_err(dev, "could not request IRQ %d\n", irq);
+               serio_unregister_port(d->kbd);
+               serio_unregister_port(d->aux);
+               return ret;
+       }
+
+       /* enable ports */
+       writel(KM_CSR_K_CLAMP_3 | KM_CSR_M_CLAMP_3, &regs->km_csr);
+
+       return 0;
+}
+
+static int ioc3kbd_remove(struct platform_device *pdev)
+{
+       struct ioc3kbd_data *d = platform_get_drvdata(pdev);
+
+       free_irq(d->irq, d);
+
+       serio_unregister_port(d->kbd);
+       serio_unregister_port(d->aux);
+
+       return 0;
+}
+
+static struct platform_driver ioc3kbd_driver = {
+       .probe          = ioc3kbd_probe,
+       .remove         = ioc3kbd_remove,
+       .driver = {
+               .name = "ioc3-kbd",
+       },
+};
+module_platform_driver(ioc3kbd_driver);
+
+MODULE_AUTHOR("Thomas Bogendoerfer <tbogendoerfer@suse.de>");
+MODULE_DESCRIPTION("SGI IOC3 serio driver");
+MODULE_LICENSE("GPL");
index 51ddb20..8fd7fc3 100644 (file)
@@ -333,7 +333,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
                req->xfer[1].len = 2;
 
                /* for 1uF, settle for 800 usec; no cap, 100 usec.  */
-               req->xfer[1].delay_usecs = ts->vref_delay_usecs;
+               req->xfer[1].delay.value = ts->vref_delay_usecs;
+               req->xfer[1].delay.unit = SPI_DELAY_UNIT_USECS;
                spi_message_add_tail(&req->xfer[1], &req->msg);
 
                /* Enable reference voltage */
@@ -1018,7 +1019,8 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
         * have had enough time to stabilize.
         */
        if (pdata->settle_delay_usecs) {
-               x->delay_usecs = pdata->settle_delay_usecs;
+               x->delay.value = pdata->settle_delay_usecs;
+               x->delay.unit = SPI_DELAY_UNIT_USECS;
 
                x++;
                x->tx_buf = &packet->read_y;
@@ -1061,7 +1063,8 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
 
        /* ... maybe discard first sample ... */
        if (pdata->settle_delay_usecs) {
-               x->delay_usecs = pdata->settle_delay_usecs;
+               x->delay.value = pdata->settle_delay_usecs;
+               x->delay.unit = SPI_DELAY_UNIT_USECS;
 
                x++;
                x->tx_buf = &packet->read_x;
@@ -1094,7 +1097,8 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
 
                /* ... maybe discard first sample ... */
                if (pdata->settle_delay_usecs) {
-                       x->delay_usecs = pdata->settle_delay_usecs;
+                       x->delay.value = pdata->settle_delay_usecs;
+                       x->delay.unit = SPI_DELAY_UNIT_USECS;
 
                        x++;
                        x->tx_buf = &packet->read_z1;
@@ -1125,7 +1129,8 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
 
                /* ... maybe discard first sample ... */
                if (pdata->settle_delay_usecs) {
-                       x->delay_usecs = pdata->settle_delay_usecs;
+                       x->delay.value = pdata->settle_delay_usecs;
+                       x->delay.unit = SPI_DELAY_UNIT_USECS;
 
                        x++;
                        x->tx_buf = &packet->read_z2;
index d61731c..d258772 100644 (file)
  *    http://www.glyn.com/Products/Displays
  */
 
-#include <linux/module.h>
-#include <linux/ratelimit.h>
-#include <linux/irq.h>
-#include <linux/interrupt.h>
-#include <linux/input.h>
-#include <linux/i2c.h>
-#include <linux/kernel.h>
-#include <linux/uaccess.h>
-#include <linux/delay.h>
 #include <linux/debugfs.h>
-#include <linux/slab.h>
+#include <linux/delay.h>
 #include <linux/gpio/consumer.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
 #include <linux/input/mt.h>
 #include <linux/input/touchscreen.h>
-#include <asm/unaligned.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/ratelimit.h>
 #include <linux/regulator/consumer.h>
+#include <linux/slab.h>
+#include <linux/uaccess.h>
+
+#include <asm/unaligned.h>
 
 #define WORK_REGISTER_THRESHOLD                0x00
 #define WORK_REGISTER_REPORT_RATE      0x08
@@ -1050,6 +1051,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
 {
        const struct edt_i2c_chip_data *chip_data;
        struct edt_ft5x06_ts_data *tsdata;
+       u8 buf[2] = { 0xfc, 0x00 };
        struct input_dev *input;
        unsigned long irq_flags;
        int error;
@@ -1140,6 +1142,12 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
                return error;
        }
 
+       /*
+        * Dummy read access. EP0700MLP1 returns bogus data on the first
+        * register read access and ignores writes.
+        */
+       edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf);
+
        edt_ft5x06_ts_set_regs(tsdata);
        edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
        edt_ft5x06_ts_get_parameters(tsdata);
@@ -1200,7 +1208,6 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
                return error;
 
        edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
-       device_init_wakeup(&client->dev, 1);
 
        dev_dbg(&client->dev,
                "EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n",
@@ -1220,29 +1227,6 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client)
        return 0;
 }
 
-static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-
-       if (device_may_wakeup(dev))
-               enable_irq_wake(client->irq);
-
-       return 0;
-}
-
-static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-
-       if (device_may_wakeup(dev))
-               disable_irq_wake(client->irq);
-
-       return 0;
-}
-
-static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops,
-                        edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume);
-
 static const struct edt_i2c_chip_data edt_ft5x06_data = {
        .max_support_points = 5,
 };
@@ -1281,7 +1265,6 @@ static struct i2c_driver edt_ft5x06_ts_driver = {
        .driver = {
                .name = "edt_ft5x06",
                .of_match_table = edt_ft5x06_of_match,
-               .pm = &edt_ft5x06_ts_pm_ops,
        },
        .id_table = edt_ft5x06_ts_id,
        .probe    = edt_ft5x06_ts_probe,
index d4ad24e..4911799 100644 (file)
 #define CMD_HEADER_WRITE       0x54
 #define CMD_HEADER_READ                0x53
 #define CMD_HEADER_6B_READ     0x5B
+#define CMD_HEADER_ROM_READ    0x96
 #define CMD_HEADER_RESP                0x52
 #define CMD_HEADER_6B_RESP     0x9B
+#define CMD_HEADER_ROM_RESP    0x95
 #define CMD_HEADER_HELLO       0x55
 #define CMD_HEADER_REK         0x66
 
@@ -200,6 +202,10 @@ static int elants_i2c_execute_command(struct i2c_client *client,
                expected_response = CMD_HEADER_6B_RESP;
                break;
 
+       case CMD_HEADER_ROM_READ:
+               expected_response = CMD_HEADER_ROM_RESP;
+               break;
+
        default:
                dev_err(&client->dev, "%s: invalid command %*ph\n",
                        __func__, (int)cmd_size, cmd);
@@ -556,6 +562,8 @@ static int elants_i2c_initialize(struct elants_data *ts)
 
        /* hw version is available even if device in recovery state */
        error2 = elants_i2c_query_hw_version(ts);
+       if (!error2)
+               error2 = elants_i2c_query_bc_version(ts);
        if (!error)
                error = error2;
 
@@ -564,8 +572,6 @@ static int elants_i2c_initialize(struct elants_data *ts)
        if (!error)
                error = elants_i2c_query_test_version(ts);
        if (!error)
-               error = elants_i2c_query_bc_version(ts);
-       if (!error)
                error = elants_i2c_query_ts_info(ts);
 
        if (error)
@@ -613,39 +619,94 @@ static int elants_i2c_fw_write_page(struct i2c_client *client,
        return error;
 }
 
+static int elants_i2c_validate_remark_id(struct elants_data *ts,
+                                        const struct firmware *fw)
+{
+       struct i2c_client *client = ts->client;
+       int error;
+       const u8 cmd[] = { CMD_HEADER_ROM_READ, 0x80, 0x1F, 0x00, 0x00, 0x21 };
+       u8 resp[6] = { 0 };
+       u16 ts_remark_id = 0;
+       u16 fw_remark_id = 0;
+
+       /* Compare TS Remark ID and FW Remark ID */
+       error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
+                                       resp, sizeof(resp));
+       if (error) {
+               dev_err(&client->dev, "failed to query Remark ID: %d\n", error);
+               return error;
+       }
+
+       ts_remark_id = get_unaligned_be16(&resp[3]);
+
+       fw_remark_id = get_unaligned_le16(&fw->data[fw->size - 4]);
+
+       if (fw_remark_id != ts_remark_id) {
+               dev_err(&client->dev,
+                       "Remark ID Mismatched: ts_remark_id=0x%04x, fw_remark_id=0x%04x.\n",
+                       ts_remark_id, fw_remark_id);
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int elants_i2c_do_update_firmware(struct i2c_client *client,
                                         const struct firmware *fw,
                                         bool force)
 {
+       struct elants_data *ts = i2c_get_clientdata(client);
        const u8 enter_iap[] = { 0x45, 0x49, 0x41, 0x50 };
        const u8 enter_iap2[] = { 0x54, 0x00, 0x12, 0x34 };
        const u8 iap_ack[] = { 0x55, 0xaa, 0x33, 0xcc };
-       const u8 close_idle[] = {0x54, 0x2c, 0x01, 0x01};
+       const u8 close_idle[] = { 0x54, 0x2c, 0x01, 0x01 };
        u8 buf[HEADER_SIZE];
        u16 send_id;
        int page, n_fw_pages;
        int error;
+       bool check_remark_id = ts->iap_version >= 0x60;
 
        /* Recovery mode detection! */
        if (force) {
                dev_dbg(&client->dev, "Recovery mode procedure\n");
+
+               if (check_remark_id) {
+                       error = elants_i2c_validate_remark_id(ts, fw);
+                       if (error)
+                               return error;
+               }
+
                error = elants_i2c_send(client, enter_iap2, sizeof(enter_iap2));
+               if (error) {
+                       dev_err(&client->dev, "failed to enter IAP mode: %d\n",
+                               error);
+                       return error;
+               }
        } else {
                /* Start IAP Procedure */
                dev_dbg(&client->dev, "Normal IAP procedure\n");
+
                /* Close idle mode */
                error = elants_i2c_send(client, close_idle, sizeof(close_idle));
                if (error)
                        dev_err(&client->dev, "Failed close idle: %d\n", error);
                msleep(60);
+
                elants_i2c_sw_reset(client);
                msleep(20);
-               error = elants_i2c_send(client, enter_iap, sizeof(enter_iap));
-       }
 
-       if (error) {
-               dev_err(&client->dev, "failed to enter IAP mode: %d\n", error);
-               return error;
+               if (check_remark_id) {
+                       error = elants_i2c_validate_remark_id(ts, fw);
+                       if (error)
+                               return error;
+               }
+
+               error = elants_i2c_send(client, enter_iap, sizeof(enter_iap));
+               if (error) {
+                       dev_err(&client->dev, "failed to enter IAP mode: %d\n",
+                               error);
+                       return error;
+               }
        }
 
        msleep(20);
index 0b9d78a..d2fade9 100644 (file)
@@ -82,7 +82,7 @@ config IOMMU_DEBUGFS
 config IOMMU_DEFAULT_PASSTHROUGH
        bool "IOMMU passthrough by default"
        depends on IOMMU_API
-        help
+       help
          Enable passthrough by default, removing the need to pass in
          iommu.passthrough=on or iommu=pt through command line. If this
          is enabled, you can still disable with iommu.passthrough=off
@@ -91,8 +91,8 @@ config IOMMU_DEFAULT_PASSTHROUGH
          If unsure, say N here.
 
 config OF_IOMMU
-       def_bool y
-       depends on OF && IOMMU_API
+       def_bool y
+       depends on OF && IOMMU_API
 
 # IOMMU-agnostic DMA-mapping layer
 config IOMMU_DMA
@@ -214,6 +214,7 @@ config INTEL_IOMMU_SVM
        select PCI_PASID
        select PCI_PRI
        select MMU_NOTIFIER
+       select IOASID
        help
          Shared Virtual Memory (SVM) provides a facility for devices
          to access DMA resources through process address space by
@@ -248,6 +249,18 @@ config INTEL_IOMMU_FLOPPY_WA
          workaround will setup a 1:1 mapping for the first
          16MiB to make floppy (an ISA device) work.
 
+config INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON
+       bool "Enable Intel IOMMU scalable mode by default"
+       depends on INTEL_IOMMU
+       help
+         Selecting this option will enable by default the scalable mode if
+         hardware presents the capability. The scalable mode is defined in
+         VT-d 3.0. The scalable mode capability could be checked by reading
+         /sys/devices/virtual/iommu/dmar*/intel-iommu/ecap. If this option
+         is not selected, scalable mode support could also be enabled by
+         passing intel_iommu=sm_on to the kernel. If not sure, please use
+         the default value.
+
 config IRQ_REMAP
        bool "Support for Interrupt Remapping"
        depends on X86_64 && X86_IO_APIC && PCI_MSI && ACPI
@@ -356,7 +369,7 @@ config SPAPR_TCE_IOMMU
 
 # ARM IOMMU support
 config ARM_SMMU
-       bool "ARM Ltd. System MMU (SMMU) Support"
+       tristate "ARM Ltd. System MMU (SMMU) Support"
        depends on (ARM64 || ARM) && MMU
        select IOMMU_API
        select IOMMU_IO_PGTABLE_LPAE
@@ -368,6 +381,18 @@ config ARM_SMMU
          Say Y here if your SoC includes an IOMMU device implementing
          the ARM SMMU architecture.
 
+config ARM_SMMU_LEGACY_DT_BINDINGS
+       bool "Support the legacy \"mmu-masters\" devicetree bindings"
+       depends on ARM_SMMU=y && OF
+       help
+         Support for the badly designed and deprecated "mmu-masters"
+         devicetree bindings. This allows some DMA masters to attach
+         to the SMMU but does not provide any support via the DMA API.
+         If you're lucky, you might be able to get VFIO up and running.
+
+         If you say Y here then you'll make me very sad. Instead, say N
+         and move your firmware to the utopian future that was 2016.
+
 config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
        bool "Default to disabling bypass on ARM SMMU v1 and v2"
        depends on ARM_SMMU
@@ -394,7 +419,7 @@ config ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT
          config.
 
 config ARM_SMMU_V3
-       bool "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
+       tristate "ARM Ltd. System MMU Version 3 (SMMUv3) Support"
        depends on ARM64
        select IOMMU_API
        select IOMMU_IO_PGTABLE_LPAE
index 97814cc..2104fb8 100644 (file)
@@ -14,7 +14,8 @@ obj-$(CONFIG_MSM_IOMMU) += msm_iommu.o
 obj-$(CONFIG_AMD_IOMMU) += amd_iommu.o amd_iommu_init.o amd_iommu_quirks.o
 obj-$(CONFIG_AMD_IOMMU_DEBUGFS) += amd_iommu_debugfs.o
 obj-$(CONFIG_AMD_IOMMU_V2) += amd_iommu_v2.o
-obj-$(CONFIG_ARM_SMMU) += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
+obj-$(CONFIG_ARM_SMMU) += arm-smmu-mod.o
+arm-smmu-mod-objs += arm-smmu.o arm-smmu-impl.o arm-smmu-qcom.o
 obj-$(CONFIG_ARM_SMMU_V3) += arm-smmu-v3.o
 obj-$(CONFIG_DMAR_TABLE) += dmar.o
 obj-$(CONFIG_INTEL_IOMMU) += intel-iommu.o intel-pasid.o
index 7a6c056..aac132b 100644 (file)
@@ -2294,7 +2294,6 @@ int __init amd_iommu_init_api(void)
 int __init amd_iommu_init_dma_ops(void)
 {
        swiotlb        = (iommu_default_passthrough() || sme_me_mask) ? 1 : 0;
-       iommu_detected = 1;
 
        if (amd_iommu_unmap_flush)
                pr_info("IO/TLB flush on unmap enabled\n");
@@ -2638,15 +2637,6 @@ static void amd_iommu_get_resv_regions(struct device *dev,
        list_add_tail(&region->list, head);
 }
 
-static void amd_iommu_put_resv_regions(struct device *dev,
-                                    struct list_head *head)
-{
-       struct iommu_resv_region *entry, *next;
-
-       list_for_each_entry_safe(entry, next, head, list)
-               kfree(entry);
-}
-
 static bool amd_iommu_is_attach_deferred(struct iommu_domain *domain,
                                         struct device *dev)
 {
@@ -2685,7 +2675,7 @@ const struct iommu_ops amd_iommu_ops = {
        .device_group = amd_iommu_device_group,
        .domain_get_attr = amd_iommu_domain_get_attr,
        .get_resv_regions = amd_iommu_get_resv_regions,
-       .put_resv_regions = amd_iommu_put_resv_regions,
+       .put_resv_regions = generic_iommu_put_resv_regions,
        .is_attach_deferred = amd_iommu_is_attach_deferred,
        .pgsize_bitmap  = AMD_IOMMU_PGSIZES,
        .flush_iotlb_all = amd_iommu_flush_iotlb_all,
index 823cc4e..2759a8d 100644 (file)
@@ -71,6 +71,8 @@
 #define IVHD_FLAG_ISOC_EN_MASK          0x08
 
 #define IVMD_FLAG_EXCL_RANGE            0x08
+#define IVMD_FLAG_IW                    0x04
+#define IVMD_FLAG_IR                    0x02
 #define IVMD_FLAG_UNITY_MAP             0x01
 
 #define ACPI_DEVFLAG_INITPASS           0x01
@@ -147,7 +149,7 @@ bool amd_iommu_dump;
 bool amd_iommu_irq_remap __read_mostly;
 
 int amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_VAPIC;
-static int amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
+static int amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
 
 static bool amd_iommu_detected;
 static bool __initdata amd_iommu_disabled;
@@ -714,7 +716,7 @@ static void iommu_enable_ppr_log(struct amd_iommu *iommu)
        writel(0x00, iommu->mmio_base + MMIO_PPR_HEAD_OFFSET);
        writel(0x00, iommu->mmio_base + MMIO_PPR_TAIL_OFFSET);
 
-       iommu_feature_enable(iommu, CONTROL_PPFLOG_EN);
+       iommu_feature_enable(iommu, CONTROL_PPRLOG_EN);
        iommu_feature_enable(iommu, CONTROL_PPR_EN);
 }
 
@@ -1116,21 +1118,17 @@ static int __init add_early_maps(void)
  */
 static void __init set_device_exclusion_range(u16 devid, struct ivmd_header *m)
 {
-       struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
-
        if (!(m->flags & IVMD_FLAG_EXCL_RANGE))
                return;
 
-       if (iommu) {
-               /*
-                * We only can configure exclusion ranges per IOMMU, not
-                * per device. But we can enable the exclusion range per
-                * device. This is done here
-                */
-               set_dev_entry_bit(devid, DEV_ENTRY_EX);
-               iommu->exclusion_start = m->range_start;
-               iommu->exclusion_length = m->range_length;
-       }
+       /*
+        * Treat per-device exclusion ranges as r/w unity-mapped regions
+        * since some buggy BIOSes might lead to the overwritten exclusion
+        * range (exclusion_start and exclusion_length members). This
+        * happens when there are multiple exclusion ranges (IVMD entries)
+        * defined in ACPI table.
+        */
+       m->flags = (IVMD_FLAG_IW | IVMD_FLAG_IR | IVMD_FLAG_UNITY_MAP);
 }
 
 /*
@@ -1523,8 +1521,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
                        iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
                if (((h->efr_attr & (0x1 << IOMMU_FEAT_GASUP_SHIFT)) == 0))
                        amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
-               if (((h->efr_attr & (0x1 << IOMMU_FEAT_XTSUP_SHIFT)) == 0))
-                       amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
                break;
        case 0x11:
        case 0x40:
@@ -1534,8 +1530,15 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
                        iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
                if (((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0))
                        amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
-               if (((h->efr_reg & (0x1 << IOMMU_EFR_XTSUP_SHIFT)) == 0))
-                       amd_iommu_xt_mode = IRQ_REMAP_XAPIC_MODE;
+               /*
+                * Note: Since iommu_update_intcapxt() leverages
+                * the IOMMU MMIO access to MSI capability block registers
+                * for MSI address lo/hi/data, we need to check both
+                * EFR[XtSup] and EFR[MsiCapMmioSup] for x2APIC support.
+                */
+               if ((h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT)) &&
+                   (h->efr_reg & BIT(IOMMU_EFR_MSICAPMMIOSUP_SHIFT)))
+                       amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
                break;
        default:
                return -EINVAL;
@@ -1727,7 +1730,6 @@ static const struct attribute_group *amd_iommu_groups[] = {
 static int __init iommu_init_pci(struct amd_iommu *iommu)
 {
        int cap_ptr = iommu->cap_ptr;
-       u32 range, misc, low, high;
        int ret;
 
        iommu->dev = pci_get_domain_bus_and_slot(0, PCI_BUS_NUM(iommu->devid),
@@ -1740,19 +1742,12 @@ static int __init iommu_init_pci(struct amd_iommu *iommu)
 
        pci_read_config_dword(iommu->dev, cap_ptr + MMIO_CAP_HDR_OFFSET,
                              &iommu->cap);
-       pci_read_config_dword(iommu->dev, cap_ptr + MMIO_RANGE_OFFSET,
-                             &range);
-       pci_read_config_dword(iommu->dev, cap_ptr + MMIO_MISC_OFFSET,
-                             &misc);
 
        if (!(iommu->cap & (1 << IOMMU_CAP_IOTLB)))
                amd_iommu_iotlb_sup = false;
 
        /* read extended feature bits */
-       low  = readl(iommu->mmio_base + MMIO_EXT_FEATURES);
-       high = readl(iommu->mmio_base + MMIO_EXT_FEATURES + 4);
-
-       iommu->features = ((u64)high << 32) | low;
+       iommu->features = readq(iommu->mmio_base + MMIO_EXT_FEATURES);
 
        if (iommu_feature(iommu, FEATURE_GT)) {
                int glxval;
@@ -1996,8 +1991,8 @@ static int iommu_init_intcapxt(struct amd_iommu *iommu)
        struct irq_affinity_notify *notify = &iommu->intcapxt_notify;
 
        /**
-        * IntCapXT requires XTSup=1, which can be inferred
-        * amd_iommu_xt_mode.
+        * IntCapXT requires XTSup=1 and MsiCapMmioSup=1,
+        * which can be inferred from amd_iommu_xt_mode.
         */
        if (amd_iommu_xt_mode != IRQ_REMAP_X2APIC_MODE)
                return 0;
@@ -2044,7 +2039,7 @@ enable_faults:
        iommu_feature_enable(iommu, CONTROL_EVT_INT_EN);
 
        if (iommu->ppr_log != NULL)
-               iommu_feature_enable(iommu, CONTROL_PPFINT_EN);
+               iommu_feature_enable(iommu, CONTROL_PPRINT_EN);
 
        iommu_ga_log_enable(iommu);
 
index f52f59d..f8d01d6 100644 (file)
 #define CONTROL_COHERENT_EN     0x0aULL
 #define CONTROL_ISOC_EN         0x0bULL
 #define CONTROL_CMDBUF_EN       0x0cULL
-#define CONTROL_PPFLOG_EN       0x0dULL
-#define CONTROL_PPFINT_EN       0x0eULL
+#define CONTROL_PPRLOG_EN       0x0dULL
+#define CONTROL_PPRINT_EN       0x0eULL
 #define CONTROL_PPR_EN          0x0fULL
 #define CONTROL_GT_EN           0x10ULL
 #define CONTROL_GA_EN           0x11ULL
 #define IOMMU_CAP_EFR     27
 
 /* IOMMU Feature Reporting Field (for IVHD type 10h */
-#define IOMMU_FEAT_XTSUP_SHIFT 0
 #define IOMMU_FEAT_GASUP_SHIFT 6
 
 /* IOMMU Extended Feature Register (EFR) */
 #define IOMMU_EFR_XTSUP_SHIFT  2
 #define IOMMU_EFR_GASUP_SHIFT  7
+#define IOMMU_EFR_MSICAPMMIOSUP_SHIFT  46
 
 #define MAX_DOMAIN_ID 65536
 
@@ -463,7 +463,6 @@ struct amd_irte_ops;
  * independent of their use.
  */
 struct protection_domain {
-       struct list_head list;  /* for list of all protection domains */
        struct list_head dev_list; /* List of all devices in this domain */
        struct iommu_domain domain; /* generic domain handle used by
                                       iommu core code */
index b2fe72a..74d97a8 100644 (file)
@@ -119,7 +119,7 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu)
         * Secure has also cleared SACR.CACHE_LOCK for this to take effect...
         */
        reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_ID7);
-       major = FIELD_GET(ID7_MAJOR, reg);
+       major = FIELD_GET(ARM_SMMU_ID7_MAJOR, reg);
        reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sACR);
        if (major >= 2)
                reg &= ~ARM_MMU500_ACR_CACHE_LOCK;
index effe72e..aa3ac2a 100644 (file)
@@ -21,8 +21,7 @@
 #include <linux/io-pgtable.h>
 #include <linux/iommu.h>
 #include <linux/iopoll.h>
-#include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 
 #define STRTAB_STE_0_S1FMT             GENMASK_ULL(5, 4)
 #define STRTAB_STE_0_S1FMT_LINEAR      0
+#define STRTAB_STE_0_S1FMT_64K_L2      2
 #define STRTAB_STE_0_S1CTXPTR_MASK     GENMASK_ULL(51, 6)
 #define STRTAB_STE_0_S1CDMAX           GENMASK_ULL(63, 59)
 
+#define STRTAB_STE_1_S1DSS             GENMASK_ULL(1, 0)
+#define STRTAB_STE_1_S1DSS_TERMINATE   0x0
+#define STRTAB_STE_1_S1DSS_BYPASS      0x1
+#define STRTAB_STE_1_S1DSS_SSID0       0x2
+
 #define STRTAB_STE_1_S1C_CACHE_NC      0UL
 #define STRTAB_STE_1_S1C_CACHE_WBRA    1UL
 #define STRTAB_STE_1_S1C_CACHE_WT      2UL
 
 #define STRTAB_STE_2_S2VMID            GENMASK_ULL(15, 0)
 #define STRTAB_STE_2_VTCR              GENMASK_ULL(50, 32)
+#define STRTAB_STE_2_VTCR_S2T0SZ       GENMASK_ULL(5, 0)
+#define STRTAB_STE_2_VTCR_S2SL0                GENMASK_ULL(7, 6)
+#define STRTAB_STE_2_VTCR_S2IR0                GENMASK_ULL(9, 8)
+#define STRTAB_STE_2_VTCR_S2OR0                GENMASK_ULL(11, 10)
+#define STRTAB_STE_2_VTCR_S2SH0                GENMASK_ULL(13, 12)
+#define STRTAB_STE_2_VTCR_S2TG         GENMASK_ULL(15, 14)
+#define STRTAB_STE_2_VTCR_S2PS         GENMASK_ULL(18, 16)
 #define STRTAB_STE_2_S2AA64            (1UL << 51)
 #define STRTAB_STE_2_S2ENDI            (1UL << 52)
 #define STRTAB_STE_2_S2PTW             (1UL << 54)
 
 #define STRTAB_STE_3_S2TTB_MASK                GENMASK_ULL(51, 4)
 
-/* Context descriptor (stage-1 only) */
+/*
+ * Context descriptors.
+ *
+ * Linear: when less than 1024 SSIDs are supported
+ * 2lvl: at most 1024 L1 entries,
+ *       1024 lazy entries per table.
+ */
+#define CTXDESC_SPLIT                  10
+#define CTXDESC_L2_ENTRIES             (1 << CTXDESC_SPLIT)
+
+#define CTXDESC_L1_DESC_DWORDS         1
+#define CTXDESC_L1_DESC_V              (1UL << 0)
+#define CTXDESC_L1_DESC_L2PTR_MASK     GENMASK_ULL(51, 12)
+
 #define CTXDESC_CD_DWORDS              8
 #define CTXDESC_CD_0_TCR_T0SZ          GENMASK_ULL(5, 0)
-#define ARM64_TCR_T0SZ                 GENMASK_ULL(5, 0)
 #define CTXDESC_CD_0_TCR_TG0           GENMASK_ULL(7, 6)
-#define ARM64_TCR_TG0                  GENMASK_ULL(15, 14)
 #define CTXDESC_CD_0_TCR_IRGN0         GENMASK_ULL(9, 8)
-#define ARM64_TCR_IRGN0                        GENMASK_ULL(9, 8)
 #define CTXDESC_CD_0_TCR_ORGN0         GENMASK_ULL(11, 10)
-#define ARM64_TCR_ORGN0                        GENMASK_ULL(11, 10)
 #define CTXDESC_CD_0_TCR_SH0           GENMASK_ULL(13, 12)
-#define ARM64_TCR_SH0                  GENMASK_ULL(13, 12)
 #define CTXDESC_CD_0_TCR_EPD0          (1ULL << 14)
-#define ARM64_TCR_EPD0                 (1ULL << 7)
 #define CTXDESC_CD_0_TCR_EPD1          (1ULL << 30)
-#define ARM64_TCR_EPD1                 (1ULL << 23)
 
 #define CTXDESC_CD_0_ENDI              (1UL << 15)
 #define CTXDESC_CD_0_V                 (1UL << 31)
 
 #define CTXDESC_CD_0_TCR_IPS           GENMASK_ULL(34, 32)
-#define ARM64_TCR_IPS                  GENMASK_ULL(34, 32)
 #define CTXDESC_CD_0_TCR_TBI0          (1ULL << 38)
-#define ARM64_TCR_TBI0                 (1ULL << 37)
 
 #define CTXDESC_CD_0_AA64              (1UL << 41)
 #define CTXDESC_CD_0_S                 (1UL << 44)
 
 #define CTXDESC_CD_1_TTB0_MASK         GENMASK_ULL(51, 4)
 
-/* Convert between AArch64 (CPU) TCR format and SMMU CD format */
-#define ARM_SMMU_TCR2CD(tcr, fld)      FIELD_PREP(CTXDESC_CD_0_TCR_##fld, \
-                                       FIELD_GET(ARM64_TCR_##fld, tcr))
+/*
+ * When the SMMU only supports linear context descriptor tables, pick a
+ * reasonable size limit (64kB).
+ */
+#define CTXDESC_LINEAR_CDMAX           ilog2(SZ_64K / (CTXDESC_CD_DWORDS << 3))
 
 /* Command queue */
 #define CMDQ_ENT_SZ_SHIFT              4
 #define CMDQ_PREFETCH_1_SIZE           GENMASK_ULL(4, 0)
 #define CMDQ_PREFETCH_1_ADDR_MASK      GENMASK_ULL(63, 12)
 
+#define CMDQ_CFGI_0_SSID               GENMASK_ULL(31, 12)
 #define CMDQ_CFGI_0_SID                        GENMASK_ULL(63, 32)
 #define CMDQ_CFGI_1_LEAF               (1UL << 0)
 #define CMDQ_CFGI_1_RANGE              GENMASK_ULL(4, 0)
 #define MSI_IOVA_BASE                  0x8000000
 #define MSI_IOVA_LENGTH                        0x100000
 
-/*
- * not really modular, but the easiest way to keep compat with existing
- * bootargs behaviour is to continue using module_param_named here.
- */
 static bool disable_bypass = 1;
 module_param_named(disable_bypass, disable_bypass, bool, S_IRUGO);
 MODULE_PARM_DESC(disable_bypass,
@@ -440,8 +455,11 @@ struct arm_smmu_cmdq_ent {
 
                #define CMDQ_OP_CFGI_STE        0x3
                #define CMDQ_OP_CFGI_ALL        0x4
+               #define CMDQ_OP_CFGI_CD         0x5
+               #define CMDQ_OP_CFGI_CD_ALL     0x6
                struct {
                        u32                     sid;
+                       u32                     ssid;
                        union {
                                bool            leaf;
                                u8              span;
@@ -547,16 +565,30 @@ struct arm_smmu_strtab_l1_desc {
        dma_addr_t                      l2ptr_dma;
 };
 
+struct arm_smmu_ctx_desc {
+       u16                             asid;
+       u64                             ttbr;
+       u64                             tcr;
+       u64                             mair;
+};
+
+struct arm_smmu_l1_ctx_desc {
+       __le64                          *l2ptr;
+       dma_addr_t                      l2ptr_dma;
+};
+
+struct arm_smmu_ctx_desc_cfg {
+       __le64                          *cdtab;
+       dma_addr_t                      cdtab_dma;
+       struct arm_smmu_l1_ctx_desc     *l1_desc;
+       unsigned int                    num_l1_ents;
+};
+
 struct arm_smmu_s1_cfg {
-       __le64                          *cdptr;
-       dma_addr_t                      cdptr_dma;
-
-       struct arm_smmu_ctx_desc {
-               u16     asid;
-               u64     ttbr;
-               u64     tcr;
-               u64     mair;
-       }                               cd;
+       struct arm_smmu_ctx_desc_cfg    cdcfg;
+       struct arm_smmu_ctx_desc        cd;
+       u8                              s1fmt;
+       u8                              s1cdmax;
 };
 
 struct arm_smmu_s2_cfg {
@@ -638,6 +670,7 @@ struct arm_smmu_master {
        u32                             *sids;
        unsigned int                    num_sids;
        bool                            ats_enabled;
+       unsigned int                    ssid_bits;
 };
 
 /* SMMU private data for an IOMMU domain */
@@ -847,15 +880,22 @@ static int arm_smmu_cmdq_build_cmd(u64 *cmd, struct arm_smmu_cmdq_ent *ent)
                cmd[1] |= FIELD_PREP(CMDQ_PREFETCH_1_SIZE, ent->prefetch.size);
                cmd[1] |= ent->prefetch.addr & CMDQ_PREFETCH_1_ADDR_MASK;
                break;
+       case CMDQ_OP_CFGI_CD:
+               cmd[0] |= FIELD_PREP(CMDQ_CFGI_0_SSID, ent->cfgi.ssid);
+               /* Fallthrough */
        case CMDQ_OP_CFGI_STE:
                cmd[0] |= FIELD_PREP(CMDQ_CFGI_0_SID, ent->cfgi.sid);
                cmd[1] |= FIELD_PREP(CMDQ_CFGI_1_LEAF, ent->cfgi.leaf);
                break;
+       case CMDQ_OP_CFGI_CD_ALL:
+               cmd[0] |= FIELD_PREP(CMDQ_CFGI_0_SID, ent->cfgi.sid);
+               break;
        case CMDQ_OP_CFGI_ALL:
                /* Cover the entire SID range */
                cmd[1] |= FIELD_PREP(CMDQ_CFGI_1_RANGE, 31);
                break;
        case CMDQ_OP_TLBI_NH_VA:
+               cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_VMID, ent->tlbi.vmid);
                cmd[0] |= FIELD_PREP(CMDQ_TLBI_0_ASID, ent->tlbi.asid);
                cmd[1] |= FIELD_PREP(CMDQ_TLBI_1_LEAF, ent->tlbi.leaf);
                cmd[1] |= ent->tlbi.addr & CMDQ_TLBI_1_VA_MASK;
@@ -1443,50 +1483,238 @@ static int arm_smmu_cmdq_issue_sync(struct arm_smmu_device *smmu)
 }
 
 /* Context descriptor manipulation functions */
-static u64 arm_smmu_cpu_tcr_to_cd(u64 tcr)
+static void arm_smmu_sync_cd(struct arm_smmu_domain *smmu_domain,
+                            int ssid, bool leaf)
 {
-       u64 val = 0;
+       size_t i;
+       unsigned long flags;
+       struct arm_smmu_master *master;
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
+       struct arm_smmu_cmdq_ent cmd = {
+               .opcode = CMDQ_OP_CFGI_CD,
+               .cfgi   = {
+                       .ssid   = ssid,
+                       .leaf   = leaf,
+               },
+       };
+
+       spin_lock_irqsave(&smmu_domain->devices_lock, flags);
+       list_for_each_entry(master, &smmu_domain->devices, domain_head) {
+               for (i = 0; i < master->num_sids; i++) {
+                       cmd.cfgi.sid = master->sids[i];
+                       arm_smmu_cmdq_issue_cmd(smmu, &cmd);
+               }
+       }
+       spin_unlock_irqrestore(&smmu_domain->devices_lock, flags);
+
+       arm_smmu_cmdq_issue_sync(smmu);
+}
 
-       /* Repack the TCR. Just care about TTBR0 for now */
-       val |= ARM_SMMU_TCR2CD(tcr, T0SZ);
-       val |= ARM_SMMU_TCR2CD(tcr, TG0);
-       val |= ARM_SMMU_TCR2CD(tcr, IRGN0);
-       val |= ARM_SMMU_TCR2CD(tcr, ORGN0);
-       val |= ARM_SMMU_TCR2CD(tcr, SH0);
-       val |= ARM_SMMU_TCR2CD(tcr, EPD0);
-       val |= ARM_SMMU_TCR2CD(tcr, EPD1);
-       val |= ARM_SMMU_TCR2CD(tcr, IPS);
+static int arm_smmu_alloc_cd_leaf_table(struct arm_smmu_device *smmu,
+                                       struct arm_smmu_l1_ctx_desc *l1_desc)
+{
+       size_t size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
 
-       return val;
+       l1_desc->l2ptr = dmam_alloc_coherent(smmu->dev, size,
+                                            &l1_desc->l2ptr_dma, GFP_KERNEL);
+       if (!l1_desc->l2ptr) {
+               dev_warn(smmu->dev,
+                        "failed to allocate context descriptor table\n");
+               return -ENOMEM;
+       }
+       return 0;
 }
 
-static void arm_smmu_write_ctx_desc(struct arm_smmu_device *smmu,
-                                   struct arm_smmu_s1_cfg *cfg)
+static void arm_smmu_write_cd_l1_desc(__le64 *dst,
+                                     struct arm_smmu_l1_ctx_desc *l1_desc)
 {
-       u64 val;
+       u64 val = (l1_desc->l2ptr_dma & CTXDESC_L1_DESC_L2PTR_MASK) |
+                 CTXDESC_L1_DESC_V;
+
+       WRITE_ONCE(*dst, cpu_to_le64(val));
+}
+
+static __le64 *arm_smmu_get_cd_ptr(struct arm_smmu_domain *smmu_domain,
+                                  u32 ssid)
+{
+       __le64 *l1ptr;
+       unsigned int idx;
+       struct arm_smmu_l1_ctx_desc *l1_desc;
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
+       struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg;
 
+       if (smmu_domain->s1_cfg.s1fmt == STRTAB_STE_0_S1FMT_LINEAR)
+               return cdcfg->cdtab + ssid * CTXDESC_CD_DWORDS;
+
+       idx = ssid >> CTXDESC_SPLIT;
+       l1_desc = &cdcfg->l1_desc[idx];
+       if (!l1_desc->l2ptr) {
+               if (arm_smmu_alloc_cd_leaf_table(smmu, l1_desc))
+                       return NULL;
+
+               l1ptr = cdcfg->cdtab + idx * CTXDESC_L1_DESC_DWORDS;
+               arm_smmu_write_cd_l1_desc(l1ptr, l1_desc);
+               /* An invalid L1CD can be cached */
+               arm_smmu_sync_cd(smmu_domain, ssid, false);
+       }
+       idx = ssid & (CTXDESC_L2_ENTRIES - 1);
+       return l1_desc->l2ptr + idx * CTXDESC_CD_DWORDS;
+}
+
+static int arm_smmu_write_ctx_desc(struct arm_smmu_domain *smmu_domain,
+                                  int ssid, struct arm_smmu_ctx_desc *cd)
+{
        /*
-        * We don't need to issue any invalidation here, as we'll invalidate
-        * the STE when installing the new entry anyway.
+        * This function handles the following cases:
+        *
+        * (1) Install primary CD, for normal DMA traffic (SSID = 0).
+        * (2) Install a secondary CD, for SID+SSID traffic.
+        * (3) Update ASID of a CD. Atomically write the first 64 bits of the
+        *     CD, then invalidate the old entry and mappings.
+        * (4) Remove a secondary CD.
         */
-       val = arm_smmu_cpu_tcr_to_cd(cfg->cd.tcr) |
+       u64 val;
+       bool cd_live;
+       __le64 *cdptr;
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
+
+       if (WARN_ON(ssid >= (1 << smmu_domain->s1_cfg.s1cdmax)))
+               return -E2BIG;
+
+       cdptr = arm_smmu_get_cd_ptr(smmu_domain, ssid);
+       if (!cdptr)
+               return -ENOMEM;
+
+       val = le64_to_cpu(cdptr[0]);
+       cd_live = !!(val & CTXDESC_CD_0_V);
+
+       if (!cd) { /* (4) */
+               val = 0;
+       } else if (cd_live) { /* (3) */
+               val &= ~CTXDESC_CD_0_ASID;
+               val |= FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid);
+               /*
+                * Until CD+TLB invalidation, both ASIDs may be used for tagging
+                * this substream's traffic
+                */
+       } else { /* (1) and (2) */
+               cdptr[1] = cpu_to_le64(cd->ttbr & CTXDESC_CD_1_TTB0_MASK);
+               cdptr[2] = 0;
+               cdptr[3] = cpu_to_le64(cd->mair);
+
+               /*
+                * STE is live, and the SMMU might read dwords of this CD in any
+                * order. Ensure that it observes valid values before reading
+                * V=1.
+                */
+               arm_smmu_sync_cd(smmu_domain, ssid, true);
+
+               val = cd->tcr |
 #ifdef __BIG_ENDIAN
-             CTXDESC_CD_0_ENDI |
+                       CTXDESC_CD_0_ENDI |
 #endif
-             CTXDESC_CD_0_R | CTXDESC_CD_0_A | CTXDESC_CD_0_ASET |
-             CTXDESC_CD_0_AA64 | FIELD_PREP(CTXDESC_CD_0_ASID, cfg->cd.asid) |
-             CTXDESC_CD_0_V;
+                       CTXDESC_CD_0_R | CTXDESC_CD_0_A | CTXDESC_CD_0_ASET |
+                       CTXDESC_CD_0_AA64 |
+                       FIELD_PREP(CTXDESC_CD_0_ASID, cd->asid) |
+                       CTXDESC_CD_0_V;
 
-       /* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */
-       if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE)
-               val |= CTXDESC_CD_0_S;
+               /* STALL_MODEL==0b10 && CD.S==0 is ILLEGAL */
+               if (smmu->features & ARM_SMMU_FEAT_STALL_FORCE)
+                       val |= CTXDESC_CD_0_S;
+       }
 
-       cfg->cdptr[0] = cpu_to_le64(val);
+       /*
+        * The SMMU accesses 64-bit values atomically. See IHI0070Ca 3.21.3
+        * "Configuration structures and configuration invalidation completion"
+        *
+        *   The size of single-copy atomic reads made by the SMMU is
+        *   IMPLEMENTATION DEFINED but must be at least 64 bits. Any single
+        *   field within an aligned 64-bit span of a structure can be altered
+        *   without first making the structure invalid.
+        */
+       WRITE_ONCE(cdptr[0], cpu_to_le64(val));
+       arm_smmu_sync_cd(smmu_domain, ssid, true);
+       return 0;
+}
+
+static int arm_smmu_alloc_cd_tables(struct arm_smmu_domain *smmu_domain)
+{
+       int ret;
+       size_t l1size;
+       size_t max_contexts;
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
+       struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
+       struct arm_smmu_ctx_desc_cfg *cdcfg = &cfg->cdcfg;
+
+       max_contexts = 1 << cfg->s1cdmax;
+
+       if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB) ||
+           max_contexts <= CTXDESC_L2_ENTRIES) {
+               cfg->s1fmt = STRTAB_STE_0_S1FMT_LINEAR;
+               cdcfg->num_l1_ents = max_contexts;
 
-       val = cfg->cd.ttbr & CTXDESC_CD_1_TTB0_MASK;
-       cfg->cdptr[1] = cpu_to_le64(val);
+               l1size = max_contexts * (CTXDESC_CD_DWORDS << 3);
+       } else {
+               cfg->s1fmt = STRTAB_STE_0_S1FMT_64K_L2;
+               cdcfg->num_l1_ents = DIV_ROUND_UP(max_contexts,
+                                                 CTXDESC_L2_ENTRIES);
+
+               cdcfg->l1_desc = devm_kcalloc(smmu->dev, cdcfg->num_l1_ents,
+                                             sizeof(*cdcfg->l1_desc),
+                                             GFP_KERNEL);
+               if (!cdcfg->l1_desc)
+                       return -ENOMEM;
+
+               l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
+       }
+
+       cdcfg->cdtab = dmam_alloc_coherent(smmu->dev, l1size, &cdcfg->cdtab_dma,
+                                          GFP_KERNEL);
+       if (!cdcfg->cdtab) {
+               dev_warn(smmu->dev, "failed to allocate context descriptor\n");
+               ret = -ENOMEM;
+               goto err_free_l1;
+       }
+
+       return 0;
 
-       cfg->cdptr[3] = cpu_to_le64(cfg->cd.mair);
+err_free_l1:
+       if (cdcfg->l1_desc) {
+               devm_kfree(smmu->dev, cdcfg->l1_desc);
+               cdcfg->l1_desc = NULL;
+       }
+       return ret;
+}
+
+static void arm_smmu_free_cd_tables(struct arm_smmu_domain *smmu_domain)
+{
+       int i;
+       size_t size, l1size;
+       struct arm_smmu_device *smmu = smmu_domain->smmu;
+       struct arm_smmu_ctx_desc_cfg *cdcfg = &smmu_domain->s1_cfg.cdcfg;
+
+       if (cdcfg->l1_desc) {
+               size = CTXDESC_L2_ENTRIES * (CTXDESC_CD_DWORDS << 3);
+
+               for (i = 0; i < cdcfg->num_l1_ents; i++) {
+                       if (!cdcfg->l1_desc[i].l2ptr)
+                               continue;
+
+                       dmam_free_coherent(smmu->dev, size,
+                                          cdcfg->l1_desc[i].l2ptr,
+                                          cdcfg->l1_desc[i].l2ptr_dma);
+               }
+               devm_kfree(smmu->dev, cdcfg->l1_desc);
+               cdcfg->l1_desc = NULL;
+
+               l1size = cdcfg->num_l1_ents * (CTXDESC_L1_DESC_DWORDS << 3);
+       } else {
+               l1size = cdcfg->num_l1_ents * (CTXDESC_CD_DWORDS << 3);
+       }
+
+       dmam_free_coherent(smmu->dev, l1size, cdcfg->cdtab, cdcfg->cdtab_dma);
+       cdcfg->cdtab_dma = 0;
+       cdcfg->cdtab = NULL;
 }
 
 /* Stream table manipulation functions */
@@ -1608,6 +1836,7 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
        if (s1_cfg) {
                BUG_ON(ste_live);
                dst[1] = cpu_to_le64(
+                        FIELD_PREP(STRTAB_STE_1_S1DSS, STRTAB_STE_1_S1DSS_SSID0) |
                         FIELD_PREP(STRTAB_STE_1_S1CIR, STRTAB_STE_1_S1C_CACHE_WBRA) |
                         FIELD_PREP(STRTAB_STE_1_S1COR, STRTAB_STE_1_S1C_CACHE_WBRA) |
                         FIELD_PREP(STRTAB_STE_1_S1CSH, ARM_SMMU_SH_ISH) |
@@ -1617,8 +1846,10 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
                   !(smmu->features & ARM_SMMU_FEAT_STALL_FORCE))
                        dst[1] |= cpu_to_le64(STRTAB_STE_1_S1STALLD);
 
-               val |= (s1_cfg->cdptr_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
-                       FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS);
+               val |= (s1_cfg->cdcfg.cdtab_dma & STRTAB_STE_0_S1CTXPTR_MASK) |
+                       FIELD_PREP(STRTAB_STE_0_CFG, STRTAB_STE_0_CFG_S1_TRANS) |
+                       FIELD_PREP(STRTAB_STE_0_S1CDMAX, s1_cfg->s1cdmax) |
+                       FIELD_PREP(STRTAB_STE_0_S1FMT, s1_cfg->s1fmt);
        }
 
        if (s2_cfg) {
@@ -1642,7 +1873,8 @@ static void arm_smmu_write_strtab_ent(struct arm_smmu_master *master, u32 sid,
                                                 STRTAB_STE_1_EATS_TRANS));
 
        arm_smmu_sync_ste_for_sid(smmu, sid);
-       dst[0] = cpu_to_le64(val);
+       /* See comment in arm_smmu_write_ctx_desc() */
+       WRITE_ONCE(dst[0], cpu_to_le64(val));
        arm_smmu_sync_ste_for_sid(smmu, sid);
 
        /* It's likely that we'll want to use the new STE soon */
@@ -1675,7 +1907,7 @@ static int arm_smmu_init_l2_strtab(struct arm_smmu_device *smmu, u32 sid)
 
        desc->span = STRTAB_SPLIT + 1;
        desc->l2ptr = dmam_alloc_coherent(smmu->dev, size, &desc->l2ptr_dma,
-                                         GFP_KERNEL | __GFP_ZERO);
+                                         GFP_KERNEL);
        if (!desc->l2ptr) {
                dev_err(smmu->dev,
                        "failed to allocate l2 stream table for SID %u\n",
@@ -2131,12 +2363,8 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
        if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1) {
                struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
 
-               if (cfg->cdptr) {
-                       dmam_free_coherent(smmu_domain->smmu->dev,
-                                          CTXDESC_CD_DWORDS << 3,
-                                          cfg->cdptr,
-                                          cfg->cdptr_dma);
-
+               if (cfg->cdcfg.cdtab) {
+                       arm_smmu_free_cd_tables(smmu_domain);
                        arm_smmu_bitmap_free(smmu->asid_map, cfg->cd.asid);
                }
        } else {
@@ -2149,55 +2377,82 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 }
 
 static int arm_smmu_domain_finalise_s1(struct arm_smmu_domain *smmu_domain,
+                                      struct arm_smmu_master *master,
                                       struct io_pgtable_cfg *pgtbl_cfg)
 {
        int ret;
        int asid;
        struct arm_smmu_device *smmu = smmu_domain->smmu;
        struct arm_smmu_s1_cfg *cfg = &smmu_domain->s1_cfg;
+       typeof(&pgtbl_cfg->arm_lpae_s1_cfg.tcr) tcr = &pgtbl_cfg->arm_lpae_s1_cfg.tcr;
 
        asid = arm_smmu_bitmap_alloc(smmu->asid_map, smmu->asid_bits);
        if (asid < 0)
                return asid;
 
-       cfg->cdptr = dmam_alloc_coherent(smmu->dev, CTXDESC_CD_DWORDS << 3,
-                                        &cfg->cdptr_dma,
-                                        GFP_KERNEL | __GFP_ZERO);
-       if (!cfg->cdptr) {
-               dev_warn(smmu->dev, "failed to allocate context descriptor\n");
-               ret = -ENOMEM;
+       cfg->s1cdmax = master->ssid_bits;
+
+       ret = arm_smmu_alloc_cd_tables(smmu_domain);
+       if (ret)
                goto out_free_asid;
-       }
 
        cfg->cd.asid    = (u16)asid;
-       cfg->cd.ttbr    = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
-       cfg->cd.tcr     = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
+       cfg->cd.ttbr    = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
+       cfg->cd.tcr     = FIELD_PREP(CTXDESC_CD_0_TCR_T0SZ, tcr->tsz) |
+                         FIELD_PREP(CTXDESC_CD_0_TCR_TG0, tcr->tg) |
+                         FIELD_PREP(CTXDESC_CD_0_TCR_IRGN0, tcr->irgn) |
+                         FIELD_PREP(CTXDESC_CD_0_TCR_ORGN0, tcr->orgn) |
+                         FIELD_PREP(CTXDESC_CD_0_TCR_SH0, tcr->sh) |
+                         FIELD_PREP(CTXDESC_CD_0_TCR_IPS, tcr->ips) |
+                         CTXDESC_CD_0_TCR_EPD1 | CTXDESC_CD_0_AA64;
        cfg->cd.mair    = pgtbl_cfg->arm_lpae_s1_cfg.mair;
+
+       /*
+        * Note that this will end up calling arm_smmu_sync_cd() before
+        * the master has been added to the devices list for this domain.
+        * This isn't an issue because the STE hasn't been installed yet.
+        */
+       ret = arm_smmu_write_ctx_desc(smmu_domain, 0, &cfg->cd);
+       if (ret)
+               goto out_free_cd_tables;
+
        return 0;
 
+out_free_cd_tables:
+       arm_smmu_free_cd_tables(smmu_domain);
 out_free_asid:
        arm_smmu_bitmap_free(smmu->asid_map, asid);
        return ret;
 }
 
 static int arm_smmu_domain_finalise_s2(struct arm_smmu_domain *smmu_domain,
+                                      struct arm_smmu_master *master,
                                       struct io_pgtable_cfg *pgtbl_cfg)
 {
        int vmid;
        struct arm_smmu_device *smmu = smmu_domain->smmu;
        struct arm_smmu_s2_cfg *cfg = &smmu_domain->s2_cfg;
+       typeof(&pgtbl_cfg->arm_lpae_s2_cfg.vtcr) vtcr;
 
        vmid = arm_smmu_bitmap_alloc(smmu->vmid_map, smmu->vmid_bits);
        if (vmid < 0)
                return vmid;
 
+       vtcr = &pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
        cfg->vmid       = (u16)vmid;
        cfg->vttbr      = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
-       cfg->vtcr       = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
+       cfg->vtcr       = FIELD_PREP(STRTAB_STE_2_VTCR_S2T0SZ, vtcr->tsz) |
+                         FIELD_PREP(STRTAB_STE_2_VTCR_S2SL0, vtcr->sl) |
+                         FIELD_PREP(STRTAB_STE_2_VTCR_S2IR0, vtcr->irgn) |
+                         FIELD_PREP(STRTAB_STE_2_VTCR_S2OR0, vtcr->orgn) |
+                         FIELD_PREP(STRTAB_STE_2_VTCR_S2SH0, vtcr->sh) |
+                         FIELD_PREP(STRTAB_STE_2_VTCR_S2TG, vtcr->tg) |
+                         FIELD_PREP(STRTAB_STE_2_VTCR_S2PS, vtcr->ps);
        return 0;
 }
 
-static int arm_smmu_domain_finalise(struct iommu_domain *domain)
+static int arm_smmu_domain_finalise(struct iommu_domain *domain,
+                                   struct arm_smmu_master *master)
 {
        int ret;
        unsigned long ias, oas;
@@ -2205,6 +2460,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
        struct io_pgtable_cfg pgtbl_cfg;
        struct io_pgtable_ops *pgtbl_ops;
        int (*finalise_stage_fn)(struct arm_smmu_domain *,
+                                struct arm_smmu_master *,
                                 struct io_pgtable_cfg *);
        struct arm_smmu_domain *smmu_domain = to_smmu_domain(domain);
        struct arm_smmu_device *smmu = smmu_domain->smmu;
@@ -2259,7 +2515,7 @@ static int arm_smmu_domain_finalise(struct iommu_domain *domain)
        domain->geometry.aperture_end = (1UL << pgtbl_cfg.ias) - 1;
        domain->geometry.force_aperture = true;
 
-       ret = finalise_stage_fn(smmu_domain, &pgtbl_cfg);
+       ret = finalise_stage_fn(smmu_domain, master, &pgtbl_cfg);
        if (ret < 0) {
                free_io_pgtable_ops(pgtbl_ops);
                return ret;
@@ -2412,7 +2668,7 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
 
        if (!smmu_domain->smmu) {
                smmu_domain->smmu = smmu;
-               ret = arm_smmu_domain_finalise(domain);
+               ret = arm_smmu_domain_finalise(domain, master);
                if (ret) {
                        smmu_domain->smmu = NULL;
                        goto out_unlock;
@@ -2424,6 +2680,13 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
                        dev_name(smmu->dev));
                ret = -ENXIO;
                goto out_unlock;
+       } else if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1 &&
+                  master->ssid_bits != smmu_domain->s1_cfg.s1cdmax) {
+               dev_err(dev,
+                       "cannot attach to incompatible domain (%u SSID bits != %u)\n",
+                       smmu_domain->s1_cfg.s1cdmax, master->ssid_bits);
+               ret = -EINVAL;
+               goto out_unlock;
        }
 
        master->domain = smmu_domain;
@@ -2431,9 +2694,6 @@ static int arm_smmu_attach_dev(struct iommu_domain *domain, struct device *dev)
        if (smmu_domain->stage != ARM_SMMU_DOMAIN_BYPASS)
                master->ats_enabled = arm_smmu_ats_supported(master);
 
-       if (smmu_domain->stage == ARM_SMMU_DOMAIN_S1)
-               arm_smmu_write_ctx_desc(smmu, &smmu_domain->s1_cfg);
-
        arm_smmu_install_ste_for_dev(master);
 
        spin_lock_irqsave(&smmu_domain->devices_lock, flags);
@@ -2534,51 +2794,66 @@ static int arm_smmu_add_device(struct device *dev)
 
        if (!fwspec || fwspec->ops != &arm_smmu_ops)
                return -ENODEV;
-       /*
-        * We _can_ actually withstand dodgy bus code re-calling add_device()
-        * without an intervening remove_device()/of_xlate() sequence, but
-        * we're not going to do so quietly...
-        */
-       if (WARN_ON_ONCE(fwspec->iommu_priv)) {
-               master = fwspec->iommu_priv;
-               smmu = master->smmu;
-       } else {
-               smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
-               if (!smmu)
-                       return -ENODEV;
-               master = kzalloc(sizeof(*master), GFP_KERNEL);
-               if (!master)
-                       return -ENOMEM;
 
-               master->dev = dev;
-               master->smmu = smmu;
-               master->sids = fwspec->ids;
-               master->num_sids = fwspec->num_ids;
-               fwspec->iommu_priv = master;
-       }
+       if (WARN_ON_ONCE(fwspec->iommu_priv))
+               return -EBUSY;
+
+       smmu = arm_smmu_get_by_fwnode(fwspec->iommu_fwnode);
+       if (!smmu)
+               return -ENODEV;
+
+       master = kzalloc(sizeof(*master), GFP_KERNEL);
+       if (!master)
+               return -ENOMEM;
+
+       master->dev = dev;
+       master->smmu = smmu;
+       master->sids = fwspec->ids;
+       master->num_sids = fwspec->num_ids;
+       fwspec->iommu_priv = master;
 
        /* Check the SIDs are in range of the SMMU and our stream table */
        for (i = 0; i < master->num_sids; i++) {
                u32 sid = master->sids[i];
 
-               if (!arm_smmu_sid_in_range(smmu, sid))
-                       return -ERANGE;
+               if (!arm_smmu_sid_in_range(smmu, sid)) {
+                       ret = -ERANGE;
+                       goto err_free_master;
+               }
 
                /* Ensure l2 strtab is initialised */
                if (smmu->features & ARM_SMMU_FEAT_2_LVL_STRTAB) {
                        ret = arm_smmu_init_l2_strtab(smmu, sid);
                        if (ret)
-                               return ret;
+                               goto err_free_master;
                }
        }
 
+       master->ssid_bits = min(smmu->ssid_bits, fwspec->num_pasid_bits);
+
+       if (!(smmu->features & ARM_SMMU_FEAT_2_LVL_CDTAB))
+               master->ssid_bits = min_t(u8, master->ssid_bits,
+                                         CTXDESC_LINEAR_CDMAX);
+
+       ret = iommu_device_link(&smmu->iommu, dev);
+       if (ret)
+               goto err_free_master;
+
        group = iommu_group_get_for_dev(dev);
-       if (!IS_ERR(group)) {
-               iommu_group_put(group);
-               iommu_device_link(&smmu->iommu, dev);
+       if (IS_ERR(group)) {
+               ret = PTR_ERR(group);
+               goto err_unlink;
        }
 
-       return PTR_ERR_OR_ZERO(group);
+       iommu_group_put(group);
+       return 0;
+
+err_unlink:
+       iommu_device_unlink(&smmu->iommu, dev);
+err_free_master:
+       kfree(master);
+       fwspec->iommu_priv = NULL;
+       return ret;
 }
 
 static void arm_smmu_remove_device(struct device *dev)
@@ -2710,15 +2985,6 @@ static void arm_smmu_get_resv_regions(struct device *dev,
        iommu_dma_get_resv_regions(dev, head);
 }
 
-static void arm_smmu_put_resv_regions(struct device *dev,
-                                     struct list_head *head)
-{
-       struct iommu_resv_region *entry, *next;
-
-       list_for_each_entry_safe(entry, next, head, list)
-               kfree(entry);
-}
-
 static struct iommu_ops arm_smmu_ops = {
        .capable                = arm_smmu_capable,
        .domain_alloc           = arm_smmu_domain_alloc,
@@ -2736,7 +3002,7 @@ static struct iommu_ops arm_smmu_ops = {
        .domain_set_attr        = arm_smmu_domain_set_attr,
        .of_xlate               = arm_smmu_of_xlate,
        .get_resv_regions       = arm_smmu_get_resv_regions,
-       .put_resv_regions       = arm_smmu_put_resv_regions,
+       .put_resv_regions       = generic_iommu_put_resv_regions,
        .pgsize_bitmap          = -1UL, /* Restricted during device attach */
 };
 
@@ -2883,7 +3149,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu)
 
        l1size = cfg->num_l1_ents * (STRTAB_L1_DESC_DWORDS << 3);
        strtab = dmam_alloc_coherent(smmu->dev, l1size, &cfg->strtab_dma,
-                                    GFP_KERNEL | __GFP_ZERO);
+                                    GFP_KERNEL);
        if (!strtab) {
                dev_err(smmu->dev,
                        "failed to allocate l1 stream table (%u bytes)\n",
@@ -2910,7 +3176,7 @@ static int arm_smmu_init_strtab_linear(struct arm_smmu_device *smmu)
 
        size = (1 << smmu->sid_bits) * (STRTAB_STE_DWORDS << 3);
        strtab = dmam_alloc_coherent(smmu->dev, size, &cfg->strtab_dma,
-                                    GFP_KERNEL | __GFP_ZERO);
+                                    GFP_KERNEL);
        if (!strtab) {
                dev_err(smmu->dev,
                        "failed to allocate linear stream table (%u bytes)\n",
@@ -3570,6 +3836,43 @@ static unsigned long arm_smmu_resource_size(struct arm_smmu_device *smmu)
                return SZ_128K;
 }
 
+static int arm_smmu_set_bus_ops(struct iommu_ops *ops)
+{
+       int err;
+
+#ifdef CONFIG_PCI
+       if (pci_bus_type.iommu_ops != ops) {
+               err = bus_set_iommu(&pci_bus_type, ops);
+               if (err)
+                       return err;
+       }
+#endif
+#ifdef CONFIG_ARM_AMBA
+       if (amba_bustype.iommu_ops != ops) {
+               err = bus_set_iommu(&amba_bustype, ops);
+               if (err)
+                       goto err_reset_pci_ops;
+       }
+#endif
+       if (platform_bus_type.iommu_ops != ops) {
+               err = bus_set_iommu(&platform_bus_type, ops);
+               if (err)
+                       goto err_reset_amba_ops;
+       }
+
+       return 0;
+
+err_reset_amba_ops:
+#ifdef CONFIG_ARM_AMBA
+       bus_set_iommu(&amba_bustype, NULL);
+#endif
+err_reset_pci_ops: __maybe_unused;
+#ifdef CONFIG_PCI
+       bus_set_iommu(&pci_bus_type, NULL);
+#endif
+       return err;
+}
+
 static int arm_smmu_device_probe(struct platform_device *pdev)
 {
        int irq, ret;
@@ -3599,7 +3902,7 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
 
        /* Base address */
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (resource_size(res) + 1 < arm_smmu_resource_size(smmu)) {
+       if (resource_size(res) < arm_smmu_resource_size(smmu)) {
                dev_err(dev, "MMIO region too small (%pr)\n", res);
                return -EINVAL;
        }
@@ -3660,48 +3963,45 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
                return ret;
        }
 
-#ifdef CONFIG_PCI
-       if (pci_bus_type.iommu_ops != &arm_smmu_ops) {
-               pci_request_acs();
-               ret = bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
-               if (ret)
-                       return ret;
-       }
-#endif
-#ifdef CONFIG_ARM_AMBA
-       if (amba_bustype.iommu_ops != &arm_smmu_ops) {
-               ret = bus_set_iommu(&amba_bustype, &arm_smmu_ops);
-               if (ret)
-                       return ret;
-       }
-#endif
-       if (platform_bus_type.iommu_ops != &arm_smmu_ops) {
-               ret = bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
-               if (ret)
-                       return ret;
-       }
-       return 0;
+       return arm_smmu_set_bus_ops(&arm_smmu_ops);
 }
 
-static void arm_smmu_device_shutdown(struct platform_device *pdev)
+static int arm_smmu_device_remove(struct platform_device *pdev)
 {
        struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
 
+       arm_smmu_set_bus_ops(NULL);
+       iommu_device_unregister(&smmu->iommu);
+       iommu_device_sysfs_remove(&smmu->iommu);
        arm_smmu_device_disable(smmu);
+
+       return 0;
+}
+
+static void arm_smmu_device_shutdown(struct platform_device *pdev)
+{
+       arm_smmu_device_remove(pdev);
 }
 
 static const struct of_device_id arm_smmu_of_match[] = {
        { .compatible = "arm,smmu-v3", },
        { },
 };
+MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
 static struct platform_driver arm_smmu_driver = {
        .driver = {
-               .name           = "arm-smmu-v3",
-               .of_match_table = of_match_ptr(arm_smmu_of_match),
-               .suppress_bind_attrs = true,
+               .name                   = "arm-smmu-v3",
+               .of_match_table         = arm_smmu_of_match,
+               .suppress_bind_attrs    = true,
        },
        .probe  = arm_smmu_device_probe,
+       .remove = arm_smmu_device_remove,
        .shutdown = arm_smmu_device_shutdown,
 };
-builtin_platform_driver(arm_smmu_driver);
+module_platform_driver(arm_smmu_driver);
+
+MODULE_DESCRIPTION("IOMMU API for ARM architected SMMUv3 implementations");
+MODULE_AUTHOR("Will Deacon <will@kernel.org>");
+MODULE_ALIAS("platform:arm-smmu-v3");
+MODULE_LICENSE("GPL v2");
index 4f1a350..16c4b87 100644 (file)
@@ -27,8 +27,7 @@
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/iopoll.h>
-#include <linux/init.h>
-#include <linux/moduleparam.h>
+#include <linux/module.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #define MSI_IOVA_LENGTH                        0x100000
 
 static int force_stage;
-/*
- * not really modular, but the easiest way to keep compat with existing
- * bootargs behaviour is to continue using module_param() here.
- */
 module_param(force_stage, int, S_IRUGO);
 MODULE_PARM_DESC(force_stage,
        "Force SMMU mappings to be installed at a particular stage of translation. A value of '1' or '2' forces the corresponding stage. All other values are ignored (i.e. no stage is forced). Note that selecting a specific stage will disable support for nested translation.");
@@ -131,6 +126,12 @@ static struct arm_smmu_domain *to_smmu_domain(struct iommu_domain *dom)
        return container_of(dom, struct arm_smmu_domain, domain);
 }
 
+static struct platform_driver arm_smmu_driver;
+static struct iommu_ops arm_smmu_ops;
+
+#ifdef CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS
+static int arm_smmu_bus_init(struct iommu_ops *ops);
+
 static struct device_node *dev_get_dev_node(struct device *dev)
 {
        if (dev_is_pci(dev)) {
@@ -166,9 +167,6 @@ static int __find_legacy_master_phandle(struct device *dev, void *data)
        return err == -ENOENT ? 0 : err;
 }
 
-static struct platform_driver arm_smmu_driver;
-static struct iommu_ops arm_smmu_ops;
-
 static int arm_smmu_register_legacy_master(struct device *dev,
                                           struct arm_smmu_device **smmu)
 {
@@ -220,6 +218,27 @@ static int arm_smmu_register_legacy_master(struct device *dev,
        return err;
 }
 
+/*
+ * With the legacy DT binding in play, we have no guarantees about
+ * probe order, but then we're also not doing default domains, so we can
+ * delay setting bus ops until we're sure every possible SMMU is ready,
+ * and that way ensure that no add_device() calls get missed.
+ */
+static int arm_smmu_legacy_bus_init(void)
+{
+       if (using_legacy_binding)
+               return arm_smmu_bus_init(&arm_smmu_ops);
+       return 0;
+}
+device_initcall_sync(arm_smmu_legacy_bus_init);
+#else
+static int arm_smmu_register_legacy_master(struct device *dev,
+                                          struct arm_smmu_device **smmu)
+{
+       return -ENODEV;
+}
+#endif /* CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS */
+
 static int __arm_smmu_alloc_bitmap(unsigned long *map, int start, int end)
 {
        int idx;
@@ -252,7 +271,7 @@ static void __arm_smmu_tlb_sync(struct arm_smmu_device *smmu, int page,
        for (delay = 1; delay < TLB_LOOP_TIMEOUT; delay *= 2) {
                for (spin_cnt = TLB_SPIN_COUNT; spin_cnt > 0; spin_cnt--) {
                        reg = arm_smmu_readl(smmu, page, status);
-                       if (!(reg & sTLBGSTATUS_GSACTIVE))
+                       if (!(reg & ARM_SMMU_sTLBGSTATUS_GSACTIVE))
                                return;
                        cpu_relax();
                }
@@ -459,7 +478,7 @@ static irqreturn_t arm_smmu_context_fault(int irq, void *dev)
        int idx = smmu_domain->cfg.cbndx;
 
        fsr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSR);
-       if (!(fsr & FSR_FAULT))
+       if (!(fsr & ARM_SMMU_FSR_FAULT))
                return IRQ_NONE;
 
        fsynr = arm_smmu_cb_read(smmu, idx, ARM_SMMU_CB_FSYNR0);
@@ -491,7 +510,7 @@ static irqreturn_t arm_smmu_global_fault(int irq, void *dev)
 
        if (__ratelimit(&rs)) {
                if (IS_ENABLED(CONFIG_ARM_SMMU_DISABLE_BYPASS_BY_DEFAULT) &&
-                   (gfsr & sGFSR_USF))
+                   (gfsr & ARM_SMMU_sGFSR_USF))
                        dev_err(smmu->dev,
                                "Blocked unknown Stream ID 0x%hx; boot with \"arm-smmu.disable_bypass=0\" to allow, but this may have security implications\n",
                                (u16)gfsynr1);
@@ -521,26 +540,28 @@ static void arm_smmu_init_context_bank(struct arm_smmu_domain *smmu_domain,
                if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
                        cb->tcr[0] = pgtbl_cfg->arm_v7s_cfg.tcr;
                } else {
-                       cb->tcr[0] = pgtbl_cfg->arm_lpae_s1_cfg.tcr;
-                       cb->tcr[1] = pgtbl_cfg->arm_lpae_s1_cfg.tcr >> 32;
-                       cb->tcr[1] |= FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM);
+                       cb->tcr[0] = arm_smmu_lpae_tcr(pgtbl_cfg);
+                       cb->tcr[1] = arm_smmu_lpae_tcr2(pgtbl_cfg);
                        if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
-                               cb->tcr[1] |= TCR2_AS;
+                               cb->tcr[1] |= ARM_SMMU_TCR2_AS;
+                       else
+                               cb->tcr[0] |= ARM_SMMU_TCR_EAE;
                }
        } else {
-               cb->tcr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vtcr;
+               cb->tcr[0] = arm_smmu_lpae_vtcr(pgtbl_cfg);
        }
 
        /* TTBRs */
        if (stage1) {
                if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH32_S) {
-                       cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr[0];
-                       cb->ttbr[1] = pgtbl_cfg->arm_v7s_cfg.ttbr[1];
+                       cb->ttbr[0] = pgtbl_cfg->arm_v7s_cfg.ttbr;
+                       cb->ttbr[1] = 0;
                } else {
-                       cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[0];
-                       cb->ttbr[0] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
-                       cb->ttbr[1] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr[1];
-                       cb->ttbr[1] |= FIELD_PREP(TTBRn_ASID, cfg->asid);
+                       cb->ttbr[0] = pgtbl_cfg->arm_lpae_s1_cfg.ttbr;
+                       cb->ttbr[0] |= FIELD_PREP(ARM_SMMU_TTBRn_ASID,
+                                                 cfg->asid);
+                       cb->ttbr[1] = FIELD_PREP(ARM_SMMU_TTBRn_ASID,
+                                                cfg->asid);
                }
        } else {
                cb->ttbr[0] = pgtbl_cfg->arm_lpae_s2_cfg.vttbr;
@@ -576,31 +597,33 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
        /* CBA2R */
        if (smmu->version > ARM_SMMU_V1) {
                if (cfg->fmt == ARM_SMMU_CTX_FMT_AARCH64)
-                       reg = CBA2R_VA64;
+                       reg = ARM_SMMU_CBA2R_VA64;
                else
                        reg = 0;
                /* 16-bit VMIDs live in CBA2R */
                if (smmu->features & ARM_SMMU_FEAT_VMID16)
-                       reg |= FIELD_PREP(CBA2R_VMID16, cfg->vmid);
+                       reg |= FIELD_PREP(ARM_SMMU_CBA2R_VMID16, cfg->vmid);
 
                arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBA2R(idx), reg);
        }
 
        /* CBAR */
-       reg = FIELD_PREP(CBAR_TYPE, cfg->cbar);
+       reg = FIELD_PREP(ARM_SMMU_CBAR_TYPE, cfg->cbar);
        if (smmu->version < ARM_SMMU_V2)
-               reg |= FIELD_PREP(CBAR_IRPTNDX, cfg->irptndx);
+               reg |= FIELD_PREP(ARM_SMMU_CBAR_IRPTNDX, cfg->irptndx);
 
        /*
         * Use the weakest shareability/memory types, so they are
         * overridden by the ttbcr/pte.
         */
        if (stage1) {
-               reg |= FIELD_PREP(CBAR_S1_BPSHCFG, CBAR_S1_BPSHCFG_NSH) |
-                       FIELD_PREP(CBAR_S1_MEMATTR, CBAR_S1_MEMATTR_WB);
+               reg |= FIELD_PREP(ARM_SMMU_CBAR_S1_BPSHCFG,
+                                 ARM_SMMU_CBAR_S1_BPSHCFG_NSH) |
+                      FIELD_PREP(ARM_SMMU_CBAR_S1_MEMATTR,
+                                 ARM_SMMU_CBAR_S1_MEMATTR_WB);
        } else if (!(smmu->features & ARM_SMMU_FEAT_VMID16)) {
                /* 8-bit VMIDs live in CBAR */
-               reg |= FIELD_PREP(CBAR_VMID, cfg->vmid);
+               reg |= FIELD_PREP(ARM_SMMU_CBAR_VMID, cfg->vmid);
        }
        arm_smmu_gr1_write(smmu, ARM_SMMU_GR1_CBAR(idx), reg);
 
@@ -632,11 +655,12 @@ static void arm_smmu_write_context_bank(struct arm_smmu_device *smmu, int idx)
        }
 
        /* SCTLR */
-       reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE | SCTLR_M;
+       reg = ARM_SMMU_SCTLR_CFIE | ARM_SMMU_SCTLR_CFRE | ARM_SMMU_SCTLR_AFE |
+             ARM_SMMU_SCTLR_TRE | ARM_SMMU_SCTLR_M;
        if (stage1)
-               reg |= SCTLR_S1_ASIDPNE;
+               reg |= ARM_SMMU_SCTLR_S1_ASIDPNE;
        if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
-               reg |= SCTLR_E;
+               reg |= ARM_SMMU_SCTLR_E;
 
        arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_SCTLR, reg);
 }
@@ -818,7 +842,7 @@ static int arm_smmu_init_domain_context(struct iommu_domain *domain,
        if (ret < 0) {
                dev_err(smmu->dev, "failed to request context IRQ %d (%u)\n",
                        cfg->irptndx, irq);
-               cfg->irptndx = INVALID_IRPTNDX;
+               cfg->irptndx = ARM_SMMU_INVALID_IRPTNDX;
        }
 
        mutex_unlock(&smmu_domain->init_mutex);
@@ -856,7 +880,7 @@ static void arm_smmu_destroy_domain_context(struct iommu_domain *domain)
        smmu->cbs[cfg->cbndx].cfg = NULL;
        arm_smmu_write_context_bank(smmu, cfg->cbndx);
 
-       if (cfg->irptndx != INVALID_IRPTNDX) {
+       if (cfg->irptndx != ARM_SMMU_INVALID_IRPTNDX) {
                irq = smmu->irqs[smmu->num_global_irqs + cfg->irptndx];
                devm_free_irq(smmu->dev, irq, domain);
        }
@@ -912,23 +936,24 @@ static void arm_smmu_domain_free(struct iommu_domain *domain)
 static void arm_smmu_write_smr(struct arm_smmu_device *smmu, int idx)
 {
        struct arm_smmu_smr *smr = smmu->smrs + idx;
-       u32 reg = FIELD_PREP(SMR_ID, smr->id) | FIELD_PREP(SMR_MASK, smr->mask);
+       u32 reg = FIELD_PREP(ARM_SMMU_SMR_ID, smr->id) |
+                 FIELD_PREP(ARM_SMMU_SMR_MASK, smr->mask);
 
        if (!(smmu->features & ARM_SMMU_FEAT_EXIDS) && smr->valid)
-               reg |= SMR_VALID;
+               reg |= ARM_SMMU_SMR_VALID;
        arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(idx), reg);
 }
 
 static void arm_smmu_write_s2cr(struct arm_smmu_device *smmu, int idx)
 {
        struct arm_smmu_s2cr *s2cr = smmu->s2crs + idx;
-       u32 reg = FIELD_PREP(S2CR_TYPE, s2cr->type) |
-                 FIELD_PREP(S2CR_CBNDX, s2cr->cbndx) |
-                 FIELD_PREP(S2CR_PRIVCFG, s2cr->privcfg);
+       u32 reg = FIELD_PREP(ARM_SMMU_S2CR_TYPE, s2cr->type) |
+                 FIELD_PREP(ARM_SMMU_S2CR_CBNDX, s2cr->cbndx) |
+                 FIELD_PREP(ARM_SMMU_S2CR_PRIVCFG, s2cr->privcfg);
 
        if (smmu->features & ARM_SMMU_FEAT_EXIDS && smmu->smrs &&
            smmu->smrs[idx].valid)
-               reg |= S2CR_EXIDVALID;
+               reg |= ARM_SMMU_S2CR_EXIDVALID;
        arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_S2CR(idx), reg);
 }
 
@@ -946,24 +971,37 @@ static void arm_smmu_write_sme(struct arm_smmu_device *smmu, int idx)
 static void arm_smmu_test_smr_masks(struct arm_smmu_device *smmu)
 {
        u32 smr;
+       int i;
 
        if (!smmu->smrs)
                return;
-
+       /*
+        * If we've had to accommodate firmware memory regions, we may
+        * have live SMRs by now; tread carefully...
+        *
+        * Somewhat perversely, not having a free SMR for this test implies we
+        * can get away without it anyway, as we'll only be able to 'allocate'
+        * these SMRs for the ID/mask values we're already trusting to be OK.
+        */
+       for (i = 0; i < smmu->num_mapping_groups; i++)
+               if (!smmu->smrs[i].valid)
+                       goto smr_ok;
+       return;
+smr_ok:
        /*
         * SMR.ID bits may not be preserved if the corresponding MASK
         * bits are set, so check each one separately. We can reject
         * masters later if they try to claim IDs outside these masks.
         */
-       smr = FIELD_PREP(SMR_ID, smmu->streamid_mask);
-       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(0), smr);
-       smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(0));
-       smmu->streamid_mask = FIELD_GET(SMR_ID, smr);
+       smr = FIELD_PREP(ARM_SMMU_SMR_ID, smmu->streamid_mask);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(i), smr);
+       smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+       smmu->streamid_mask = FIELD_GET(ARM_SMMU_SMR_ID, smr);
 
-       smr = FIELD_PREP(SMR_MASK, smmu->streamid_mask);
-       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(0), smr);
-       smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(0));
-       smmu->smr_mask_mask = FIELD_GET(SMR_MASK, smr);
+       smr = FIELD_PREP(ARM_SMMU_SMR_MASK, smmu->streamid_mask);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_SMR(i), smr);
+       smr = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_SMR(i));
+       smmu->smr_mask_mask = FIELD_GET(ARM_SMMU_SMR_MASK, smr);
 }
 
 static int arm_smmu_find_sme(struct arm_smmu_device *smmu, u16 id, u16 mask)
@@ -1032,8 +1070,8 @@ static int arm_smmu_master_alloc_smes(struct device *dev)
        mutex_lock(&smmu->stream_map_mutex);
        /* Figure out a viable stream map entry allocation */
        for_each_cfg_sme(fwspec, i, idx) {
-               u16 sid = FIELD_GET(SMR_ID, fwspec->ids[i]);
-               u16 mask = FIELD_GET(SMR_MASK, fwspec->ids[i]);
+               u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
+               u16 mask = FIELD_GET(ARM_SMMU_SMR_MASK, fwspec->ids[i]);
 
                if (idx != INVALID_SMENDX) {
                        ret = -EEXIST;
@@ -1277,7 +1315,8 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
                arm_smmu_cb_write(smmu, idx, ARM_SMMU_CB_ATS1PR, va);
 
        reg = arm_smmu_page(smmu, ARM_SMMU_CB(smmu, idx)) + ARM_SMMU_CB_ATSR;
-       if (readl_poll_timeout_atomic(reg, tmp, !(tmp & ATSR_ACTIVE), 5, 50)) {
+       if (readl_poll_timeout_atomic(reg, tmp, !(tmp & ARM_SMMU_ATSR_ACTIVE),
+                                     5, 50)) {
                spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
                dev_err(dev,
                        "iova to phys timed out on %pad. Falling back to software table walk.\n",
@@ -1287,7 +1326,7 @@ static phys_addr_t arm_smmu_iova_to_phys_hard(struct iommu_domain *domain,
 
        phys = arm_smmu_cb_readq(smmu, idx, ARM_SMMU_CB_PAR);
        spin_unlock_irqrestore(&smmu_domain->cb_lock, flags);
-       if (phys & CB_PAR_F) {
+       if (phys & ARM_SMMU_CB_PAR_F) {
                dev_err(dev, "translation fault!\n");
                dev_err(dev, "PAR = 0x%llx\n", phys);
                return 0;
@@ -1368,8 +1407,8 @@ static int arm_smmu_add_device(struct device *dev)
 
        ret = -EINVAL;
        for (i = 0; i < fwspec->num_ids; i++) {
-               u16 sid = FIELD_GET(SMR_ID, fwspec->ids[i]);
-               u16 mask = FIELD_GET(SMR_MASK, fwspec->ids[i]);
+               u16 sid = FIELD_GET(ARM_SMMU_SMR_ID, fwspec->ids[i]);
+               u16 mask = FIELD_GET(ARM_SMMU_SMR_MASK, fwspec->ids[i]);
 
                if (sid & ~smmu->streamid_mask) {
                        dev_err(dev, "stream ID 0x%x out of range for SMMU (0x%x)\n",
@@ -1550,12 +1589,12 @@ static int arm_smmu_of_xlate(struct device *dev, struct of_phandle_args *args)
        u32 mask, fwid = 0;
 
        if (args->args_count > 0)
-               fwid |= FIELD_PREP(SMR_ID, args->args[0]);
+               fwid |= FIELD_PREP(ARM_SMMU_SMR_ID, args->args[0]);
 
        if (args->args_count > 1)
-               fwid |= FIELD_PREP(SMR_MASK, args->args[1]);
+               fwid |= FIELD_PREP(ARM_SMMU_SMR_MASK, args->args[1]);
        else if (!of_property_read_u32(args->np, "stream-match-mask", &mask))
-               fwid |= FIELD_PREP(SMR_MASK, mask);
+               fwid |= FIELD_PREP(ARM_SMMU_SMR_MASK, mask);
 
        return iommu_fwspec_add_ids(dev, &fwid, 1);
 }
@@ -1576,15 +1615,6 @@ static void arm_smmu_get_resv_regions(struct device *dev,
        iommu_dma_get_resv_regions(dev, head);
 }
 
-static void arm_smmu_put_resv_regions(struct device *dev,
-                                     struct list_head *head)
-{
-       struct iommu_resv_region *entry, *next;
-
-       list_for_each_entry_safe(entry, next, head, list)
-               kfree(entry);
-}
-
 static struct iommu_ops arm_smmu_ops = {
        .capable                = arm_smmu_capable,
        .domain_alloc           = arm_smmu_domain_alloc,
@@ -1602,7 +1632,7 @@ static struct iommu_ops arm_smmu_ops = {
        .domain_set_attr        = arm_smmu_domain_set_attr,
        .of_xlate               = arm_smmu_of_xlate,
        .get_resv_regions       = arm_smmu_get_resv_regions,
-       .put_resv_regions       = arm_smmu_put_resv_regions,
+       .put_resv_regions       = generic_iommu_put_resv_regions,
        .pgsize_bitmap          = -1UL, /* Restricted during device attach */
 };
 
@@ -1625,7 +1655,7 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
        /* Make sure all context banks are disabled and clear CB_FSR  */
        for (i = 0; i < smmu->num_context_banks; ++i) {
                arm_smmu_write_context_bank(smmu, i);
-               arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_FSR, FSR_FAULT);
+               arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_FSR, ARM_SMMU_FSR_FAULT);
        }
 
        /* Invalidate the TLB, just in case */
@@ -1635,29 +1665,30 @@ static void arm_smmu_device_reset(struct arm_smmu_device *smmu)
        reg = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_sCR0);
 
        /* Enable fault reporting */
-       reg |= (sCR0_GFRE | sCR0_GFIE | sCR0_GCFGFRE | sCR0_GCFGFIE);
+       reg |= (ARM_SMMU_sCR0_GFRE | ARM_SMMU_sCR0_GFIE |
+               ARM_SMMU_sCR0_GCFGFRE | ARM_SMMU_sCR0_GCFGFIE);
 
        /* Disable TLB broadcasting. */
-       reg |= (sCR0_VMIDPNE | sCR0_PTM);
+       reg |= (ARM_SMMU_sCR0_VMIDPNE | ARM_SMMU_sCR0_PTM);
 
        /* Enable client access, handling unmatched streams as appropriate */
-       reg &= ~sCR0_CLIENTPD;
+       reg &= ~ARM_SMMU_sCR0_CLIENTPD;
        if (disable_bypass)
-               reg |= sCR0_USFCFG;
+               reg |= ARM_SMMU_sCR0_USFCFG;
        else
-               reg &= ~sCR0_USFCFG;
+               reg &= ~ARM_SMMU_sCR0_USFCFG;
 
        /* Disable forced broadcasting */
-       reg &= ~sCR0_FB;
+       reg &= ~ARM_SMMU_sCR0_FB;
 
        /* Don't upgrade barriers */
-       reg &= ~(sCR0_BSU);
+       reg &= ~(ARM_SMMU_sCR0_BSU);
 
        if (smmu->features & ARM_SMMU_FEAT_VMID16)
-               reg |= sCR0_VMID16EN;
+               reg |= ARM_SMMU_sCR0_VMID16EN;
 
        if (smmu->features & ARM_SMMU_FEAT_EXIDS)
-               reg |= sCR0_EXIDENABLE;
+               reg |= ARM_SMMU_sCR0_EXIDENABLE;
 
        if (smmu->impl && smmu->impl->reset)
                smmu->impl->reset(smmu);
@@ -1702,21 +1733,21 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 
        /* Restrict available stages based on module parameter */
        if (force_stage == 1)
-               id &= ~(ID0_S2TS | ID0_NTS);
+               id &= ~(ARM_SMMU_ID0_S2TS | ARM_SMMU_ID0_NTS);
        else if (force_stage == 2)
-               id &= ~(ID0_S1TS | ID0_NTS);
+               id &= ~(ARM_SMMU_ID0_S1TS | ARM_SMMU_ID0_NTS);
 
-       if (id & ID0_S1TS) {
+       if (id & ARM_SMMU_ID0_S1TS) {
                smmu->features |= ARM_SMMU_FEAT_TRANS_S1;
                dev_notice(smmu->dev, "\tstage 1 translation\n");
        }
 
-       if (id & ID0_S2TS) {
+       if (id & ARM_SMMU_ID0_S2TS) {
                smmu->features |= ARM_SMMU_FEAT_TRANS_S2;
                dev_notice(smmu->dev, "\tstage 2 translation\n");
        }
 
-       if (id & ID0_NTS) {
+       if (id & ARM_SMMU_ID0_NTS) {
                smmu->features |= ARM_SMMU_FEAT_TRANS_NESTED;
                dev_notice(smmu->dev, "\tnested translation\n");
        }
@@ -1727,8 +1758,8 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
                return -ENODEV;
        }
 
-       if ((id & ID0_S1TS) &&
-               ((smmu->version < ARM_SMMU_V2) || !(id & ID0_ATOSNS))) {
+       if ((id & ARM_SMMU_ID0_S1TS) &&
+           ((smmu->version < ARM_SMMU_V2) || !(id & ARM_SMMU_ID0_ATOSNS))) {
                smmu->features |= ARM_SMMU_FEAT_TRANS_OPS;
                dev_notice(smmu->dev, "\taddress translation ops\n");
        }
@@ -1739,7 +1770,7 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
         * Fortunately, this also opens up a workaround for systems where the
         * ID register value has ended up configured incorrectly.
         */
-       cttw_reg = !!(id & ID0_CTTW);
+       cttw_reg = !!(id & ARM_SMMU_ID0_CTTW);
        if (cttw_fw || cttw_reg)
                dev_notice(smmu->dev, "\t%scoherent table walk\n",
                           cttw_fw ? "" : "non-");
@@ -1748,16 +1779,16 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
                           "\t(IDR0.CTTW overridden by FW configuration)\n");
 
        /* Max. number of entries we have for stream matching/indexing */
-       if (smmu->version == ARM_SMMU_V2 && id & ID0_EXIDS) {
+       if (smmu->version == ARM_SMMU_V2 && id & ARM_SMMU_ID0_EXIDS) {
                smmu->features |= ARM_SMMU_FEAT_EXIDS;
                size = 1 << 16;
        } else {
-               size = 1 << FIELD_GET(ID0_NUMSIDB, id);
+               size = 1 << FIELD_GET(ARM_SMMU_ID0_NUMSIDB, id);
        }
        smmu->streamid_mask = size - 1;
-       if (id & ID0_SMS) {
+       if (id & ARM_SMMU_ID0_SMS) {
                smmu->features |= ARM_SMMU_FEAT_STREAM_MATCH;
-               size = FIELD_GET(ID0_NUMSMRG, id);
+               size = FIELD_GET(ARM_SMMU_ID0_NUMSMRG, id);
                if (size == 0) {
                        dev_err(smmu->dev,
                                "stream-matching supported, but no SMRs present!\n");
@@ -1785,18 +1816,19 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
        mutex_init(&smmu->stream_map_mutex);
        spin_lock_init(&smmu->global_sync_lock);
 
-       if (smmu->version < ARM_SMMU_V2 || !(id & ID0_PTFS_NO_AARCH32)) {
+       if (smmu->version < ARM_SMMU_V2 ||
+           !(id & ARM_SMMU_ID0_PTFS_NO_AARCH32)) {
                smmu->features |= ARM_SMMU_FEAT_FMT_AARCH32_L;
-               if (!(id & ID0_PTFS_NO_AARCH32S))
+               if (!(id & ARM_SMMU_ID0_PTFS_NO_AARCH32S))
                        smmu->features |= ARM_SMMU_FEAT_FMT_AARCH32_S;
        }
 
        /* ID1 */
        id = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_ID1);
-       smmu->pgshift = (id & ID1_PAGESIZE) ? 16 : 12;
+       smmu->pgshift = (id & ARM_SMMU_ID1_PAGESIZE) ? 16 : 12;
 
        /* Check for size mismatch of SMMU address space from mapped region */
-       size = 1 << (FIELD_GET(ID1_NUMPAGENDXB, id) + 1);
+       size = 1 << (FIELD_GET(ARM_SMMU_ID1_NUMPAGENDXB, id) + 1);
        if (smmu->numpage != 2 * size << smmu->pgshift)
                dev_warn(smmu->dev,
                        "SMMU address space size (0x%x) differs from mapped region size (0x%x)!\n",
@@ -1804,8 +1836,8 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
        /* Now properly encode NUMPAGE to subsequently derive SMMU_CB_BASE */
        smmu->numpage = size;
 
-       smmu->num_s2_context_banks = FIELD_GET(ID1_NUMS2CB, id);
-       smmu->num_context_banks = FIELD_GET(ID1_NUMCB, id);
+       smmu->num_s2_context_banks = FIELD_GET(ARM_SMMU_ID1_NUMS2CB, id);
+       smmu->num_context_banks = FIELD_GET(ARM_SMMU_ID1_NUMCB, id);
        if (smmu->num_s2_context_banks > smmu->num_context_banks) {
                dev_err(smmu->dev, "impossible number of S2 context banks!\n");
                return -ENODEV;
@@ -1819,14 +1851,14 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
 
        /* ID2 */
        id = arm_smmu_gr0_read(smmu, ARM_SMMU_GR0_ID2);
-       size = arm_smmu_id_size_to_bits(FIELD_GET(ID2_IAS, id));
+       size = arm_smmu_id_size_to_bits(FIELD_GET(ARM_SMMU_ID2_IAS, id));
        smmu->ipa_size = size;
 
        /* The output mask is also applied for bypass */
-       size = arm_smmu_id_size_to_bits(FIELD_GET(ID2_OAS, id));
+       size = arm_smmu_id_size_to_bits(FIELD_GET(ARM_SMMU_ID2_OAS, id));
        smmu->pa_size = size;
 
-       if (id & ID2_VMID16)
+       if (id & ARM_SMMU_ID2_VMID16)
                smmu->features |= ARM_SMMU_FEAT_VMID16;
 
        /*
@@ -1843,13 +1875,13 @@ static int arm_smmu_device_cfg_probe(struct arm_smmu_device *smmu)
                if (smmu->version == ARM_SMMU_V1_64K)
                        smmu->features |= ARM_SMMU_FEAT_FMT_AARCH64_64K;
        } else {
-               size = FIELD_GET(ID2_UBS, id);
+               size = FIELD_GET(ARM_SMMU_ID2_UBS, id);
                smmu->va_size = arm_smmu_id_size_to_bits(size);
-               if (id & ID2_PTFS_4K)
+               if (id & ARM_SMMU_ID2_PTFS_4K)
                        smmu->features |= ARM_SMMU_FEAT_FMT_AARCH64_4K;
-               if (id & ID2_PTFS_16K)
+               if (id & ARM_SMMU_ID2_PTFS_16K)
                        smmu->features |= ARM_SMMU_FEAT_FMT_AARCH64_16K;
-               if (id & ID2_PTFS_64K)
+               if (id & ARM_SMMU_ID2_PTFS_64K)
                        smmu->features |= ARM_SMMU_FEAT_FMT_AARCH64_64K;
        }
 
@@ -1911,6 +1943,7 @@ static const struct of_device_id arm_smmu_of_match[] = {
        { .compatible = "qcom,smmu-v2", .data = &qcom_smmuv2 },
        { },
 };
+MODULE_DEVICE_TABLE(of, arm_smmu_of_match);
 
 #ifdef CONFIG_ACPI
 static int acpi_smmu_get_data(u32 model, struct arm_smmu_device *smmu)
@@ -1997,8 +2030,10 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
 
        legacy_binding = of_find_property(dev->of_node, "mmu-masters", NULL);
        if (legacy_binding && !using_generic_binding) {
-               if (!using_legacy_binding)
-                       pr_notice("deprecated \"mmu-masters\" DT property in use; DMA API support unavailable\n");
+               if (!using_legacy_binding) {
+                       pr_notice("deprecated \"mmu-masters\" DT property in use; %s support unavailable\n",
+                                 IS_ENABLED(CONFIG_ARM_SMMU_LEGACY_DT_BINDINGS) ? "DMA API" : "SMMU");
+               }
                using_legacy_binding = true;
        } else if (!legacy_binding && !using_legacy_binding) {
                using_generic_binding = true;
@@ -2013,25 +2048,50 @@ static int arm_smmu_device_dt_probe(struct platform_device *pdev,
        return 0;
 }
 
-static void arm_smmu_bus_init(void)
+static int arm_smmu_bus_init(struct iommu_ops *ops)
 {
+       int err;
+
        /* Oh, for a proper bus abstraction */
-       if (!iommu_present(&platform_bus_type))
-               bus_set_iommu(&platform_bus_type, &arm_smmu_ops);
+       if (!iommu_present(&platform_bus_type)) {
+               err = bus_set_iommu(&platform_bus_type, ops);
+               if (err)
+                       return err;
+       }
 #ifdef CONFIG_ARM_AMBA
-       if (!iommu_present(&amba_bustype))
-               bus_set_iommu(&amba_bustype, &arm_smmu_ops);
+       if (!iommu_present(&amba_bustype)) {
+               err = bus_set_iommu(&amba_bustype, ops);
+               if (err)
+                       goto err_reset_platform_ops;
+       }
 #endif
 #ifdef CONFIG_PCI
        if (!iommu_present(&pci_bus_type)) {
-               pci_request_acs();
-               bus_set_iommu(&pci_bus_type, &arm_smmu_ops);
+               err = bus_set_iommu(&pci_bus_type, ops);
+               if (err)
+                       goto err_reset_amba_ops;
        }
 #endif
 #ifdef CONFIG_FSL_MC_BUS
-       if (!iommu_present(&fsl_mc_bus_type))
-               bus_set_iommu(&fsl_mc_bus_type, &arm_smmu_ops);
+       if (!iommu_present(&fsl_mc_bus_type)) {
+               err = bus_set_iommu(&fsl_mc_bus_type, ops);
+               if (err)
+                       goto err_reset_pci_ops;
+       }
 #endif
+       return 0;
+
+err_reset_pci_ops: __maybe_unused;
+#ifdef CONFIG_PCI
+       bus_set_iommu(&pci_bus_type, NULL);
+#endif
+err_reset_amba_ops: __maybe_unused;
+#ifdef CONFIG_ARM_AMBA
+       bus_set_iommu(&amba_bustype, NULL);
+#endif
+err_reset_platform_ops: __maybe_unused;
+       bus_set_iommu(&platform_bus_type, NULL);
+       return err;
 }
 
 static int arm_smmu_device_probe(struct platform_device *pdev)
@@ -2177,38 +2237,28 @@ static int arm_smmu_device_probe(struct platform_device *pdev)
         * ready to handle default domain setup as soon as any SMMU exists.
         */
        if (!using_legacy_binding)
-               arm_smmu_bus_init();
+               return arm_smmu_bus_init(&arm_smmu_ops);
 
        return 0;
 }
 
-/*
- * With the legacy DT binding in play, though, we have no guarantees about
- * probe order, but then we're also not doing default domains, so we can
- * delay setting bus ops until we're sure every possible SMMU is ready,
- * and that way ensure that no add_device() calls get missed.
- */
-static int arm_smmu_legacy_bus_init(void)
-{
-       if (using_legacy_binding)
-               arm_smmu_bus_init();
-       return 0;
-}
-device_initcall_sync(arm_smmu_legacy_bus_init);
-
-static void arm_smmu_device_shutdown(struct platform_device *pdev)
+static int arm_smmu_device_remove(struct platform_device *pdev)
 {
        struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
 
        if (!smmu)
-               return;
+               return -ENODEV;
 
        if (!bitmap_empty(smmu->context_map, ARM_SMMU_MAX_CBS))
                dev_err(&pdev->dev, "removing device with active domains!\n");
 
+       arm_smmu_bus_init(NULL);
+       iommu_device_unregister(&smmu->iommu);
+       iommu_device_sysfs_remove(&smmu->iommu);
+
        arm_smmu_rpm_get(smmu);
        /* Turn the thing off */
-       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sCR0, sCR0_CLIENTPD);
+       arm_smmu_gr0_write(smmu, ARM_SMMU_GR0_sCR0, ARM_SMMU_sCR0_CLIENTPD);
        arm_smmu_rpm_put(smmu);
 
        if (pm_runtime_enabled(smmu->dev))
@@ -2217,6 +2267,12 @@ static void arm_smmu_device_shutdown(struct platform_device *pdev)
                clk_bulk_disable(smmu->num_clks, smmu->clks);
 
        clk_bulk_unprepare(smmu->num_clks, smmu->clks);
+       return 0;
+}
+
+static void arm_smmu_device_shutdown(struct platform_device *pdev)
+{
+       arm_smmu_device_remove(pdev);
 }
 
 static int __maybe_unused arm_smmu_runtime_resume(struct device *dev)
@@ -2267,11 +2323,17 @@ static const struct dev_pm_ops arm_smmu_pm_ops = {
 static struct platform_driver arm_smmu_driver = {
        .driver = {
                .name                   = "arm-smmu",
-               .of_match_table         = of_match_ptr(arm_smmu_of_match),
+               .of_match_table         = arm_smmu_of_match,
                .pm                     = &arm_smmu_pm_ops,
-               .suppress_bind_attrs    = true,
+               .suppress_bind_attrs    = true,
        },
        .probe  = arm_smmu_device_probe,
+       .remove = arm_smmu_device_remove,
        .shutdown = arm_smmu_device_shutdown,
 };
-builtin_platform_driver(arm_smmu_driver);
+module_platform_driver(arm_smmu_driver);
+
+MODULE_DESCRIPTION("IOMMU API for ARM architected SMMU implementations");
+MODULE_AUTHOR("Will Deacon <will@kernel.org>");
+MODULE_ALIAS("platform:arm-smmu");
+MODULE_LICENSE("GPL v2");
index 62b9f0c..8d1cd54 100644 (file)
@@ -11,6 +11,7 @@
 #define _ARM_SMMU_H
 
 #include <linux/atomic.h>
+#include <linux/bitfield.h>
 #include <linux/bits.h>
 #include <linux/clk.h>
 #include <linux/device.h>
 
 /* Configuration registers */
 #define ARM_SMMU_GR0_sCR0              0x0
-#define sCR0_VMID16EN                  BIT(31)
-#define sCR0_BSU                       GENMASK(15, 14)
-#define sCR0_FB                                BIT(13)
-#define sCR0_PTM                       BIT(12)
-#define sCR0_VMIDPNE                   BIT(11)
-#define sCR0_USFCFG                    BIT(10)
-#define sCR0_GCFGFIE                   BIT(5)
-#define sCR0_GCFGFRE                   BIT(4)
-#define sCR0_EXIDENABLE                        BIT(3)
-#define sCR0_GFIE                      BIT(2)
-#define sCR0_GFRE                      BIT(1)
-#define sCR0_CLIENTPD                  BIT(0)
+#define ARM_SMMU_sCR0_VMID16EN         BIT(31)
+#define ARM_SMMU_sCR0_BSU              GENMASK(15, 14)
+#define ARM_SMMU_sCR0_FB               BIT(13)
+#define ARM_SMMU_sCR0_PTM              BIT(12)
+#define ARM_SMMU_sCR0_VMIDPNE          BIT(11)
+#define ARM_SMMU_sCR0_USFCFG           BIT(10)
+#define ARM_SMMU_sCR0_GCFGFIE          BIT(5)
+#define ARM_SMMU_sCR0_GCFGFRE          BIT(4)
+#define ARM_SMMU_sCR0_EXIDENABLE       BIT(3)
+#define ARM_SMMU_sCR0_GFIE             BIT(2)
+#define ARM_SMMU_sCR0_GFRE             BIT(1)
+#define ARM_SMMU_sCR0_CLIENTPD         BIT(0)
 
 /* Auxiliary Configuration register */
 #define ARM_SMMU_GR0_sACR              0x10
 
 /* Identification registers */
 #define ARM_SMMU_GR0_ID0               0x20
-#define ID0_S1TS                       BIT(30)
-#define ID0_S2TS                       BIT(29)
-#define ID0_NTS                                BIT(28)
-#define ID0_SMS                                BIT(27)
-#define ID0_ATOSNS                     BIT(26)
-#define ID0_PTFS_NO_AARCH32            BIT(25)
-#define ID0_PTFS_NO_AARCH32S           BIT(24)
-#define ID0_NUMIRPT                    GENMASK(23, 16)
-#define ID0_CTTW                       BIT(14)
-#define ID0_NUMSIDB                    GENMASK(12, 9)
-#define ID0_EXIDS                      BIT(8)
-#define ID0_NUMSMRG                    GENMASK(7, 0)
+#define ARM_SMMU_ID0_S1TS              BIT(30)
+#define ARM_SMMU_ID0_S2TS              BIT(29)
+#define ARM_SMMU_ID0_NTS               BIT(28)
+#define ARM_SMMU_ID0_SMS               BIT(27)
+#define ARM_SMMU_ID0_ATOSNS            BIT(26)
+#define ARM_SMMU_ID0_PTFS_NO_AARCH32   BIT(25)
+#define ARM_SMMU_ID0_PTFS_NO_AARCH32S  BIT(24)
+#define ARM_SMMU_ID0_NUMIRPT           GENMASK(23, 16)
+#define ARM_SMMU_ID0_CTTW              BIT(14)
+#define ARM_SMMU_ID0_NUMSIDB           GENMASK(12, 9)
+#define ARM_SMMU_ID0_EXIDS             BIT(8)
+#define ARM_SMMU_ID0_NUMSMRG           GENMASK(7, 0)
 
 #define ARM_SMMU_GR0_ID1               0x24
-#define ID1_PAGESIZE                   BIT(31)
-#define ID1_NUMPAGENDXB                        GENMASK(30, 28)
-#define ID1_NUMS2CB                    GENMASK(23, 16)
-#define ID1_NUMCB                      GENMASK(7, 0)
+#define ARM_SMMU_ID1_PAGESIZE          BIT(31)
+#define ARM_SMMU_ID1_NUMPAGENDXB       GENMASK(30, 28)
+#define ARM_SMMU_ID1_NUMS2CB           GENMASK(23, 16)
+#define ARM_SMMU_ID1_NUMCB             GENMASK(7, 0)
 
 #define ARM_SMMU_GR0_ID2               0x28
-#define ID2_VMID16                     BIT(15)
-#define ID2_PTFS_64K                   BIT(14)
-#define ID2_PTFS_16K                   BIT(13)
-#define ID2_PTFS_4K                    BIT(12)
-#define ID2_UBS                                GENMASK(11, 8)
-#define ID2_OAS                                GENMASK(7, 4)
-#define ID2_IAS                                GENMASK(3, 0)
+#define ARM_SMMU_ID2_VMID16            BIT(15)
+#define ARM_SMMU_ID2_PTFS_64K          BIT(14)
+#define ARM_SMMU_ID2_PTFS_16K          BIT(13)
+#define ARM_SMMU_ID2_PTFS_4K           BIT(12)
+#define ARM_SMMU_ID2_UBS               GENMASK(11, 8)
+#define ARM_SMMU_ID2_OAS               GENMASK(7, 4)
+#define ARM_SMMU_ID2_IAS               GENMASK(3, 0)
 
 #define ARM_SMMU_GR0_ID3               0x2c
 #define ARM_SMMU_GR0_ID4               0x30
 #define ARM_SMMU_GR0_ID6               0x38
 
 #define ARM_SMMU_GR0_ID7               0x3c
-#define ID7_MAJOR                      GENMASK(7, 4)
-#define ID7_MINOR                      GENMASK(3, 0)
+#define ARM_SMMU_ID7_MAJOR             GENMASK(7, 4)
+#define ARM_SMMU_ID7_MINOR             GENMASK(3, 0)
 
 #define ARM_SMMU_GR0_sGFSR             0x48
-#define sGFSR_USF                      BIT(1)
+#define ARM_SMMU_sGFSR_USF             BIT(1)
 
 #define ARM_SMMU_GR0_sGFSYNR0          0x50
 #define ARM_SMMU_GR0_sGFSYNR1          0x54
 #define ARM_SMMU_GR0_sTLBGSYNC         0x70
 
 #define ARM_SMMU_GR0_sTLBGSTATUS       0x74
-#define sTLBGSTATUS_GSACTIVE           BIT(0)
+#define ARM_SMMU_sTLBGSTATUS_GSACTIVE  BIT(0)
 
 /* Stream mapping registers */
 #define ARM_SMMU_GR0_SMR(n)            (0x800 + ((n) << 2))
-#define SMR_VALID                      BIT(31)
-#define SMR_MASK                       GENMASK(31, 16)
-#define SMR_ID                         GENMASK(15, 0)
+#define ARM_SMMU_SMR_VALID             BIT(31)
+#define ARM_SMMU_SMR_MASK              GENMASK(31, 16)
+#define ARM_SMMU_SMR_ID                        GENMASK(15, 0)
 
 #define ARM_SMMU_GR0_S2CR(n)           (0xc00 + ((n) << 2))
-#define S2CR_PRIVCFG                   GENMASK(25, 24)
+#define ARM_SMMU_S2CR_PRIVCFG          GENMASK(25, 24)
 enum arm_smmu_s2cr_privcfg {
        S2CR_PRIVCFG_DEFAULT,
        S2CR_PRIVCFG_DIPAN,
        S2CR_PRIVCFG_UNPRIV,
        S2CR_PRIVCFG_PRIV,
 };
-#define S2CR_TYPE                      GENMASK(17, 16)
+#define ARM_SMMU_S2CR_TYPE             GENMASK(17, 16)
 enum arm_smmu_s2cr_type {
        S2CR_TYPE_TRANS,
        S2CR_TYPE_BYPASS,
        S2CR_TYPE_FAULT,
 };
-#define S2CR_EXIDVALID                 BIT(10)
-#define S2CR_CBNDX                     GENMASK(7, 0)
+#define ARM_SMMU_S2CR_EXIDVALID                BIT(10)
+#define ARM_SMMU_S2CR_CBNDX            GENMASK(7, 0)
 
 /* Context bank attribute registers */
 #define ARM_SMMU_GR1_CBAR(n)           (0x0 + ((n) << 2))
-#define CBAR_IRPTNDX                   GENMASK(31, 24)
-#define CBAR_TYPE                      GENMASK(17, 16)
+#define ARM_SMMU_CBAR_IRPTNDX          GENMASK(31, 24)
+#define ARM_SMMU_CBAR_TYPE             GENMASK(17, 16)
 enum arm_smmu_cbar_type {
        CBAR_TYPE_S2_TRANS,
        CBAR_TYPE_S1_TRANS_S2_BYPASS,
        CBAR_TYPE_S1_TRANS_S2_FAULT,
        CBAR_TYPE_S1_TRANS_S2_TRANS,
 };
-#define CBAR_S1_MEMATTR                        GENMASK(15, 12)
-#define CBAR_S1_MEMATTR_WB             0xf
-#define CBAR_S1_BPSHCFG                        GENMASK(9, 8)
-#define CBAR_S1_BPSHCFG_NSH            3
-#define CBAR_VMID                      GENMASK(7, 0)
+#define ARM_SMMU_CBAR_S1_MEMATTR       GENMASK(15, 12)
+#define ARM_SMMU_CBAR_S1_MEMATTR_WB    0xf
+#define ARM_SMMU_CBAR_S1_BPSHCFG       GENMASK(9, 8)
+#define ARM_SMMU_CBAR_S1_BPSHCFG_NSH   3
+#define ARM_SMMU_CBAR_VMID             GENMASK(7, 0)
 
 #define ARM_SMMU_GR1_CBFRSYNRA(n)      (0x400 + ((n) << 2))
 
 #define ARM_SMMU_GR1_CBA2R(n)          (0x800 + ((n) << 2))
-#define CBA2R_VMID16                   GENMASK(31, 16)
-#define CBA2R_VA64                     BIT(0)
+#define ARM_SMMU_CBA2R_VMID16          GENMASK(31, 16)
+#define ARM_SMMU_CBA2R_VA64            BIT(0)
 
 #define ARM_SMMU_CB_SCTLR              0x0
-#define SCTLR_S1_ASIDPNE               BIT(12)
-#define SCTLR_CFCFG                    BIT(7)
-#define SCTLR_CFIE                     BIT(6)
-#define SCTLR_CFRE                     BIT(5)
-#define SCTLR_E                                BIT(4)
-#define SCTLR_AFE                      BIT(2)
-#define SCTLR_TRE                      BIT(1)
-#define SCTLR_M                                BIT(0)
+#define ARM_SMMU_SCTLR_S1_ASIDPNE      BIT(12)
+#define ARM_SMMU_SCTLR_CFCFG           BIT(7)
+#define ARM_SMMU_SCTLR_CFIE            BIT(6)
+#define ARM_SMMU_SCTLR_CFRE            BIT(5)
+#define ARM_SMMU_SCTLR_E               BIT(4)
+#define ARM_SMMU_SCTLR_AFE             BIT(2)
+#define ARM_SMMU_SCTLR_TRE             BIT(1)
+#define ARM_SMMU_SCTLR_M               BIT(0)
 
 #define ARM_SMMU_CB_ACTLR              0x4
 
 #define ARM_SMMU_CB_RESUME             0x8
-#define RESUME_TERMINATE               BIT(0)
+#define ARM_SMMU_RESUME_TERMINATE      BIT(0)
 
 #define ARM_SMMU_CB_TCR2               0x10
-#define TCR2_SEP                       GENMASK(17, 15)
-#define TCR2_SEP_UPSTREAM              0x7
-#define TCR2_AS                                BIT(4)
+#define ARM_SMMU_TCR2_SEP              GENMASK(17, 15)
+#define ARM_SMMU_TCR2_SEP_UPSTREAM     0x7
+#define ARM_SMMU_TCR2_AS               BIT(4)
+#define ARM_SMMU_TCR2_PASIZE           GENMASK(3, 0)
 
 #define ARM_SMMU_CB_TTBR0              0x20
 #define ARM_SMMU_CB_TTBR1              0x28
-#define TTBRn_ASID                     GENMASK_ULL(63, 48)
+#define ARM_SMMU_TTBRn_ASID            GENMASK_ULL(63, 48)
 
 #define ARM_SMMU_CB_TCR                        0x30
+#define ARM_SMMU_TCR_EAE               BIT(31)
+#define ARM_SMMU_TCR_EPD1              BIT(23)
+#define ARM_SMMU_TCR_TG0               GENMASK(15, 14)
+#define ARM_SMMU_TCR_SH0               GENMASK(13, 12)
+#define ARM_SMMU_TCR_ORGN0             GENMASK(11, 10)
+#define ARM_SMMU_TCR_IRGN0             GENMASK(9, 8)
+#define ARM_SMMU_TCR_T0SZ              GENMASK(5, 0)
+
+#define ARM_SMMU_VTCR_RES1             BIT(31)
+#define ARM_SMMU_VTCR_PS               GENMASK(18, 16)
+#define ARM_SMMU_VTCR_TG0              ARM_SMMU_TCR_TG0
+#define ARM_SMMU_VTCR_SH0              ARM_SMMU_TCR_SH0
+#define ARM_SMMU_VTCR_ORGN0            ARM_SMMU_TCR_ORGN0
+#define ARM_SMMU_VTCR_IRGN0            ARM_SMMU_TCR_IRGN0
+#define ARM_SMMU_VTCR_SL0              GENMASK(7, 6)
+#define ARM_SMMU_VTCR_T0SZ             ARM_SMMU_TCR_T0SZ
+
 #define ARM_SMMU_CB_CONTEXTIDR         0x34
 #define ARM_SMMU_CB_S1_MAIR0           0x38
 #define ARM_SMMU_CB_S1_MAIR1           0x3c
 
 #define ARM_SMMU_CB_PAR                        0x50
-#define CB_PAR_F                       BIT(0)
+#define ARM_SMMU_CB_PAR_F              BIT(0)
 
 #define ARM_SMMU_CB_FSR                        0x58
-#define FSR_MULTI                      BIT(31)
-#define FSR_SS                         BIT(30)
-#define FSR_UUT                                BIT(8)
-#define FSR_ASF                                BIT(7)
-#define FSR_TLBLKF                     BIT(6)
-#define FSR_TLBMCF                     BIT(5)
-#define FSR_EF                         BIT(4)
-#define FSR_PF                         BIT(3)
-#define FSR_AFF                                BIT(2)
-#define FSR_TF                         BIT(1)
-
-#define FSR_IGN                                (FSR_AFF | FSR_ASF | \
-                                        FSR_TLBMCF | FSR_TLBLKF)
-#define FSR_FAULT                      (FSR_MULTI | FSR_SS | FSR_UUT | \
-                                        FSR_EF | FSR_PF | FSR_TF | FSR_IGN)
+#define ARM_SMMU_FSR_MULTI             BIT(31)
+#define ARM_SMMU_FSR_SS                        BIT(30)
+#define ARM_SMMU_FSR_UUT               BIT(8)
+#define ARM_SMMU_FSR_ASF               BIT(7)
+#define ARM_SMMU_FSR_TLBLKF            BIT(6)
+#define ARM_SMMU_FSR_TLBMCF            BIT(5)
+#define ARM_SMMU_FSR_EF                        BIT(4)
+#define ARM_SMMU_FSR_PF                        BIT(3)
+#define ARM_SMMU_FSR_AFF               BIT(2)
+#define ARM_SMMU_FSR_TF                        BIT(1)
+
+#define ARM_SMMU_FSR_IGN               (ARM_SMMU_FSR_AFF |             \
+                                        ARM_SMMU_FSR_ASF |             \
+                                        ARM_SMMU_FSR_TLBMCF |          \
+                                        ARM_SMMU_FSR_TLBLKF)
+
+#define ARM_SMMU_FSR_FAULT             (ARM_SMMU_FSR_MULTI |           \
+                                        ARM_SMMU_FSR_SS |              \
+                                        ARM_SMMU_FSR_UUT |             \
+                                        ARM_SMMU_FSR_EF |              \
+                                        ARM_SMMU_FSR_PF |              \
+                                        ARM_SMMU_FSR_TF |              \
+                                        ARM_SMMU_FSR_IGN)
 
 #define ARM_SMMU_CB_FAR                        0x60
 
 #define ARM_SMMU_CB_FSYNR0             0x68
-#define FSYNR0_WNR                     BIT(4)
+#define ARM_SMMU_FSYNR0_WNR            BIT(4)
 
 #define ARM_SMMU_CB_S1_TLBIVA          0x600
 #define ARM_SMMU_CB_S1_TLBIASID                0x610
@@ -203,7 +230,7 @@ enum arm_smmu_cbar_type {
 #define ARM_SMMU_CB_ATS1PR             0x800
 
 #define ARM_SMMU_CB_ATSR               0x8f0
-#define ATSR_ACTIVE                    BIT(0)
+#define ARM_SMMU_ATSR_ACTIVE           BIT(0)
 
 
 /* Maximum number of context banks per SMMU */
@@ -297,7 +324,7 @@ struct arm_smmu_cfg {
        enum arm_smmu_cbar_type         cbar;
        enum arm_smmu_context_fmt       fmt;
 };
-#define INVALID_IRPTNDX                        0xff
+#define ARM_SMMU_INVALID_IRPTNDX       0xff
 
 enum arm_smmu_domain_stage {
        ARM_SMMU_DOMAIN_S1 = 0,
@@ -318,6 +345,33 @@ struct arm_smmu_domain {
        struct iommu_domain             domain;
 };
 
+static inline u32 arm_smmu_lpae_tcr(struct io_pgtable_cfg *cfg)
+{
+       return ARM_SMMU_TCR_EPD1 |
+              FIELD_PREP(ARM_SMMU_TCR_TG0, cfg->arm_lpae_s1_cfg.tcr.tg) |
+              FIELD_PREP(ARM_SMMU_TCR_SH0, cfg->arm_lpae_s1_cfg.tcr.sh) |
+              FIELD_PREP(ARM_SMMU_TCR_ORGN0, cfg->arm_lpae_s1_cfg.tcr.orgn) |
+              FIELD_PREP(ARM_SMMU_TCR_IRGN0, cfg->arm_lpae_s1_cfg.tcr.irgn) |
+              FIELD_PREP(ARM_SMMU_TCR_T0SZ, cfg->arm_lpae_s1_cfg.tcr.tsz);
+}
+
+static inline u32 arm_smmu_lpae_tcr2(struct io_pgtable_cfg *cfg)
+{
+       return FIELD_PREP(ARM_SMMU_TCR2_PASIZE, cfg->arm_lpae_s1_cfg.tcr.ips) |
+              FIELD_PREP(ARM_SMMU_TCR2_SEP, ARM_SMMU_TCR2_SEP_UPSTREAM);
+}
+
+static inline u32 arm_smmu_lpae_vtcr(struct io_pgtable_cfg *cfg)
+{
+       return ARM_SMMU_VTCR_RES1 |
+              FIELD_PREP(ARM_SMMU_VTCR_PS, cfg->arm_lpae_s2_cfg.vtcr.ps) |
+              FIELD_PREP(ARM_SMMU_VTCR_TG0, cfg->arm_lpae_s2_cfg.vtcr.tg) |
+              FIELD_PREP(ARM_SMMU_VTCR_SH0, cfg->arm_lpae_s2_cfg.vtcr.sh) |
+              FIELD_PREP(ARM_SMMU_VTCR_ORGN0, cfg->arm_lpae_s2_cfg.vtcr.orgn) |
+              FIELD_PREP(ARM_SMMU_VTCR_IRGN0, cfg->arm_lpae_s2_cfg.vtcr.irgn) |
+              FIELD_PREP(ARM_SMMU_VTCR_SL0, cfg->arm_lpae_s2_cfg.vtcr.sl) |
+              FIELD_PREP(ARM_SMMU_VTCR_T0SZ, cfg->arm_lpae_s2_cfg.vtcr.tsz);
+}
 
 /* Implementation details, yay! */
 struct arm_smmu_impl {
index 3acfa6a..071bb42 100644 (file)
@@ -244,7 +244,7 @@ int dmar_insert_dev_scope(struct dmar_pci_notify_info *info,
                     info->dev->hdr_type != PCI_HEADER_TYPE_NORMAL) ||
                    (scope->entry_type == ACPI_DMAR_SCOPE_TYPE_BRIDGE &&
                     (info->dev->hdr_type == PCI_HEADER_TYPE_NORMAL &&
-                     info->dev->class >> 8 != PCI_CLASS_BRIDGE_OTHER))) {
+                     info->dev->class >> 16 != PCI_BASE_CLASS_BRIDGE))) {
                        pr_warn("Device scope type does not match for %s\n",
                                pci_name(info->dev));
                        return -EINVAL;
@@ -1354,7 +1354,6 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
        struct qi_desc desc;
 
        if (mask) {
-               WARN_ON_ONCE(addr & ((1ULL << (VTD_PAGE_SHIFT + mask)) - 1));
                addr |= (1ULL << (VTD_PAGE_SHIFT + mask - 1)) - 1;
                desc.qw1 = QI_DEV_IOTLB_ADDR(addr) | QI_DEV_IOTLB_SIZE;
        } else
@@ -1371,6 +1370,47 @@ void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
        qi_submit_sync(&desc, iommu);
 }
 
+/* PASID-based IOTLB invalidation */
+void qi_flush_piotlb(struct intel_iommu *iommu, u16 did, u32 pasid, u64 addr,
+                    unsigned long npages, bool ih)
+{
+       struct qi_desc desc = {.qw2 = 0, .qw3 = 0};
+
+       /*
+        * npages == -1 means a PASID-selective invalidation, otherwise,
+        * a positive value for Page-selective-within-PASID invalidation.
+        * 0 is not a valid input.
+        */
+       if (WARN_ON(!npages)) {
+               pr_err("Invalid input npages = %ld\n", npages);
+               return;
+       }
+
+       if (npages == -1) {
+               desc.qw0 = QI_EIOTLB_PASID(pasid) |
+                               QI_EIOTLB_DID(did) |
+                               QI_EIOTLB_GRAN(QI_GRAN_NONG_PASID) |
+                               QI_EIOTLB_TYPE;
+               desc.qw1 = 0;
+       } else {
+               int mask = ilog2(__roundup_pow_of_two(npages));
+               unsigned long align = (1ULL << (VTD_PAGE_SHIFT + mask));
+
+               if (WARN_ON_ONCE(!ALIGN(addr, align)))
+                       addr &= ~(align - 1);
+
+               desc.qw0 = QI_EIOTLB_PASID(pasid) |
+                               QI_EIOTLB_DID(did) |
+                               QI_EIOTLB_GRAN(QI_GRAN_PSI_PASID) |
+                               QI_EIOTLB_TYPE;
+               desc.qw1 = QI_EIOTLB_ADDR(addr) |
+                               QI_EIOTLB_IH(ih) |
+                               QI_EIOTLB_AM(mask);
+       }
+
+       qi_submit_sync(&desc, iommu);
+}
+
 /*
  * Disable Queued Invalidation interface.
  */
index 471f05d..c1257be 100644 (file)
@@ -5,6 +5,7 @@
  * Authors: Gayatri Kammela <gayatri.kammela@intel.com>
  *         Sohil Mehta <sohil.mehta@intel.com>
  *         Jacob Pan <jacob.jun.pan@linux.intel.com>
+ *         Lu Baolu <baolu.lu@linux.intel.com>
  */
 
 #include <linux/debugfs.h>
@@ -283,6 +284,77 @@ static int dmar_translation_struct_show(struct seq_file *m, void *unused)
 }
 DEFINE_SHOW_ATTRIBUTE(dmar_translation_struct);
 
+static inline unsigned long level_to_directory_size(int level)
+{
+       return BIT_ULL(VTD_PAGE_SHIFT + VTD_STRIDE_SHIFT * (level - 1));
+}
+
+static inline void
+dump_page_info(struct seq_file *m, unsigned long iova, u64 *path)
+{
+       seq_printf(m, "0x%013lx |\t0x%016llx\t0x%016llx\t0x%016llx\t0x%016llx\t0x%016llx\n",
+                  iova >> VTD_PAGE_SHIFT, path[5], path[4],
+                  path[3], path[2], path[1]);
+}
+
+static void pgtable_walk_level(struct seq_file *m, struct dma_pte *pde,
+                              int level, unsigned long start,
+                              u64 *path)
+{
+       int i;
+
+       if (level > 5 || level < 1)
+               return;
+
+       for (i = 0; i < BIT_ULL(VTD_STRIDE_SHIFT);
+                       i++, pde++, start += level_to_directory_size(level)) {
+               if (!dma_pte_present(pde))
+                       continue;
+
+               path[level] = pde->val;
+               if (dma_pte_superpage(pde) || level == 1)
+                       dump_page_info(m, start, path);
+               else
+                       pgtable_walk_level(m, phys_to_virt(dma_pte_addr(pde)),
+                                          level - 1, start, path);
+               path[level] = 0;
+       }
+}
+
+static int show_device_domain_translation(struct device *dev, void *data)
+{
+       struct dmar_domain *domain = find_domain(dev);
+       struct seq_file *m = data;
+       u64 path[6] = { 0 };
+
+       if (!domain)
+               return 0;
+
+       seq_printf(m, "Device %s with pasid %d @0x%llx\n",
+                  dev_name(dev), domain->default_pasid,
+                  (u64)virt_to_phys(domain->pgd));
+       seq_puts(m, "IOVA_PFN\t\tPML5E\t\t\tPML4E\t\t\tPDPE\t\t\tPDE\t\t\tPTE\n");
+
+       pgtable_walk_level(m, domain->pgd, domain->agaw + 2, 0, path);
+       seq_putc(m, '\n');
+
+       return 0;
+}
+
+static int domain_translation_struct_show(struct seq_file *m, void *unused)
+{
+       unsigned long flags;
+       int ret;
+
+       spin_lock_irqsave(&device_domain_lock, flags);
+       ret = bus_for_each_dev(&pci_bus_type, NULL, m,
+                              show_device_domain_translation);
+       spin_unlock_irqrestore(&device_domain_lock, flags);
+
+       return ret;
+}
+DEFINE_SHOW_ATTRIBUTE(domain_translation_struct);
+
 #ifdef CONFIG_IRQ_REMAP
 static void ir_tbl_remap_entry_show(struct seq_file *m,
                                    struct intel_iommu *iommu)
@@ -396,6 +468,9 @@ void __init intel_iommu_debugfs_init(void)
                            &iommu_regset_fops);
        debugfs_create_file("dmar_translation_struct", 0444, intel_iommu_debug,
                            NULL, &dmar_translation_struct_fops);
+       debugfs_create_file("domain_translation_struct", 0444,
+                           intel_iommu_debug, NULL,
+                           &domain_translation_struct_fops);
 #ifdef CONFIG_IRQ_REMAP
        debugfs_create_file("ir_translation_struct", 0444, intel_iommu_debug,
                            NULL, &ir_translation_struct_fops);
index 35a4a3a..9dc3767 100644 (file)
@@ -307,6 +307,20 @@ static int hw_pass_through = 1;
  */
 #define DOMAIN_FLAG_LOSE_CHILDREN              BIT(1)
 
+/*
+ * When VT-d works in the scalable mode, it allows DMA translation to
+ * happen through either first level or second level page table. This
+ * bit marks that the DMA translation for the domain goes through the
+ * first level page table, otherwise, it goes through the second level.
+ */
+#define DOMAIN_FLAG_USE_FIRST_LEVEL            BIT(2)
+
+/*
+ * Domain represents a virtual machine which demands iommu nested
+ * translation mode support.
+ */
+#define DOMAIN_FLAG_NESTING_MODE               BIT(3)
+
 #define for_each_domain_iommu(idx, domain)                     \
        for (idx = 0; idx < g_num_of_iommus; idx++)             \
                if (domain->iommu_refcnt[idx])
@@ -355,9 +369,14 @@ static phys_addr_t intel_iommu_iova_to_phys(struct iommu_domain *domain,
 int dmar_disabled = 0;
 #else
 int dmar_disabled = 1;
-#endif /*CONFIG_INTEL_IOMMU_DEFAULT_ON*/
+#endif /* CONFIG_INTEL_IOMMU_DEFAULT_ON */
 
+#ifdef INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON
+int intel_iommu_sm = 1;
+#else
 int intel_iommu_sm;
+#endif /* INTEL_IOMMU_SCALABLE_MODE_DEFAULT_ON */
+
 int intel_iommu_enabled = 0;
 EXPORT_SYMBOL_GPL(intel_iommu_enabled);
 
@@ -368,7 +387,6 @@ static int intel_iommu_superpage = 1;
 static int iommu_identity_mapping;
 static int intel_no_bounce;
 
-#define IDENTMAP_ALL           1
 #define IDENTMAP_GFX           2
 #define IDENTMAP_AZALIA                4
 
@@ -377,7 +395,7 @@ EXPORT_SYMBOL_GPL(intel_iommu_gfx_mapped);
 
 #define DUMMY_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-1))
 #define DEFER_DEVICE_DOMAIN_INFO ((struct device_domain_info *)(-2))
-static DEFINE_SPINLOCK(device_domain_lock);
+DEFINE_SPINLOCK(device_domain_lock);
 static LIST_HEAD(device_domain_list);
 
 #define device_needs_bounce(d) (!intel_no_bounce && dev_is_pci(d) &&   \
@@ -552,6 +570,11 @@ static inline int domain_type_is_si(struct dmar_domain *domain)
        return domain->flags & DOMAIN_FLAG_STATIC_IDENTITY;
 }
 
+static inline bool domain_use_first_level(struct dmar_domain *domain)
+{
+       return domain->flags & DOMAIN_FLAG_USE_FIRST_LEVEL;
+}
+
 static inline int domain_pfn_supported(struct dmar_domain *domain,
                                       unsigned long pfn)
 {
@@ -661,11 +684,12 @@ static int domain_update_iommu_snooping(struct intel_iommu *skip)
        return ret;
 }
 
-static int domain_update_iommu_superpage(struct intel_iommu *skip)
+static int domain_update_iommu_superpage(struct dmar_domain *domain,
+                                        struct intel_iommu *skip)
 {
        struct dmar_drhd_unit *drhd;
        struct intel_iommu *iommu;
-       int mask = 0xf;
+       int mask = 0x3;
 
        if (!intel_iommu_superpage) {
                return 0;
@@ -675,7 +699,13 @@ static int domain_update_iommu_superpage(struct intel_iommu *skip)
        rcu_read_lock();
        for_each_active_iommu(iommu, drhd) {
                if (iommu != skip) {
-                       mask &= cap_super_page_val(iommu->cap);
+                       if (domain && domain_use_first_level(domain)) {
+                               if (!cap_fl1gp_support(iommu->cap))
+                                       mask = 0x1;
+                       } else {
+                               mask &= cap_super_page_val(iommu->cap);
+                       }
+
                        if (!mask)
                                break;
                }
@@ -690,7 +720,7 @@ static void domain_update_iommu_cap(struct dmar_domain *domain)
 {
        domain_update_iommu_coherency(domain);
        domain->iommu_snooping = domain_update_iommu_snooping(NULL);
-       domain->iommu_superpage = domain_update_iommu_superpage(NULL);
+       domain->iommu_superpage = domain_update_iommu_superpage(domain, NULL);
 }
 
 struct context_entry *iommu_context_addr(struct intel_iommu *iommu, u8 bus,
@@ -907,6 +937,8 @@ static struct dma_pte *pfn_to_dma_pte(struct dmar_domain *domain,
 
                        domain_flush_cache(domain, tmp_page, VTD_PAGE_SIZE);
                        pteval = ((uint64_t)virt_to_dma_pfn(tmp_page) << VTD_PAGE_SHIFT) | DMA_PTE_READ | DMA_PTE_WRITE;
+                       if (domain_use_first_level(domain))
+                               pteval |= DMA_FL_PTE_XD;
                        if (cmpxchg64(&pte->val, 0ULL, pteval))
                                /* Someone else set it while we were thinking; use theirs. */
                                free_pgtable_page(tmp_page);
@@ -1477,6 +1509,20 @@ static void iommu_flush_dev_iotlb(struct dmar_domain *domain,
        spin_unlock_irqrestore(&device_domain_lock, flags);
 }
 
+static void domain_flush_piotlb(struct intel_iommu *iommu,
+                               struct dmar_domain *domain,
+                               u64 addr, unsigned long npages, bool ih)
+{
+       u16 did = domain->iommu_did[iommu->seq_id];
+
+       if (domain->default_pasid)
+               qi_flush_piotlb(iommu, did, domain->default_pasid,
+                               addr, npages, ih);
+
+       if (!list_empty(&domain->devices))
+               qi_flush_piotlb(iommu, did, PASID_RID2PASID, addr, npages, ih);
+}
+
 static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
                                  struct dmar_domain *domain,
                                  unsigned long pfn, unsigned int pages,
@@ -1490,18 +1536,23 @@ static void iommu_flush_iotlb_psi(struct intel_iommu *iommu,
 
        if (ih)
                ih = 1 << 6;
-       /*
-        * Fallback to domain selective flush if no PSI support or the size is
-        * too big.
-        * PSI requires page size to be 2 ^ x, and the base address is naturally
-        * aligned to the size
-        */
-       if (!cap_pgsel_inv(iommu->cap) || mask > cap_max_amask_val(iommu->cap))
-               iommu->flush.flush_iotlb(iommu, did, 0, 0,
-                                               DMA_TLB_DSI_FLUSH);
-       else
-               iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
-                                               DMA_TLB_PSI_FLUSH);
+
+       if (domain_use_first_level(domain)) {
+               domain_flush_piotlb(iommu, domain, addr, pages, ih);
+       } else {
+               /*
+                * Fallback to domain selective flush if no PSI support or
+                * the size is too big. PSI requires page size to be 2 ^ x,
+                * and the base address is naturally aligned to the size.
+                */
+               if (!cap_pgsel_inv(iommu->cap) ||
+                   mask > cap_max_amask_val(iommu->cap))
+                       iommu->flush.flush_iotlb(iommu, did, 0, 0,
+                                                       DMA_TLB_DSI_FLUSH);
+               else
+                       iommu->flush.flush_iotlb(iommu, did, addr | ih, mask,
+                                                       DMA_TLB_PSI_FLUSH);
+       }
 
        /*
         * In caching mode, changes of pages from non-present to present require
@@ -1516,8 +1567,11 @@ static inline void __mapping_notify_one(struct intel_iommu *iommu,
                                        struct dmar_domain *domain,
                                        unsigned long pfn, unsigned int pages)
 {
-       /* It's a non-present to present mapping. Only flush if caching mode */
-       if (cap_caching_mode(iommu->cap))
+       /*
+        * It's a non-present to present mapping. Only flush if caching mode
+        * and second level.
+        */
+       if (cap_caching_mode(iommu->cap) && !domain_use_first_level(domain))
                iommu_flush_iotlb_psi(iommu, domain, pfn, pages, 0, 1);
        else
                iommu_flush_write_buffer(iommu);
@@ -1534,7 +1588,11 @@ static void iommu_flush_iova(struct iova_domain *iovad)
                struct intel_iommu *iommu = g_iommus[idx];
                u16 did = domain->iommu_did[iommu->seq_id];
 
-               iommu->flush.flush_iotlb(iommu, did, 0, 0, DMA_TLB_DSI_FLUSH);
+               if (domain_use_first_level(domain))
+                       domain_flush_piotlb(iommu, domain, 0, -1, 0);
+               else
+                       iommu->flush.flush_iotlb(iommu, did, 0, 0,
+                                                DMA_TLB_DSI_FLUSH);
 
                if (!cap_caching_mode(iommu->cap))
                        iommu_flush_dev_iotlb(get_iommu_domain(iommu, did),
@@ -1703,6 +1761,33 @@ static void free_dmar_iommu(struct intel_iommu *iommu)
 #endif
 }
 
+/*
+ * Check and return whether first level is used by default for
+ * DMA translation.
+ */
+static bool first_level_by_default(void)
+{
+       struct dmar_drhd_unit *drhd;
+       struct intel_iommu *iommu;
+       static int first_level_support = -1;
+
+       if (likely(first_level_support != -1))
+               return first_level_support;
+
+       first_level_support = 1;
+
+       rcu_read_lock();
+       for_each_active_iommu(iommu, drhd) {
+               if (!sm_supported(iommu) || !ecap_flts(iommu->ecap)) {
+                       first_level_support = 0;
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
+       return first_level_support;
+}
+
 static struct dmar_domain *alloc_domain(int flags)
 {
        struct dmar_domain *domain;
@@ -1714,6 +1799,8 @@ static struct dmar_domain *alloc_domain(int flags)
        memset(domain, 0, sizeof(*domain));
        domain->nid = NUMA_NO_NODE;
        domain->flags = flags;
+       if (first_level_by_default())
+               domain->flags |= DOMAIN_FLAG_USE_FIRST_LEVEL;
        domain->has_iotlb_device = false;
        INIT_LIST_HEAD(&domain->devices);
 
@@ -1843,14 +1930,16 @@ static int domain_init(struct dmar_domain *domain, struct intel_iommu *iommu,
 {
        int adjust_width, agaw;
        unsigned long sagaw;
-       int err;
+       int ret;
 
        init_iova_domain(&domain->iovad, VTD_PAGE_SIZE, IOVA_START_PFN);
 
-       err = init_iova_flush_queue(&domain->iovad,
-                                   iommu_flush_iova, iova_entry_free);
-       if (err)
-               return err;
+       if (!intel_iommu_strict) {
+               ret = init_iova_flush_queue(&domain->iovad,
+                                           iommu_flush_iova, iova_entry_free);
+               if (ret)
+                       pr_info("iova flush queue initialization failed\n");
+       }
 
        domain_reserve_special_ranges(domain);
 
@@ -2223,17 +2312,20 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
        unsigned long sg_res = 0;
        unsigned int largepage_lvl = 0;
        unsigned long lvl_pages = 0;
+       u64 attr;
 
        BUG_ON(!domain_pfn_supported(domain, iov_pfn + nr_pages - 1));
 
        if ((prot & (DMA_PTE_READ|DMA_PTE_WRITE)) == 0)
                return -EINVAL;
 
-       prot &= DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP;
+       attr = prot & (DMA_PTE_READ | DMA_PTE_WRITE | DMA_PTE_SNP);
+       if (domain_use_first_level(domain))
+               attr |= DMA_FL_PTE_PRESENT | DMA_FL_PTE_XD;
 
        if (!sg) {
                sg_res = nr_pages;
-               pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | prot;
+               pteval = ((phys_addr_t)phys_pfn << VTD_PAGE_SHIFT) | attr;
        }
 
        while (nr_pages > 0) {
@@ -2245,7 +2337,7 @@ static int __domain_mapping(struct dmar_domain *domain, unsigned long iov_pfn,
                        sg_res = aligned_nrpages(sg->offset, sg->length);
                        sg->dma_address = ((dma_addr_t)iov_pfn << VTD_PAGE_SHIFT) + pgoff;
                        sg->dma_length = sg->length;
-                       pteval = (sg_phys(sg) - pgoff) | prot;
+                       pteval = (sg_phys(sg) - pgoff) | attr;
                        phys_pfn = pteval >> VTD_PAGE_SHIFT;
                }
 
@@ -2414,7 +2506,7 @@ static void domain_remove_dev_info(struct dmar_domain *domain)
        spin_unlock_irqrestore(&device_domain_lock, flags);
 }
 
-static struct dmar_domain *find_domain(struct device *dev)
+struct dmar_domain *find_domain(struct device *dev)
 {
        struct device_domain_info *info;
 
@@ -2460,6 +2552,36 @@ dmar_search_domain_by_dev_info(int segment, int bus, int devfn)
        return NULL;
 }
 
+static int domain_setup_first_level(struct intel_iommu *iommu,
+                                   struct dmar_domain *domain,
+                                   struct device *dev,
+                                   int pasid)
+{
+       int flags = PASID_FLAG_SUPERVISOR_MODE;
+       struct dma_pte *pgd = domain->pgd;
+       int agaw, level;
+
+       /*
+        * Skip top levels of page tables for iommu which has
+        * less agaw than default. Unnecessary for PT mode.
+        */
+       for (agaw = domain->agaw; agaw > iommu->agaw; agaw--) {
+               pgd = phys_to_virt(dma_pte_addr(pgd));
+               if (!dma_pte_present(pgd))
+                       return -ENOMEM;
+       }
+
+       level = agaw_to_level(agaw);
+       if (level != 4 && level != 5)
+               return -EINVAL;
+
+       flags |= (level == 5) ? PASID_FLAG_FL5LP : 0;
+
+       return intel_pasid_setup_first_level(iommu, dev, (pgd_t *)pgd, pasid,
+                                            domain->iommu_did[iommu->seq_id],
+                                            flags);
+}
+
 static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
                                                    int bus, int devfn,
                                                    struct device *dev,
@@ -2559,6 +2681,9 @@ static struct dmar_domain *dmar_insert_one_dev_info(struct intel_iommu *iommu,
                if (hw_pass_through && domain_type_is_si(domain))
                        ret = intel_pasid_setup_pass_through(iommu, domain,
                                        dev, PASID_RID2PASID);
+               else if (domain_use_first_level(domain))
+                       ret = domain_setup_first_level(iommu, domain, dev,
+                                       PASID_RID2PASID);
                else
                        ret = intel_pasid_setup_second_level(iommu, domain,
                                        dev, PASID_RID2PASID);
@@ -2764,10 +2889,8 @@ static int __init si_domain_init(int hw)
        }
 
        /*
-        * Normally we use DMA domains for devices which have RMRRs. But we
-        * loose this requirement for graphic and usb devices. Identity map
-        * the RMRRs for graphic and USB devices so that they could use the
-        * si_domain.
+        * Identity map the RMRRs so that devices with RMRRs could also use
+        * the si_domain.
         */
        for_each_rmrr_units(rmrr) {
                for_each_active_dev_scope(rmrr->devices, rmrr->devices_cnt,
@@ -2775,9 +2898,6 @@ static int __init si_domain_init(int hw)
                        unsigned long long start = rmrr->base_address;
                        unsigned long long end = rmrr->end_address;
 
-                       if (device_is_rmrr_locked(dev))
-                               continue;
-
                        if (WARN_ON(end < start ||
                                    end >> agaw_to_width(si_domain->agaw)))
                                continue;
@@ -2916,9 +3036,6 @@ static int device_def_domain_type(struct device *dev)
        if (dev_is_pci(dev)) {
                struct pci_dev *pdev = to_pci_dev(dev);
 
-               if (device_is_rmrr_locked(dev))
-                       return IOMMU_DOMAIN_DMA;
-
                /*
                 * Prevent any device marked as untrusted from getting
                 * placed into the statically identity mapping domain.
@@ -2956,13 +3073,9 @@ static int device_def_domain_type(struct device *dev)
                                return IOMMU_DOMAIN_DMA;
                } else if (pci_pcie_type(pdev) == PCI_EXP_TYPE_PCI_BRIDGE)
                        return IOMMU_DOMAIN_DMA;
-       } else {
-               if (device_has_rmrr(dev))
-                       return IOMMU_DOMAIN_DMA;
        }
 
-       return (iommu_identity_mapping & IDENTMAP_ALL) ?
-                       IOMMU_DOMAIN_IDENTITY : 0;
+       return 0;
 }
 
 static void intel_iommu_init_qi(struct intel_iommu *iommu)
@@ -3291,10 +3404,7 @@ static int __init init_dmars(void)
 
                if (!ecap_pass_through(iommu->ecap))
                        hw_pass_through = 0;
-#ifdef CONFIG_INTEL_IOMMU_SVM
-               if (pasid_supported(iommu))
-                       intel_svm_init(iommu);
-#endif
+               intel_svm_check(iommu);
        }
 
        /*
@@ -3309,9 +3419,6 @@ static int __init init_dmars(void)
                iommu->flush.flush_iotlb(iommu, 0, 0, 0, DMA_TLB_GLOBAL_FLUSH);
        }
 
-       if (iommu_default_passthrough())
-               iommu_identity_mapping |= IDENTMAP_ALL;
-
 #ifdef CONFIG_INTEL_IOMMU_BROKEN_GFX_WA
        dmar_map_gfx = 0;
 #endif
@@ -3384,8 +3491,21 @@ static unsigned long intel_alloc_iova(struct device *dev,
 {
        unsigned long iova_pfn;
 
-       /* Restrict dma_mask to the width that the iommu can handle */
-       dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw), dma_mask);
+       /*
+        * Restrict dma_mask to the width that the iommu can handle.
+        * First-level translation restricts the input-address to a
+        * canonical address (i.e., address bits 63:N have the same
+        * value as address bit [N-1], where N is 48-bits with 4-level
+        * paging and 57-bits with 5-level paging). Hence, skip bit
+        * [N-1].
+        */
+       if (domain_use_first_level(domain))
+               dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw - 1),
+                                dma_mask);
+       else
+               dma_mask = min_t(uint64_t, DOMAIN_MAX_ADDR(domain->gaw),
+                                dma_mask);
+
        /* Ensure we reserve the whole size-aligned region */
        nrpages = __roundup_pow_of_two(nrpages);
 
@@ -3403,7 +3523,8 @@ static unsigned long intel_alloc_iova(struct device *dev,
        iova_pfn = alloc_iova_fast(&domain->iovad, nrpages,
                                   IOVA_PFN(dma_mask), true);
        if (unlikely(!iova_pfn)) {
-               dev_err(dev, "Allocating %ld-page iova failed", nrpages);
+               dev_err_once(dev, "Allocating %ld-page iova failed\n",
+                            nrpages);
                return 0;
        }
 
@@ -3771,8 +3892,8 @@ static int intel_map_sg(struct device *dev, struct scatterlist *sglist, int nele
                return 0;
        }
 
-       trace_map_sg(dev, iova_pfn << PAGE_SHIFT,
-                    sg_phys(sglist), size << VTD_PAGE_SHIFT);
+       for_each_sg(sglist, sg, nelems, i)
+               trace_map_sg(dev, i + 1, nelems, sg);
 
        return nelems;
 }
@@ -3984,6 +4105,9 @@ bounce_map_sg(struct device *dev, struct scatterlist *sglist, int nelems,
                sg_dma_len(sg) = sg->length;
        }
 
+       for_each_sg(sglist, sg, nelems, i)
+               trace_bounce_map_sg(dev, i + 1, nelems, sg);
+
        return nelems;
 
 out_unmap:
@@ -4312,16 +4436,31 @@ static void __init init_iommu_pm_ops(void)
 static inline void init_iommu_pm_ops(void) {}
 #endif /* CONFIG_PM */
 
+static int rmrr_sanity_check(struct acpi_dmar_reserved_memory *rmrr)
+{
+       if (!IS_ALIGNED(rmrr->base_address, PAGE_SIZE) ||
+           !IS_ALIGNED(rmrr->end_address + 1, PAGE_SIZE) ||
+           rmrr->end_address <= rmrr->base_address ||
+           arch_rmrr_sanity_check(rmrr))
+               return -EINVAL;
+
+       return 0;
+}
+
 int __init dmar_parse_one_rmrr(struct acpi_dmar_header *header, void *arg)
 {
        struct acpi_dmar_reserved_memory *rmrr;
        struct dmar_rmrr_unit *rmrru;
-       int ret;
 
        rmrr = (struct acpi_dmar_reserved_memory *)header;
-       ret = arch_rmrr_sanity_check(rmrr);
-       if (ret)
-               return ret;
+       if (rmrr_sanity_check(rmrr))
+               WARN_TAINT(1, TAINT_FIRMWARE_WORKAROUND,
+                          "Your BIOS is broken; bad RMRR [%#018Lx-%#018Lx]\n"
+                          "BIOS vendor: %s; Ver: %s; Product Version: %s\n",
+                          rmrr->base_address, rmrr->end_address,
+                          dmi_get_system_info(DMI_BIOS_VENDOR),
+                          dmi_get_system_info(DMI_BIOS_VERSION),
+                          dmi_get_system_info(DMI_PRODUCT_VERSION));
 
        rmrru = kzalloc(sizeof(*rmrru), GFP_KERNEL);
        if (!rmrru)
@@ -4467,7 +4606,7 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
                        iommu->name);
                return -ENXIO;
        }
-       sp = domain_update_iommu_superpage(iommu) - 1;
+       sp = domain_update_iommu_superpage(NULL, iommu) - 1;
        if (sp >= 0 && !(cap_super_page_val(iommu->cap) & (1 << sp))) {
                pr_warn("%s: Doesn't support large page.\n",
                        iommu->name);
@@ -4487,10 +4626,7 @@ static int intel_iommu_add(struct dmar_drhd_unit *dmaru)
        if (ret)
                goto out;
 
-#ifdef CONFIG_INTEL_IOMMU_SVM
-       if (pasid_supported(iommu))
-               intel_svm_init(iommu);
-#endif
+       intel_svm_check(iommu);
 
        if (dmaru->ignored) {
                /*
@@ -4895,7 +5031,7 @@ static int __init platform_optin_force_iommu(void)
         * map for all devices except those marked as being untrusted.
         */
        if (dmar_disabled)
-               iommu_identity_mapping |= IDENTMAP_ALL;
+               iommu_set_default_passthrough(false);
 
        dmar_disabled = 0;
        no_iommu = 0;
@@ -5195,6 +5331,7 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
 {
        struct dmar_domain *dmar_domain;
        struct iommu_domain *domain;
+       int ret;
 
        switch (type) {
        case IOMMU_DOMAIN_DMA:
@@ -5211,11 +5348,12 @@ static struct iommu_domain *intel_iommu_domain_alloc(unsigned type)
                        return NULL;
                }
 
-               if (type == IOMMU_DOMAIN_DMA &&
-                   init_iova_flush_queue(&dmar_domain->iovad,
-                                         iommu_flush_iova, iova_entry_free)) {
-                       pr_warn("iova flush queue initialization failed\n");
-                       intel_iommu_strict = 1;
+               if (!intel_iommu_strict && type == IOMMU_DOMAIN_DMA) {
+                       ret = init_iova_flush_queue(&dmar_domain->iovad,
+                                                   iommu_flush_iova,
+                                                   iova_entry_free);
+                       if (ret)
+                               pr_info("iova flush queue initialization failed\n");
                }
 
                domain_update_iommu_cap(dmar_domain);
@@ -5281,7 +5419,7 @@ static void auxiliary_unlink_device(struct dmar_domain *domain,
        domain->auxd_refcnt--;
 
        if (!domain->auxd_refcnt && domain->default_pasid > 0)
-               intel_pasid_free_id(domain->default_pasid);
+               ioasid_free(domain->default_pasid);
 }
 
 static int aux_domain_add_dev(struct dmar_domain *domain,
@@ -5299,10 +5437,11 @@ static int aux_domain_add_dev(struct dmar_domain *domain,
        if (domain->default_pasid <= 0) {
                int pasid;
 
-               pasid = intel_pasid_alloc_id(domain, PASID_MIN,
-                                            pci_max_pasids(to_pci_dev(dev)),
-                                            GFP_KERNEL);
-               if (pasid <= 0) {
+               /* No private data needed for the default pasid */
+               pasid = ioasid_alloc(NULL, PASID_MIN,
+                                    pci_max_pasids(to_pci_dev(dev)) - 1,
+                                    NULL);
+               if (pasid == INVALID_IOASID) {
                        pr_err("Can't allocate default pasid\n");
                        return -ENODEV;
                }
@@ -5320,8 +5459,12 @@ static int aux_domain_add_dev(struct dmar_domain *domain,
                goto attach_failed;
 
        /* Setup the PASID entry for mediated devices: */
-       ret = intel_pasid_setup_second_level(iommu, domain, dev,
-                                            domain->default_pasid);
+       if (domain_use_first_level(domain))
+               ret = domain_setup_first_level(iommu, domain, dev,
+                                              domain->default_pasid);
+       else
+               ret = intel_pasid_setup_second_level(iommu, domain, dev,
+                                                    domain->default_pasid);
        if (ret)
                goto table_failed;
        spin_unlock(&iommu->lock);
@@ -5338,7 +5481,7 @@ attach_failed:
        spin_unlock(&iommu->lock);
        spin_unlock_irqrestore(&device_domain_lock, flags);
        if (!domain->auxd_refcnt && domain->default_pasid > 0)
-               intel_pasid_free_id(domain->default_pasid);
+               ioasid_free(domain->default_pasid);
 
        return ret;
 }
@@ -5592,6 +5735,24 @@ static inline bool iommu_pasid_support(void)
        return ret;
 }
 
+static inline bool nested_mode_support(void)
+{
+       struct dmar_drhd_unit *drhd;
+       struct intel_iommu *iommu;
+       bool ret = true;
+
+       rcu_read_lock();
+       for_each_active_iommu(iommu, drhd) {
+               if (!sm_supported(iommu) || !ecap_nest(iommu->ecap)) {
+                       ret = false;
+                       break;
+               }
+       }
+       rcu_read_unlock();
+
+       return ret;
+}
+
 static bool intel_iommu_capable(enum iommu_cap cap)
 {
        if (cap == IOMMU_CAP_CACHE_COHERENCY)
@@ -5749,15 +5910,6 @@ static void intel_iommu_get_resv_regions(struct device *device,
        list_add_tail(&reg->list, head);
 }
 
-static void intel_iommu_put_resv_regions(struct device *dev,
-                                        struct list_head *head)
-{
-       struct iommu_resv_region *entry, *next;
-
-       list_for_each_entry_safe(entry, next, head, list)
-               kfree(entry);
-}
-
 int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev)
 {
        struct device_domain_info *info;
@@ -5984,10 +6136,42 @@ static bool intel_iommu_is_attach_deferred(struct iommu_domain *domain,
        return dev->archdata.iommu == DEFER_DEVICE_DOMAIN_INFO;
 }
 
+static int
+intel_iommu_domain_set_attr(struct iommu_domain *domain,
+                           enum iommu_attr attr, void *data)
+{
+       struct dmar_domain *dmar_domain = to_dmar_domain(domain);
+       unsigned long flags;
+       int ret = 0;
+
+       if (domain->type != IOMMU_DOMAIN_UNMANAGED)
+               return -EINVAL;
+
+       switch (attr) {
+       case DOMAIN_ATTR_NESTING:
+               spin_lock_irqsave(&device_domain_lock, flags);
+               if (nested_mode_support() &&
+                   list_empty(&dmar_domain->devices)) {
+                       dmar_domain->flags |= DOMAIN_FLAG_NESTING_MODE;
+                       dmar_domain->flags &= ~DOMAIN_FLAG_USE_FIRST_LEVEL;
+               } else {
+                       ret = -ENODEV;
+               }
+               spin_unlock_irqrestore(&device_domain_lock, flags);
+               break;
+       default:
+               ret = -EINVAL;
+               break;
+       }
+
+       return ret;
+}
+
 const struct iommu_ops intel_iommu_ops = {
        .capable                = intel_iommu_capable,
        .domain_alloc           = intel_iommu_domain_alloc,
        .domain_free            = intel_iommu_domain_free,
+       .domain_set_attr        = intel_iommu_domain_set_attr,
        .attach_dev             = intel_iommu_attach_device,
        .detach_dev             = intel_iommu_detach_device,
        .aux_attach_dev         = intel_iommu_aux_attach_device,
@@ -5999,7 +6183,7 @@ const struct iommu_ops intel_iommu_ops = {
        .add_device             = intel_iommu_add_device,
        .remove_device          = intel_iommu_remove_device,
        .get_resv_regions       = intel_iommu_get_resv_regions,
-       .put_resv_regions       = intel_iommu_put_resv_regions,
+       .put_resv_regions       = generic_iommu_put_resv_regions,
        .apply_resv_region      = intel_iommu_apply_resv_region,
        .device_group           = intel_iommu_device_group,
        .dev_has_feat           = intel_iommu_dev_has_feat,
index 040a445..22b30f1 100644 (file)
  */
 static DEFINE_SPINLOCK(pasid_lock);
 u32 intel_pasid_max_id = PASID_MAX;
-static DEFINE_IDR(pasid_idr);
-
-int intel_pasid_alloc_id(void *ptr, int start, int end, gfp_t gfp)
-{
-       int ret, min, max;
-
-       min = max_t(int, start, PASID_MIN);
-       max = min_t(int, end, intel_pasid_max_id);
-
-       WARN_ON(in_interrupt());
-       idr_preload(gfp);
-       spin_lock(&pasid_lock);
-       ret = idr_alloc(&pasid_idr, ptr, min, max, GFP_ATOMIC);
-       spin_unlock(&pasid_lock);
-       idr_preload_end();
-
-       return ret;
-}
-
-void intel_pasid_free_id(int pasid)
-{
-       spin_lock(&pasid_lock);
-       idr_remove(&pasid_idr, pasid);
-       spin_unlock(&pasid_lock);
-}
-
-void *intel_pasid_lookup_id(int pasid)
-{
-       void *p;
-
-       spin_lock(&pasid_lock);
-       p = idr_find(&pasid_idr, pasid);
-       spin_unlock(&pasid_lock);
-
-       return p;
-}
 
 /*
  * Per device pasid table management:
@@ -465,6 +429,21 @@ void intel_pasid_tear_down_entry(struct intel_iommu *iommu,
                devtlb_invalidation_with_pasid(iommu, dev, pasid);
 }
 
+static void pasid_flush_caches(struct intel_iommu *iommu,
+                               struct pasid_entry *pte,
+                               int pasid, u16 did)
+{
+       if (!ecap_coherent(iommu->ecap))
+               clflush_cache_range(pte, sizeof(*pte));
+
+       if (cap_caching_mode(iommu->cap)) {
+               pasid_cache_invalidation_with_pasid(iommu, did, pasid);
+               iotlb_invalidation_with_pasid(iommu, did, pasid);
+       } else {
+               iommu_flush_write_buffer(iommu);
+       }
+}
+
 /*
  * Set up the scalable mode pasid table entry for first only
  * translation type.
@@ -498,10 +477,15 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
                pasid_set_sre(pte);
        }
 
-#ifdef CONFIG_X86
-       if (cpu_feature_enabled(X86_FEATURE_LA57))
-               pasid_set_flpm(pte, 1);
-#endif /* CONFIG_X86 */
+       if (flags & PASID_FLAG_FL5LP) {
+               if (cap_5lp_support(iommu->cap)) {
+                       pasid_set_flpm(pte, 1);
+               } else {
+                       pr_err("No 5-level paging support for first-level\n");
+                       pasid_clear_entry(pte);
+                       return -EINVAL;
+               }
+       }
 
        pasid_set_domain_id(pte, did);
        pasid_set_address_width(pte, iommu->agaw);
@@ -510,16 +494,7 @@ int intel_pasid_setup_first_level(struct intel_iommu *iommu,
        /* Setup Present and PASID Granular Transfer Type: */
        pasid_set_translation_type(pte, 1);
        pasid_set_present(pte);
-
-       if (!ecap_coherent(iommu->ecap))
-               clflush_cache_range(pte, sizeof(*pte));
-
-       if (cap_caching_mode(iommu->cap)) {
-               pasid_cache_invalidation_with_pasid(iommu, did, pasid);
-               iotlb_invalidation_with_pasid(iommu, did, pasid);
-       } else {
-               iommu_flush_write_buffer(iommu);
-       }
+       pasid_flush_caches(iommu, pte, pasid, did);
 
        return 0;
 }
@@ -583,16 +558,7 @@ int intel_pasid_setup_second_level(struct intel_iommu *iommu,
         */
        pasid_set_sre(pte);
        pasid_set_present(pte);
-
-       if (!ecap_coherent(iommu->ecap))
-               clflush_cache_range(pte, sizeof(*pte));
-
-       if (cap_caching_mode(iommu->cap)) {
-               pasid_cache_invalidation_with_pasid(iommu, did, pasid);
-               iotlb_invalidation_with_pasid(iommu, did, pasid);
-       } else {
-               iommu_flush_write_buffer(iommu);
-       }
+       pasid_flush_caches(iommu, pte, pasid, did);
 
        return 0;
 }
@@ -626,16 +592,7 @@ int intel_pasid_setup_pass_through(struct intel_iommu *iommu,
         */
        pasid_set_sre(pte);
        pasid_set_present(pte);
-
-       if (!ecap_coherent(iommu->ecap))
-               clflush_cache_range(pte, sizeof(*pte));
-
-       if (cap_caching_mode(iommu->cap)) {
-               pasid_cache_invalidation_with_pasid(iommu, did, pasid);
-               iotlb_invalidation_with_pasid(iommu, did, pasid);
-       } else {
-               iommu_flush_write_buffer(iommu);
-       }
+       pasid_flush_caches(iommu, pte, pasid, did);
 
        return 0;
 }
index fc8cd8f..92de6df 100644 (file)
  */
 #define PASID_FLAG_SUPERVISOR_MODE     BIT(0)
 
+/*
+ * The PASID_FLAG_FL5LP flag Indicates using 5-level paging for first-
+ * level translation, otherwise, 4-level paging will be used.
+ */
+#define PASID_FLAG_FL5LP               BIT(1)
+
 struct pasid_dir_entry {
        u64 val;
 };
index dca88f9..d7f2a53 100644 (file)
 #include <linux/dmar.h>
 #include <linux/interrupt.h>
 #include <linux/mm_types.h>
+#include <linux/ioasid.h>
 #include <asm/page.h>
 
 #include "intel-pasid.h"
 
 static irqreturn_t prq_event_thread(int irq, void *d);
 
-int intel_svm_init(struct intel_iommu *iommu)
-{
-       if (cpu_feature_enabled(X86_FEATURE_GBPAGES) &&
-                       !cap_fl1gp_support(iommu->cap))
-               return -EINVAL;
-
-       if (cpu_feature_enabled(X86_FEATURE_LA57) &&
-                       !cap_5lp_support(iommu->cap))
-               return -EINVAL;
-
-       return 0;
-}
-
 #define PRQ_ORDER 0
 
 int intel_svm_enable_prq(struct intel_iommu *iommu)
@@ -99,6 +87,33 @@ int intel_svm_finish_prq(struct intel_iommu *iommu)
        return 0;
 }
 
+static inline bool intel_svm_capable(struct intel_iommu *iommu)
+{
+       return iommu->flags & VTD_FLAG_SVM_CAPABLE;
+}
+
+void intel_svm_check(struct intel_iommu *iommu)
+{
+       if (!pasid_supported(iommu))
+               return;
+
+       if (cpu_feature_enabled(X86_FEATURE_GBPAGES) &&
+           !cap_fl1gp_support(iommu->cap)) {
+               pr_err("%s SVM disabled, incompatible 1GB page capability\n",
+                      iommu->name);
+               return;
+       }
+
+       if (cpu_feature_enabled(X86_FEATURE_LA57) &&
+           !cap_5lp_support(iommu->cap)) {
+               pr_err("%s SVM disabled, incompatible paging mode\n",
+                      iommu->name);
+               return;
+       }
+
+       iommu->flags |= VTD_FLAG_SVM_CAPABLE;
+}
+
 static void intel_flush_svm_range_dev (struct intel_svm *svm, struct intel_svm_dev *sdev,
                                unsigned long address, unsigned long pages, int ih)
 {
@@ -207,6 +222,10 @@ static const struct mmu_notifier_ops intel_mmuops = {
 static DEFINE_MUTEX(pasid_mutex);
 static LIST_HEAD(global_svm_list);
 
+#define for_each_svm_dev(sdev, svm, d)                 \
+       list_for_each_entry((sdev), &(svm)->devs, list) \
+               if ((d) != (sdev)->dev) {} else
+
 int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_ops *ops)
 {
        struct intel_iommu *iommu = intel_svm_device_to_iommu(dev);
@@ -220,6 +239,9 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
        if (!iommu || dmar_disabled)
                return -EINVAL;
 
+       if (!intel_svm_capable(iommu))
+               return -ENOTSUPP;
+
        if (dev_is_pci(dev)) {
                pasid_max = pci_max_pasids(to_pci_dev(dev));
                if (pasid_max < 0)
@@ -252,15 +274,14 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                                goto out;
                        }
 
-                       list_for_each_entry(sdev, &svm->devs, list) {
-                               if (dev == sdev->dev) {
-                                       if (sdev->ops != ops) {
-                                               ret = -EBUSY;
-                                               goto out;
-                                       }
-                                       sdev->users++;
-                                       goto success;
+                       /* Find the matching device in svm list */
+                       for_each_svm_dev(sdev, svm, dev) {
+                               if (sdev->ops != ops) {
+                                       ret = -EBUSY;
+                                       goto out;
                                }
+                               sdev->users++;
+                               goto success;
                        }
 
                        break;
@@ -314,16 +335,15 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                if (pasid_max > intel_pasid_max_id)
                        pasid_max = intel_pasid_max_id;
 
-               /* Do not use PASID 0 in caching mode (virtualised IOMMU) */
-               ret = intel_pasid_alloc_id(svm,
-                                          !!cap_caching_mode(iommu->cap),
-                                          pasid_max - 1, GFP_KERNEL);
-               if (ret < 0) {
+               /* Do not use PASID 0, reserved for RID to PASID */
+               svm->pasid = ioasid_alloc(NULL, PASID_MIN,
+                                         pasid_max - 1, svm);
+               if (svm->pasid == INVALID_IOASID) {
                        kfree(svm);
                        kfree(sdev);
+                       ret = -ENOSPC;
                        goto out;
                }
-               svm->pasid = ret;
                svm->notifier.ops = &intel_mmuops;
                svm->mm = mm;
                svm->flags = flags;
@@ -333,7 +353,7 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                if (mm) {
                        ret = mmu_notifier_register(&svm->notifier, mm);
                        if (ret) {
-                               intel_pasid_free_id(svm->pasid);
+                               ioasid_free(svm->pasid);
                                kfree(svm);
                                kfree(sdev);
                                goto out;
@@ -344,12 +364,14 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                ret = intel_pasid_setup_first_level(iommu, dev,
                                mm ? mm->pgd : init_mm.pgd,
                                svm->pasid, FLPT_DEFAULT_DID,
-                               mm ? 0 : PASID_FLAG_SUPERVISOR_MODE);
+                               (mm ? 0 : PASID_FLAG_SUPERVISOR_MODE) |
+                               (cpu_feature_enabled(X86_FEATURE_LA57) ?
+                                PASID_FLAG_FL5LP : 0));
                spin_unlock(&iommu->lock);
                if (ret) {
                        if (mm)
                                mmu_notifier_unregister(&svm->notifier, mm);
-                       intel_pasid_free_id(svm->pasid);
+                       ioasid_free(svm->pasid);
                        kfree(svm);
                        kfree(sdev);
                        goto out;
@@ -365,7 +387,9 @@ int intel_svm_bind_mm(struct device *dev, int *pasid, int flags, struct svm_dev_
                ret = intel_pasid_setup_first_level(iommu, dev,
                                                mm ? mm->pgd : init_mm.pgd,
                                                svm->pasid, FLPT_DEFAULT_DID,
-                                               mm ? 0 : PASID_FLAG_SUPERVISOR_MODE);
+                                               (mm ? 0 : PASID_FLAG_SUPERVISOR_MODE) |
+                                               (cpu_feature_enabled(X86_FEATURE_LA57) ?
+                                               PASID_FLAG_FL5LP : 0));
                spin_unlock(&iommu->lock);
                if (ret) {
                        kfree(sdev);
@@ -397,44 +421,45 @@ int intel_svm_unbind_mm(struct device *dev, int pasid)
        if (!iommu)
                goto out;
 
-       svm = intel_pasid_lookup_id(pasid);
+       svm = ioasid_find(NULL, pasid, NULL);
        if (!svm)
                goto out;
 
-       list_for_each_entry(sdev, &svm->devs, list) {
-               if (dev == sdev->dev) {
-                       ret = 0;
-                       sdev->users--;
-                       if (!sdev->users) {
-                               list_del_rcu(&sdev->list);
-                               /* Flush the PASID cache and IOTLB for this device.
-                                * Note that we do depend on the hardware *not* using
-                                * the PASID any more. Just as we depend on other
-                                * devices never using PASIDs that they have no right
-                                * to use. We have a *shared* PASID table, because it's
-                                * large and has to be physically contiguous. So it's
-                                * hard to be as defensive as we might like. */
-                               intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
-                               intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
-                               kfree_rcu(sdev, rcu);
-
-                               if (list_empty(&svm->devs)) {
-                                       intel_pasid_free_id(svm->pasid);
-                                       if (svm->mm)
-                                               mmu_notifier_unregister(&svm->notifier, svm->mm);
-
-                                       list_del(&svm->list);
-
-                                       /* We mandate that no page faults may be outstanding
-                                        * for the PASID when intel_svm_unbind_mm() is called.
-                                        * If that is not obeyed, subtle errors will happen.
-                                        * Let's make them less subtle... */
-                                       memset(svm, 0x6b, sizeof(*svm));
-                                       kfree(svm);
-                               }
+       if (IS_ERR(svm)) {
+               ret = PTR_ERR(svm);
+               goto out;
+       }
+
+       for_each_svm_dev(sdev, svm, dev) {
+               ret = 0;
+               sdev->users--;
+               if (!sdev->users) {
+                       list_del_rcu(&sdev->list);
+                       /* Flush the PASID cache and IOTLB for this device.
+                        * Note that we do depend on the hardware *not* using
+                        * the PASID any more. Just as we depend on other
+                        * devices never using PASIDs that they have no right
+                        * to use. We have a *shared* PASID table, because it's
+                        * large and has to be physically contiguous. So it's
+                        * hard to be as defensive as we might like. */
+                       intel_pasid_tear_down_entry(iommu, dev, svm->pasid);
+                       intel_flush_svm_range_dev(svm, sdev, 0, -1, 0);
+                       kfree_rcu(sdev, rcu);
+
+                       if (list_empty(&svm->devs)) {
+                               ioasid_free(svm->pasid);
+                               if (svm->mm)
+                                       mmu_notifier_unregister(&svm->notifier, svm->mm);
+                               list_del(&svm->list);
+                               /* We mandate that no page faults may be outstanding
+                                * for the PASID when intel_svm_unbind_mm() is called.
+                                * If that is not obeyed, subtle errors will happen.
+                                * Let's make them less subtle... */
+                               memset(svm, 0x6b, sizeof(*svm));
+                               kfree(svm);
                        }
-                       break;
                }
+               break;
        }
  out:
        mutex_unlock(&pasid_mutex);
@@ -454,10 +479,14 @@ int intel_svm_is_pasid_valid(struct device *dev, int pasid)
        if (!iommu)
                goto out;
 
-       svm = intel_pasid_lookup_id(pasid);
+       svm = ioasid_find(NULL, pasid, NULL);
        if (!svm)
                goto out;
 
+       if (IS_ERR(svm)) {
+               ret = PTR_ERR(svm);
+               goto out;
+       }
        /* init_mm is used in this case */
        if (!svm->mm)
                ret = 1;
@@ -564,13 +593,12 @@ static irqreturn_t prq_event_thread(int irq, void *d)
 
                if (!svm || svm->pasid != req->pasid) {
                        rcu_read_lock();
-                       svm = intel_pasid_lookup_id(req->pasid);
+                       svm = ioasid_find(NULL, req->pasid, NULL);
                        /* It *can't* go away, because the driver is not permitted
                         * to unbind the mm while any page faults are outstanding.
                         * So we only need RCU to protect the internal idr code. */
                        rcu_read_unlock();
-
-                       if (!svm) {
+                       if (IS_ERR_OR_NULL(svm)) {
                                pr_err("%s: Page request for invalid PASID %d: %08llx %08llx\n",
                                       iommu->name, req->pasid, ((unsigned long long *)req)[0],
                                       ((unsigned long long *)req)[1]);
@@ -654,11 +682,10 @@ static irqreturn_t prq_event_thread(int irq, void *d)
                        if (req->priv_data_present)
                                memcpy(&resp.qw2, req->priv_data,
                                       sizeof(req->priv_data));
+                       resp.qw2 = 0;
+                       resp.qw3 = 0;
+                       qi_submit_sync(&resp, iommu);
                }
-               resp.qw2 = 0;
-               resp.qw3 = 0;
-               qi_submit_sync(&resp, iommu);
-
                head = (head + sizeof(*req)) & PRQ_RING_MASK;
        }
 
index 7c3bd2c..4272fe4 100644 (file)
 #define ARM_V7S_TTBR_IRGN_ATTR(attr)                                   \
        ((((attr) & 0x1) << 6) | (((attr) & 0x2) >> 1))
 
-#define ARM_V7S_TCR_PD1                        BIT(5)
-
 #ifdef CONFIG_ZONE_DMA32
 #define ARM_V7S_TABLE_GFP_DMA GFP_DMA32
 #define ARM_V7S_TABLE_SLAB_FLAGS SLAB_CACHE_DMA32
@@ -798,8 +796,8 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
         */
        cfg->pgsize_bitmap &= SZ_4K | SZ_64K | SZ_1M | SZ_16M;
 
-       /* TCR: T0SZ=0, disable TTBR1 */
-       cfg->arm_v7s_cfg.tcr = ARM_V7S_TCR_PD1;
+       /* TCR: T0SZ=0, EAE=0 (if applicable) */
+       cfg->arm_v7s_cfg.tcr = 0;
 
        /*
         * TEX remap: the indices used map to the closest equivalent types
@@ -822,15 +820,13 @@ static struct io_pgtable *arm_v7s_alloc_pgtable(struct io_pgtable_cfg *cfg,
        /* Ensure the empty pgd is visible before any actual TTBR write */
        wmb();
 
-       /* TTBRs */
-       cfg->arm_v7s_cfg.ttbr[0] = virt_to_phys(data->pgd) |
-                                  ARM_V7S_TTBR_S | ARM_V7S_TTBR_NOS |
-                                  (cfg->coherent_walk ?
-                                  (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_WBWA) |
-                                   ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_WBWA)) :
-                                  (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_NC) |
-                                   ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_NC)));
-       cfg->arm_v7s_cfg.ttbr[1] = 0;
+       /* TTBR */
+       cfg->arm_v7s_cfg.ttbr = virt_to_phys(data->pgd) | ARM_V7S_TTBR_S |
+                               (cfg->coherent_walk ? (ARM_V7S_TTBR_NOS |
+                                ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_WBWA) |
+                                ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_WBWA)) :
+                               (ARM_V7S_TTBR_IRGN_ATTR(ARM_V7S_RGN_NC) |
+                                ARM_V7S_TTBR_ORGN_ATTR(ARM_V7S_RGN_NC)));
        return &data->iop;
 
 out_free_data:
index bdf47f7..983b084 100644 (file)
 #define ARM_LPAE_PTE_MEMATTR_DEV       (((arm_lpae_iopte)0x1) << 2)
 
 /* Register bits */
-#define ARM_32_LPAE_TCR_EAE            (1 << 31)
-#define ARM_64_LPAE_S2_TCR_RES1                (1 << 31)
+#define ARM_LPAE_TCR_TG0_4K            0
+#define ARM_LPAE_TCR_TG0_64K           1
+#define ARM_LPAE_TCR_TG0_16K           2
 
-#define ARM_LPAE_TCR_EPD1              (1 << 23)
+#define ARM_LPAE_TCR_TG1_16K           1
+#define ARM_LPAE_TCR_TG1_4K            2
+#define ARM_LPAE_TCR_TG1_64K           3
 
-#define ARM_LPAE_TCR_TG0_4K            (0 << 14)
-#define ARM_LPAE_TCR_TG0_64K           (1 << 14)
-#define ARM_LPAE_TCR_TG0_16K           (2 << 14)
-
-#define ARM_LPAE_TCR_SH0_SHIFT         12
-#define ARM_LPAE_TCR_SH0_MASK          0x3
 #define ARM_LPAE_TCR_SH_NS             0
 #define ARM_LPAE_TCR_SH_OS             2
 #define ARM_LPAE_TCR_SH_IS             3
 
-#define ARM_LPAE_TCR_ORGN0_SHIFT       10
-#define ARM_LPAE_TCR_IRGN0_SHIFT       8
-#define ARM_LPAE_TCR_RGN_MASK          0x3
 #define ARM_LPAE_TCR_RGN_NC            0
 #define ARM_LPAE_TCR_RGN_WBWA          1
 #define ARM_LPAE_TCR_RGN_WT            2
 #define ARM_LPAE_TCR_RGN_WB            3
 
-#define ARM_LPAE_TCR_SL0_SHIFT         6
-#define ARM_LPAE_TCR_SL0_MASK          0x3
+#define ARM_LPAE_VTCR_SL0_MASK         0x3
 
 #define ARM_LPAE_TCR_T0SZ_SHIFT                0
-#define ARM_LPAE_TCR_SZ_MASK           0xf
-
-#define ARM_LPAE_TCR_PS_SHIFT          16
-#define ARM_LPAE_TCR_PS_MASK           0x7
 
-#define ARM_LPAE_TCR_IPS_SHIFT         32
-#define ARM_LPAE_TCR_IPS_MASK          0x7
+#define ARM_LPAE_VTCR_PS_SHIFT         16
+#define ARM_LPAE_VTCR_PS_MASK          0x7
 
 #define ARM_LPAE_TCR_PS_32_BIT         0x0ULL
 #define ARM_LPAE_TCR_PS_36_BIT         0x1ULL
@@ -293,17 +282,11 @@ static void __arm_lpae_init_pte(struct arm_lpae_io_pgtable *data,
 {
        arm_lpae_iopte pte = prot;
 
-       if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
-               pte |= ARM_LPAE_PTE_NS;
-
        if (data->iop.fmt != ARM_MALI_LPAE && lvl == ARM_LPAE_MAX_LEVELS - 1)
                pte |= ARM_LPAE_PTE_TYPE_PAGE;
        else
                pte |= ARM_LPAE_PTE_TYPE_BLOCK;
 
-       if (data->iop.fmt != ARM_MALI_LPAE)
-               pte |= ARM_LPAE_PTE_AF;
-       pte |= ARM_LPAE_PTE_SH_IS;
        pte |= paddr_to_iopte(paddr, data);
 
        __arm_lpae_set_pte(ptep, pte, &data->iop.cfg);
@@ -460,9 +443,20 @@ static arm_lpae_iopte arm_lpae_prot_to_pte(struct arm_lpae_io_pgtable *data,
                                << ARM_LPAE_PTE_ATTRINDX_SHIFT);
        }
 
+       if (prot & IOMMU_CACHE)
+               pte |= ARM_LPAE_PTE_SH_IS;
+       else
+               pte |= ARM_LPAE_PTE_SH_OS;
+
        if (prot & IOMMU_NOEXEC)
                pte |= ARM_LPAE_PTE_XN;
 
+       if (data->iop.cfg.quirks & IO_PGTABLE_QUIRK_ARM_NS)
+               pte |= ARM_LPAE_PTE_NS;
+
+       if (data->iop.fmt != ARM_MALI_LPAE)
+               pte |= ARM_LPAE_PTE_AF;
+
        return pte;
 }
 
@@ -474,6 +468,7 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
        arm_lpae_iopte *ptep = data->pgd;
        int ret, lvl = data->start_level;
        arm_lpae_iopte prot;
+       long iaext = (long)iova >> cfg->ias;
 
        /* If no access, then nothing to do */
        if (!(iommu_prot & (IOMMU_READ | IOMMU_WRITE)))
@@ -482,7 +477,9 @@ static int arm_lpae_map(struct io_pgtable_ops *ops, unsigned long iova,
        if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size))
                return -EINVAL;
 
-       if (WARN_ON(iova >> data->iop.cfg.ias || paddr >> data->iop.cfg.oas))
+       if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
+               iaext = ~iaext;
+       if (WARN_ON(iaext || paddr >> cfg->oas))
                return -ERANGE;
 
        prot = arm_lpae_prot_to_pte(data, iommu_prot);
@@ -648,11 +645,14 @@ static size_t arm_lpae_unmap(struct io_pgtable_ops *ops, unsigned long iova,
        struct arm_lpae_io_pgtable *data = io_pgtable_ops_to_data(ops);
        struct io_pgtable_cfg *cfg = &data->iop.cfg;
        arm_lpae_iopte *ptep = data->pgd;
+       long iaext = (long)iova >> cfg->ias;
 
        if (WARN_ON(!size || (size & cfg->pgsize_bitmap) != size))
                return 0;
 
-       if (WARN_ON(iova >> data->iop.cfg.ias))
+       if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1)
+               iaext = ~iaext;
+       if (WARN_ON(iaext))
                return 0;
 
        return __arm_lpae_unmap(data, gather, iova, size, data->start_level, ptep);
@@ -787,9 +787,12 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 {
        u64 reg;
        struct arm_lpae_io_pgtable *data;
+       typeof(&cfg->arm_lpae_s1_cfg.tcr) tcr = &cfg->arm_lpae_s1_cfg.tcr;
+       bool tg1;
 
        if (cfg->quirks & ~(IO_PGTABLE_QUIRK_ARM_NS |
-                           IO_PGTABLE_QUIRK_NON_STRICT))
+                           IO_PGTABLE_QUIRK_NON_STRICT |
+                           IO_PGTABLE_QUIRK_ARM_TTBR1))
                return NULL;
 
        data = arm_lpae_alloc_pgtable(cfg);
@@ -798,58 +801,55 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 
        /* TCR */
        if (cfg->coherent_walk) {
-               reg = (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
-                     (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
-                     (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
+               tcr->sh = ARM_LPAE_TCR_SH_IS;
+               tcr->irgn = ARM_LPAE_TCR_RGN_WBWA;
+               tcr->orgn = ARM_LPAE_TCR_RGN_WBWA;
        } else {
-               reg = (ARM_LPAE_TCR_SH_OS << ARM_LPAE_TCR_SH0_SHIFT) |
-                     (ARM_LPAE_TCR_RGN_NC << ARM_LPAE_TCR_IRGN0_SHIFT) |
-                     (ARM_LPAE_TCR_RGN_NC << ARM_LPAE_TCR_ORGN0_SHIFT);
+               tcr->sh = ARM_LPAE_TCR_SH_OS;
+               tcr->irgn = ARM_LPAE_TCR_RGN_NC;
+               tcr->orgn = ARM_LPAE_TCR_RGN_NC;
        }
 
+       tg1 = cfg->quirks & IO_PGTABLE_QUIRK_ARM_TTBR1;
        switch (ARM_LPAE_GRANULE(data)) {
        case SZ_4K:
-               reg |= ARM_LPAE_TCR_TG0_4K;
+               tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_4K : ARM_LPAE_TCR_TG0_4K;
                break;
        case SZ_16K:
-               reg |= ARM_LPAE_TCR_TG0_16K;
+               tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_16K : ARM_LPAE_TCR_TG0_16K;
                break;
        case SZ_64K:
-               reg |= ARM_LPAE_TCR_TG0_64K;
+               tcr->tg = tg1 ? ARM_LPAE_TCR_TG1_64K : ARM_LPAE_TCR_TG0_64K;
                break;
        }
 
        switch (cfg->oas) {
        case 32:
-               reg |= (ARM_LPAE_TCR_PS_32_BIT << ARM_LPAE_TCR_IPS_SHIFT);
+               tcr->ips = ARM_LPAE_TCR_PS_32_BIT;
                break;
        case 36:
-               reg |= (ARM_LPAE_TCR_PS_36_BIT << ARM_LPAE_TCR_IPS_SHIFT);
+               tcr->ips = ARM_LPAE_TCR_PS_36_BIT;
                break;
        case 40:
-               reg |= (ARM_LPAE_TCR_PS_40_BIT << ARM_LPAE_TCR_IPS_SHIFT);
+               tcr->ips = ARM_LPAE_TCR_PS_40_BIT;
                break;
        case 42:
-               reg |= (ARM_LPAE_TCR_PS_42_BIT << ARM_LPAE_TCR_IPS_SHIFT);
+               tcr->ips = ARM_LPAE_TCR_PS_42_BIT;
                break;
        case 44:
-               reg |= (ARM_LPAE_TCR_PS_44_BIT << ARM_LPAE_TCR_IPS_SHIFT);
+               tcr->ips = ARM_LPAE_TCR_PS_44_BIT;
                break;
        case 48:
-               reg |= (ARM_LPAE_TCR_PS_48_BIT << ARM_LPAE_TCR_IPS_SHIFT);
+               tcr->ips = ARM_LPAE_TCR_PS_48_BIT;
                break;
        case 52:
-               reg |= (ARM_LPAE_TCR_PS_52_BIT << ARM_LPAE_TCR_IPS_SHIFT);
+               tcr->ips = ARM_LPAE_TCR_PS_52_BIT;
                break;
        default:
                goto out_free_data;
        }
 
-       reg |= (64ULL - cfg->ias) << ARM_LPAE_TCR_T0SZ_SHIFT;
-
-       /* Disable speculative walks through TTBR1 */
-       reg |= ARM_LPAE_TCR_EPD1;
-       cfg->arm_lpae_s1_cfg.tcr = reg;
+       tcr->tsz = 64ULL - cfg->ias;
 
        /* MAIRs */
        reg = (ARM_LPAE_MAIR_ATTR_NC
@@ -872,9 +872,8 @@ arm_64_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
        /* Ensure the empty pgd is visible before any actual TTBR write */
        wmb();
 
-       /* TTBRs */
-       cfg->arm_lpae_s1_cfg.ttbr[0] = virt_to_phys(data->pgd);
-       cfg->arm_lpae_s1_cfg.ttbr[1] = 0;
+       /* TTBR */
+       cfg->arm_lpae_s1_cfg.ttbr = virt_to_phys(data->pgd);
        return &data->iop;
 
 out_free_data:
@@ -885,8 +884,9 @@ out_free_data:
 static struct io_pgtable *
 arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 {
-       u64 reg, sl;
+       u64 sl;
        struct arm_lpae_io_pgtable *data;
+       typeof(&cfg->arm_lpae_s2_cfg.vtcr) vtcr = &cfg->arm_lpae_s2_cfg.vtcr;
 
        /* The NS quirk doesn't apply at stage 2 */
        if (cfg->quirks & ~(IO_PGTABLE_QUIRK_NON_STRICT))
@@ -911,55 +911,59 @@ arm_64_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
        }
 
        /* VTCR */
-       reg = ARM_64_LPAE_S2_TCR_RES1 |
-            (ARM_LPAE_TCR_SH_IS << ARM_LPAE_TCR_SH0_SHIFT) |
-            (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_IRGN0_SHIFT) |
-            (ARM_LPAE_TCR_RGN_WBWA << ARM_LPAE_TCR_ORGN0_SHIFT);
+       if (cfg->coherent_walk) {
+               vtcr->sh = ARM_LPAE_TCR_SH_IS;
+               vtcr->irgn = ARM_LPAE_TCR_RGN_WBWA;
+               vtcr->orgn = ARM_LPAE_TCR_RGN_WBWA;
+       } else {
+               vtcr->sh = ARM_LPAE_TCR_SH_OS;
+               vtcr->irgn = ARM_LPAE_TCR_RGN_NC;
+               vtcr->orgn = ARM_LPAE_TCR_RGN_NC;
+       }
 
        sl = data->start_level;
 
        switch (ARM_LPAE_GRANULE(data)) {
        case SZ_4K:
-               reg |= ARM_LPAE_TCR_TG0_4K;
+               vtcr->tg = ARM_LPAE_TCR_TG0_4K;
                sl++; /* SL0 format is different for 4K granule size */
                break;
        case SZ_16K:
-               reg |= ARM_LPAE_TCR_TG0_16K;
+               vtcr->tg = ARM_LPAE_TCR_TG0_16K;
                break;
        case SZ_64K:
-               reg |= ARM_LPAE_TCR_TG0_64K;
+               vtcr->tg = ARM_LPAE_TCR_TG0_64K;
                break;
        }
 
        switch (cfg->oas) {
        case 32:
-               reg |= (ARM_LPAE_TCR_PS_32_BIT << ARM_LPAE_TCR_PS_SHIFT);
+               vtcr->ps = ARM_LPAE_TCR_PS_32_BIT;
                break;
        case 36:
-               reg |= (ARM_LPAE_TCR_PS_36_BIT << ARM_LPAE_TCR_PS_SHIFT);
+               vtcr->ps = ARM_LPAE_TCR_PS_36_BIT;
                break;
        case 40:
-               reg |= (ARM_LPAE_TCR_PS_40_BIT << ARM_LPAE_TCR_PS_SHIFT);
+               vtcr->ps = ARM_LPAE_TCR_PS_40_BIT;
                break;
        case 42:
-               reg |= (ARM_LPAE_TCR_PS_42_BIT << ARM_LPAE_TCR_PS_SHIFT);
+               vtcr->ps = ARM_LPAE_TCR_PS_42_BIT;
                break;
        case 44:
-               reg |= (ARM_LPAE_TCR_PS_44_BIT << ARM_LPAE_TCR_PS_SHIFT);
+               vtcr->ps = ARM_LPAE_TCR_PS_44_BIT;
                break;
        case 48:
-               reg |= (ARM_LPAE_TCR_PS_48_BIT << ARM_LPAE_TCR_PS_SHIFT);
+               vtcr->ps = ARM_LPAE_TCR_PS_48_BIT;
                break;
        case 52:
-               reg |= (ARM_LPAE_TCR_PS_52_BIT << ARM_LPAE_TCR_PS_SHIFT);
+               vtcr->ps = ARM_LPAE_TCR_PS_52_BIT;
                break;
        default:
                goto out_free_data;
        }
 
-       reg |= (64ULL - cfg->ias) << ARM_LPAE_TCR_T0SZ_SHIFT;
-       reg |= (~sl & ARM_LPAE_TCR_SL0_MASK) << ARM_LPAE_TCR_SL0_SHIFT;
-       cfg->arm_lpae_s2_cfg.vtcr = reg;
+       vtcr->tsz = 64ULL - cfg->ias;
+       vtcr->sl = ~sl & ARM_LPAE_VTCR_SL0_MASK;
 
        /* Allocate pgd pages */
        data->pgd = __arm_lpae_alloc_pages(ARM_LPAE_PGD_SIZE(data),
@@ -982,35 +986,21 @@ out_free_data:
 static struct io_pgtable *
 arm_32_lpae_alloc_pgtable_s1(struct io_pgtable_cfg *cfg, void *cookie)
 {
-       struct io_pgtable *iop;
-
        if (cfg->ias > 32 || cfg->oas > 40)
                return NULL;
 
        cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G);
-       iop = arm_64_lpae_alloc_pgtable_s1(cfg, cookie);
-       if (iop) {
-               cfg->arm_lpae_s1_cfg.tcr |= ARM_32_LPAE_TCR_EAE;
-               cfg->arm_lpae_s1_cfg.tcr &= 0xffffffff;
-       }
-
-       return iop;
+       return arm_64_lpae_alloc_pgtable_s1(cfg, cookie);
 }
 
 static struct io_pgtable *
 arm_32_lpae_alloc_pgtable_s2(struct io_pgtable_cfg *cfg, void *cookie)
 {
-       struct io_pgtable *iop;
-
        if (cfg->ias > 40 || cfg->oas > 40)
                return NULL;
 
        cfg->pgsize_bitmap &= (SZ_4K | SZ_2M | SZ_1G);
-       iop = arm_64_lpae_alloc_pgtable_s2(cfg, cookie);
-       if (iop)
-               cfg->arm_lpae_s2_cfg.vtcr &= 0xffffffff;
-
-       return iop;
+       return arm_64_lpae_alloc_pgtable_s2(cfg, cookie);
 }
 
 static struct io_pgtable *
index ced53e5..94394c8 100644 (file)
@@ -63,7 +63,7 @@ void free_io_pgtable_ops(struct io_pgtable_ops *ops)
        if (!ops)
                return;
 
-       iop = container_of(ops, struct io_pgtable, ops);
+       iop = io_pgtable_ops_to_pgtable(ops);
        io_pgtable_tlb_flush_all(iop);
        io_pgtable_init_table[iop->fmt]->free(iop);
 }
index e436ff8..9986921 100644 (file)
@@ -87,6 +87,7 @@ error:
        put_device(iommu->dev);
        return ret;
 }
+EXPORT_SYMBOL_GPL(iommu_device_sysfs_add);
 
 void iommu_device_sysfs_remove(struct iommu_device *iommu)
 {
@@ -94,6 +95,8 @@ void iommu_device_sysfs_remove(struct iommu_device *iommu)
        device_unregister(iommu->dev);
        iommu->dev = NULL;
 }
+EXPORT_SYMBOL_GPL(iommu_device_sysfs_remove);
+
 /*
  * IOMMU drivers can indicate a device is managed by a given IOMMU using
  * this interface.  A link to the device will be created in the "devices"
@@ -119,6 +122,7 @@ int iommu_device_link(struct iommu_device *iommu, struct device *link)
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(iommu_device_link);
 
 void iommu_device_unlink(struct iommu_device *iommu, struct device *link)
 {
@@ -128,3 +132,4 @@ void iommu_device_unlink(struct iommu_device *iommu, struct device *link)
        sysfs_remove_link(&link->kobj, "iommu");
        sysfs_remove_link_from_group(&iommu->dev->kobj, "devices", dev_name(link));
 }
+EXPORT_SYMBOL_GPL(iommu_device_unlink);
index 3ead597..3e35284 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/bitops.h>
 #include <linux/property.h>
 #include <linux/fsl/mc.h>
+#include <linux/module.h>
 #include <trace/events/iommu.h>
 
 static struct kset *iommu_group_kset;
@@ -141,6 +142,7 @@ int iommu_device_register(struct iommu_device *iommu)
        spin_unlock(&iommu_device_lock);
        return 0;
 }
+EXPORT_SYMBOL_GPL(iommu_device_register);
 
 void iommu_device_unregister(struct iommu_device *iommu)
 {
@@ -148,6 +150,7 @@ void iommu_device_unregister(struct iommu_device *iommu)
        list_del(&iommu->list);
        spin_unlock(&iommu_device_lock);
 }
+EXPORT_SYMBOL_GPL(iommu_device_unregister);
 
 static struct iommu_param *iommu_get_dev_param(struct device *dev)
 {
@@ -183,10 +186,21 @@ int iommu_probe_device(struct device *dev)
        if (!iommu_get_dev_param(dev))
                return -ENOMEM;
 
+       if (!try_module_get(ops->owner)) {
+               ret = -EINVAL;
+               goto err_free_dev_param;
+       }
+
        ret = ops->add_device(dev);
        if (ret)
-               iommu_free_dev_param(dev);
+               goto err_module_put;
+
+       return 0;
 
+err_module_put:
+       module_put(ops->owner);
+err_free_dev_param:
+       iommu_free_dev_param(dev);
        return ret;
 }
 
@@ -197,7 +211,10 @@ void iommu_release_device(struct device *dev)
        if (dev->iommu_group)
                ops->remove_device(dev);
 
-       iommu_free_dev_param(dev);
+       if (dev->iommu_param) {
+               module_put(ops->owner);
+               iommu_free_dev_param(dev);
+       }
 }
 
 static struct iommu_domain *__iommu_domain_alloc(struct bus_type *bus,
@@ -887,6 +904,7 @@ struct iommu_group *iommu_group_ref_get(struct iommu_group *group)
        kobject_get(group->devices_kobj);
        return group;
 }
+EXPORT_SYMBOL_GPL(iommu_group_ref_get);
 
 /**
  * iommu_group_put - Decrement group reference
@@ -1260,6 +1278,7 @@ struct iommu_group *generic_device_group(struct device *dev)
 {
        return iommu_group_alloc();
 }
+EXPORT_SYMBOL_GPL(generic_device_group);
 
 /*
  * Use standard PCI bus topology, isolation features, and DMA alias quirks
@@ -1327,6 +1346,7 @@ struct iommu_group *pci_device_group(struct device *dev)
        /* No shared group found, allocate new */
        return iommu_group_alloc();
 }
+EXPORT_SYMBOL_GPL(pci_device_group);
 
 /* Get the IOMMU group for device on fsl-mc bus */
 struct iommu_group *fsl_mc_device_group(struct device *dev)
@@ -1339,6 +1359,7 @@ struct iommu_group *fsl_mc_device_group(struct device *dev)
                group = iommu_group_alloc();
        return group;
 }
+EXPORT_SYMBOL_GPL(fsl_mc_device_group);
 
 /**
  * iommu_group_get_for_dev - Find or create the IOMMU group for a device
@@ -1407,6 +1428,7 @@ struct iommu_group *iommu_group_get_for_dev(struct device *dev)
 
        return group;
 }
+EXPORT_SYMBOL(iommu_group_get_for_dev);
 
 struct iommu_domain *iommu_group_default_domain(struct iommu_group *group)
 {
@@ -1537,6 +1559,11 @@ int bus_set_iommu(struct bus_type *bus, const struct iommu_ops *ops)
 {
        int err;
 
+       if (ops == NULL) {
+               bus->iommu_ops = NULL;
+               return 0;
+       }
+
        if (bus->iommu_ops != NULL)
                return -EBUSY;
 
@@ -2230,6 +2257,25 @@ void iommu_put_resv_regions(struct device *dev, struct list_head *list)
                ops->put_resv_regions(dev, list);
 }
 
+/**
+ * generic_iommu_put_resv_regions - Reserved region driver helper
+ * @dev: device for which to free reserved regions
+ * @list: reserved region list for device
+ *
+ * IOMMU drivers can use this to implement their .put_resv_regions() callback
+ * for simple reservations. Memory allocated for each reserved region will be
+ * freed. If an IOMMU driver allocates additional resources per region, it is
+ * going to have to implement a custom callback.
+ */
+void generic_iommu_put_resv_regions(struct device *dev, struct list_head *list)
+{
+       struct iommu_resv_region *entry, *next;
+
+       list_for_each_entry_safe(entry, next, list, list)
+               kfree(entry);
+}
+EXPORT_SYMBOL(generic_iommu_put_resv_regions);
+
 struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
                                                  size_t length, int prot,
                                                  enum iommu_resv_type type)
@@ -2247,6 +2293,7 @@ struct iommu_resv_region *iommu_alloc_resv_region(phys_addr_t start,
        region->type = type;
        return region;
 }
+EXPORT_SYMBOL_GPL(iommu_alloc_resv_region);
 
 static int
 request_default_domain_for_dev(struct device *dev, unsigned long type)
index c7a914b..0e6a953 100644 (file)
@@ -233,7 +233,7 @@ static DEFINE_MUTEX(iova_cache_mutex);
 
 struct iova *alloc_iova_mem(void)
 {
-       return kmem_cache_zalloc(iova_cache, GFP_ATOMIC);
+       return kmem_cache_zalloc(iova_cache, GFP_ATOMIC | __GFP_NOWARN);
 }
 EXPORT_SYMBOL(alloc_iova_mem);
 
index d02edd2..ecb3f94 100644 (file)
@@ -374,7 +374,7 @@ static void ipmmu_domain_setup_context(struct ipmmu_vmsa_domain *domain)
        u32 tmp;
 
        /* TTBR0 */
-       ttbr = domain->cfg.arm_lpae_s1_cfg.ttbr[0];
+       ttbr = domain->cfg.arm_lpae_s1_cfg.ttbr;
        ipmmu_ctx_write_root(domain, IMTTLBR0, ttbr);
        ipmmu_ctx_write_root(domain, IMTTUBR0, ttbr >> 32);
 
index 93f14bc..94a6df1 100644 (file)
@@ -279,8 +279,8 @@ static void __program_context(void __iomem *base, int ctx,
        SET_V2PCFG(base, ctx, 0x3);
 
        SET_TTBCR(base, ctx, priv->cfg.arm_v7s_cfg.tcr);
-       SET_TTBR0(base, ctx, priv->cfg.arm_v7s_cfg.ttbr[0]);
-       SET_TTBR1(base, ctx, priv->cfg.arm_v7s_cfg.ttbr[1]);
+       SET_TTBR0(base, ctx, priv->cfg.arm_v7s_cfg.ttbr);
+       SET_TTBR1(base, ctx, 0);
 
        /* Set prrr and nmrr */
        SET_PRRR(base, ctx, priv->cfg.arm_v7s_cfg.prrr);
index 6fc1f5e..95945f4 100644 (file)
@@ -367,7 +367,7 @@ static int mtk_iommu_attach_device(struct iommu_domain *domain,
        /* Update the pgtable base address register of the M4U HW */
        if (!data->m4u_dom) {
                data->m4u_dom = dom;
-               writel(dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
+               writel(dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
                       data->base + REG_MMU_PT_BASE_ADDR);
        }
 
@@ -765,7 +765,7 @@ static int __maybe_unused mtk_iommu_resume(struct device *dev)
        writel_relaxed(reg->ivrp_paddr, base + REG_MMU_IVRP_PADDR);
        writel_relaxed(reg->vld_pa_rng, base + REG_MMU_VLD_PA_RNG);
        if (m4u_dom)
-               writel(m4u_dom->cfg.arm_v7s_cfg.ttbr[0] & MMU_PT_ADDR_MASK,
+               writel(m4u_dom->cfg.arm_v7s_cfg.ttbr & MMU_PT_ADDR_MASK,
                       base + REG_MMU_PT_BASE_ADDR);
        return 0;
 }
index 026ad2b..20738aa 100644 (file)
@@ -8,11 +8,12 @@
 #include <linux/export.h>
 #include <linux/iommu.h>
 #include <linux/limits.h>
-#include <linux/pci.h>
+#include <linux/module.h>
 #include <linux/msi.h>
 #include <linux/of.h>
 #include <linux/of_iommu.h>
 #include <linux/of_pci.h>
+#include <linux/pci.h>
 #include <linux/slab.h>
 #include <linux/fsl/mc.h>
 
@@ -91,16 +92,16 @@ static int of_iommu_xlate(struct device *dev,
 {
        const struct iommu_ops *ops;
        struct fwnode_handle *fwnode = &iommu_spec->np->fwnode;
-       int err;
+       int ret;
 
        ops = iommu_ops_from_fwnode(fwnode);
        if ((ops && !ops->of_xlate) ||
            !of_device_is_available(iommu_spec->np))
                return NO_IOMMU;
 
-       err = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
-       if (err)
-               return err;
+       ret = iommu_fwspec_init(dev, &iommu_spec->np->fwnode, ops);
+       if (ret)
+               return ret;
        /*
         * The otherwise-empty fwspec handily serves to indicate the specific
         * IOMMU device we're waiting for, which will be useful if we ever get
@@ -109,7 +110,12 @@ static int of_iommu_xlate(struct device *dev,
        if (!ops)
                return driver_deferred_probe_check_state(dev);
 
-       return ops->of_xlate(dev, iommu_spec);
+       if (!try_module_get(ops->owner))
+               return -ENODEV;
+
+       ret = ops->of_xlate(dev, iommu_spec);
+       module_put(ops->owner);
+       return ret;
 }
 
 struct of_pci_iommu_alias_info {
@@ -179,6 +185,7 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
                        .np = master_np,
                };
 
+               pci_request_acs();
                err = pci_for_each_dma_alias(to_pci_dev(dev),
                                             of_pci_iommu_init, &info);
        } else if (dev_is_fsl_mc(dev)) {
@@ -196,8 +203,12 @@ const struct iommu_ops *of_iommu_configure(struct device *dev,
                        if (err)
                                break;
                }
-       }
 
+               fwspec = dev_iommu_fwspec_get(dev);
+               if (!err && fwspec)
+                       of_property_read_u32(master_np, "pasid-num-bits",
+                                            &fwspec->num_pasid_bits);
+       }
 
        /*
         * Two success conditions can be represented by non-negative err here:
index 52f3829..39759db 100644 (file)
@@ -201,7 +201,7 @@ static irqreturn_t qcom_iommu_fault(int irq, void *dev)
 
        fsr = iommu_readl(ctx, ARM_SMMU_CB_FSR);
 
-       if (!(fsr & FSR_FAULT))
+       if (!(fsr & ARM_SMMU_FSR_FAULT))
                return IRQ_NONE;
 
        fsynr = iommu_readl(ctx, ARM_SMMU_CB_FSYNR0);
@@ -215,7 +215,7 @@ static irqreturn_t qcom_iommu_fault(int irq, void *dev)
        }
 
        iommu_writel(ctx, ARM_SMMU_CB_FSR, fsr);
-       iommu_writel(ctx, ARM_SMMU_CB_RESUME, RESUME_TERMINATE);
+       iommu_writel(ctx, ARM_SMMU_CB_RESUME, ARM_SMMU_RESUME_TERMINATE);
 
        return IRQ_HANDLED;
 }
@@ -269,18 +269,15 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
 
                /* TTBRs */
                iommu_writeq(ctx, ARM_SMMU_CB_TTBR0,
-                               pgtbl_cfg.arm_lpae_s1_cfg.ttbr[0] |
-                               FIELD_PREP(TTBRn_ASID, ctx->asid));
-               iommu_writeq(ctx, ARM_SMMU_CB_TTBR1,
-                               pgtbl_cfg.arm_lpae_s1_cfg.ttbr[1] |
-                               FIELD_PREP(TTBRn_ASID, ctx->asid));
+                               pgtbl_cfg.arm_lpae_s1_cfg.ttbr |
+                               FIELD_PREP(ARM_SMMU_TTBRn_ASID, ctx->asid));
+               iommu_writeq(ctx, ARM_SMMU_CB_TTBR1, 0);
 
                /* TCR */
                iommu_writel(ctx, ARM_SMMU_CB_TCR2,
-                               (pgtbl_cfg.arm_lpae_s1_cfg.tcr >> 32) |
-                               FIELD_PREP(TCR2_SEP, TCR2_SEP_UPSTREAM));
+                               arm_smmu_lpae_tcr2(&pgtbl_cfg));
                iommu_writel(ctx, ARM_SMMU_CB_TCR,
-                               pgtbl_cfg.arm_lpae_s1_cfg.tcr);
+                            arm_smmu_lpae_tcr(&pgtbl_cfg) | ARM_SMMU_TCR_EAE);
 
                /* MAIRs (stage-1 only) */
                iommu_writel(ctx, ARM_SMMU_CB_S1_MAIR0,
@@ -289,11 +286,13 @@ static int qcom_iommu_init_domain(struct iommu_domain *domain,
                                pgtbl_cfg.arm_lpae_s1_cfg.mair >> 32);
 
                /* SCTLR */
-               reg = SCTLR_CFIE | SCTLR_CFRE | SCTLR_AFE | SCTLR_TRE |
-                       SCTLR_M | SCTLR_S1_ASIDPNE | SCTLR_CFCFG;
+               reg = ARM_SMMU_SCTLR_CFIE | ARM_SMMU_SCTLR_CFRE |
+                     ARM_SMMU_SCTLR_AFE | ARM_SMMU_SCTLR_TRE |
+                     ARM_SMMU_SCTLR_M | ARM_SMMU_SCTLR_S1_ASIDPNE |
+                     ARM_SMMU_SCTLR_CFCFG;
 
                if (IS_ENABLED(CONFIG_BIG_ENDIAN))
-                       reg |= SCTLR_E;
+                       reg |= ARM_SMMU_SCTLR_E;
 
                iommu_writel(ctx, ARM_SMMU_CB_SCTLR, reg);
 
index 315c7cc..cce329d 100644 (file)
@@ -837,14 +837,6 @@ static void viommu_get_resv_regions(struct device *dev, struct list_head *head)
        iommu_dma_get_resv_regions(dev, head);
 }
 
-static void viommu_put_resv_regions(struct device *dev, struct list_head *head)
-{
-       struct iommu_resv_region *entry, *next;
-
-       list_for_each_entry_safe(entry, next, head, list)
-               kfree(entry);
-}
-
 static struct iommu_ops viommu_ops;
 static struct virtio_driver virtio_iommu_drv;
 
@@ -914,7 +906,7 @@ static int viommu_add_device(struct device *dev)
 err_unlink_dev:
        iommu_device_unlink(&viommu->iommu, dev);
 err_free_dev:
-       viommu_put_resv_regions(dev, &vdev->resv_regions);
+       generic_iommu_put_resv_regions(dev, &vdev->resv_regions);
        kfree(vdev);
 
        return ret;
@@ -932,7 +924,7 @@ static void viommu_remove_device(struct device *dev)
 
        iommu_group_remove_device(dev);
        iommu_device_unlink(&vdev->viommu->iommu, dev);
-       viommu_put_resv_regions(dev, &vdev->resv_regions);
+       generic_iommu_put_resv_regions(dev, &vdev->resv_regions);
        kfree(vdev);
 }
 
@@ -961,7 +953,7 @@ static struct iommu_ops viommu_ops = {
        .remove_device          = viommu_remove_device,
        .device_group           = viommu_device_group,
        .get_resv_regions       = viommu_get_resv_regions,
-       .put_resv_regions       = viommu_put_resv_regions,
+       .put_resv_regions       = generic_iommu_put_resv_regions,
        .of_xlate               = viommu_of_xlate,
 };
 
index 1006c69..6d39773 100644 (file)
@@ -438,7 +438,7 @@ config CSKY_MPINTC
        help
          Say yes here to enable C-SKY SMP interrupt controller driver used
          for C-SKY SMP system.
-         In fact it's not mmio map in hw and it use ld/st to visit the
+         In fact it's not mmio map in hardware and it uses ld/st to visit the
          controller's register inside CPU.
 
 config CSKY_APB_INTC
@@ -446,7 +446,7 @@ config CSKY_APB_INTC
        depends on CSKY
        help
          Say yes here to enable C-SKY APB interrupt controller driver used
-         by C-SKY single core SOC system. It use mmio map apb-bus to visit
+         by C-SKY single core SOC system. It uses mmio map apb-bus to visit
          the controller's register.
 
 config IMX_IRQSTEER
index f717586..1ee95f5 100644 (file)
@@ -661,7 +661,7 @@ static struct its_collection *its_build_invall_cmd(struct its_node *its,
                                                   struct its_cmd_desc *desc)
 {
        its_encode_cmd(cmd, GITS_CMD_INVALL);
-       its_encode_collection(cmd, desc->its_mapc_cmd.col->col_id);
+       its_encode_collection(cmd, desc->its_invall_cmd.col->col_id);
 
        its_fixup_cmd(cmd);
 
@@ -2376,6 +2376,8 @@ static u64 inherit_vpe_l1_table_from_its(void)
                        continue;
 
                /* We have a winner! */
+               gic_data_rdist()->vpe_l1_base = its->tables[2].base;
+
                val  = GICR_VPROPBASER_4_1_VALID;
                if (baser & GITS_BASER_INDIRECT)
                        val |= GICR_VPROPBASER_4_1_INDIRECT;
@@ -2413,14 +2415,12 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask)
 
        for_each_possible_cpu(cpu) {
                void __iomem *base = gic_data_rdist_cpu(cpu)->rd_base;
-               u32 tmp;
 
                if (!base || cpu == smp_processor_id())
                        continue;
 
                val = gic_read_typer(base + GICR_TYPER);
-               tmp = compute_common_aff(val);
-               if (tmp != aff)
+               if (aff != compute_common_aff(val))
                        continue;
 
                /*
@@ -2429,9 +2429,10 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask)
                 * ours wrt CommonLPIAff. Let's use its own VPROPBASER.
                 * Make sure we don't write the Z bit in that case.
                 */
-               val = gits_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
+               val = gicr_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
                val &= ~GICR_VPROPBASER_4_1_Z;
 
+               gic_data_rdist()->vpe_l1_base = gic_data_rdist_cpu(cpu)->vpe_l1_base;
                *mask = gic_data_rdist_cpu(cpu)->vpe_table_mask;
 
                return val;
@@ -2440,6 +2441,72 @@ static u64 inherit_vpe_l1_table_from_rd(cpumask_t **mask)
        return 0;
 }
 
+static bool allocate_vpe_l2_table(int cpu, u32 id)
+{
+       void __iomem *base = gic_data_rdist_cpu(cpu)->rd_base;
+       u64 val, gpsz, npg;
+       unsigned int psz, esz, idx;
+       struct page *page;
+       __le64 *table;
+
+       if (!gic_rdists->has_rvpeid)
+               return true;
+
+       val  = gicr_read_vpropbaser(base + SZ_128K + GICR_VPROPBASER);
+
+       esz  = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val) + 1;
+       gpsz = FIELD_GET(GICR_VPROPBASER_4_1_PAGE_SIZE, val);
+       npg  = FIELD_GET(GICR_VPROPBASER_4_1_SIZE, val) + 1;
+
+       switch (gpsz) {
+       default:
+               WARN_ON(1);
+               /* fall through */
+       case GIC_PAGE_SIZE_4K:
+               psz = SZ_4K;
+               break;
+       case GIC_PAGE_SIZE_16K:
+               psz = SZ_16K;
+               break;
+       case GIC_PAGE_SIZE_64K:
+               psz = SZ_64K;
+               break;
+       }
+
+       /* Don't allow vpe_id that exceeds single, flat table limit */
+       if (!(val & GICR_VPROPBASER_4_1_INDIRECT))
+               return (id < (npg * psz / (esz * SZ_8)));
+
+       /* Compute 1st level table index & check if that exceeds table limit */
+       idx = id >> ilog2(psz / (esz * SZ_8));
+       if (idx >= (npg * psz / GITS_LVL1_ENTRY_SIZE))
+               return false;
+
+       table = gic_data_rdist_cpu(cpu)->vpe_l1_base;
+
+       /* Allocate memory for 2nd level table */
+       if (!table[idx]) {
+               page = alloc_pages(GFP_KERNEL | __GFP_ZERO, get_order(psz));
+               if (!page)
+                       return false;
+
+               /* Flush Lvl2 table to PoC if hw doesn't support coherency */
+               if (!(val & GICR_VPROPBASER_SHAREABILITY_MASK))
+                       gic_flush_dcache_to_poc(page_address(page), psz);
+
+               table[idx] = cpu_to_le64(page_to_phys(page) | GITS_BASER_VALID);
+
+               /* Flush Lvl1 entry to PoC if hw doesn't support coherency */
+               if (!(val & GICR_VPROPBASER_SHAREABILITY_MASK))
+                       gic_flush_dcache_to_poc(table + idx, GITS_LVL1_ENTRY_SIZE);
+
+               /* Ensure updated table contents are visible to RD hardware */
+               dsb(sy);
+       }
+
+       return true;
+}
+
 static int allocate_vpe_l1_table(void)
 {
        void __iomem *vlpi_base = gic_data_rdist_vlpi_base();
@@ -2457,8 +2524,8 @@ static int allocate_vpe_l1_table(void)
         * effect of making sure no doorbell will be generated and we can
         * then safely clear VPROPBASER.Valid.
         */
-       if (gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER) & GICR_VPENDBASER_Valid)
-               gits_write_vpendbaser(GICR_VPENDBASER_PendingLast,
+       if (gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER) & GICR_VPENDBASER_Valid)
+               gicr_write_vpendbaser(GICR_VPENDBASER_PendingLast,
                                      vlpi_base + GICR_VPENDBASER);
 
        /*
@@ -2481,8 +2548,8 @@ static int allocate_vpe_l1_table(void)
 
        /* First probe the page size */
        val = FIELD_PREP(GICR_VPROPBASER_4_1_PAGE_SIZE, GIC_PAGE_SIZE_64K);
-       gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
-       val = gits_read_vpropbaser(vlpi_base + GICR_VPROPBASER);
+       gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+       val = gicr_read_vpropbaser(vlpi_base + GICR_VPROPBASER);
        gpsz = FIELD_GET(GICR_VPROPBASER_4_1_PAGE_SIZE, val);
        esz = FIELD_GET(GICR_VPROPBASER_4_1_ENTRY_SIZE, val);
 
@@ -2531,7 +2598,7 @@ static int allocate_vpe_l1_table(void)
                npg = 1;
        }
 
-       val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, npg);
+       val |= FIELD_PREP(GICR_VPROPBASER_4_1_SIZE, npg - 1);
 
        /* Right, that's the number of CPU pages we need for L1 */
        np = DIV_ROUND_UP(npg * psz, PAGE_SIZE);
@@ -2542,7 +2609,7 @@ static int allocate_vpe_l1_table(void)
        if (!page)
                return -ENOMEM;
 
-       gic_data_rdist()->vpe_l1_page = page;
+       gic_data_rdist()->vpe_l1_base = page_address(page);
        pa = virt_to_phys(page_address(page));
        WARN_ON(!IS_ALIGNED(pa, psz));
 
@@ -2553,7 +2620,7 @@ static int allocate_vpe_l1_table(void)
        val |= GICR_VPROPBASER_4_1_VALID;
 
 out:
-       gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+       gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
        cpumask_set_cpu(smp_processor_id(), gic_data_rdist()->vpe_table_mask);
 
        pr_debug("CPU%d: VPROPBASER = %llx %*pbl\n",
@@ -2660,14 +2727,14 @@ static u64 its_clear_vpend_valid(void __iomem *vlpi_base, u64 clr, u64 set)
        bool clean;
        u64 val;
 
-       val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+       val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
        val &= ~GICR_VPENDBASER_Valid;
        val &= ~clr;
        val |= set;
-       gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+       gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
 
        do {
-               val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
+               val = gicr_read_vpendbaser(vlpi_base + GICR_VPENDBASER);
                clean = !(val & GICR_VPENDBASER_Dirty);
                if (!clean) {
                        count--;
@@ -2782,7 +2849,7 @@ static void its_cpu_init_lpis(void)
                val = (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
                pr_debug("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n",
                        smp_processor_id(), val);
-               gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+               gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
 
                /*
                 * Also clear Valid bit of GICR_VPENDBASER, in case some
@@ -2790,7 +2857,6 @@ static void its_cpu_init_lpis(void)
                 * corrupting memory.
                 */
                val = its_clear_vpend_valid(vlpi_base, 0, 0);
-               WARN_ON(val & GICR_VPENDBASER_Dirty);
        }
 
        if (allocate_vpe_l1_table()) {
@@ -2954,6 +3020,7 @@ static bool its_alloc_device_table(struct its_node *its, u32 dev_id)
 static bool its_alloc_vpe_table(u32 vpe_id)
 {
        struct its_node *its;
+       int cpu;
 
        /*
         * Make sure the L2 tables are allocated on *all* v4 ITSs. We
@@ -2976,6 +3043,19 @@ static bool its_alloc_vpe_table(u32 vpe_id)
                        return false;
        }
 
+       /* Non v4.1? No need to iterate RDs and go back early. */
+       if (!gic_rdists->has_rvpeid)
+               return true;
+
+       /*
+        * Make sure the L2 tables are allocated for all copies of
+        * the L1 table on *all* v4.1 RDs.
+        */
+       for_each_possible_cpu(cpu) {
+               if (!allocate_vpe_l2_table(cpu, vpe_id))
+                       return false;
+       }
+
        return true;
 }
 
@@ -3443,7 +3523,7 @@ static void its_vpe_schedule(struct its_vpe *vpe)
        val |= (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK;
        val |= GICR_VPROPBASER_RaWb;
        val |= GICR_VPROPBASER_InnerShareable;
-       gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
+       gicr_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER);
 
        val  = virt_to_phys(page_address(vpe->vpt_page)) &
                GENMASK_ULL(51, 16);
@@ -3461,7 +3541,7 @@ static void its_vpe_schedule(struct its_vpe *vpe)
        val |= GICR_VPENDBASER_PendingLast;
        val |= vpe->idai ? GICR_VPENDBASER_IDAI : 0;
        val |= GICR_VPENDBASER_Valid;
-       gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+       gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
 }
 
 static void its_vpe_deschedule(struct its_vpe *vpe)
@@ -3661,7 +3741,7 @@ static void its_vpe_4_1_schedule(struct its_vpe *vpe,
        val |= info->g1en ? GICR_VPENDBASER_4_1_VGRP1EN : 0;
        val |= FIELD_PREP(GICR_VPENDBASER_4_1_VPEID, vpe->vpe_id);
 
-       gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
+       gicr_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER);
 }
 
 static void its_vpe_4_1_deschedule(struct its_vpe *vpe,
index 286f982..c1f7af9 100644 (file)
@@ -1839,6 +1839,7 @@ static struct
        struct redist_region *redist_regs;
        u32 nr_redist_regions;
        bool single_redist;
+       int enabled_rdists;
        u32 maint_irq;
        int maint_irq_mode;
        phys_addr_t vcpu_base;
@@ -1933,8 +1934,10 @@ static int __init gic_acpi_match_gicc(union acpi_subtable_headers *header,
         * If GICC is enabled and has valid gicr base address, then it means
         * GICR base is presented via GICC
         */
-       if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address)
+       if ((gicc->flags & ACPI_MADT_ENABLED) && gicc->gicr_base_address) {
+               acpi_data.enabled_rdists++;
                return 0;
+       }
 
        /*
         * It's perfectly valid firmware can pass disabled GICC entry, driver
@@ -1964,8 +1967,10 @@ static int __init gic_acpi_count_gicr_regions(void)
 
        count = acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_INTERRUPT,
                                      gic_acpi_match_gicc, 0);
-       if (count > 0)
+       if (count > 0) {
                acpi_data.single_redist = true;
+               count = acpi_data.enabled_rdists;
+       }
 
        return count;
 }
index eadbe59..b5ed4ea 100644 (file)
@@ -199,8 +199,8 @@ static ssize_t empty_read(struct file *file, char __user *buf,
        return 0;
 }
 
-static const struct file_operations empty_fops = {
-       .read   = empty_read,
+static const struct proc_ops empty_proc_ops = {
+       .proc_read      = empty_read,
 };
 
 // ---------------------------------------------------------------------------
@@ -214,7 +214,7 @@ kcapi_proc_init(void)
        proc_create_seq("capi/contrstats",   0, NULL, &seq_contrstats_ops);
        proc_create_seq("capi/applications", 0, NULL, &seq_applications_ops);
        proc_create_seq("capi/applstats",    0, NULL, &seq_applstats_ops);
-       proc_create("capi/driver",           0, NULL, &empty_fops);
+       proc_create("capi/driver",           0, NULL, &empty_proc_ops);
 }
 
 void
index 4b68520..d82f1de 100644 (file)
@@ -836,6 +836,16 @@ config LEDS_LM36274
          Say Y to enable the LM36274 LED driver for TI LMU devices.
          This supports the LED device LM36274.
 
+config LEDS_TPS6105X
+       tristate "LED support for TI TPS6105X"
+       depends on LEDS_CLASS
+       depends on TPS6105X
+       default y if TPS6105X
+       help
+         This driver supports TPS61050/TPS61052 LED chips.
+         It is a single boost converter primarily for white LEDs and
+         audio amplifiers.
+
 comment "LED Triggers"
 source "drivers/leds/trigger/Kconfig"
 
index 2da39e8..d7e1107 100644 (file)
@@ -85,6 +85,7 @@ obj-$(CONFIG_LEDS_LM3601X)            += leds-lm3601x.o
 obj-$(CONFIG_LEDS_TI_LMU_COMMON)       += leds-ti-lmu-common.o
 obj-$(CONFIG_LEDS_LM3697)              += leds-lm3697.o
 obj-$(CONFIG_LEDS_LM36274)             += leds-lm36274.o
+obj-$(CONFIG_LEDS_TPS6105X)            += leds-tps6105x.o
 
 # LED SPI Drivers
 obj-$(CONFIG_LEDS_CR0014114)           += leds-cr0014114.o
index 4387743..1fc40e8 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/spinlock.h>
 #include <linux/timer.h>
 #include <uapi/linux/uleds.h>
+#include <linux/of.h>
 #include "leds.h"
 
 static struct class *leds_class;
@@ -214,6 +215,98 @@ static int led_resume(struct device *dev)
 
 static SIMPLE_DEV_PM_OPS(leds_class_dev_pm_ops, led_suspend, led_resume);
 
+/**
+ * of_led_get() - request a LED device via the LED framework
+ * @np: device node to get the LED device from
+ * @index: the index of the LED
+ *
+ * Returns the LED device parsed from the phandle specified in the "leds"
+ * property of a device tree node or a negative error-code on failure.
+ */
+struct led_classdev *of_led_get(struct device_node *np, int index)
+{
+       struct device *led_dev;
+       struct led_classdev *led_cdev;
+       struct device_node *led_node;
+
+       led_node = of_parse_phandle(np, "leds", index);
+       if (!led_node)
+               return ERR_PTR(-ENOENT);
+
+       led_dev = class_find_device_by_of_node(leds_class, led_node);
+       of_node_put(led_node);
+
+       if (!led_dev)
+               return ERR_PTR(-EPROBE_DEFER);
+
+       led_cdev = dev_get_drvdata(led_dev);
+
+       if (!try_module_get(led_cdev->dev->parent->driver->owner))
+               return ERR_PTR(-ENODEV);
+
+       return led_cdev;
+}
+EXPORT_SYMBOL_GPL(of_led_get);
+
+/**
+ * led_put() - release a LED device
+ * @led_cdev: LED device
+ */
+void led_put(struct led_classdev *led_cdev)
+{
+       module_put(led_cdev->dev->parent->driver->owner);
+}
+EXPORT_SYMBOL_GPL(led_put);
+
+static void devm_led_release(struct device *dev, void *res)
+{
+       struct led_classdev **p = res;
+
+       led_put(*p);
+}
+
+/**
+ * devm_of_led_get - Resource-managed request of a LED device
+ * @dev:       LED consumer
+ * @index:     index of the LED to obtain in the consumer
+ *
+ * The device node of the device is parse to find the request LED device.
+ * The LED device returned from this function is automatically released
+ * on driver detach.
+ *
+ * @return a pointer to a LED device or ERR_PTR(errno) on failure.
+ */
+struct led_classdev *__must_check devm_of_led_get(struct device *dev,
+                                                 int index)
+{
+       struct led_classdev *led;
+       struct led_classdev **dr;
+
+       if (!dev)
+               return ERR_PTR(-EINVAL);
+
+       /* Not using device tree? */
+       if (!IS_ENABLED(CONFIG_OF) || !dev->of_node)
+               return ERR_PTR(-ENOTSUPP);
+
+       led = of_led_get(dev->of_node, index);
+       if (IS_ERR(led))
+               return led;
+
+       dr = devres_alloc(devm_led_release, sizeof(struct led_classdev *),
+                         GFP_KERNEL);
+       if (!dr) {
+               led_put(led);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       *dr = led;
+       devres_add(dev, dr);
+
+       return led;
+}
+EXPORT_SYMBOL_GPL(devm_of_led_get);
+
 static int led_classdev_next_name(const char *init_name, char *name,
                                  size_t len)
 {
@@ -276,8 +369,10 @@ int led_classdev_register_ext(struct device *parent,
                mutex_unlock(&led_cdev->led_access);
                return PTR_ERR(led_cdev->dev);
        }
-       if (init_data && init_data->fwnode)
+       if (init_data && init_data->fwnode) {
                led_cdev->dev->fwnode = init_data->fwnode;
+               led_cdev->dev->of_node = to_of_node(init_data->fwnode);
+       }
 
        if (ret)
                dev_warn(parent, "Led %s renamed to %s due to name collision",
index e7ec6bf..bd61a82 100644 (file)
@@ -10,7 +10,7 @@
 
 #include <linux/module.h>
 #include <linux/i2c.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/delay.h>
 #include <linux/leds.h>
 #include <linux/leds-bd2802.h>
@@ -67,6 +67,7 @@ struct led_state {
 struct bd2802_led {
        struct bd2802_led_platform_data *pdata;
        struct i2c_client               *client;
+       struct gpio_desc                *reset;
        struct rw_semaphore             rwsem;
 
        struct led_state                led[2];
@@ -200,7 +201,7 @@ static void bd2802_update_state(struct bd2802_led *led, enum led_ids id,
                return;
 
        if (bd2802_is_all_off(led) && !led->adf_on) {
-               gpio_set_value(led->pdata->reset_gpio, 0);
+               gpiod_set_value(led->reset, 1);
                return;
        }
 
@@ -226,7 +227,7 @@ static void bd2802_configure(struct bd2802_led *led)
 
 static void bd2802_reset_cancel(struct bd2802_led *led)
 {
-       gpio_set_value(led->pdata->reset_gpio, 1);
+       gpiod_set_value(led->reset, 0);
        udelay(100);
        bd2802_configure(led);
 }
@@ -420,7 +421,7 @@ static void bd2802_disable_adv_conf(struct bd2802_led *led)
                                                bd2802_addr_attributes[i]);
 
        if (bd2802_is_all_off(led))
-               gpio_set_value(led->pdata->reset_gpio, 0);
+               gpiod_set_value(led->reset, 1);
 
        led->adf_on = 0;
 }
@@ -670,8 +671,16 @@ static int bd2802_probe(struct i2c_client *client,
        pdata = led->pdata = dev_get_platdata(&client->dev);
        i2c_set_clientdata(client, led);
 
-       /* Configure RESET GPIO (L: RESET, H: RESET cancel) */
-       gpio_request_one(pdata->reset_gpio, GPIOF_OUT_INIT_HIGH, "RGB_RESETB");
+       /*
+        * Configure RESET GPIO (L: RESET, H: RESET cancel)
+        *
+        * We request the reset GPIO as OUT_LOW which means de-asserted,
+        * board files specifying this GPIO line in a machine descriptor
+        * table should take care to specify GPIO_ACTIVE_LOW for this line.
+        */
+       led->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_LOW);
+       if (IS_ERR(led->reset))
+               return PTR_ERR(led->reset);
 
        /* Tacss = min 0.1ms */
        udelay(100);
@@ -685,7 +694,7 @@ static int bd2802_probe(struct i2c_client *client,
                dev_info(&client->dev, "return 0x%02x\n", ret);
 
        /* To save the power, reset BD2802 after detecting */
-       gpio_set_value(led->pdata->reset_gpio, 0);
+       gpiod_set_value(led->reset, 1);
 
        /* Default attributes */
        led->wave_pattern = BD2802_PATTERN_HALF;
@@ -720,7 +729,7 @@ static int bd2802_remove(struct i2c_client *client)
        struct bd2802_led *led = i2c_get_clientdata(client);
        int i;
 
-       gpio_set_value(led->pdata->reset_gpio, 0);
+       gpiod_set_value(led->reset, 1);
        bd2802_unregister_led_classdev(led);
        if (led->adf_on)
                bd2802_disable_adv_conf(led);
@@ -750,7 +759,7 @@ static int bd2802_suspend(struct device *dev)
        struct i2c_client *client = to_i2c_client(dev);
        struct bd2802_led *led = i2c_get_clientdata(client);
 
-       gpio_set_value(led->pdata->reset_gpio, 0);
+       gpiod_set_value(led->reset, 1);
 
        return 0;
 }
index 491268b..188a57d 100644 (file)
@@ -578,6 +578,12 @@ static int lm3532_parse_node(struct lm3532_data *priv)
                priv->runtime_ramp_down = lm3532_get_ramp_index(ramp_time);
 
        device_for_each_child_node(priv->dev, child) {
+               struct led_init_data idata = {
+                       .fwnode = child,
+                       .default_label = ":",
+                       .devicename = priv->client->name,
+               };
+
                led = &priv->leds[i];
 
                ret = fwnode_property_read_u32(child, "reg", &control_bank);
@@ -652,7 +658,7 @@ static int lm3532_parse_node(struct lm3532_data *priv)
                led->led_dev.name = led->label;
                led->led_dev.brightness_set_blocking = lm3532_brightness_set;
 
-               ret = devm_led_classdev_register(priv->dev, &led->led_dev);
+               ret = devm_led_classdev_register_ext(priv->dev, &led->led_dev, &idata);
                if (ret) {
                        dev_err(&priv->client->dev, "led register err: %d\n",
                                ret);
index 4805754..4232906 100644 (file)
@@ -106,7 +106,7 @@ static int lm3642_control(struct lm3642_chip_data *chip,
        ret = regmap_read(chip->regmap, REG_FLAG, &chip->last_flag);
        if (ret < 0) {
                dev_err(chip->dev, "Failed to read REG_FLAG Register\n");
-               goto out;
+               return ret;
        }
 
        if (chip->last_flag)
@@ -146,11 +146,11 @@ static int lm3642_control(struct lm3642_chip_data *chip,
                break;
 
        default:
-               return ret;
+               return -EINVAL;
        }
        if (ret < 0) {
                dev_err(chip->dev, "Failed to write REG_I_CTRL Register\n");
-               goto out;
+               return ret;
        }
 
        if (chip->tx_pin)
@@ -159,13 +159,12 @@ static int lm3642_control(struct lm3642_chip_data *chip,
        ret = regmap_update_bits(chip->regmap, REG_ENABLE,
                                 MODE_BITS_MASK << MODE_BITS_SHIFT,
                                 opmode << MODE_BITS_SHIFT);
-out:
        return ret;
 }
 
 /* torch */
 
-/* torch pin config for lm3642*/
+/* torch pin config for lm3642 */
 static ssize_t lm3642_torch_pin_store(struct device *dev,
                                      struct device_attribute *attr,
                                      const char *buf, size_t size)
@@ -178,7 +177,7 @@ static ssize_t lm3642_torch_pin_store(struct device *dev,
 
        ret = kstrtouint(buf, 10, &state);
        if (ret)
-               goto out_strtoint;
+               return ret;
        if (state != 0)
                state = 0x01 << TORCH_PIN_EN_SHIFT;
 
@@ -186,16 +185,12 @@ static ssize_t lm3642_torch_pin_store(struct device *dev,
        ret = regmap_update_bits(chip->regmap, REG_ENABLE,
                                 TORCH_PIN_EN_MASK << TORCH_PIN_EN_SHIFT,
                                 state);
-       if (ret < 0)
-               goto out;
+       if (ret < 0) {
+               dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+               return ret;
+       }
 
        return size;
-out:
-       dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
-       return ret;
-out_strtoint:
-       dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
-       return ret;
 }
 
 static DEVICE_ATTR(torch_pin, S_IWUSR, NULL, lm3642_torch_pin_store);
@@ -229,7 +224,7 @@ static ssize_t lm3642_strobe_pin_store(struct device *dev,
 
        ret = kstrtouint(buf, 10, &state);
        if (ret)
-               goto out_strtoint;
+               return ret;
        if (state != 0)
                state = 0x01 << STROBE_PIN_EN_SHIFT;
 
@@ -237,16 +232,12 @@ static ssize_t lm3642_strobe_pin_store(struct device *dev,
        ret = regmap_update_bits(chip->regmap, REG_ENABLE,
                                 STROBE_PIN_EN_MASK << STROBE_PIN_EN_SHIFT,
                                 state);
-       if (ret < 0)
-               goto out;
+       if (ret < 0) {
+               dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
+               return ret;
+       }
 
        return size;
-out:
-       dev_err(chip->dev, "%s:i2c access fail to register\n", __func__);
-       return ret;
-out_strtoint:
-       dev_err(chip->dev, "%s: fail to change str to int\n", __func__);
-       return ret;
 }
 
 static DEVICE_ATTR(strobe_pin, S_IWUSR, NULL, lm3642_strobe_pin_store);
index 8b40810..28a51ae 100644 (file)
@@ -6,6 +6,7 @@
 #include <linux/i2c.h>
 #include <linux/init.h>
 #include <linux/leds.h>
+#include <linux/log2.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/of.h>
@@ -114,6 +115,9 @@ struct lm3692x_led {
        struct regulator *regulator;
        int led_enable;
        int model_id;
+
+       u8 boost_ctrl, brightness_ctrl;
+       bool enabled;
 };
 
 static const struct reg_default lm3692x_reg_defs[] = {
@@ -162,44 +166,14 @@ static int lm3692x_fault_check(struct lm3692x_led *led)
        return read_buf;
 }
 
-static int lm3692x_brightness_set(struct led_classdev *led_cdev,
-                               enum led_brightness brt_val)
-{
-       struct lm3692x_led *led =
-                       container_of(led_cdev, struct lm3692x_led, led_dev);
-       int ret;
-       int led_brightness_lsb = (brt_val >> 5);
-
-       mutex_lock(&led->lock);
-
-       ret = lm3692x_fault_check(led);
-       if (ret) {
-               dev_err(&led->client->dev, "Cannot read/clear faults: %d\n",
-                       ret);
-               goto out;
-       }
-
-       ret = regmap_write(led->regmap, LM3692X_BRT_MSB, brt_val);
-       if (ret) {
-               dev_err(&led->client->dev, "Cannot write MSB: %d\n", ret);
-               goto out;
-       }
-
-       ret = regmap_write(led->regmap, LM3692X_BRT_LSB, led_brightness_lsb);
-       if (ret) {
-               dev_err(&led->client->dev, "Cannot write LSB: %d\n", ret);
-               goto out;
-       }
-out:
-       mutex_unlock(&led->lock);
-       return ret;
-}
-
-static int lm3692x_init(struct lm3692x_led *led)
+static int lm3692x_leds_enable(struct lm3692x_led *led)
 {
        int enable_state;
        int ret, reg_ret;
 
+       if (led->enabled)
+               return 0;
+
        if (led->regulator) {
                ret = regulator_enable(led->regulator);
                if (ret) {
@@ -249,10 +223,7 @@ static int lm3692x_init(struct lm3692x_led *led)
        if (ret)
                goto out;
 
-       ret = regmap_write(led->regmap, LM3692X_BOOST_CTRL,
-                       LM3692X_BOOST_SW_1MHZ |
-                       LM3692X_BOOST_SW_NO_SHIFT |
-                       LM3692X_OCP_PROT_1_5A);
+       ret = regmap_write(led->regmap, LM3692X_BOOST_CTRL, led->boost_ctrl);
        if (ret)
                goto out;
 
@@ -305,6 +276,7 @@ static int lm3692x_init(struct lm3692x_led *led)
        ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_ENABLE_MASK,
                                 enable_state | LM3692X_DEVICE_EN);
 
+       led->enabled = true;
        return ret;
 out:
        dev_err(&led->client->dev, "Fail writing initialization values\n");
@@ -322,10 +294,92 @@ out:
        return ret;
 }
 
+static int lm3692x_leds_disable(struct lm3692x_led *led)
+{
+       int ret;
+
+       if (!led->enabled)
+               return 0;
+
+       ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN, 0);
+       if (ret) {
+               dev_err(&led->client->dev, "Failed to disable regulator: %d\n",
+                       ret);
+               return ret;
+       }
+
+       if (led->enable_gpio)
+               gpiod_direction_output(led->enable_gpio, 0);
+
+       if (led->regulator) {
+               ret = regulator_disable(led->regulator);
+               if (ret)
+                       dev_err(&led->client->dev,
+                               "Failed to disable regulator: %d\n", ret);
+       }
+
+       led->enabled = false;
+       return ret;
+}
+
+static int lm3692x_brightness_set(struct led_classdev *led_cdev,
+                               enum led_brightness brt_val)
+{
+       struct lm3692x_led *led =
+                       container_of(led_cdev, struct lm3692x_led, led_dev);
+       int ret;
+       int led_brightness_lsb = (brt_val >> 5);
+
+       mutex_lock(&led->lock);
+
+       if (brt_val == 0) {
+               ret = lm3692x_leds_disable(led);
+               goto out;
+       } else {
+               lm3692x_leds_enable(led);
+       }
+
+       ret = lm3692x_fault_check(led);
+       if (ret) {
+               dev_err(&led->client->dev, "Cannot read/clear faults: %d\n",
+                       ret);
+               goto out;
+       }
+
+       ret = regmap_write(led->regmap, LM3692X_BRT_MSB, brt_val);
+       if (ret) {
+               dev_err(&led->client->dev, "Cannot write MSB: %d\n", ret);
+               goto out;
+       }
+
+       ret = regmap_write(led->regmap, LM3692X_BRT_LSB, led_brightness_lsb);
+       if (ret) {
+               dev_err(&led->client->dev, "Cannot write LSB: %d\n", ret);
+               goto out;
+       }
+out:
+       mutex_unlock(&led->lock);
+       return ret;
+}
+
+static enum led_brightness lm3692x_max_brightness(struct lm3692x_led *led,
+                                                 u32 max_cur)
+{
+       u32 max_code;
+
+       /* see p.12 of LM36922 data sheet for brightness formula */
+       max_code = ((max_cur * 1000) - 37806) / 12195;
+       if (max_code > 0x7FF)
+               max_code = 0x7FF;
+
+       return max_code >> 3;
+}
+
 static int lm3692x_probe_dt(struct lm3692x_led *led)
 {
        struct fwnode_handle *child = NULL;
        struct led_init_data init_data = {};
+       u32 ovp, max_cur;
        int ret;
 
        led->enable_gpio = devm_gpiod_get_optional(&led->client->dev,
@@ -350,6 +404,32 @@ static int lm3692x_probe_dt(struct lm3692x_led *led)
                led->regulator = NULL;
        }
 
+       led->boost_ctrl = LM3692X_BOOST_SW_1MHZ |
+               LM3692X_BOOST_SW_NO_SHIFT |
+               LM3692X_OCP_PROT_1_5A;
+       ret = device_property_read_u32(&led->client->dev,
+                                      "ti,ovp-microvolt", &ovp);
+       if (ret) {
+               led->boost_ctrl |= LM3692X_OVP_29V;
+       } else {
+               switch (ovp) {
+               case 17000000:
+                       break;
+               case 21000000:
+                       led->boost_ctrl |= LM3692X_OVP_21V;
+                       break;
+               case 25000000:
+                       led->boost_ctrl |= LM3692X_OVP_25V;
+                       break;
+               case 29000000:
+                       led->boost_ctrl |= LM3692X_OVP_29V;
+                       break;
+               default:
+                       dev_err(&led->client->dev, "Invalid OVP %d\n", ovp);
+                       return -EINVAL;
+               }
+       }
+
        child = device_get_next_child_node(&led->client->dev, child);
        if (!child) {
                dev_err(&led->client->dev, "No LED Child node\n");
@@ -365,6 +445,10 @@ static int lm3692x_probe_dt(struct lm3692x_led *led)
                return ret;
        }
 
+       ret = fwnode_property_read_u32(child, "led-max-microamp", &max_cur);
+       led->led_dev.max_brightness = ret ? LED_FULL :
+               lm3692x_max_brightness(led, max_cur);
+
        init_data.fwnode = child;
        init_data.devicename = led->client->name;
        init_data.default_label = ":";
@@ -407,7 +491,7 @@ static int lm3692x_probe(struct i2c_client *client,
        if (ret)
                return ret;
 
-       ret = lm3692x_init(led);
+       ret = lm3692x_leds_enable(led);
        if (ret)
                return ret;
 
@@ -419,23 +503,9 @@ static int lm3692x_remove(struct i2c_client *client)
        struct lm3692x_led *led = i2c_get_clientdata(client);
        int ret;
 
-       ret = regmap_update_bits(led->regmap, LM3692X_EN, LM3692X_DEVICE_EN, 0);
-       if (ret) {
-               dev_err(&led->client->dev, "Failed to disable regulator: %d\n",
-                       ret);
+       ret = lm3692x_leds_disable(led);
+       if (ret)
                return ret;
-       }
-
-       if (led->enable_gpio)
-               gpiod_direction_output(led->enable_gpio, 0);
-
-       if (led->regulator) {
-               ret = regulator_disable(led->regulator);
-               if (ret)
-                       dev_err(&led->client->dev,
-                               "Failed to disable regulator: %d\n", ret);
-       }
-
        mutex_destroy(&led->lock);
 
        return 0;
index 4afc317..66cdc00 100644 (file)
@@ -40,6 +40,8 @@
 #define PCA963X_LED_PWM                0x2     /* Controlled through PWM */
 #define PCA963X_LED_GRP_PWM    0x3     /* Controlled through PWM/GRPPWM */
 
+#define PCA963X_MODE2_OUTDRV   0x04    /* Open-drain or totem pole */
+#define PCA963X_MODE2_INVRT    0x10    /* Normal or inverted direction */
 #define PCA963X_MODE2_DMBLNK   0x20    /* Enable blinking */
 
 #define PCA963X_MODE1          0x00
@@ -438,12 +440,12 @@ static int pca963x_probe(struct i2c_client *client,
                                                    PCA963X_MODE2);
                /* Configure output: open-drain or totem pole (push-pull) */
                if (pdata->outdrv == PCA963X_OPEN_DRAIN)
-                       mode2 |= 0x01;
+                       mode2 &= ~PCA963X_MODE2_OUTDRV;
                else
-                       mode2 |= 0x05;
+                       mode2 |= PCA963X_MODE2_OUTDRV;
                /* Configure direction: normal or inverted */
                if (pdata->dir == PCA963X_INVERTED)
-                       mode2 |= 0x10;
+                       mode2 |= PCA963X_MODE2_INVRT;
                i2c_smbus_write_byte_data(pca963x->chip->client, PCA963X_MODE2,
                                          mode2);
        }
diff --git a/drivers/leds/leds-tps6105x.c b/drivers/leds/leds-tps6105x.c
new file mode 100644 (file)
index 0000000..09fd88a
--- /dev/null
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 Sven Van Asbroeck
+ */
+
+#include <linux/leds.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/tps6105x.h>
+#include <linux/regmap.h>
+
+struct tps6105x_priv {
+       struct regmap *regmap;
+       struct led_classdev cdev;
+       struct fwnode_handle *fwnode;
+};
+
+static void tps6105x_handle_put(void *data)
+{
+       struct tps6105x_priv *priv = data;
+
+       fwnode_handle_put(priv->fwnode);
+}
+
+static int tps6105x_brightness_set(struct led_classdev *cdev,
+                                 enum led_brightness brightness)
+{
+       struct tps6105x_priv *priv = container_of(cdev, struct tps6105x_priv,
+                                                       cdev);
+
+       return regmap_update_bits(priv->regmap, TPS6105X_REG_0,
+                                 TPS6105X_REG0_TORCHC_MASK,
+                                 brightness << TPS6105X_REG0_TORCHC_SHIFT);
+}
+
+static int tps6105x_led_probe(struct platform_device *pdev)
+{
+       struct tps6105x *tps6105x = dev_get_platdata(&pdev->dev);
+       struct tps6105x_platform_data *pdata = tps6105x->pdata;
+       struct led_init_data init_data = { };
+       struct tps6105x_priv *priv;
+       int ret;
+
+       /* This instance is not set for torch mode so bail out */
+       if (pdata->mode != TPS6105X_MODE_TORCH) {
+               dev_info(&pdev->dev,
+                       "chip not in torch mode, exit probe");
+               return -EINVAL;
+       }
+
+       priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       /* fwnode/devicetree is optional. NULL is allowed for priv->fwnode */
+       priv->fwnode = device_get_next_child_node(pdev->dev.parent, NULL);
+       ret = devm_add_action_or_reset(&pdev->dev, tps6105x_handle_put, priv);
+       if (ret)
+               return ret;
+       priv->regmap = tps6105x->regmap;
+       priv->cdev.brightness_set_blocking = tps6105x_brightness_set;
+       priv->cdev.max_brightness = 7;
+       init_data.devicename = "tps6105x";
+       init_data.default_label = ":torch";
+       init_data.fwnode = priv->fwnode;
+
+       ret = regmap_update_bits(tps6105x->regmap, TPS6105X_REG_0,
+                                TPS6105X_REG0_MODE_MASK |
+                                       TPS6105X_REG0_TORCHC_MASK,
+                                TPS6105X_REG0_MODE_TORCH <<
+                                       TPS6105X_REG0_MODE_SHIFT);
+       if (ret)
+               return ret;
+
+       return devm_led_classdev_register_ext(&pdev->dev, &priv->cdev,
+                                             &init_data);
+}
+
+static struct platform_driver led_driver = {
+       .probe = tps6105x_led_probe,
+       .driver = {
+               .name = "tps6105x-leds",
+       },
+};
+
+module_platform_driver(led_driver);
+
+MODULE_DESCRIPTION("TPS6105x LED driver");
+MODULE_AUTHOR("Sven Van Asbroeck <TheSven73@gmail.com>");
+MODULE_LICENSE("GPL v2");
index 574e122..cbd46c1 100644 (file)
@@ -178,7 +178,7 @@ config THERM_ADT746X
        depends on I2C && I2C_POWERMAC && PPC_PMAC && !PPC_PMAC64
        help
          This driver provides some thermostat and fan control for the
-          iBook G4, and the ATI based aluminium PowerBooks, allowing slightly
+         iBook G4, and the ATI based aluminium PowerBooks, allowing slightly
          better fan behaviour by default, and some manual control.
 
 config WINDFARM
@@ -214,7 +214,7 @@ config WINDFARM_PM91
        select I2C_POWERMAC
        help
          This driver provides thermal control for the PowerMac9,1
-          which is the recent (SMU based) single CPU desktop G5
+         which is the recent (SMU based) single CPU desktop G5
 
 config WINDFARM_PM112
        tristate "Support for thermal management on PowerMac11,2"
@@ -242,7 +242,7 @@ config PMAC_RACKMETER
        depends on PPC_PMAC
        help
          This driver provides some support to control the front panel
-          blue LEDs "vu-meter" of the XServer macs.
+         blue LEDs "vu-meter" of the XServer macs.
 
 config SENSORS_AMS
        tristate "Apple Motion Sensor driver"
index 21d532a..d38fb78 100644 (file)
@@ -212,7 +212,7 @@ static int pmu_info_proc_show(struct seq_file *m, void *v);
 static int pmu_irqstats_proc_show(struct seq_file *m, void *v);
 static int pmu_battery_proc_show(struct seq_file *m, void *v);
 static void pmu_pass_intr(unsigned char *data, int len);
-static const struct file_operations pmu_options_proc_fops;
+static const struct proc_ops pmu_options_proc_ops;
 
 #ifdef CONFIG_ADB
 const struct adb_driver via_pmu_driver = {
@@ -573,7 +573,7 @@ static int __init via_pmu_dev_init(void)
                proc_pmu_irqstats = proc_create_single("interrupts", 0,
                                proc_pmu_root, pmu_irqstats_proc_show);
                proc_pmu_options = proc_create("options", 0600, proc_pmu_root,
-                                               &pmu_options_proc_fops);
+                                               &pmu_options_proc_ops);
        }
        return 0;
 }
@@ -974,13 +974,12 @@ static ssize_t pmu_options_proc_write(struct file *file,
        return fcount;
 }
 
-static const struct file_operations pmu_options_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = pmu_options_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = pmu_options_proc_write,
+static const struct proc_ops pmu_options_proc_ops = {
+       .proc_open      = pmu_options_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = pmu_options_proc_write,
 };
 
 #ifdef CONFIG_ADB
index 19f0867..02b7b28 100644 (file)
@@ -143,7 +143,6 @@ static const struct mbox_chan_ops a37xx_mbox_ops = {
 static int armada_37xx_mbox_probe(struct platform_device *pdev)
 {
        struct a37xx_mbox *mbox;
-       struct resource *regs;
        struct mbox_chan *chans;
        int ret;
 
@@ -156,9 +155,7 @@ static int armada_37xx_mbox_probe(struct platform_device *pdev)
        if (!chans)
                return -ENOMEM;
 
-       regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-
-       mbox->base = devm_ioremap_resource(&pdev->dev, regs);
+       mbox->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(mbox->base)) {
                dev_err(&pdev->dev, "ioremap failed\n");
                return PTR_ERR(mbox->base);
index adf26a2..74a9849 100644 (file)
@@ -330,6 +330,9 @@ struct cached_dev {
         */
        atomic_t                has_dirty;
 
+#define BCH_CACHE_READA_ALL            0
+#define BCH_CACHE_READA_META_ONLY      1
+       unsigned int            cache_readahead_policy;
        struct bch_ratelimit    writeback_rate;
        struct delayed_work     writeback_rate_update;
 
index c71365e..a50dcfd 100644 (file)
@@ -397,7 +397,8 @@ void bch_btree_keys_stats(struct btree_keys *b, struct bset_stats *state);
 
 /* Bkey utility code */
 
-#define bset_bkey_last(i)      bkey_idx((struct bkey *) (i)->d, (i)->keys)
+#define bset_bkey_last(i)      bkey_idx((struct bkey *) (i)->d, \
+                                        (unsigned int)(i)->keys)
 
 static inline struct bkey *bset_bkey_idx(struct bset *i, unsigned int idx)
 {
index 33ddc52..6730820 100644 (file)
@@ -422,7 +422,8 @@ err:
 static void btree_flush_write(struct cache_set *c)
 {
        struct btree *b, *t, *btree_nodes[BTREE_FLUSH_NR];
-       unsigned int i, nr, ref_nr;
+       unsigned int i, nr;
+       int ref_nr;
        atomic_t *fifo_front_p, *now_fifo_front_p;
        size_t mask;
 
index 73478a9..820d840 100644 (file)
@@ -379,13 +379,20 @@ static bool check_should_bypass(struct cached_dev *dc, struct bio *bio)
                goto skip;
 
        /*
-        * Flag for bypass if the IO is for read-ahead or background,
-        * unless the read-ahead request is for metadata
+        * If the bio is for read-ahead or background IO, bypass it or
+        * not depends on the following situations,
+        * - If the IO is for meta data, always cache it and no bypass
+        * - If the IO is not meta data, check dc->cache_reada_policy,
+        *      BCH_CACHE_READA_ALL: cache it and not bypass
+        *      BCH_CACHE_READA_META_ONLY: not cache it and bypass
+        * That is, read-ahead request for metadata always get cached
         * (eg, for gfs2 or xfs).
         */
-       if (bio->bi_opf & (REQ_RAHEAD|REQ_BACKGROUND) &&
-           !(bio->bi_opf & (REQ_META|REQ_PRIO)))
-               goto skip;
+       if ((bio->bi_opf & (REQ_RAHEAD|REQ_BACKGROUND))) {
+               if (!(bio->bi_opf & (REQ_META|REQ_PRIO)) &&
+                   (dc->cache_readahead_policy != BCH_CACHE_READA_ALL))
+                       goto skip;
+       }
 
        if (bio->bi_iter.bi_sector & (c->sb.block_size - 1) ||
            bio_sectors(bio) & (c->sb.block_size - 1)) {
index ba1c937..503aafe 100644 (file)
@@ -109,9 +109,13 @@ int bch_cache_accounting_add_kobjs(struct cache_accounting *acc,
 
 void bch_cache_accounting_clear(struct cache_accounting *acc)
 {
-       memset(&acc->total.cache_hits,
-              0,
-              sizeof(struct cache_stats));
+       acc->total.cache_hits = 0;
+       acc->total.cache_misses = 0;
+       acc->total.cache_bypass_hits = 0;
+       acc->total.cache_bypass_misses = 0;
+       acc->total.cache_readaheads = 0;
+       acc->total.cache_miss_collisions = 0;
+       acc->total.sectors_bypassed = 0;
 }
 
 void bch_cache_accounting_destroy(struct cache_accounting *acc)
index 3dea1d5..2749daf 100644 (file)
@@ -609,12 +609,13 @@ int bch_prio_write(struct cache *ca, bool wait)
        return 0;
 }
 
-static void prio_read(struct cache *ca, uint64_t bucket)
+static int prio_read(struct cache *ca, uint64_t bucket)
 {
        struct prio_set *p = ca->disk_buckets;
        struct bucket_disk *d = p->data + prios_per_bucket(ca), *end = d;
        struct bucket *b;
        unsigned int bucket_nr = 0;
+       int ret = -EIO;
 
        for (b = ca->buckets;
             b < ca->buckets + ca->sb.nbuckets;
@@ -627,11 +628,15 @@ static void prio_read(struct cache *ca, uint64_t bucket)
                        prio_io(ca, bucket, REQ_OP_READ, 0);
 
                        if (p->csum !=
-                           bch_crc64(&p->magic, bucket_bytes(ca) - 8))
+                           bch_crc64(&p->magic, bucket_bytes(ca) - 8)) {
                                pr_warn("bad csum reading priorities");
+                               goto out;
+                       }
 
-                       if (p->magic != pset_magic(&ca->sb))
+                       if (p->magic != pset_magic(&ca->sb)) {
                                pr_warn("bad magic reading priorities");
+                               goto out;
+                       }
 
                        bucket = p->next_bucket;
                        d = p->data;
@@ -640,6 +645,10 @@ static void prio_read(struct cache *ca, uint64_t bucket)
                b->prio = le16_to_cpu(d->prio);
                b->gen = b->last_gc = d->gen;
        }
+
+       ret = 0;
+out:
+       return ret;
 }
 
 /* Bcache device */
@@ -1873,8 +1882,10 @@ static int run_cache_set(struct cache_set *c)
                j = &list_entry(journal.prev, struct journal_replay, list)->j;
 
                err = "IO error reading priorities";
-               for_each_cache(ca, c, i)
-                       prio_read(ca, j->prio_bucket[ca->sb.nr_this_dev]);
+               for_each_cache(ca, c, i) {
+                       if (prio_read(ca, j->prio_bucket[ca->sb.nr_this_dev]))
+                               goto err;
+               }
 
                /*
                 * If prio_read() fails it'll call cache_set_error and we'll
index 733e2dd..3470fae 100644 (file)
@@ -27,6 +27,12 @@ static const char * const bch_cache_modes[] = {
        NULL
 };
 
+static const char * const bch_reada_cache_policies[] = {
+       "all",
+       "meta-only",
+       NULL
+};
+
 /* Default is 0 ("auto") */
 static const char * const bch_stop_on_failure_modes[] = {
        "auto",
@@ -100,6 +106,7 @@ rw_attribute(congested_write_threshold_us);
 rw_attribute(sequential_cutoff);
 rw_attribute(data_csum);
 rw_attribute(cache_mode);
+rw_attribute(readahead_cache_policy);
 rw_attribute(stop_when_cache_set_failed);
 rw_attribute(writeback_metadata);
 rw_attribute(writeback_running);
@@ -168,6 +175,11 @@ SHOW(__bch_cached_dev)
                                               bch_cache_modes,
                                               BDEV_CACHE_MODE(&dc->sb));
 
+       if (attr == &sysfs_readahead_cache_policy)
+               return bch_snprint_string_list(buf, PAGE_SIZE,
+                                             bch_reada_cache_policies,
+                                             dc->cache_readahead_policy);
+
        if (attr == &sysfs_stop_when_cache_set_failed)
                return bch_snprint_string_list(buf, PAGE_SIZE,
                                               bch_stop_on_failure_modes,
@@ -353,6 +365,15 @@ STORE(__cached_dev)
                }
        }
 
+       if (attr == &sysfs_readahead_cache_policy) {
+               v = __sysfs_match_string(bch_reada_cache_policies, -1, buf);
+               if (v < 0)
+                       return v;
+
+               if ((unsigned int) v != dc->cache_readahead_policy)
+                       dc->cache_readahead_policy = v;
+       }
+
        if (attr == &sysfs_stop_when_cache_set_failed) {
                v = __sysfs_match_string(bch_stop_on_failure_modes, -1, buf);
                if (v < 0)
@@ -467,6 +488,7 @@ static struct attribute *bch_cached_dev_files[] = {
        &sysfs_data_csum,
 #endif
        &sysfs_cache_mode,
+       &sysfs_readahead_cache_policy,
        &sysfs_stop_when_cache_set_failed,
        &sysfs_writeback_metadata,
        &sysfs_writeback_running,
index e230052..b952bd4 100644 (file)
@@ -364,7 +364,7 @@ static int read_page(struct file *file, unsigned long index,
        int ret = 0;
        struct inode *inode = file_inode(file);
        struct buffer_head *bh;
-       sector_t block;
+       sector_t block, blk_cur;
 
        pr_debug("read bitmap file (%dB @ %llu)\n", (int)PAGE_SIZE,
                 (unsigned long long)index << PAGE_SHIFT);
@@ -375,17 +375,21 @@ static int read_page(struct file *file, unsigned long index,
                goto out;
        }
        attach_page_buffers(page, bh);
-       block = index << (PAGE_SHIFT - inode->i_blkbits);
+       blk_cur = index << (PAGE_SHIFT - inode->i_blkbits);
        while (bh) {
+               block = blk_cur;
+
                if (count == 0)
                        bh->b_blocknr = 0;
                else {
-                       bh->b_blocknr = bmap(inode, block);
-                       if (bh->b_blocknr == 0) {
-                               /* Cannot use this file! */
+                       ret = bmap(inode, &block);
+                       if (ret || !block) {
                                ret = -EINVAL;
+                               bh->b_blocknr = 0;
                                goto out;
                        }
+
+                       bh->b_blocknr = block;
                        bh->b_bdev = inode->i_sb->s_bdev;
                        if (count < (1<<inode->i_blkbits))
                                count = 0;
@@ -399,7 +403,7 @@ static int read_page(struct file *file, unsigned long index,
                        set_buffer_mapped(bh);
                        submit_bh(REQ_OP_READ, 0, bh);
                }
-               block++;
+               blk_cur++;
                bh = bh->b_this_page;
        }
        page->index = index;
index 4824d50..469f551 100644 (file)
@@ -8279,13 +8279,12 @@ static __poll_t mdstat_poll(struct file *filp, poll_table *wait)
        return mask;
 }
 
-static const struct file_operations md_seq_fops = {
-       .owner          = THIS_MODULE,
-       .open           = md_seq_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-       .poll           = mdstat_poll,
+static const struct proc_ops mdstat_proc_ops = {
+       .proc_open      = md_seq_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
+       .proc_poll      = mdstat_poll,
 };
 
 int register_md_personality(struct md_personality *p)
@@ -9454,7 +9453,7 @@ static void md_geninit(void)
 {
        pr_debug("md: sizeof(mdp_super_t) = %d\n", (int)sizeof(mdp_super_t));
 
-       proc_create("mdstat", S_IRUGO, NULL, &md_seq_fops);
+       proc_create("mdstat", S_IRUGO, NULL, &mdstat_proc_ops);
 }
 
 static int __init md_init(void)
index f048e89..0e7e277 100644 (file)
@@ -14,7 +14,6 @@
 #include <linux/cec.h>
 #include <linux/slab.h>
 #include <linux/interrupt.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
 #include <media/cec.h>
index 095f8a3..886aea5 100644 (file)
@@ -267,7 +267,6 @@ static int mvebu_devbus_probe(struct platform_device *pdev)
        struct devbus_read_params r;
        struct devbus_write_params w;
        struct devbus *devbus;
-       struct resource *res;
        struct clk *clk;
        unsigned long rate;
        int err;
@@ -277,8 +276,7 @@ static int mvebu_devbus_probe(struct platform_device *pdev)
                return -ENOMEM;
 
        devbus->dev = dev;
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       devbus->base = devm_ioremap_resource(&pdev->dev, res);
+       devbus->base = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(devbus->base))
                return PTR_ERR(devbus->base);
 
index e9c3ce9..20a8406 100644 (file)
@@ -8,7 +8,7 @@ config SAMSUNG_MC
 if SAMSUNG_MC
 
 config EXYNOS5422_DMC
-       tristate "EXYNOS5422 Dynamic Memory Controller driver"
+       tristate "Exynos5422 Dynamic Memory Controller driver"
        depends on ARCH_EXYNOS || (COMPILE_TEST && HAS_IOMEM)
        select DDR
        depends on DEVFREQ_GOV_SIMPLE_ONDEMAND
index c27c610..6510d7b 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2015 Samsung Electronics Co., Ltd.
 //           http://www.samsung.com/
 //
-// EXYNOS - SROM Controller support
+// Exynos - SROM Controller support
 // Author: Pankaj Dubey <pankaj.dubey@samsung.com>
 
 #include <linux/io.h>
index 47dbf6d..81a1b1d 100644 (file)
@@ -1374,7 +1374,6 @@ static int exynos5_dmc_probe(struct platform_device *pdev)
        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);
@@ -1386,13 +1385,11 @@ static int exynos5_dmc_probe(struct platform_device *pdev)
        dmc->dev = dev;
        platform_set_drvdata(pdev, dmc);
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       dmc->base_drexi0 = devm_ioremap_resource(dev, res);
+       dmc->base_drexi0 = devm_platform_ioremap_resource(pdev, 0);
        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);
+       dmc->base_drexi1 = devm_platform_ioremap_resource(pdev, 1);
        if (IS_ERR(dmc->base_drexi1))
                return PTR_ERR(dmc->base_drexi1);
 
index 3d23c42..529d10b 100644 (file)
@@ -13,4 +13,5 @@ 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
+obj-$(CONFIG_ARCH_TEGRA_186_SOC) += tegra186.o tegra186-emc.o
+obj-$(CONFIG_ARCH_TEGRA_194_SOC) += tegra186.o tegra186-emc.o
index 464f0ce..21f0524 100644 (file)
@@ -467,12 +467,20 @@ struct tegra_emc {
 
        void __iomem *regs;
 
+       struct clk *clk;
+
        enum emc_dram_type dram_type;
        unsigned int dram_num;
 
        struct emc_timing last_timing;
        struct emc_timing *timings;
        unsigned int num_timings;
+
+       struct {
+               struct dentry *root;
+               unsigned long min_rate;
+               unsigned long max_rate;
+       } debugfs;
 };
 
 /* Timing change sequence functions */
@@ -998,38 +1006,51 @@ tegra_emc_find_node_by_ram_code(struct device_node *node, u32 ram_code)
        return NULL;
 }
 
-/* Debugfs entry */
+/*
+ * debugfs interface
+ *
+ * The memory controller driver exposes some files in debugfs that can be used
+ * to control the EMC frequency. The top-level directory can be found here:
+ *
+ *   /sys/kernel/debug/emc
+ *
+ * It contains the following files:
+ *
+ *   - available_rates: This file contains a list of valid, space-separated
+ *     EMC frequencies.
+ *
+ *   - min_rate: Writing a value to this file sets the given frequency as the
+ *       floor of the permitted range. If this is higher than the currently
+ *       configured EMC frequency, this will cause the frequency to be
+ *       increased so that it stays within the valid range.
+ *
+ *   - max_rate: Similarily to the min_rate file, writing a value to this file
+ *       sets the given frequency as the ceiling of the permitted range. If
+ *       the value is lower than the currently configured EMC frequency, this
+ *       will cause the frequency to be decreased so that it stays within the
+ *       valid range.
+ */
 
-static int emc_debug_rate_get(void *data, u64 *rate)
+static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate)
 {
-       struct clk *c = data;
-
-       *rate = clk_get_rate(c);
-
-       return 0;
-}
+       unsigned int i;
 
-static int emc_debug_rate_set(void *data, u64 rate)
-{
-       struct clk *c = data;
+       for (i = 0; i < emc->num_timings; i++)
+               if (rate == emc->timings[i].rate)
+                       return true;
 
-       return clk_set_rate(c, rate);
+       return false;
 }
 
-DEFINE_SIMPLE_ATTRIBUTE(emc_debug_rate_fops, emc_debug_rate_get,
-                       emc_debug_rate_set, "%lld\n");
-
-static int emc_debug_supported_rates_show(struct seq_file *s, void *data)
+static int tegra_emc_debug_available_rates_show(struct seq_file *s,
+                                               void *data)
 {
        struct tegra_emc *emc = s->private;
        const char *prefix = "";
        unsigned int i;
 
        for (i = 0; i < emc->num_timings; i++) {
-               struct emc_timing *timing = &emc->timings[i];
-
-               seq_printf(s, "%s%lu", prefix, timing->rate);
-
+               seq_printf(s, "%s%lu", prefix, emc->timings[i].rate);
                prefix = " ";
        }
 
@@ -1038,46 +1059,126 @@ static int emc_debug_supported_rates_show(struct seq_file *s, void *data)
        return 0;
 }
 
-static int emc_debug_supported_rates_open(struct inode *inode,
-                                         struct file *file)
+static int tegra_emc_debug_available_rates_open(struct inode *inode,
+                                               struct file *file)
 {
-       return single_open(file, emc_debug_supported_rates_show,
+       return single_open(file, tegra_emc_debug_available_rates_show,
                           inode->i_private);
 }
 
-static const struct file_operations emc_debug_supported_rates_fops = {
-       .open = emc_debug_supported_rates_open,
+static const struct file_operations tegra_emc_debug_available_rates_fops = {
+       .open = tegra_emc_debug_available_rates_open,
        .read = seq_read,
        .llseek = seq_lseek,
        .release = single_release,
 };
 
+static int tegra_emc_debug_min_rate_get(void *data, u64 *rate)
+{
+       struct tegra_emc *emc = data;
+
+       *rate = emc->debugfs.min_rate;
+
+       return 0;
+}
+
+static int tegra_emc_debug_min_rate_set(void *data, u64 rate)
+{
+       struct tegra_emc *emc = data;
+       int err;
+
+       if (!tegra_emc_validate_rate(emc, rate))
+               return -EINVAL;
+
+       err = clk_set_min_rate(emc->clk, rate);
+       if (err < 0)
+               return err;
+
+       emc->debugfs.min_rate = rate;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_min_rate_fops,
+                       tegra_emc_debug_min_rate_get,
+                       tegra_emc_debug_min_rate_set, "%llu\n");
+
+static int tegra_emc_debug_max_rate_get(void *data, u64 *rate)
+{
+       struct tegra_emc *emc = data;
+
+       *rate = emc->debugfs.max_rate;
+
+       return 0;
+}
+
+static int tegra_emc_debug_max_rate_set(void *data, u64 rate)
+{
+       struct tegra_emc *emc = data;
+       int err;
+
+       if (!tegra_emc_validate_rate(emc, rate))
+               return -EINVAL;
+
+       err = clk_set_max_rate(emc->clk, rate);
+       if (err < 0)
+               return err;
+
+       emc->debugfs.max_rate = rate;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_max_rate_fops,
+                       tegra_emc_debug_max_rate_get,
+                       tegra_emc_debug_max_rate_set, "%llu\n");
+
 static void emc_debugfs_init(struct device *dev, struct tegra_emc *emc)
 {
-       struct dentry *root, *file;
-       struct clk *clk;
+       unsigned int i;
+       int err;
 
-       root = debugfs_create_dir("emc", NULL);
-       if (!root) {
-               dev_err(dev, "failed to create debugfs directory\n");
-               return;
+       emc->clk = devm_clk_get(dev, "emc");
+       if (IS_ERR(emc->clk)) {
+               if (PTR_ERR(emc->clk) != -ENODEV) {
+                       dev_err(dev, "failed to get EMC clock: %ld\n",
+                               PTR_ERR(emc->clk));
+                       return;
+               }
        }
 
-       clk = clk_get_sys("tegra-clk-debug", "emc");
-       if (IS_ERR(clk)) {
-               dev_err(dev, "failed to get debug clock: %ld\n", PTR_ERR(clk));
+       emc->debugfs.min_rate = ULONG_MAX;
+       emc->debugfs.max_rate = 0;
+
+       for (i = 0; i < emc->num_timings; i++) {
+               if (emc->timings[i].rate < emc->debugfs.min_rate)
+                       emc->debugfs.min_rate = emc->timings[i].rate;
+
+               if (emc->timings[i].rate > emc->debugfs.max_rate)
+                       emc->debugfs.max_rate = emc->timings[i].rate;
+       }
+
+       err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
+                                emc->debugfs.max_rate);
+       if (err < 0) {
+               dev_err(dev, "failed to set rate range [%lu-%lu] for %pC\n",
+                       emc->debugfs.min_rate, emc->debugfs.max_rate,
+                       emc->clk);
                return;
        }
 
-       file = debugfs_create_file("rate", S_IRUGO | S_IWUSR, root, clk,
-                                  &emc_debug_rate_fops);
-       if (!file)
-               dev_err(dev, "failed to create debugfs entry\n");
+       emc->debugfs.root = debugfs_create_dir("emc", NULL);
+       if (!emc->debugfs.root) {
+               dev_err(dev, "failed to create debugfs directory\n");
+               return;
+       }
 
-       file = debugfs_create_file("supported_rates", S_IRUGO, root, emc,
-                                  &emc_debug_supported_rates_fops);
-       if (!file)
-               dev_err(dev, "failed to create debugfs entry\n");
+       debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root, emc,
+                           &tegra_emc_debug_available_rates_fops);
+       debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+                           emc, &tegra_emc_debug_min_rate_fops);
+       debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+                           emc, &tegra_emc_debug_max_rate_fops);
 }
 
 static int tegra_emc_probe(struct platform_device *pdev)
diff --git a/drivers/memory/tegra/tegra186-emc.c b/drivers/memory/tegra/tegra186-emc.c
new file mode 100644 (file)
index 0000000..97f26bc
--- /dev/null
@@ -0,0 +1,293 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2019 NVIDIA CORPORATION.  All rights reserved.
+ */
+
+#include <linux/clk.h>
+#include <linux/debugfs.h>
+#include <linux/module.h>
+#include <linux/mod_devicetable.h>
+#include <linux/platform_device.h>
+
+#include <soc/tegra/bpmp.h>
+
+struct tegra186_emc_dvfs {
+       unsigned long latency;
+       unsigned long rate;
+};
+
+struct tegra186_emc {
+       struct tegra_bpmp *bpmp;
+       struct device *dev;
+       struct clk *clk;
+
+       struct tegra186_emc_dvfs *dvfs;
+       unsigned int num_dvfs;
+
+       struct {
+               struct dentry *root;
+               unsigned long min_rate;
+               unsigned long max_rate;
+       } debugfs;
+};
+
+/*
+ * debugfs interface
+ *
+ * The memory controller driver exposes some files in debugfs that can be used
+ * to control the EMC frequency. The top-level directory can be found here:
+ *
+ *   /sys/kernel/debug/emc
+ *
+ * It contains the following files:
+ *
+ *   - available_rates: This file contains a list of valid, space-separated
+ *     EMC frequencies.
+ *
+ *   - min_rate: Writing a value to this file sets the given frequency as the
+ *       floor of the permitted range. If this is higher than the currently
+ *       configured EMC frequency, this will cause the frequency to be
+ *       increased so that it stays within the valid range.
+ *
+ *   - max_rate: Similarily to the min_rate file, writing a value to this file
+ *       sets the given frequency as the ceiling of the permitted range. If
+ *       the value is lower than the currently configured EMC frequency, this
+ *       will cause the frequency to be decreased so that it stays within the
+ *       valid range.
+ */
+
+static bool tegra186_emc_validate_rate(struct tegra186_emc *emc,
+                                      unsigned long rate)
+{
+       unsigned int i;
+
+       for (i = 0; i < emc->num_dvfs; i++)
+               if (rate == emc->dvfs[i].rate)
+                       return true;
+
+       return false;
+}
+
+static int tegra186_emc_debug_available_rates_show(struct seq_file *s,
+                                                  void *data)
+{
+       struct tegra186_emc *emc = s->private;
+       const char *prefix = "";
+       unsigned int i;
+
+       for (i = 0; i < emc->num_dvfs; i++) {
+               seq_printf(s, "%s%lu", prefix, emc->dvfs[i].rate);
+               prefix = " ";
+       }
+
+       seq_puts(s, "\n");
+
+       return 0;
+}
+
+static int tegra186_emc_debug_available_rates_open(struct inode *inode,
+                                                  struct file *file)
+{
+       return single_open(file, tegra186_emc_debug_available_rates_show,
+                          inode->i_private);
+}
+
+static const struct file_operations tegra186_emc_debug_available_rates_fops = {
+       .open = tegra186_emc_debug_available_rates_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int tegra186_emc_debug_min_rate_get(void *data, u64 *rate)
+{
+       struct tegra186_emc *emc = data;
+
+       *rate = emc->debugfs.min_rate;
+
+       return 0;
+}
+
+static int tegra186_emc_debug_min_rate_set(void *data, u64 rate)
+{
+       struct tegra186_emc *emc = data;
+       int err;
+
+       if (!tegra186_emc_validate_rate(emc, rate))
+               return -EINVAL;
+
+       err = clk_set_min_rate(emc->clk, rate);
+       if (err < 0)
+               return err;
+
+       emc->debugfs.min_rate = rate;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra186_emc_debug_min_rate_fops,
+                       tegra186_emc_debug_min_rate_get,
+                       tegra186_emc_debug_min_rate_set, "%llu\n");
+
+static int tegra186_emc_debug_max_rate_get(void *data, u64 *rate)
+{
+       struct tegra186_emc *emc = data;
+
+       *rate = emc->debugfs.max_rate;
+
+       return 0;
+}
+
+static int tegra186_emc_debug_max_rate_set(void *data, u64 rate)
+{
+       struct tegra186_emc *emc = data;
+       int err;
+
+       if (!tegra186_emc_validate_rate(emc, rate))
+               return -EINVAL;
+
+       err = clk_set_max_rate(emc->clk, rate);
+       if (err < 0)
+               return err;
+
+       emc->debugfs.max_rate = rate;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra186_emc_debug_max_rate_fops,
+                       tegra186_emc_debug_max_rate_get,
+                       tegra186_emc_debug_max_rate_set, "%llu\n");
+
+static int tegra186_emc_probe(struct platform_device *pdev)
+{
+       struct mrq_emc_dvfs_latency_response response;
+       struct tegra_bpmp_message msg;
+       struct tegra186_emc *emc;
+       unsigned int i;
+       int err;
+
+       emc = devm_kzalloc(&pdev->dev, sizeof(*emc), GFP_KERNEL);
+       if (!emc)
+               return -ENOMEM;
+
+       emc->bpmp = tegra_bpmp_get(&pdev->dev);
+       if (IS_ERR(emc->bpmp)) {
+               err = PTR_ERR(emc->bpmp);
+
+               if (err != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "failed to get BPMP: %d\n", err);
+
+               return err;
+       }
+
+       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;
+       }
+
+       platform_set_drvdata(pdev, emc);
+       emc->dev = &pdev->dev;
+
+       memset(&msg, 0, sizeof(msg));
+       msg.mrq = MRQ_EMC_DVFS_LATENCY;
+       msg.tx.data = NULL;
+       msg.tx.size = 0;
+       msg.rx.data = &response;
+       msg.rx.size = sizeof(response);
+
+       err = tegra_bpmp_transfer(emc->bpmp, &msg);
+       if (err < 0) {
+               dev_err(&pdev->dev, "failed to EMC DVFS pairs: %d\n", err);
+               return err;
+       }
+
+       emc->debugfs.min_rate = ULONG_MAX;
+       emc->debugfs.max_rate = 0;
+
+       emc->num_dvfs = response.num_pairs;
+
+       emc->dvfs = devm_kmalloc_array(&pdev->dev, emc->num_dvfs,
+                                      sizeof(*emc->dvfs), GFP_KERNEL);
+       if (!emc->dvfs)
+               return -ENOMEM;
+
+       dev_dbg(&pdev->dev, "%u DVFS pairs:\n", emc->num_dvfs);
+
+       for (i = 0; i < emc->num_dvfs; i++) {
+               emc->dvfs[i].rate = response.pairs[i].freq * 1000;
+               emc->dvfs[i].latency = response.pairs[i].latency;
+
+               if (emc->dvfs[i].rate < emc->debugfs.min_rate)
+                       emc->debugfs.min_rate = emc->dvfs[i].rate;
+
+               if (emc->dvfs[i].rate > emc->debugfs.max_rate)
+                       emc->debugfs.max_rate = emc->dvfs[i].rate;
+
+               dev_dbg(&pdev->dev, "  %2u: %lu Hz -> %lu us\n", i,
+                       emc->dvfs[i].rate, emc->dvfs[i].latency);
+       }
+
+       err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
+                                emc->debugfs.max_rate);
+       if (err < 0) {
+               dev_err(&pdev->dev,
+                       "failed to set rate range [%lu-%lu] for %pC\n",
+                       emc->debugfs.min_rate, emc->debugfs.max_rate,
+                       emc->clk);
+               return err;
+       }
+
+       emc->debugfs.root = debugfs_create_dir("emc", NULL);
+       if (!emc->debugfs.root) {
+               dev_err(&pdev->dev, "failed to create debugfs directory\n");
+               return 0;
+       }
+
+       debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root,
+                           emc, &tegra186_emc_debug_available_rates_fops);
+       debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+                           emc, &tegra186_emc_debug_min_rate_fops);
+       debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+                           emc, &tegra186_emc_debug_max_rate_fops);
+
+       return 0;
+}
+
+static int tegra186_emc_remove(struct platform_device *pdev)
+{
+       struct tegra186_emc *emc = platform_get_drvdata(pdev);
+
+       debugfs_remove_recursive(emc->debugfs.root);
+       tegra_bpmp_put(emc->bpmp);
+
+       return 0;
+}
+
+static const struct of_device_id tegra186_emc_of_match[] = {
+#if defined(CONFIG_ARCH_TEGRA186_SOC)
+       { .compatible = "nvidia,tegra186-emc" },
+#endif
+#if defined(CONFIG_ARCH_TEGRA194_SOC)
+       { .compatible = "nvidia,tegra194-emc" },
+#endif
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tegra186_emc_of_match);
+
+static struct platform_driver tegra186_emc_driver = {
+       .driver = {
+               .name = "tegra186-emc",
+               .of_match_table = tegra186_emc_of_match,
+               .suppress_bind_attrs = true,
+       },
+       .probe = tegra186_emc_probe,
+       .remove = tegra186_emc_remove,
+};
+module_platform_driver(tegra186_emc_driver);
+
+MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
+MODULE_DESCRIPTION("NVIDIA Tegra186 External Memory Controller driver");
+MODULE_LICENSE("GPL v2");
index 441213a..5d53f11 100644 (file)
@@ -6,16 +6,18 @@
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
 
+#if defined(CONFIG_ARCH_TEGRA_186_SOC)
 #include <dt-bindings/memory/tegra186-mc.h>
+#endif
 
-struct tegra_mc {
-       struct device *dev;
-       void __iomem *regs;
-};
+#if defined(CONFIG_ARCH_TEGRA_194_SOC)
+#include <dt-bindings/memory/tegra194-mc.h>
+#endif
 
-struct tegra_mc_client {
+struct tegra186_mc_client {
        const char *name;
        unsigned int sid;
        struct {
@@ -24,7 +26,46 @@ struct tegra_mc_client {
        } regs;
 };
 
-static const struct tegra_mc_client tegra186_mc_clients[] = {
+struct tegra186_mc_soc {
+       const struct tegra186_mc_client *clients;
+       unsigned int num_clients;
+};
+
+struct tegra186_mc {
+       struct device *dev;
+       void __iomem *regs;
+
+       const struct tegra186_mc_soc *soc;
+};
+
+static void tegra186_mc_program_sid(struct tegra186_mc *mc)
+{
+       unsigned int i;
+
+       for (i = 0; i < mc->soc->num_clients; i++) {
+               const struct tegra186_mc_client *client = &mc->soc->clients[i];
+               u32 override, security;
+
+               override = readl(mc->regs + client->regs.override);
+               security = readl(mc->regs + client->regs.security);
+
+               dev_dbg(mc->dev, "client %s: override: %x security: %x\n",
+                       client->name, override, security);
+
+               dev_dbg(mc->dev, "setting SID %u for %s\n", client->sid,
+                       client->name);
+               writel(client->sid, mc->regs + client->regs.override);
+
+               override = readl(mc->regs + client->regs.override);
+               security = readl(mc->regs + client->regs.security);
+
+               dev_dbg(mc->dev, "client %s: override: %x security: %x\n",
+                       client->name, override, security);
+       }
+}
+
+#if defined(CONFIG_ARCH_TEGRA_186_SOC)
+static const struct tegra186_mc_client tegra186_mc_clients[] = {
        {
                .name = "ptcr",
                .sid = TEGRA186_SID_PASSTHROUGH,
@@ -532,64 +573,1030 @@ static const struct tegra_mc_client tegra186_mc_clients[] = {
        },
 };
 
-static int tegra186_mc_probe(struct platform_device *pdev)
-{
-       struct resource *res;
-       struct tegra_mc *mc;
-       unsigned int i;
-       int err = 0;
-
-       mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
-       if (!mc)
-               return -ENOMEM;
-
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       mc->regs = devm_ioremap_resource(&pdev->dev, res);
-       if (IS_ERR(mc->regs))
-               return PTR_ERR(mc->regs);
-
-       mc->dev = &pdev->dev;
-
-       for (i = 0; i < ARRAY_SIZE(tegra186_mc_clients); i++) {
-               const struct tegra_mc_client *client = &tegra186_mc_clients[i];
-               u32 override, security;
-
-               override = readl(mc->regs + client->regs.override);
-               security = readl(mc->regs + client->regs.security);
-
-               dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
-                       client->name, override, security);
-
-               dev_dbg(&pdev->dev, "setting SID %u for %s\n", client->sid,
-                       client->name);
-               writel(client->sid, mc->regs + client->regs.override);
-
-               override = readl(mc->regs + client->regs.override);
-               security = readl(mc->regs + client->regs.security);
-
-               dev_dbg(&pdev->dev, "client %s: override: %x security: %x\n",
-                       client->name, override, security);
-       }
-
-       platform_set_drvdata(pdev, mc);
-
-       return err;
-}
-
-static const struct of_device_id tegra186_mc_of_match[] = {
-       { .compatible = "nvidia,tegra186-mc", },
-       { /* sentinel */ }
+static const struct tegra186_mc_soc tegra186_mc_soc = {
+       .num_clients = ARRAY_SIZE(tegra186_mc_clients),
+       .clients = tegra186_mc_clients,
+};
+#endif
+
+#if defined(CONFIG_ARCH_TEGRA_194_SOC)
+static const struct tegra186_mc_client tegra194_mc_clients[] = {
+       {
+               .name = "ptcr",
+               .sid = TEGRA194_SID_PASSTHROUGH,
+               .regs = {
+                       .override = 0x000,
+                       .security = 0x004,
+               },
+       }, {
+               .name = "miu7r",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x008,
+                       .security = 0x00c,
+               },
+       }, {
+               .name = "miu7w",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x010,
+                       .security = 0x014,
+               },
+       }, {
+               .name = "hdar",
+               .sid = TEGRA194_SID_HDA,
+               .regs = {
+                       .override = 0x0a8,
+                       .security = 0x0ac,
+               },
+       }, {
+               .name = "host1xdmar",
+               .sid = TEGRA194_SID_HOST1X,
+               .regs = {
+                       .override = 0x0b0,
+                       .security = 0x0b4,
+               },
+       }, {
+               .name = "nvencsrd",
+               .sid = TEGRA194_SID_NVENC,
+               .regs = {
+                       .override = 0x0e0,
+                       .security = 0x0e4,
+               },
+       }, {
+               .name = "satar",
+               .sid = TEGRA194_SID_SATA,
+               .regs = {
+                       .override = 0x0f8,
+                       .security = 0x0fc,
+               },
+       }, {
+               .name = "mpcorer",
+               .sid = TEGRA194_SID_PASSTHROUGH,
+               .regs = {
+                       .override = 0x138,
+                       .security = 0x13c,
+               },
+       }, {
+               .name = "nvencswr",
+               .sid = TEGRA194_SID_NVENC,
+               .regs = {
+                       .override = 0x158,
+                       .security = 0x15c,
+               },
+       }, {
+               .name = "hdaw",
+               .sid = TEGRA194_SID_HDA,
+               .regs = {
+                       .override = 0x1a8,
+                       .security = 0x1ac,
+               },
+       }, {
+               .name = "mpcorew",
+               .sid = TEGRA194_SID_PASSTHROUGH,
+               .regs = {
+                       .override = 0x1c8,
+                       .security = 0x1cc,
+               },
+       }, {
+               .name = "sataw",
+               .sid = TEGRA194_SID_SATA,
+               .regs = {
+                       .override = 0x1e8,
+                       .security = 0x1ec,
+               },
+       }, {
+               .name = "ispra",
+               .sid = TEGRA194_SID_ISP,
+               .regs = {
+                       .override = 0x220,
+                       .security = 0x224,
+               },
+       }, {
+               .name = "ispfalr",
+               .sid = TEGRA194_SID_ISP_FALCON,
+               .regs = {
+                       .override = 0x228,
+                       .security = 0x22c,
+               },
+       }, {
+               .name = "ispwa",
+               .sid = TEGRA194_SID_ISP,
+               .regs = {
+                       .override = 0x230,
+                       .security = 0x234,
+               },
+       }, {
+               .name = "ispwb",
+               .sid = TEGRA194_SID_ISP,
+               .regs = {
+                       .override = 0x238,
+                       .security = 0x23c,
+               },
+       }, {
+               .name = "xusb_hostr",
+               .sid = TEGRA194_SID_XUSB_HOST,
+               .regs = {
+                       .override = 0x250,
+                       .security = 0x254,
+               },
+       }, {
+               .name = "xusb_hostw",
+               .sid = TEGRA194_SID_XUSB_HOST,
+               .regs = {
+                       .override = 0x258,
+                       .security = 0x25c,
+               },
+       }, {
+               .name = "xusb_devr",
+               .sid = TEGRA194_SID_XUSB_DEV,
+               .regs = {
+                       .override = 0x260,
+                       .security = 0x264,
+               },
+       }, {
+               .name = "xusb_devw",
+               .sid = TEGRA194_SID_XUSB_DEV,
+               .regs = {
+                       .override = 0x268,
+                       .security = 0x26c,
+               },
+       }, {
+               .name = "sdmmcra",
+               .sid = TEGRA194_SID_SDMMC1,
+               .regs = {
+                       .override = 0x300,
+                       .security = 0x304,
+               },
+       }, {
+               .name = "sdmmcr",
+               .sid = TEGRA194_SID_SDMMC3,
+               .regs = {
+                       .override = 0x310,
+                       .security = 0x314,
+               },
+       }, {
+               .name = "sdmmcrab",
+               .sid = TEGRA194_SID_SDMMC4,
+               .regs = {
+                       .override = 0x318,
+                       .security = 0x31c,
+               },
+       }, {
+               .name = "sdmmcwa",
+               .sid = TEGRA194_SID_SDMMC1,
+               .regs = {
+                       .override = 0x320,
+                       .security = 0x324,
+               },
+       }, {
+               .name = "sdmmcw",
+               .sid = TEGRA194_SID_SDMMC3,
+               .regs = {
+                       .override = 0x330,
+                       .security = 0x334,
+               },
+       }, {
+               .name = "sdmmcwab",
+               .sid = TEGRA194_SID_SDMMC4,
+               .regs = {
+                       .override = 0x338,
+                       .security = 0x33c,
+               },
+       }, {
+               .name = "vicsrd",
+               .sid = TEGRA194_SID_VIC,
+               .regs = {
+                       .override = 0x360,
+                       .security = 0x364,
+               },
+       }, {
+               .name = "vicswr",
+               .sid = TEGRA194_SID_VIC,
+               .regs = {
+                       .override = 0x368,
+                       .security = 0x36c,
+               },
+       }, {
+               .name = "viw",
+               .sid = TEGRA194_SID_VI,
+               .regs = {
+                       .override = 0x390,
+                       .security = 0x394,
+               },
+       }, {
+               .name = "nvdecsrd",
+               .sid = TEGRA194_SID_NVDEC,
+               .regs = {
+                       .override = 0x3c0,
+                       .security = 0x3c4,
+               },
+       }, {
+               .name = "nvdecswr",
+               .sid = TEGRA194_SID_NVDEC,
+               .regs = {
+                       .override = 0x3c8,
+                       .security = 0x3cc,
+               },
+       }, {
+               .name = "aper",
+               .sid = TEGRA194_SID_APE,
+               .regs = {
+                       .override = 0x3c0,
+                       .security = 0x3c4,
+               },
+       }, {
+               .name = "apew",
+               .sid = TEGRA194_SID_APE,
+               .regs = {
+                       .override = 0x3d0,
+                       .security = 0x3d4,
+               },
+       }, {
+               .name = "nvjpgsrd",
+               .sid = TEGRA194_SID_NVJPG,
+               .regs = {
+                       .override = 0x3f0,
+                       .security = 0x3f4,
+               },
+       }, {
+               .name = "nvjpgswr",
+               .sid = TEGRA194_SID_NVJPG,
+               .regs = {
+                       .override = 0x3f0,
+                       .security = 0x3f4,
+               },
+       }, {
+               .name = "axiapr",
+               .sid = TEGRA194_SID_PASSTHROUGH,
+               .regs = {
+                       .override = 0x410,
+                       .security = 0x414,
+               },
+       }, {
+               .name = "axiapw",
+               .sid = TEGRA194_SID_PASSTHROUGH,
+               .regs = {
+                       .override = 0x418,
+                       .security = 0x41c,
+               },
+       }, {
+               .name = "etrr",
+               .sid = TEGRA194_SID_ETR,
+               .regs = {
+                       .override = 0x420,
+                       .security = 0x424,
+               },
+       }, {
+               .name = "etrw",
+               .sid = TEGRA194_SID_ETR,
+               .regs = {
+                       .override = 0x428,
+                       .security = 0x42c,
+               },
+       }, {
+               .name = "axisr",
+               .sid = TEGRA194_SID_PASSTHROUGH,
+               .regs = {
+                       .override = 0x460,
+                       .security = 0x464,
+               },
+       }, {
+               .name = "axisw",
+               .sid = TEGRA194_SID_PASSTHROUGH,
+               .regs = {
+                       .override = 0x468,
+                       .security = 0x46c,
+               },
+       }, {
+               .name = "eqosr",
+               .sid = TEGRA194_SID_EQOS,
+               .regs = {
+                       .override = 0x470,
+                       .security = 0x474,
+               },
+       }, {
+               .name = "eqosw",
+               .sid = TEGRA194_SID_EQOS,
+               .regs = {
+                       .override = 0x478,
+                       .security = 0x47c,
+               },
+       }, {
+               .name = "ufshcr",
+               .sid = TEGRA194_SID_UFSHC,
+               .regs = {
+                       .override = 0x480,
+                       .security = 0x484,
+               },
+       }, {
+               .name = "ufshcw",
+               .sid = TEGRA194_SID_UFSHC,
+               .regs = {
+                       .override = 0x488,
+                       .security = 0x48c,
+               },
+       }, {
+               .name = "nvdisplayr",
+               .sid = TEGRA194_SID_NVDISPLAY,
+               .regs = {
+                       .override = 0x490,
+                       .security = 0x494,
+               },
+       }, {
+               .name = "bpmpr",
+               .sid = TEGRA194_SID_BPMP,
+               .regs = {
+                       .override = 0x498,
+                       .security = 0x49c,
+               },
+       }, {
+               .name = "bpmpw",
+               .sid = TEGRA194_SID_BPMP,
+               .regs = {
+                       .override = 0x4a0,
+                       .security = 0x4a4,
+               },
+       }, {
+               .name = "bpmpdmar",
+               .sid = TEGRA194_SID_BPMP,
+               .regs = {
+                       .override = 0x4a8,
+                       .security = 0x4ac,
+               },
+       }, {
+               .name = "bpmpdmaw",
+               .sid = TEGRA194_SID_BPMP,
+               .regs = {
+                       .override = 0x4b0,
+                       .security = 0x4b4,
+               },
+       }, {
+               .name = "aonr",
+               .sid = TEGRA194_SID_AON,
+               .regs = {
+                       .override = 0x4b8,
+                       .security = 0x4bc,
+               },
+       }, {
+               .name = "aonw",
+               .sid = TEGRA194_SID_AON,
+               .regs = {
+                       .override = 0x4c0,
+                       .security = 0x4c4,
+               },
+       }, {
+               .name = "aondmar",
+               .sid = TEGRA194_SID_AON,
+               .regs = {
+                       .override = 0x4c8,
+                       .security = 0x4cc,
+               },
+       }, {
+               .name = "aondmaw",
+               .sid = TEGRA194_SID_AON,
+               .regs = {
+                       .override = 0x4d0,
+                       .security = 0x4d4,
+               },
+       }, {
+               .name = "scer",
+               .sid = TEGRA194_SID_SCE,
+               .regs = {
+                       .override = 0x4d8,
+                       .security = 0x4dc,
+               },
+       }, {
+               .name = "scew",
+               .sid = TEGRA194_SID_SCE,
+               .regs = {
+                       .override = 0x4e0,
+                       .security = 0x4e4,
+               },
+       }, {
+               .name = "scedmar",
+               .sid = TEGRA194_SID_SCE,
+               .regs = {
+                       .override = 0x4e8,
+                       .security = 0x4ec,
+               },
+       }, {
+               .name = "scedmaw",
+               .sid = TEGRA194_SID_SCE,
+               .regs = {
+                       .override = 0x4f0,
+                       .security = 0x4f4,
+               },
+       }, {
+               .name = "apedmar",
+               .sid = TEGRA194_SID_APE,
+               .regs = {
+                       .override = 0x4f8,
+                       .security = 0x4fc,
+               },
+       }, {
+               .name = "apedmaw",
+               .sid = TEGRA194_SID_APE,
+               .regs = {
+                       .override = 0x500,
+                       .security = 0x504,
+               },
+       }, {
+               .name = "nvdisplayr1",
+               .sid = TEGRA194_SID_NVDISPLAY,
+               .regs = {
+                       .override = 0x508,
+                       .security = 0x50c,
+               },
+       }, {
+               .name = "vicsrd1",
+               .sid = TEGRA194_SID_VIC,
+               .regs = {
+                       .override = 0x510,
+                       .security = 0x514,
+               },
+       }, {
+               .name = "nvdecsrd1",
+               .sid = TEGRA194_SID_NVDEC,
+               .regs = {
+                       .override = 0x518,
+                       .security = 0x51c,
+               },
+       }, {
+               .name = "miu0r",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x530,
+                       .security = 0x534,
+               },
+       }, {
+               .name = "miu0w",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x538,
+                       .security = 0x53c,
+               },
+       }, {
+               .name = "miu1r",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x540,
+                       .security = 0x544,
+               },
+       }, {
+               .name = "miu1w",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x548,
+                       .security = 0x54c,
+               },
+       }, {
+               .name = "miu2r",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x570,
+                       .security = 0x574,
+               },
+       }, {
+               .name = "miu2w",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x578,
+                       .security = 0x57c,
+               },
+       }, {
+               .name = "miu3r",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x580,
+                       .security = 0x584,
+               },
+       }, {
+               .name = "miu3w",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x588,
+                       .security = 0x58c,
+               },
+       }, {
+               .name = "miu4r",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x590,
+                       .security = 0x594,
+               },
+       }, {
+               .name = "miu4w",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x598,
+                       .security = 0x59c,
+               },
+       }, {
+               .name = "dpmur",
+               .sid = TEGRA194_SID_PASSTHROUGH,
+               .regs = {
+                       .override = 0x598,
+                       .security = 0x59c,
+               },
+       }, {
+               .name = "vifalr",
+               .sid = TEGRA194_SID_VI_FALCON,
+               .regs = {
+                       .override = 0x5e0,
+                       .security = 0x5e4,
+               },
+       }, {
+               .name = "vifalw",
+               .sid = TEGRA194_SID_VI_FALCON,
+               .regs = {
+                       .override = 0x5e8,
+                       .security = 0x5ec,
+               },
+       }, {
+               .name = "dla0rda",
+               .sid = TEGRA194_SID_NVDLA0,
+               .regs = {
+                       .override = 0x5f0,
+                       .security = 0x5f4,
+               },
+       }, {
+               .name = "dla0falrdb",
+               .sid = TEGRA194_SID_NVDLA0,
+               .regs = {
+                       .override = 0x5f8,
+                       .security = 0x5fc,
+               },
+       }, {
+               .name = "dla0wra",
+               .sid = TEGRA194_SID_NVDLA0,
+               .regs = {
+                       .override = 0x600,
+                       .security = 0x604,
+               },
+       }, {
+               .name = "dla0falwrb",
+               .sid = TEGRA194_SID_NVDLA0,
+               .regs = {
+                       .override = 0x608,
+                       .security = 0x60c,
+               },
+       }, {
+               .name = "dla1rda",
+               .sid = TEGRA194_SID_NVDLA1,
+               .regs = {
+                       .override = 0x610,
+                       .security = 0x614,
+               },
+       }, {
+               .name = "dla1falrdb",
+               .sid = TEGRA194_SID_NVDLA1,
+               .regs = {
+                       .override = 0x618,
+                       .security = 0x61c,
+               },
+       }, {
+               .name = "dla1wra",
+               .sid = TEGRA194_SID_NVDLA1,
+               .regs = {
+                       .override = 0x620,
+                       .security = 0x624,
+               },
+       }, {
+               .name = "dla1falwrb",
+               .sid = TEGRA194_SID_NVDLA1,
+               .regs = {
+                       .override = 0x628,
+                       .security = 0x62c,
+               },
+       }, {
+               .name = "pva0rda",
+               .sid = TEGRA194_SID_PVA0,
+               .regs = {
+                       .override = 0x630,
+                       .security = 0x634,
+               },
+       }, {
+               .name = "pva0rdb",
+               .sid = TEGRA194_SID_PVA0,
+               .regs = {
+                       .override = 0x638,
+                       .security = 0x63c,
+               },
+       }, {
+               .name = "pva0rdc",
+               .sid = TEGRA194_SID_PVA0,
+               .regs = {
+                       .override = 0x640,
+                       .security = 0x644,
+               },
+       }, {
+               .name = "pva0wra",
+               .sid = TEGRA194_SID_PVA0,
+               .regs = {
+                       .override = 0x648,
+                       .security = 0x64c,
+               },
+       }, {
+               .name = "pva0wrb",
+               .sid = TEGRA194_SID_PVA0,
+               .regs = {
+                       .override = 0x650,
+                       .security = 0x654,
+               },
+       }, {
+               .name = "pva0wrc",
+               .sid = TEGRA194_SID_PVA0,
+               .regs = {
+                       .override = 0x658,
+                       .security = 0x65c,
+               },
+       }, {
+               .name = "pva1rda",
+               .sid = TEGRA194_SID_PVA1,
+               .regs = {
+                       .override = 0x660,
+                       .security = 0x664,
+               },
+       }, {
+               .name = "pva1rdb",
+               .sid = TEGRA194_SID_PVA1,
+               .regs = {
+                       .override = 0x668,
+                       .security = 0x66c,
+               },
+       }, {
+               .name = "pva1rdc",
+               .sid = TEGRA194_SID_PVA1,
+               .regs = {
+                       .override = 0x670,
+                       .security = 0x674,
+               },
+       }, {
+               .name = "pva1wra",
+               .sid = TEGRA194_SID_PVA1,
+               .regs = {
+                       .override = 0x678,
+                       .security = 0x67c,
+               },
+       }, {
+               .name = "pva1wrb",
+               .sid = TEGRA194_SID_PVA1,
+               .regs = {
+                       .override = 0x680,
+                       .security = 0x684,
+               },
+       }, {
+               .name = "pva1wrc",
+               .sid = TEGRA194_SID_PVA1,
+               .regs = {
+                       .override = 0x688,
+                       .security = 0x68c,
+               },
+       }, {
+               .name = "rcer",
+               .sid = TEGRA194_SID_RCE,
+               .regs = {
+                       .override = 0x690,
+                       .security = 0x694,
+               },
+       }, {
+               .name = "rcew",
+               .sid = TEGRA194_SID_RCE,
+               .regs = {
+                       .override = 0x698,
+                       .security = 0x69c,
+               },
+       }, {
+               .name = "rcedmar",
+               .sid = TEGRA194_SID_RCE,
+               .regs = {
+                       .override = 0x6a0,
+                       .security = 0x6a4,
+               },
+       }, {
+               .name = "rcedmaw",
+               .sid = TEGRA194_SID_RCE,
+               .regs = {
+                       .override = 0x6a8,
+                       .security = 0x6ac,
+               },
+       }, {
+               .name = "nvenc1srd",
+               .sid = TEGRA194_SID_NVENC1,
+               .regs = {
+                       .override = 0x6b0,
+                       .security = 0x6b4,
+               },
+       }, {
+               .name = "nvenc1swr",
+               .sid = TEGRA194_SID_NVENC1,
+               .regs = {
+                       .override = 0x6b8,
+                       .security = 0x6bc,
+               },
+       }, {
+               .name = "pcie0r",
+               .sid = TEGRA194_SID_PCIE0,
+               .regs = {
+                       .override = 0x6c0,
+                       .security = 0x6c4,
+               },
+       }, {
+               .name = "pcie0w",
+               .sid = TEGRA194_SID_PCIE0,
+               .regs = {
+                       .override = 0x6c8,
+                       .security = 0x6cc,
+               },
+       }, {
+               .name = "pcie1r",
+               .sid = TEGRA194_SID_PCIE1,
+               .regs = {
+                       .override = 0x6d0,
+                       .security = 0x6d4,
+               },
+       }, {
+               .name = "pcie1w",
+               .sid = TEGRA194_SID_PCIE1,
+               .regs = {
+                       .override = 0x6d8,
+                       .security = 0x6dc,
+               },
+       }, {
+               .name = "pcie2ar",
+               .sid = TEGRA194_SID_PCIE2,
+               .regs = {
+                       .override = 0x6e0,
+                       .security = 0x6e4,
+               },
+       }, {
+               .name = "pcie2aw",
+               .sid = TEGRA194_SID_PCIE2,
+               .regs = {
+                       .override = 0x6e8,
+                       .security = 0x6ec,
+               },
+       }, {
+               .name = "pcie3r",
+               .sid = TEGRA194_SID_PCIE3,
+               .regs = {
+                       .override = 0x6f0,
+                       .security = 0x6f4,
+               },
+       }, {
+               .name = "pcie3w",
+               .sid = TEGRA194_SID_PCIE3,
+               .regs = {
+                       .override = 0x6f8,
+                       .security = 0x6fc,
+               },
+       }, {
+               .name = "pcie4r",
+               .sid = TEGRA194_SID_PCIE4,
+               .regs = {
+                       .override = 0x700,
+                       .security = 0x704,
+               },
+       }, {
+               .name = "pcie4w",
+               .sid = TEGRA194_SID_PCIE4,
+               .regs = {
+                       .override = 0x708,
+                       .security = 0x70c,
+               },
+       }, {
+               .name = "pcie5r",
+               .sid = TEGRA194_SID_PCIE5,
+               .regs = {
+                       .override = 0x710,
+                       .security = 0x714,
+               },
+       }, {
+               .name = "pcie5w",
+               .sid = TEGRA194_SID_PCIE5,
+               .regs = {
+                       .override = 0x718,
+                       .security = 0x71c,
+               },
+       }, {
+               .name = "ispfalw",
+               .sid = TEGRA194_SID_ISP_FALCON,
+               .regs = {
+                       .override = 0x720,
+                       .security = 0x724,
+               },
+       }, {
+               .name = "dla0rda1",
+               .sid = TEGRA194_SID_NVDLA0,
+               .regs = {
+                       .override = 0x748,
+                       .security = 0x74c,
+               },
+       }, {
+               .name = "dla1rda1",
+               .sid = TEGRA194_SID_NVDLA1,
+               .regs = {
+                       .override = 0x750,
+                       .security = 0x754,
+               },
+       }, {
+               .name = "pva0rda1",
+               .sid = TEGRA194_SID_PVA0,
+               .regs = {
+                       .override = 0x758,
+                       .security = 0x75c,
+               },
+       }, {
+               .name = "pva0rdb1",
+               .sid = TEGRA194_SID_PVA0,
+               .regs = {
+                       .override = 0x760,
+                       .security = 0x764,
+               },
+       }, {
+               .name = "pva1rda1",
+               .sid = TEGRA194_SID_PVA1,
+               .regs = {
+                       .override = 0x768,
+                       .security = 0x76c,
+               },
+       }, {
+               .name = "pva1rdb1",
+               .sid = TEGRA194_SID_PVA1,
+               .regs = {
+                       .override = 0x770,
+                       .security = 0x774,
+               },
+       }, {
+               .name = "pcie5r1",
+               .sid = TEGRA194_SID_PCIE5,
+               .regs = {
+                       .override = 0x778,
+                       .security = 0x77c,
+               },
+       }, {
+               .name = "nvencsrd1",
+               .sid = TEGRA194_SID_NVENC,
+               .regs = {
+                       .override = 0x780,
+                       .security = 0x784,
+               },
+       }, {
+               .name = "nvenc1srd1",
+               .sid = TEGRA194_SID_NVENC1,
+               .regs = {
+                       .override = 0x788,
+                       .security = 0x78c,
+               },
+       }, {
+               .name = "ispra1",
+               .sid = TEGRA194_SID_ISP,
+               .regs = {
+                       .override = 0x790,
+                       .security = 0x794,
+               },
+       }, {
+               .name = "pcie0r1",
+               .sid = TEGRA194_SID_PCIE0,
+               .regs = {
+                       .override = 0x798,
+                       .security = 0x79c,
+               },
+       }, {
+               .name = "nvdec1srd",
+               .sid = TEGRA194_SID_NVDEC1,
+               .regs = {
+                       .override = 0x7c8,
+                       .security = 0x7cc,
+               },
+       }, {
+               .name = "nvdec1srd1",
+               .sid = TEGRA194_SID_NVDEC1,
+               .regs = {
+                       .override = 0x7d0,
+                       .security = 0x7d4,
+               },
+       }, {
+               .name = "nvdec1swr",
+               .sid = TEGRA194_SID_NVDEC1,
+               .regs = {
+                       .override = 0x7d8,
+                       .security = 0x7dc,
+               },
+       }, {
+               .name = "miu5r",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x7e0,
+                       .security = 0x7e4,
+               },
+       }, {
+               .name = "miu5w",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x7e8,
+                       .security = 0x7ec,
+               },
+       }, {
+               .name = "miu6r",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x7f0,
+                       .security = 0x7f4,
+               },
+       }, {
+               .name = "miu6w",
+               .sid = TEGRA194_SID_MIU,
+               .regs = {
+                       .override = 0x7f8,
+                       .security = 0x7fc,
+               },
+       },
+};
+
+static const struct tegra186_mc_soc tegra194_mc_soc = {
+       .num_clients = ARRAY_SIZE(tegra194_mc_clients),
+       .clients = tegra194_mc_clients,
+};
+#endif
+
+static int tegra186_mc_probe(struct platform_device *pdev)
+{
+       struct tegra186_mc *mc;
+       struct resource *res;
+       int err;
+
+       mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
+       if (!mc)
+               return -ENOMEM;
+
+       mc->soc = of_device_get_match_data(&pdev->dev);
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       mc->regs = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(mc->regs))
+               return PTR_ERR(mc->regs);
+
+       mc->dev = &pdev->dev;
+
+       err = of_platform_populate(pdev->dev.of_node, NULL, NULL, &pdev->dev);
+       if (err < 0)
+               return err;
+
+       platform_set_drvdata(pdev, mc);
+       tegra186_mc_program_sid(mc);
+
+       return 0;
+}
+
+static int tegra186_mc_remove(struct platform_device *pdev)
+{
+       struct tegra186_mc *mc = platform_get_drvdata(pdev);
+
+       of_platform_depopulate(mc->dev);
+
+       return 0;
+}
+
+static const struct of_device_id tegra186_mc_of_match[] = {
+#if defined(CONFIG_ARCH_TEGRA_186_SOC)
+       { .compatible = "nvidia,tegra186-mc", .data = &tegra186_mc_soc },
+#endif
+#if defined(CONFIG_ARCH_TEGRA_194_SOC)
+       { .compatible = "nvidia,tegra194-mc", .data = &tegra194_mc_soc },
+#endif
+       { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, tegra186_mc_of_match);
+
+static int tegra186_mc_suspend(struct device *dev)
+{
+       return 0;
+}
+
+static int tegra186_mc_resume(struct device *dev)
+{
+       struct tegra186_mc *mc = dev_get_drvdata(dev);
+
+       tegra186_mc_program_sid(mc);
+
+       return 0;
+}
+
+static const struct dev_pm_ops tegra186_mc_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(tegra186_mc_suspend, tegra186_mc_resume)
 };
-MODULE_DEVICE_TABLE(of, tegra186_mc_of_match);
 
 static struct platform_driver tegra186_mc_driver = {
        .driver = {
                .name = "tegra186-mc",
                .of_match_table = tegra186_mc_of_match,
+               .pm = &tegra186_mc_pm_ops,
                .suppress_bind_attrs = true,
        },
-       .prevent_deferred_probe = true,
        .probe = tegra186_mc_probe,
+       .remove = tegra186_mc_remove,
 };
 module_platform_driver(tegra186_mc_driver);
 
index 1b23b1c..8ae474d 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/clk.h>
 #include <linux/clk/tegra.h>
 #include <linux/completion.h>
+#include <linux/debugfs.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
@@ -150,6 +151,12 @@ struct tegra_emc {
 
        struct emc_timing *timings;
        unsigned int num_timings;
+
+       struct {
+               struct dentry *root;
+               unsigned long min_rate;
+               unsigned long max_rate;
+       } debugfs;
 };
 
 static irqreturn_t tegra_emc_isr(int irq, void *data)
@@ -478,6 +485,171 @@ static long emc_round_rate(unsigned long rate,
        return timing->rate;
 }
 
+/*
+ * debugfs interface
+ *
+ * The memory controller driver exposes some files in debugfs that can be used
+ * to control the EMC frequency. The top-level directory can be found here:
+ *
+ *   /sys/kernel/debug/emc
+ *
+ * It contains the following files:
+ *
+ *   - available_rates: This file contains a list of valid, space-separated
+ *     EMC frequencies.
+ *
+ *   - min_rate: Writing a value to this file sets the given frequency as the
+ *       floor of the permitted range. If this is higher than the currently
+ *       configured EMC frequency, this will cause the frequency to be
+ *       increased so that it stays within the valid range.
+ *
+ *   - max_rate: Similarily to the min_rate file, writing a value to this file
+ *       sets the given frequency as the ceiling of the permitted range. If
+ *       the value is lower than the currently configured EMC frequency, this
+ *       will cause the frequency to be decreased so that it stays within the
+ *       valid range.
+ */
+
+static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate)
+{
+       unsigned int i;
+
+       for (i = 0; i < emc->num_timings; i++)
+               if (rate == emc->timings[i].rate)
+                       return true;
+
+       return false;
+}
+
+static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data)
+{
+       struct tegra_emc *emc = s->private;
+       const char *prefix = "";
+       unsigned int i;
+
+       for (i = 0; i < emc->num_timings; i++) {
+               seq_printf(s, "%s%lu", prefix, emc->timings[i].rate);
+               prefix = " ";
+       }
+
+       seq_puts(s, "\n");
+
+       return 0;
+}
+
+static int tegra_emc_debug_available_rates_open(struct inode *inode,
+                                               struct file *file)
+{
+       return single_open(file, tegra_emc_debug_available_rates_show,
+                          inode->i_private);
+}
+
+static const struct file_operations tegra_emc_debug_available_rates_fops = {
+       .open = tegra_emc_debug_available_rates_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int tegra_emc_debug_min_rate_get(void *data, u64 *rate)
+{
+       struct tegra_emc *emc = data;
+
+       *rate = emc->debugfs.min_rate;
+
+       return 0;
+}
+
+static int tegra_emc_debug_min_rate_set(void *data, u64 rate)
+{
+       struct tegra_emc *emc = data;
+       int err;
+
+       if (!tegra_emc_validate_rate(emc, rate))
+               return -EINVAL;
+
+       err = clk_set_min_rate(emc->clk, rate);
+       if (err < 0)
+               return err;
+
+       emc->debugfs.min_rate = rate;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_min_rate_fops,
+                       tegra_emc_debug_min_rate_get,
+                       tegra_emc_debug_min_rate_set, "%llu\n");
+
+static int tegra_emc_debug_max_rate_get(void *data, u64 *rate)
+{
+       struct tegra_emc *emc = data;
+
+       *rate = emc->debugfs.max_rate;
+
+       return 0;
+}
+
+static int tegra_emc_debug_max_rate_set(void *data, u64 rate)
+{
+       struct tegra_emc *emc = data;
+       int err;
+
+       if (!tegra_emc_validate_rate(emc, rate))
+               return -EINVAL;
+
+       err = clk_set_max_rate(emc->clk, rate);
+       if (err < 0)
+               return err;
+
+       emc->debugfs.max_rate = rate;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_max_rate_fops,
+                       tegra_emc_debug_max_rate_get,
+                       tegra_emc_debug_max_rate_set, "%llu\n");
+
+static void tegra_emc_debugfs_init(struct tegra_emc *emc)
+{
+       struct device *dev = emc->dev;
+       unsigned int i;
+       int err;
+
+       emc->debugfs.min_rate = ULONG_MAX;
+       emc->debugfs.max_rate = 0;
+
+       for (i = 0; i < emc->num_timings; i++) {
+               if (emc->timings[i].rate < emc->debugfs.min_rate)
+                       emc->debugfs.min_rate = emc->timings[i].rate;
+
+               if (emc->timings[i].rate > emc->debugfs.max_rate)
+                       emc->debugfs.max_rate = emc->timings[i].rate;
+       }
+
+       err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
+                                emc->debugfs.max_rate);
+       if (err < 0) {
+               dev_err(dev, "failed to set rate range [%lu-%lu] for %pC\n",
+                       emc->debugfs.min_rate, emc->debugfs.max_rate,
+                       emc->clk);
+       }
+
+       emc->debugfs.root = debugfs_create_dir("emc", NULL);
+       if (!emc->debugfs.root) {
+               dev_err(emc->dev, "failed to create debugfs directory\n");
+               return;
+       }
+
+       debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root,
+                           emc, &tegra_emc_debug_available_rates_fops);
+       debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+                           emc, &tegra_emc_debug_min_rate_fops);
+       debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+                           emc, &tegra_emc_debug_max_rate_fops);
+}
+
 static int tegra_emc_probe(struct platform_device *pdev)
 {
        struct device_node *np;
@@ -550,6 +722,9 @@ static int tegra_emc_probe(struct platform_device *pdev)
                goto unset_cb;
        }
 
+       platform_set_drvdata(pdev, emc);
+       tegra_emc_debugfs_init(emc);
+
        return 0;
 
 unset_cb:
index b420268..cc04824 100644 (file)
@@ -436,7 +436,7 @@ static const struct tegra_mc_client tegra210_mc_clients[] = {
                        .reg = 0x37c,
                        .shift = 0,
                        .mask = 0xff,
-                       .def = 0x39,
+                       .def = 0x7a,
                },
        }, {
                .id = 0x4b,
index 0b6a5e4..e3efd95 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/clk.h>
 #include <linux/clk/tegra.h>
 #include <linux/completion.h>
+#include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/interrupt.h>
@@ -331,7 +332,9 @@ struct tegra_emc {
        struct clk *clk;
        void __iomem *regs;
        unsigned int irq;
+       bool bad_state;
 
+       struct emc_timing *new_timing;
        struct emc_timing *timings;
        unsigned int num_timings;
 
@@ -345,10 +348,74 @@ struct tegra_emc {
        bool vref_cal_toggle : 1;
        bool zcal_long : 1;
        bool dll_on : 1;
-       bool prepared : 1;
-       bool bad_state : 1;
+
+       struct {
+               struct dentry *root;
+               unsigned long min_rate;
+               unsigned long max_rate;
+       } debugfs;
 };
 
+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 void emc_complete_clk_change(struct tegra_emc *emc)
+{
+       struct emc_timing *timing = emc->new_timing;
+       unsigned int dram_num;
+       bool failed = false;
+       int err;
+
+       /* re-enable auto-refresh */
+       dram_num = tegra_mc_get_emem_device_count(emc->mc);
+       writel_relaxed(EMC_REFCTRL_ENABLE_ALL(dram_num),
+                      emc->regs + EMC_REFCTRL);
+
+       /* 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);
+
+       /* wait for writes to settle */
+       udelay(2);
+
+       /* update restored timing */
+       err = emc_seq_update_timing(emc);
+       if (err)
+               failed = true;
+
+       /* restore early ACK */
+       mc_writel(emc->mc, emc->mc_override, MC_EMEM_ARB_OVERRIDE);
+
+       WRITE_ONCE(emc->bad_state, failed);
+}
+
 static irqreturn_t tegra_emc_isr(int irq, void *data)
 {
        struct tegra_emc *emc = data;
@@ -359,10 +426,6 @@ static irqreturn_t tegra_emc_isr(int irq, void *data)
        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,
@@ -371,6 +434,18 @@ static irqreturn_t tegra_emc_isr(int irq, void *data)
        /* clear interrupts */
        writel_relaxed(status, emc->regs + EMC_INTSTATUS);
 
+       /* notify about EMC-CAR handshake completion */
+       if (status & EMC_CLKCHANGE_COMPLETE_INT) {
+               if (completion_done(&emc->clk_handshake_complete)) {
+                       dev_err_ratelimited(emc->dev,
+                                           "bogus handshake interrupt\n");
+                       return IRQ_NONE;
+               }
+
+               emc_complete_clk_change(emc);
+               complete(&emc->clk_handshake_complete);
+       }
+
        return IRQ_HANDLED;
 }
 
@@ -438,24 +513,6 @@ static bool emc_dqs_preset(struct tegra_emc *emc, struct emc_timing *timing,
        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;
@@ -582,8 +639,7 @@ static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
                                !(val & EMC_AUTO_CAL_STATUS_ACTIVE), 1, 300);
                        if (err) {
                                dev_err(emc->dev,
-                                       "failed to disable auto-cal: %d\n",
-                                       err);
+                                       "auto-cal finish timeout: %d\n", err);
                                return err;
                        }
 
@@ -621,9 +677,6 @@ static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
                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);
 
@@ -739,20 +792,18 @@ static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
                                       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);
+       /*
+        * Read and discard an arbitrary MC register (Note: EMC registers
+        * can't be used) to ensure the register writes are completed.
+        */
+       mc_readl(emc->mc, MC_EMEM_ARB_OVERRIDE);
 
-       /* interrupt can be re-enabled now */
-       enable_irq(emc->irq);
+       reinit_completion(&emc->clk_handshake_complete);
 
-       emc->bad_state = false;
-       emc->prepared = true;
+       emc->new_timing = timing;
 
        return 0;
 }
@@ -760,52 +811,25 @@ static int emc_prepare_timing_change(struct tegra_emc *emc, unsigned long rate)
 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;
+       if (READ_ONCE(emc->bad_state))
+               return -EIO;
 
-       return ret;
+       return 0;
 }
 
 static int emc_unprepare_timing_change(struct tegra_emc *emc,
                                       unsigned long rate)
 {
-       if (emc->prepared && !emc->bad_state) {
+       if (!emc->bad_state) {
                /* shouldn't ever happen in practice */
                dev_err(emc->dev, "timing configuration can't be reverted\n");
                emc->bad_state = true;
@@ -823,7 +847,13 @@ static int emc_clk_change_notify(struct notifier_block *nb,
 
        switch (msg) {
        case PRE_RATE_CHANGE:
+               /*
+                * Disable interrupt since read accesses are prohibited after
+                * stalling.
+                */
+               disable_irq(emc->irq);
                err = emc_prepare_timing_change(emc, cnd->new_rate);
+               enable_irq(emc->irq);
                break;
 
        case ABORT_RATE_CHANGE:
@@ -1083,6 +1113,171 @@ static long emc_round_rate(unsigned long rate,
        return timing->rate;
 }
 
+/*
+ * debugfs interface
+ *
+ * The memory controller driver exposes some files in debugfs that can be used
+ * to control the EMC frequency. The top-level directory can be found here:
+ *
+ *   /sys/kernel/debug/emc
+ *
+ * It contains the following files:
+ *
+ *   - available_rates: This file contains a list of valid, space-separated
+ *     EMC frequencies.
+ *
+ *   - min_rate: Writing a value to this file sets the given frequency as the
+ *       floor of the permitted range. If this is higher than the currently
+ *       configured EMC frequency, this will cause the frequency to be
+ *       increased so that it stays within the valid range.
+ *
+ *   - max_rate: Similarily to the min_rate file, writing a value to this file
+ *       sets the given frequency as the ceiling of the permitted range. If
+ *       the value is lower than the currently configured EMC frequency, this
+ *       will cause the frequency to be decreased so that it stays within the
+ *       valid range.
+ */
+
+static bool tegra_emc_validate_rate(struct tegra_emc *emc, unsigned long rate)
+{
+       unsigned int i;
+
+       for (i = 0; i < emc->num_timings; i++)
+               if (rate == emc->timings[i].rate)
+                       return true;
+
+       return false;
+}
+
+static int tegra_emc_debug_available_rates_show(struct seq_file *s, void *data)
+{
+       struct tegra_emc *emc = s->private;
+       const char *prefix = "";
+       unsigned int i;
+
+       for (i = 0; i < emc->num_timings; i++) {
+               seq_printf(s, "%s%lu", prefix, emc->timings[i].rate);
+               prefix = " ";
+       }
+
+       seq_puts(s, "\n");
+
+       return 0;
+}
+
+static int tegra_emc_debug_available_rates_open(struct inode *inode,
+                                               struct file *file)
+{
+       return single_open(file, tegra_emc_debug_available_rates_show,
+                          inode->i_private);
+}
+
+static const struct file_operations tegra_emc_debug_available_rates_fops = {
+       .open = tegra_emc_debug_available_rates_open,
+       .read = seq_read,
+       .llseek = seq_lseek,
+       .release = single_release,
+};
+
+static int tegra_emc_debug_min_rate_get(void *data, u64 *rate)
+{
+       struct tegra_emc *emc = data;
+
+       *rate = emc->debugfs.min_rate;
+
+       return 0;
+}
+
+static int tegra_emc_debug_min_rate_set(void *data, u64 rate)
+{
+       struct tegra_emc *emc = data;
+       int err;
+
+       if (!tegra_emc_validate_rate(emc, rate))
+               return -EINVAL;
+
+       err = clk_set_min_rate(emc->clk, rate);
+       if (err < 0)
+               return err;
+
+       emc->debugfs.min_rate = rate;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_min_rate_fops,
+                       tegra_emc_debug_min_rate_get,
+                       tegra_emc_debug_min_rate_set, "%llu\n");
+
+static int tegra_emc_debug_max_rate_get(void *data, u64 *rate)
+{
+       struct tegra_emc *emc = data;
+
+       *rate = emc->debugfs.max_rate;
+
+       return 0;
+}
+
+static int tegra_emc_debug_max_rate_set(void *data, u64 rate)
+{
+       struct tegra_emc *emc = data;
+       int err;
+
+       if (!tegra_emc_validate_rate(emc, rate))
+               return -EINVAL;
+
+       err = clk_set_max_rate(emc->clk, rate);
+       if (err < 0)
+               return err;
+
+       emc->debugfs.max_rate = rate;
+
+       return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(tegra_emc_debug_max_rate_fops,
+                       tegra_emc_debug_max_rate_get,
+                       tegra_emc_debug_max_rate_set, "%llu\n");
+
+static void tegra_emc_debugfs_init(struct tegra_emc *emc)
+{
+       struct device *dev = emc->dev;
+       unsigned int i;
+       int err;
+
+       emc->debugfs.min_rate = ULONG_MAX;
+       emc->debugfs.max_rate = 0;
+
+       for (i = 0; i < emc->num_timings; i++) {
+               if (emc->timings[i].rate < emc->debugfs.min_rate)
+                       emc->debugfs.min_rate = emc->timings[i].rate;
+
+               if (emc->timings[i].rate > emc->debugfs.max_rate)
+                       emc->debugfs.max_rate = emc->timings[i].rate;
+       }
+
+       err = clk_set_rate_range(emc->clk, emc->debugfs.min_rate,
+                                emc->debugfs.max_rate);
+       if (err < 0) {
+               dev_err(dev, "failed to set rate range [%lu-%lu] for %pC\n",
+                       emc->debugfs.min_rate, emc->debugfs.max_rate,
+                       emc->clk);
+       }
+
+       emc->debugfs.root = debugfs_create_dir("emc", NULL);
+       if (!emc->debugfs.root) {
+               dev_err(emc->dev, "failed to create debugfs directory\n");
+               return;
+       }
+
+       debugfs_create_file("available_rates", S_IRUGO, emc->debugfs.root,
+                           emc, &tegra_emc_debug_available_rates_fops);
+       debugfs_create_file("min_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+                           emc, &tegra_emc_debug_min_rate_fops);
+       debugfs_create_file("max_rate", S_IRUGO | S_IWUSR, emc->debugfs.root,
+                           emc, &tegra_emc_debug_max_rate_fops);
+}
+
 static int tegra_emc_probe(struct platform_device *pdev)
 {
        struct platform_device *mc;
@@ -1169,6 +1364,7 @@ static int tegra_emc_probe(struct platform_device *pdev)
        }
 
        platform_set_drvdata(pdev, emc);
+       tegra_emc_debugfs_init(emc);
 
        return 0;
 
@@ -1181,13 +1377,17 @@ unset_cb:
 static int tegra_emc_suspend(struct device *dev)
 {
        struct tegra_emc *emc = dev_get_drvdata(dev);
+       int err;
 
-       /*
-        * 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)
+       /* take exclusive control over the clock's rate */
+       err = clk_rate_exclusive_get(emc->clk);
+       if (err) {
+               dev_err(emc->dev, "failed to acquire clk: %d\n", err);
+               return err;
+       }
+
+       /* suspending in a bad state will hang machine */
+       if (WARN(emc->bad_state, "hardware in a bad state\n"))
                return -EINVAL;
 
        emc->bad_state = true;
@@ -1202,6 +1402,8 @@ static int tegra_emc_resume(struct device *dev)
        emc_setup_hw(emc);
        emc->bad_state = false;
 
+       clk_rate_exclusive_put(emc->clk);
+
        return 0;
 }
 
index 7a4a41d..2b20329 100644 (file)
@@ -758,6 +758,7 @@ config MFD_MAX77650
        depends on OF || COMPILE_TEST
        select MFD_CORE
        select REGMAP_I2C
+       select REGMAP_IRQ
        help
          Say Y here to add support for Maxim Semiconductor MAX77650 and
          MAX77651 Power Management ICs. This is the core multifunction
@@ -1065,7 +1066,7 @@ config MFD_RN5T618
          functionality of the device.
 
 config MFD_SEC_CORE
-       tristate "SAMSUNG Electronics PMIC Series Support"
+       tristate "Samsung Electronics PMIC Series Support"
        depends on I2C=y
        select MFD_CORE
        select REGMAP_I2C
@@ -1906,6 +1907,21 @@ config MFD_ROHM_BD70528
          10 bits SAR ADC for battery temperature monitor and 1S battery
          charger.
 
+config MFD_ROHM_BD71828
+       tristate "ROHM BD71828 Power Management IC"
+       depends on I2C=y
+       depends on OF
+       select REGMAP_I2C
+       select REGMAP_IRQ
+       select MFD_CORE
+       help
+         Select this option to get support for the ROHM BD71828 Power
+         Management IC. BD71828GW is a single-chip power management IC for
+         battery-powered portable devices. The IC integrates 7 buck
+         converters, 7 LDOs, and a 1500 mA single-cell linear charger.
+         Also included is a Coulomb counter, a real-time clock (RTC), and
+         a 32.768 kHz clock gate.
+
 config MFD_STM32_LPTIMER
        tristate "Support for STM32 Low-Power Timer"
        depends on (ARCH_STM32 && OF) || COMPILE_TEST
@@ -1960,6 +1976,18 @@ config MFD_STMFX
          additional drivers must be enabled in order to use the functionality
          of the device.
 
+config MFD_WCD934X
+       tristate "Support for WCD9340/WCD9341 Codec"
+       depends on SLIMBUS
+       select REGMAP
+       select REGMAP_SLIMBUS
+       select REGMAP_IRQ
+       select MFD_CORE
+       help
+         Support for the Qualcomm WCD9340/WCD9341 Codec.
+         This driver provides common support WCD934x audio codec and its
+         associated Pin Controller, Soundwire Controller and Audio codec.
+
 menu "Multimedia Capabilities Port drivers"
        depends on ARCH_SA1100
 
index 5fe930c..b83f172 100644 (file)
@@ -58,6 +58,7 @@ endif
 ifeq ($(CONFIG_MFD_CS47L24),y)
 obj-$(CONFIG_MFD_ARIZONA)      += cs47l24-tables.o
 endif
+obj-$(CONFIG_MFD_WCD934X)      += wcd934x.o
 obj-$(CONFIG_MFD_WM8400)       += wm8400-core.o
 wm831x-objs                    := wm831x-core.o wm831x-irq.o wm831x-otp.o
 wm831x-objs                    += wm831x-auxadc.o
@@ -252,6 +253,7 @@ obj-$(CONFIG_MFD_MXS_LRADC)     += mxs-lradc.o
 obj-$(CONFIG_MFD_SC27XX_PMIC)  += sprd-sc27xx-spi.o
 obj-$(CONFIG_RAVE_SP_CORE)     += rave-sp.o
 obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o
+obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o
 obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o
 obj-$(CONFIG_MFD_STMFX)        += stmfx.o
 
index bafc729..a3bac9d 100644 (file)
@@ -631,8 +631,8 @@ static const struct mfd_cell ab8500_devs[] = {
                    NULL, NULL, 0, 0, "stericsson,ab8500-ext-regulator"),
        OF_MFD_CELL("ab8500-regulator",
                    NULL, NULL, 0, 0, "stericsson,ab8500-regulator"),
-       OF_MFD_CELL("abx500-clk",
-                   NULL, NULL, 0, 0, "stericsson,abx500-clk"),
+       OF_MFD_CELL("ab8500-clk",
+                   NULL, NULL, 0, 0, "stericsson,ab8500-clk"),
        OF_MFD_CELL("ab8500-gpadc",
                    NULL, NULL, 0, 0, "stericsson,ab8500-gpadc"),
        OF_MFD_CELL("ab8500-rtc",
@@ -718,17 +718,20 @@ static const struct mfd_cell ab8505_devs[] = {
 #ifdef CONFIG_DEBUG_FS
        {
                .name = "ab8500-debug",
+               .of_compatible = "stericsson,ab8500-debug",
        },
 #endif
        {
                .name = "ab8500-sysctrl",
+               .of_compatible = "stericsson,ab8500-sysctrl",
        },
        {
                .name = "ab8500-regulator",
+               .of_compatible = "stericsson,ab8505-regulator",
        },
        {
                .name = "abx500-clk",
-               .of_compatible = "stericsson,abx500-clk",
+               .of_compatible = "stericsson,ab8500-clk",
        },
        {
                .name = "ab8500-gpadc",
@@ -736,25 +739,32 @@ static const struct mfd_cell ab8505_devs[] = {
        },
        {
                .name = "ab8500-rtc",
+               .of_compatible = "stericsson,ab8500-rtc",
        },
        {
                .name = "ab8500-acc-det",
+               .of_compatible = "stericsson,ab8500-acc-det",
        },
        {
                .name = "ab8500-poweron-key",
+               .of_compatible = "stericsson,ab8500-poweron-key",
        },
        {
                .name = "ab8500-pwm",
+               .of_compatible = "stericsson,ab8500-pwm",
                .id = 1,
        },
        {
                .name = "pinctrl-ab8505",
+               .of_compatible = "stericsson,ab8505-gpio",
        },
        {
                .name = "ab8500-usb",
+               .of_compatible = "stericsson,ab8500-usb",
        },
        {
                .name = "ab8500-codec",
+               .of_compatible = "stericsson,ab8500-codec",
        },
        {
                .name = "ab-iddet",
@@ -1276,7 +1286,7 @@ static int ab8500_probe(struct platform_device *pdev)
 
 static const struct platform_device_id ab8500_id[] = {
        { "ab8500-core", AB8500_VERSION_AB8500 },
-       { "ab8505-i2c", AB8500_VERSION_AB8505 },
+       { "ab8505-core", AB8500_VERSION_AB8505 },
        { "ab9540-i2c", AB8500_VERSION_AB9540 },
        { "ab8540-i2c", AB8500_VERSION_AB8540 },
        { }
index 64013c5..3c2414b 100644 (file)
@@ -19,6 +19,7 @@
 
 struct atmel_hlcdc_regmap {
        void __iomem *regs;
+       struct device *dev;
 };
 
 static const struct mfd_cell atmel_hlcdc_cells[] = {
@@ -39,10 +40,17 @@ static int regmap_atmel_hlcdc_reg_write(void *context, unsigned int reg,
 
        if (reg <= ATMEL_HLCDC_DIS) {
                u32 status;
-
-               readl_poll_timeout_atomic(hregmap->regs + ATMEL_HLCDC_SR,
-                                         status, !(status & ATMEL_HLCDC_SIP),
-                                         1, 100);
+               int ret;
+
+               ret = readl_poll_timeout_atomic(hregmap->regs + ATMEL_HLCDC_SR,
+                                               status,
+                                               !(status & ATMEL_HLCDC_SIP),
+                                               1, 100);
+               if (ret) {
+                       dev_err(hregmap->dev,
+                               "Timeout! Clock domain synchronization is in progress!\n");
+                       return ret;
+               }
        }
 
        writel(val, hregmap->regs + reg);
@@ -90,6 +98,8 @@ static int atmel_hlcdc_probe(struct platform_device *pdev)
        if (IS_ERR(hregmap->regs))
                return PTR_ERR(hregmap->regs);
 
+       hregmap->dev = &pdev->dev;
+
        hlcdc->irq = platform_get_irq(pdev, 0);
        if (hlcdc->irq < 0)
                return hlcdc->irq;
index a4aaada..aa59496 100644 (file)
@@ -126,7 +126,7 @@ static const struct regmap_range axp288_writeable_ranges[] = {
 static const struct regmap_range axp288_volatile_ranges[] = {
        regmap_reg_range(AXP20X_PWR_INPUT_STATUS, AXP288_POWER_REASON),
        regmap_reg_range(AXP288_BC_GLOBAL, AXP288_BC_GLOBAL),
-       regmap_reg_range(AXP288_BC_DET_STAT, AXP288_BC_DET_STAT),
+       regmap_reg_range(AXP288_BC_DET_STAT, AXP20X_VBUS_IPSOUT_MGMT),
        regmap_reg_range(AXP20X_CHRG_BAK_CTRL, AXP20X_CHRG_BAK_CTRL),
        regmap_reg_range(AXP20X_IRQ1_EN, AXP20X_IPSOUT_V_HIGH_L),
        regmap_reg_range(AXP20X_TIMER_CTRL, AXP20X_TIMER_CTRL),
index c4b977a..39e6116 100644 (file)
@@ -5,8 +5,8 @@
  * Copyright (C) 2014 Google, Inc.
  */
 
+#include <linux/kconfig.h>
 #include <linux/mfd/core.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/mod_devicetable.h>
 #include <linux/of_platform.h>
@@ -87,6 +87,10 @@ static const struct mfd_cell cros_usbpd_charger_cells[] = {
        { .name = "cros-usbpd-logger", },
 };
 
+static const struct mfd_cell cros_usbpd_notify_cells[] = {
+       { .name = "cros-usbpd-notify", },
+};
+
 static const struct cros_feature_to_cells cros_subdevices[] = {
        {
                .id             = EC_FEATURE_CEC,
@@ -203,6 +207,23 @@ static int ec_device_probe(struct platform_device *pdev)
        }
 
        /*
+        * The PD notifier driver cell is separate since it only needs to be
+        * explicitly added on platforms that don't have the PD notifier ACPI
+        * device entry defined.
+        */
+       if (IS_ENABLED(CONFIG_OF)) {
+               if (cros_ec_check_features(ec, EC_FEATURE_USB_PD)) {
+                       retval = mfd_add_hotplug_devices(ec->dev,
+                                       cros_usbpd_notify_cells,
+                                       ARRAY_SIZE(cros_usbpd_notify_cells));
+                       if (retval)
+                               dev_err(ec->dev,
+                                       "failed to add PD notify devices: %d\n",
+                                       retval);
+               }
+       }
+
+       /*
         * The following subdevices cannot be detected by sending the
         * EC_FEATURE_GET_CMD to the Embedded Controller device.
         */
index f81b453..3c77f0a 100644 (file)
@@ -112,6 +112,7 @@ static const struct reg_default cs47l15_reg_default[] = {
        { 0x000001dd, 0x0011 }, /* R477 (0x1DD) - FLL AO Control 11 */
        { 0x00000218, 0x00e6 }, /* R536 (0x218) - Mic Bias Ctrl 1 */
        { 0x0000021c, 0x0222 }, /* R540 (0x21C) - Mic Bias Ctrl 5 */
+       { 0x00000293, 0x0080 }, /* R659 (0x293) - Accessory Detect Mode 1 */
        { 0x00000299, 0x0000 }, /* R665 (0x299) - Headphone Detect 0 */
        { 0x0000029b, 0x0000 }, /* R667 (0x29B) - Headphone Detect 1 */
        { 0x000002a2, 0x0010 }, /* R674 (0x2A2) - Mic Detect 1 Control 0 */
index e696268..419c735 100644 (file)
@@ -233,6 +233,14 @@ static struct resource da9062_onkey_resources[] = {
        DEFINE_RES_NAMED(DA9062_IRQ_ONKEY, 1, "ONKEY", IORESOURCE_IRQ),
 };
 
+static struct resource da9062_gpio_resources[] = {
+       DEFINE_RES_NAMED(DA9062_IRQ_GPI0, 1, "GPI0", IORESOURCE_IRQ),
+       DEFINE_RES_NAMED(DA9062_IRQ_GPI1, 1, "GPI1", IORESOURCE_IRQ),
+       DEFINE_RES_NAMED(DA9062_IRQ_GPI2, 1, "GPI2", IORESOURCE_IRQ),
+       DEFINE_RES_NAMED(DA9062_IRQ_GPI3, 1, "GPI3", IORESOURCE_IRQ),
+       DEFINE_RES_NAMED(DA9062_IRQ_GPI4, 1, "GPI4", IORESOURCE_IRQ),
+};
+
 static const struct mfd_cell da9062_devs[] = {
        {
                .name           = "da9062-core",
@@ -248,7 +256,7 @@ static const struct mfd_cell da9062_devs[] = {
                .name           = "da9062-watchdog",
                .num_resources  = ARRAY_SIZE(da9062_wdt_resources),
                .resources      = da9062_wdt_resources,
-               .of_compatible  = "dlg,da9062-wdt",
+               .of_compatible  = "dlg,da9062-watchdog",
        },
        {
                .name           = "da9062-thermal",
@@ -266,7 +274,13 @@ static const struct mfd_cell da9062_devs[] = {
                .name           = "da9062-onkey",
                .num_resources  = ARRAY_SIZE(da9062_onkey_resources),
                .resources      = da9062_onkey_resources,
-               .of_compatible = "dlg,da9062-onkey",
+               .of_compatible  = "dlg,da9062-onkey",
+       },
+       {
+               .name           = "da9062-gpio",
+               .num_resources  = ARRAY_SIZE(da9062_gpio_resources),
+               .resources      = da9062_gpio_resources,
+               .of_compatible  = "dlg,da9062-gpio",
        },
 };
 
index 57ac58b..0452b43 100644 (file)
@@ -542,102 +542,6 @@ static struct dsiescclk dsiescclk[3] = {
        }
 };
 
-
-/*
-* Used by MCDE to setup all necessary PRCMU registers
-*/
-#define PRCMU_RESET_DSIPLL             0x00004000
-#define PRCMU_UNCLAMP_DSIPLL           0x00400800
-
-#define PRCMU_CLK_PLL_DIV_SHIFT                0
-#define PRCMU_CLK_PLL_SW_SHIFT         5
-#define PRCMU_CLK_38                   (1 << 9)
-#define PRCMU_CLK_38_SRC               (1 << 10)
-#define PRCMU_CLK_38_DIV               (1 << 11)
-
-/* PLLDIV=12, PLLSW=4 (PLLDDR) */
-#define PRCMU_DSI_CLOCK_SETTING                0x0000008C
-
-/* DPI 50000000 Hz */
-#define PRCMU_DPI_CLOCK_SETTING                ((1 << PRCMU_CLK_PLL_SW_SHIFT) | \
-                                         (16 << PRCMU_CLK_PLL_DIV_SHIFT))
-#define PRCMU_DSI_LP_CLOCK_SETTING     0x00000E00
-
-/* D=101, N=1, R=4, SELDIV2=0 */
-#define PRCMU_PLLDSI_FREQ_SETTING      0x00040165
-
-#define PRCMU_ENABLE_PLLDSI            0x00000001
-#define PRCMU_DISABLE_PLLDSI           0x00000000
-#define PRCMU_RELEASE_RESET_DSS                0x0000400C
-#define PRCMU_DSI_PLLOUT_SEL_SETTING   0x00000202
-/* ESC clk, div0=1, div1=1, div2=3 */
-#define PRCMU_ENABLE_ESCAPE_CLOCK_DIV  0x07030101
-#define PRCMU_DISABLE_ESCAPE_CLOCK_DIV 0x00030101
-#define PRCMU_DSI_RESET_SW             0x00000007
-
-#define PRCMU_PLLDSI_LOCKP_LOCKED      0x3
-
-int db8500_prcmu_enable_dsipll(void)
-{
-       int i;
-
-       /* Clear DSIPLL_RESETN */
-       writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_CLR);
-       /* Unclamp DSIPLL in/out */
-       writel(PRCMU_UNCLAMP_DSIPLL, PRCM_MMIP_LS_CLAMP_CLR);
-
-       /* Set DSI PLL FREQ */
-       writel(PRCMU_PLLDSI_FREQ_SETTING, PRCM_PLLDSI_FREQ);
-       writel(PRCMU_DSI_PLLOUT_SEL_SETTING, PRCM_DSI_PLLOUT_SEL);
-       /* Enable Escape clocks */
-       writel(PRCMU_ENABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
-
-       /* Start DSI PLL */
-       writel(PRCMU_ENABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
-       /* Reset DSI PLL */
-       writel(PRCMU_DSI_RESET_SW, PRCM_DSI_SW_RESET);
-       for (i = 0; i < 10; i++) {
-               if ((readl(PRCM_PLLDSI_LOCKP) & PRCMU_PLLDSI_LOCKP_LOCKED)
-                                       == PRCMU_PLLDSI_LOCKP_LOCKED)
-                       break;
-               udelay(100);
-       }
-       /* Set DSIPLL_RESETN */
-       writel(PRCMU_RESET_DSIPLL, PRCM_APE_RESETN_SET);
-       return 0;
-}
-
-int db8500_prcmu_disable_dsipll(void)
-{
-       /* Disable dsi pll */
-       writel(PRCMU_DISABLE_PLLDSI, PRCM_PLLDSI_ENABLE);
-       /* Disable  escapeclock */
-       writel(PRCMU_DISABLE_ESCAPE_CLOCK_DIV, PRCM_DSITVCLK_DIV);
-       return 0;
-}
-
-int db8500_prcmu_set_display_clocks(void)
-{
-       unsigned long flags;
-
-       spin_lock_irqsave(&clk_mgt_lock, flags);
-
-       /* Grab the HW semaphore. */
-       while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)
-               cpu_relax();
-
-       writel(PRCMU_DSI_CLOCK_SETTING, prcmu_base + PRCM_HDMICLK_MGT);
-       writel(PRCMU_DSI_LP_CLOCK_SETTING, prcmu_base + PRCM_TVCLK_MGT);
-       writel(PRCMU_DPI_CLOCK_SETTING, prcmu_base + PRCM_LCDCLK_MGT);
-
-       /* Release the HW semaphore. */
-       writel(0, PRCM_SEM);
-
-       spin_unlock_irqrestore(&clk_mgt_lock, flags);
-
-       return 0;
-}
-
 u32 db8500_prcmu_read(unsigned int reg)
 {
        return readl(prcmu_base + reg);
@@ -3060,30 +2964,44 @@ static const struct mfd_cell db8500_prcmu_devs[] = {
 static int db8500_prcmu_register_ab8500(struct device *parent)
 {
        struct device_node *np;
-       struct resource ab8500_resource;
+       struct resource ab850x_resource;
        const struct mfd_cell ab8500_cell = {
                .name = "ab8500-core",
                .of_compatible = "stericsson,ab8500",
                .id = AB8500_VERSION_AB8500,
-               .resources = &ab8500_resource,
+               .resources = &ab850x_resource,
                .num_resources = 1,
        };
+       const struct mfd_cell ab8505_cell = {
+               .name = "ab8505-core",
+               .of_compatible = "stericsson,ab8505",
+               .id = AB8500_VERSION_AB8505,
+               .resources = &ab850x_resource,
+               .num_resources = 1,
+       };
+       const struct mfd_cell *ab850x_cell;
 
        if (!parent->of_node)
                return -ENODEV;
 
        /* Look up the device node, sneak the IRQ out of it */
        for_each_child_of_node(parent->of_node, np) {
-               if (of_device_is_compatible(np, ab8500_cell.of_compatible))
+               if (of_device_is_compatible(np, ab8500_cell.of_compatible)) {
+                       ab850x_cell = &ab8500_cell;
                        break;
+               }
+               if (of_device_is_compatible(np, ab8505_cell.of_compatible)) {
+                       ab850x_cell = &ab8505_cell;
+                       break;
+               }
        }
        if (!np) {
-               dev_info(parent, "could not find AB8500 node in the device tree\n");
+               dev_info(parent, "could not find AB850X node in the device tree\n");
                return -ENODEV;
        }
-       of_irq_to_resource_table(np, &ab8500_resource, 1);
+       of_irq_to_resource_table(np, &ab850x_resource, 1);
 
-       return mfd_add_devices(parent, 0, &ab8500_cell, 1, NULL, 0, NULL);
+       return mfd_add_devices(parent, 0, ab850x_cell, 1, NULL, 0, NULL);
 }
 
 /**
index 381593f..7841c11 100644 (file)
@@ -722,6 +722,8 @@ static int dln2_probe(struct usb_interface *interface,
                      const struct usb_device_id *usb_id)
 {
        struct usb_host_interface *hostif = interface->cur_altsetting;
+       struct usb_endpoint_descriptor *epin;
+       struct usb_endpoint_descriptor *epout;
        struct device *dev = &interface->dev;
        struct dln2_dev *dln2;
        int ret;
@@ -731,12 +733,19 @@ static int dln2_probe(struct usb_interface *interface,
            hostif->desc.bNumEndpoints < 2)
                return -ENODEV;
 
+       epin = &hostif->endpoint[0].desc;
+       epout = &hostif->endpoint[1].desc;
+       if (!usb_endpoint_is_bulk_out(epout))
+               return -ENODEV;
+       if (!usb_endpoint_is_bulk_in(epin))
+               return -ENODEV;
+
        dln2 = kzalloc(sizeof(*dln2), GFP_KERNEL);
        if (!dln2)
                return -ENOMEM;
 
-       dln2->ep_out = hostif->endpoint[0].desc.bEndpointAddress;
-       dln2->ep_in = hostif->endpoint[1].desc.bEndpointAddress;
+       dln2->ep_out = epout->bEndpointAddress;
+       dln2->ep_in = epin->bEndpointAddress;
        dln2->usb_dev = usb_get_dev(interface_to_usbdev(interface));
        dln2->interface = interface;
        usb_set_intfdata(interface, dln2);
index b33030e..c40a6c7 100644 (file)
@@ -240,6 +240,19 @@ static const struct pci_device_id intel_lpss_pci_ids[] = {
        { PCI_VDEVICE(INTEL, 0x4b79), (kernel_ulong_t)&bxt_i2c_info },
        { PCI_VDEVICE(INTEL, 0x4b7a), (kernel_ulong_t)&bxt_i2c_info },
        { PCI_VDEVICE(INTEL, 0x4b7b), (kernel_ulong_t)&bxt_i2c_info },
+       /* JSL */
+       { PCI_VDEVICE(INTEL, 0x4da8), (kernel_ulong_t)&spt_uart_info },
+       { PCI_VDEVICE(INTEL, 0x4da9), (kernel_ulong_t)&spt_uart_info },
+       { PCI_VDEVICE(INTEL, 0x4daa), (kernel_ulong_t)&spt_info },
+       { PCI_VDEVICE(INTEL, 0x4dab), (kernel_ulong_t)&spt_info },
+       { PCI_VDEVICE(INTEL, 0x4daf), (kernel_ulong_t)&spt_uart_info },
+       { PCI_VDEVICE(INTEL, 0x4dc5), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x4dc6), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x4de8), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x4de9), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x4dea), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x4deb), (kernel_ulong_t)&bxt_i2c_info },
+       { PCI_VDEVICE(INTEL, 0x4dfb), (kernel_ulong_t)&spt_info },
        /* APL */
        { PCI_VDEVICE(INTEL, 0x5aac), (kernel_ulong_t)&apl_i2c_info },
        { PCI_VDEVICE(INTEL, 0x5aae), (kernel_ulong_t)&apl_i2c_info },
index a8cfadc..7e0835c 100644 (file)
@@ -35,6 +35,9 @@
 
 #define MADERA_32KZ_MCLK2      1
 
+#define MADERA_RESET_MIN_US    2000
+#define MADERA_RESET_MAX_US    3000
+
 static const char * const madera_core_supplies[] = {
        "AVDD",
        "DBVDD1",
@@ -199,7 +202,7 @@ EXPORT_SYMBOL_GPL(madera_name_from_type);
 #define MADERA_BOOT_POLL_INTERVAL_USEC         5000
 #define MADERA_BOOT_POLL_TIMEOUT_USEC          25000
 
-static int madera_wait_for_boot(struct madera *madera)
+static int madera_wait_for_boot_noack(struct madera *madera)
 {
        ktime_t timeout;
        unsigned int val = 0;
@@ -226,6 +229,13 @@ static int madera_wait_for_boot(struct madera *madera)
                ret = -ETIMEDOUT;
        }
 
+       return ret;
+}
+
+static int madera_wait_for_boot(struct madera *madera)
+{
+       int ret = madera_wait_for_boot_noack(madera);
+
        /*
         * BOOT_DONE defaults to unmasked on boot so we must ack it.
         * Do this even after a timeout to avoid interrupt storms.
@@ -249,16 +259,13 @@ static int madera_soft_reset(struct madera *madera)
        }
 
        /* Allow time for internal clocks to startup after reset */
-       usleep_range(1000, 2000);
+       usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
 
        return 0;
 }
 
 static void madera_enable_hard_reset(struct madera *madera)
 {
-       if (!madera->pdata.reset)
-               return;
-
        /*
         * There are many existing out-of-tree users of these codecs that we
         * can't break so preserve the expected behaviour of setting the line
@@ -269,11 +276,9 @@ static void madera_enable_hard_reset(struct madera *madera)
 
 static void madera_disable_hard_reset(struct madera *madera)
 {
-       if (!madera->pdata.reset)
-               return;
-
        gpiod_set_raw_value_cansleep(madera->pdata.reset, 1);
-       usleep_range(1000, 2000);
+
+       usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
 }
 
 static int __maybe_unused madera_runtime_resume(struct device *dev)
@@ -292,6 +297,8 @@ static int __maybe_unused madera_runtime_resume(struct device *dev)
        regcache_cache_only(madera->regmap, false);
        regcache_cache_only(madera->regmap_32bit, false);
 
+       usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
+
        ret = madera_wait_for_boot(madera);
        if (ret)
                goto err;
@@ -545,6 +552,12 @@ int madera_dev_init(struct madera *madera)
        regcache_cache_only(madera->regmap, false);
        regcache_cache_only(madera->regmap_32bit, false);
 
+       ret = madera_wait_for_boot_noack(madera);
+       if (ret) {
+               dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
+               goto err_reset;
+       }
+
        /*
         * Now we can power up and verify that this is a chip we know about
         * before we start doing any writes to its registers.
@@ -650,7 +663,7 @@ int madera_dev_init(struct madera *madera)
 
        ret = madera_wait_for_boot(madera);
        if (ret) {
-               dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
+               dev_err(madera->dev, "Failed to clear boot done: %d\n", ret);
                goto err_reset;
        }
 
index da5cd9c..ead2e79 100644 (file)
@@ -26,6 +26,7 @@ static bool rn5t618_volatile_reg(struct device *dev, unsigned int reg)
        case RN5T618_WATCHDOGCNT:
        case RN5T618_DCIRQ:
        case RN5T618_ILIMDATAH ... RN5T618_AIN0DATAL:
+       case RN5T618_ADCCNT3:
        case RN5T618_IR_ADC1 ... RN5T618_IR_ADC3:
        case RN5T618_IR_GPR:
        case RN5T618_IR_GPF:
index ef6786f..5c44d3b 100644 (file)
@@ -48,7 +48,7 @@ static struct mfd_cell bd70528_mfd_cells[] = {
         * We use BD71837 driver to drive the clock block. Only differences to
         * BD70528 clock gate are the register address and mask.
         */
-       { .name = "bd718xx-clk", },
+       { .name = "bd70528-clk", },
        { .name = "bd70528-wdt", },
        {
                .name = "bd70528-power",
@@ -236,7 +236,6 @@ static int bd70528_i2c_probe(struct i2c_client *i2c,
 
        dev_set_drvdata(&i2c->dev, &bd70528->chip);
 
-       bd70528->chip.chip_type = ROHM_CHIP_TYPE_BD70528;
        bd70528->chip.regmap = devm_regmap_init_i2c(i2c, &bd70528_regmap);
        if (IS_ERR(bd70528->chip.regmap)) {
                dev_err(&i2c->dev, "Failed to initialize Regmap\n");
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c
new file mode 100644 (file)
index 0000000..210261d
--- /dev/null
@@ -0,0 +1,344 @@
+// SPDX-License-Identifier: GPL-2.0-only
+//
+// Copyright (C) 2019 ROHM Semiconductors
+//
+// ROHM BD71828 PMIC driver
+
+#include <linux/gpio_keys.h>
+#include <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/rohm-bd71828.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/types.h>
+
+static struct gpio_keys_button button = {
+       .code = KEY_POWER,
+       .gpio = -1,
+       .type = EV_KEY,
+};
+
+static struct gpio_keys_platform_data bd71828_powerkey_data = {
+       .buttons = &button,
+       .nbuttons = 1,
+       .name = "bd71828-pwrkey",
+};
+
+static const struct resource rtc_irqs[] = {
+       DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC0, "bd71828-rtc-alm-0"),
+       DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC1, "bd71828-rtc-alm-1"),
+       DEFINE_RES_IRQ_NAMED(BD71828_INT_RTC2, "bd71828-rtc-alm-2"),
+};
+
+static struct mfd_cell bd71828_mfd_cells[] = {
+       { .name = "bd71828-pmic", },
+       { .name = "bd71828-gpio", },
+       { .name = "bd71828-led", .of_compatible = "rohm,bd71828-leds" },
+       /*
+        * We use BD71837 driver to drive the clock block. Only differences to
+        * BD70528 clock gate are the register address and mask.
+        */
+       { .name = "bd71828-clk", },
+       { .name = "bd71827-power", },
+       {
+               .name = "bd71828-rtc",
+               .resources = rtc_irqs,
+               .num_resources = ARRAY_SIZE(rtc_irqs),
+       }, {
+               .name = "gpio-keys",
+               .platform_data = &bd71828_powerkey_data,
+               .pdata_size = sizeof(bd71828_powerkey_data),
+       },
+};
+
+static const struct regmap_range volatile_ranges[] = {
+       {
+               .range_min = BD71828_REG_PS_CTRL_1,
+               .range_max = BD71828_REG_PS_CTRL_1,
+       }, {
+               .range_min = BD71828_REG_PS_CTRL_3,
+               .range_max = BD71828_REG_PS_CTRL_3,
+       }, {
+               .range_min = BD71828_REG_RTC_SEC,
+               .range_max = BD71828_REG_RTC_YEAR,
+       }, {
+               /*
+                * For now make all charger registers volatile because many
+                * needs to be and because the charger block is not that
+                * performance critical.
+                */
+               .range_min = BD71828_REG_CHG_STATE,
+               .range_max = BD71828_REG_CHG_FULL,
+       }, {
+               .range_min = BD71828_REG_INT_MAIN,
+               .range_max = BD71828_REG_IO_STAT,
+       },
+};
+
+static const struct regmap_access_table volatile_regs = {
+       .yes_ranges = &volatile_ranges[0],
+       .n_yes_ranges = ARRAY_SIZE(volatile_ranges),
+};
+
+static struct regmap_config bd71828_regmap = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .volatile_table = &volatile_regs,
+       .max_register = BD71828_MAX_REGISTER,
+       .cache_type = REGCACHE_RBTREE,
+};
+
+/*
+ * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can
+ * access corect sub-IRQ registers based on bits that are set in main IRQ
+ * register.
+ */
+
+static unsigned int bit0_offsets[] = {11};             /* RTC IRQ */
+static unsigned int bit1_offsets[] = {10};             /* TEMP IRQ */
+static unsigned int bit2_offsets[] = {6, 7, 8, 9};     /* BAT MON IRQ */
+static unsigned int bit3_offsets[] = {5};              /* BAT IRQ */
+static unsigned int bit4_offsets[] = {4};              /* CHG IRQ */
+static unsigned int bit5_offsets[] = {3};              /* VSYS IRQ */
+static unsigned int bit6_offsets[] = {1, 2};           /* DCIN IRQ */
+static unsigned int bit7_offsets[] = {0};              /* BUCK IRQ */
+
+static struct regmap_irq_sub_irq_map bd71828_sub_irq_offsets[] = {
+       REGMAP_IRQ_MAIN_REG_OFFSET(bit0_offsets),
+       REGMAP_IRQ_MAIN_REG_OFFSET(bit1_offsets),
+       REGMAP_IRQ_MAIN_REG_OFFSET(bit2_offsets),
+       REGMAP_IRQ_MAIN_REG_OFFSET(bit3_offsets),
+       REGMAP_IRQ_MAIN_REG_OFFSET(bit4_offsets),
+       REGMAP_IRQ_MAIN_REG_OFFSET(bit5_offsets),
+       REGMAP_IRQ_MAIN_REG_OFFSET(bit6_offsets),
+       REGMAP_IRQ_MAIN_REG_OFFSET(bit7_offsets),
+};
+
+static struct regmap_irq bd71828_irqs[] = {
+       REGMAP_IRQ_REG(BD71828_INT_BUCK1_OCP, 0, BD71828_INT_BUCK1_OCP_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BUCK2_OCP, 0, BD71828_INT_BUCK2_OCP_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BUCK3_OCP, 0, BD71828_INT_BUCK3_OCP_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BUCK4_OCP, 0, BD71828_INT_BUCK4_OCP_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BUCK5_OCP, 0, BD71828_INT_BUCK5_OCP_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BUCK6_OCP, 0, BD71828_INT_BUCK6_OCP_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BUCK7_OCP, 0, BD71828_INT_BUCK7_OCP_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_PGFAULT, 0, BD71828_INT_PGFAULT_MASK),
+       /* DCIN1 interrupts */
+       REGMAP_IRQ_REG(BD71828_INT_DCIN_DET, 1, BD71828_INT_DCIN_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_DCIN_RMV, 1, BD71828_INT_DCIN_RMV_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CLPS_OUT, 1, BD71828_INT_CLPS_OUT_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CLPS_IN, 1, BD71828_INT_CLPS_IN_MASK),
+       /* DCIN2 interrupts */
+       REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_RES, 2,
+                      BD71828_INT_DCIN_MON_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_DCIN_MON_DET, 2,
+                      BD71828_INT_DCIN_MON_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_LONGPUSH, 2, BD71828_INT_LONGPUSH_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_MIDPUSH, 2, BD71828_INT_MIDPUSH_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_SHORTPUSH, 2, BD71828_INT_SHORTPUSH_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_PUSH, 2, BD71828_INT_PUSH_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_WDOG, 2, BD71828_INT_WDOG_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_SWRESET, 2, BD71828_INT_SWRESET_MASK),
+       /* Vsys */
+       REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_RES, 3,
+                      BD71828_INT_VSYS_UV_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_VSYS_UV_DET, 3,
+                      BD71828_INT_VSYS_UV_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_RES, 3,
+                      BD71828_INT_VSYS_LOW_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_VSYS_LOW_DET, 3,
+                      BD71828_INT_VSYS_LOW_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_IN, 3,
+                      BD71828_INT_VSYS_HALL_IN_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_VSYS_HALL_TOGGLE, 3,
+                      BD71828_INT_VSYS_HALL_TOGGLE_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_RES, 3,
+                      BD71828_INT_VSYS_MON_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_VSYS_MON_DET, 3,
+                      BD71828_INT_VSYS_MON_DET_MASK),
+       /* Charger */
+       REGMAP_IRQ_REG(BD71828_INT_CHG_DCIN_ILIM, 4,
+                      BD71828_INT_CHG_DCIN_ILIM_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CHG_TOPOFF_TO_DONE, 4,
+                      BD71828_INT_CHG_TOPOFF_TO_DONE_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TEMP, 4,
+                      BD71828_INT_CHG_WDG_TEMP_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CHG_WDG_TIME, 4,
+                      BD71828_INT_CHG_WDG_TIME_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_RES, 4,
+                      BD71828_INT_CHG_RECHARGE_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CHG_RECHARGE_DET, 4,
+                      BD71828_INT_CHG_RECHARGE_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CHG_RANGED_TEMP_TRANSITION, 4,
+                      BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_CHG_STATE_TRANSITION, 4,
+                      BD71828_INT_CHG_STATE_TRANSITION_MASK),
+       /* Battery */
+       REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_NORMAL, 5,
+                      BD71828_INT_BAT_TEMP_NORMAL_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_ERANGE, 5,
+                      BD71828_INT_BAT_TEMP_ERANGE_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_TEMP_WARN, 5,
+                      BD71828_INT_BAT_TEMP_WARN_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_REMOVED, 5,
+                      BD71828_INT_BAT_REMOVED_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_DETECTED, 5,
+                      BD71828_INT_BAT_DETECTED_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_THERM_REMOVED, 5,
+                      BD71828_INT_THERM_REMOVED_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_THERM_DETECTED, 5,
+                      BD71828_INT_THERM_DETECTED_MASK),
+       /* Battery Mon 1 */
+       REGMAP_IRQ_REG(BD71828_INT_BAT_DEAD, 6, BD71828_INT_BAT_DEAD_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_RES, 6,
+                      BD71828_INT_BAT_SHORTC_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_SHORTC_DET, 6,
+                      BD71828_INT_BAT_SHORTC_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_RES, 6,
+                      BD71828_INT_BAT_LOW_VOLT_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_LOW_VOLT_DET, 6,
+                      BD71828_INT_BAT_LOW_VOLT_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_RES, 6,
+                      BD71828_INT_BAT_OVER_VOLT_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_VOLT_DET, 6,
+                      BD71828_INT_BAT_OVER_VOLT_DET_MASK),
+       /* Battery Mon 2 */
+       REGMAP_IRQ_REG(BD71828_INT_BAT_MON_RES, 7,
+                      BD71828_INT_BAT_MON_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_MON_DET, 7,
+                      BD71828_INT_BAT_MON_DET_MASK),
+       /* Battery Mon 3 (Coulomb counter) */
+       REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON1, 8,
+                      BD71828_INT_BAT_CC_MON1_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON2, 8,
+                      BD71828_INT_BAT_CC_MON2_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_CC_MON3, 8,
+                      BD71828_INT_BAT_CC_MON3_MASK),
+       /* Battery Mon 4 */
+       REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_RES, 9,
+                      BD71828_INT_BAT_OVER_CURR_1_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_1_DET, 9,
+                      BD71828_INT_BAT_OVER_CURR_1_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_RES, 9,
+                      BD71828_INT_BAT_OVER_CURR_2_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_2_DET, 9,
+                      BD71828_INT_BAT_OVER_CURR_2_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_RES, 9,
+                      BD71828_INT_BAT_OVER_CURR_3_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_BAT_OVER_CURR_3_DET, 9,
+                      BD71828_INT_BAT_OVER_CURR_3_DET_MASK),
+       /* Temperature */
+       REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_RES, 10,
+                      BD71828_INT_TEMP_BAT_LOW_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_LOW_DET, 10,
+                      BD71828_INT_TEMP_BAT_LOW_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_RES, 10,
+                      BD71828_INT_TEMP_BAT_HI_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_TEMP_BAT_HI_DET, 10,
+                      BD71828_INT_TEMP_BAT_HI_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_RES, 10,
+                      BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_125_DET, 10,
+                      BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_DET, 10,
+                      BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_TEMP_CHIP_OVER_VF_RES, 10,
+                      BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK),
+       /* RTC Alarm */
+       REGMAP_IRQ_REG(BD71828_INT_RTC0, 11, BD71828_INT_RTC0_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_RTC1, 11, BD71828_INT_RTC1_MASK),
+       REGMAP_IRQ_REG(BD71828_INT_RTC2, 11, BD71828_INT_RTC2_MASK),
+};
+
+static struct regmap_irq_chip bd71828_irq_chip = {
+       .name = "bd71828_irq",
+       .main_status = BD71828_REG_INT_MAIN,
+       .irqs = &bd71828_irqs[0],
+       .num_irqs = ARRAY_SIZE(bd71828_irqs),
+       .status_base = BD71828_REG_INT_BUCK,
+       .mask_base = BD71828_REG_INT_MASK_BUCK,
+       .ack_base = BD71828_REG_INT_BUCK,
+       .mask_invert = true,
+       .init_ack_masked = true,
+       .num_regs = 12,
+       .num_main_regs = 1,
+       .sub_reg_offsets = &bd71828_sub_irq_offsets[0],
+       .num_main_status_bits = 8,
+       .irq_reg_stride = 1,
+};
+
+static int bd71828_i2c_probe(struct i2c_client *i2c)
+{
+       struct rohm_regmap_dev *chip;
+       struct regmap_irq_chip_data *irq_data;
+       int ret;
+
+       if (!i2c->irq) {
+               dev_err(&i2c->dev, "No IRQ configured\n");
+               return -EINVAL;
+       }
+
+       chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL);
+       if (!chip)
+               return -ENOMEM;
+
+       dev_set_drvdata(&i2c->dev, chip);
+
+       chip->regmap = devm_regmap_init_i2c(i2c, &bd71828_regmap);
+       if (IS_ERR(chip->regmap)) {
+               dev_err(&i2c->dev, "Failed to initialize Regmap\n");
+               return PTR_ERR(chip->regmap);
+       }
+
+       ret = devm_regmap_add_irq_chip(&i2c->dev, chip->regmap,
+                                      i2c->irq, IRQF_ONESHOT, 0,
+                                      &bd71828_irq_chip, &irq_data);
+       if (ret) {
+               dev_err(&i2c->dev, "Failed to add IRQ chip\n");
+               return ret;
+       }
+
+       dev_dbg(&i2c->dev, "Registered %d IRQs for chip\n",
+               bd71828_irq_chip.num_irqs);
+
+       ret = regmap_irq_get_virq(irq_data, BD71828_INT_SHORTPUSH);
+       if (ret < 0) {
+               dev_err(&i2c->dev, "Failed to get the power-key IRQ\n");
+               return ret;
+       }
+
+       button.irq = ret;
+
+       ret = devm_mfd_add_devices(&i2c->dev, PLATFORM_DEVID_AUTO,
+                                  bd71828_mfd_cells,
+                                  ARRAY_SIZE(bd71828_mfd_cells), NULL, 0,
+                                  regmap_irq_get_domain(irq_data));
+       if (ret)
+               dev_err(&i2c->dev, "Failed to create subdevices\n");
+
+       return ret;
+}
+
+static const struct of_device_id bd71828_of_match[] = {
+       { .compatible = "rohm,bd71828", },
+       { },
+};
+MODULE_DEVICE_TABLE(of, bd71828_of_match);
+
+static struct i2c_driver bd71828_drv = {
+       .driver = {
+               .name = "rohm-bd71828",
+               .of_match_table = bd71828_of_match,
+       },
+       .probe_new = &bd71828_i2c_probe,
+};
+module_i2c_driver(bd71828_drv);
+
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("ROHM BD71828 Power Management IC driver");
+MODULE_LICENSE("GPL");
index 85e7f51..c32c1b6 100644 (file)
@@ -30,14 +30,24 @@ static struct gpio_keys_platform_data bd718xx_powerkey_data = {
        .name = "bd718xx-pwrkey",
 };
 
-static struct mfd_cell bd718xx_mfd_cells[] = {
+static struct mfd_cell bd71837_mfd_cells[] = {
        {
                .name = "gpio-keys",
                .platform_data = &bd718xx_powerkey_data,
                .pdata_size = sizeof(bd718xx_powerkey_data),
        },
-       { .name = "bd718xx-clk", },
-       { .name = "bd718xx-pmic", },
+       { .name = "bd71837-clk", },
+       { .name = "bd71837-pmic", },
+};
+
+static struct mfd_cell bd71847_mfd_cells[] = {
+       {
+               .name = "gpio-keys",
+               .platform_data = &bd718xx_powerkey_data,
+               .pdata_size = sizeof(bd718xx_powerkey_data),
+       },
+       { .name = "bd71847-clk", },
+       { .name = "bd71847-pmic", },
 };
 
 static const struct regmap_irq bd718xx_irqs[] = {
@@ -124,6 +134,9 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c,
 {
        struct bd718xx *bd718xx;
        int ret;
+       unsigned int chip_type;
+       struct mfd_cell *mfd;
+       int cells;
 
        if (!i2c->irq) {
                dev_err(&i2c->dev, "No IRQ configured\n");
@@ -136,8 +149,21 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c,
                return -ENOMEM;
 
        bd718xx->chip_irq = i2c->irq;
-       bd718xx->chip.chip_type = (unsigned int)(uintptr_t)
-                               of_device_get_match_data(&i2c->dev);
+       chip_type = (unsigned int)(uintptr_t)
+                   of_device_get_match_data(&i2c->dev);
+       switch (chip_type) {
+       case ROHM_CHIP_TYPE_BD71837:
+               mfd = bd71837_mfd_cells;
+               cells = ARRAY_SIZE(bd71837_mfd_cells);
+               break;
+       case ROHM_CHIP_TYPE_BD71847:
+               mfd = bd71847_mfd_cells;
+               cells = ARRAY_SIZE(bd71847_mfd_cells);
+               break;
+       default:
+               dev_err(&i2c->dev, "Unknown device type");
+               return -EINVAL;
+       }
        bd718xx->chip.dev = &i2c->dev;
        dev_set_drvdata(&i2c->dev, bd718xx);
 
@@ -170,8 +196,7 @@ static int bd718xx_i2c_probe(struct i2c_client *i2c,
        button.irq = ret;
 
        ret = devm_mfd_add_devices(bd718xx->chip.dev, PLATFORM_DEVID_AUTO,
-                                  bd718xx_mfd_cells,
-                                  ARRAY_SIZE(bd718xx_mfd_cells), NULL, 0,
+                                  mfd, cells, NULL, 0,
                                   regmap_irq_get_domain(bd718xx->irq_data));
        if (ret)
                dev_err(&i2c->dev, "Failed to create subdevices\n");
@@ -188,6 +213,10 @@ static const struct of_device_id bd718xx_of_match[] = {
                .compatible = "rohm,bd71847",
                .data = (void *)ROHM_CHIP_TYPE_BD71847,
        },
+       {
+               .compatible = "rohm,bd71850",
+               .data = (void *)ROHM_CHIP_TYPE_BD71847,
+       },
        { }
 };
 MODULE_DEVICE_TABLE(of, bd718xx_of_match);
index 154270f..e49787e 100644 (file)
@@ -1086,8 +1086,7 @@ static int sm501_register_gpio(struct sm501_devdata *sm)
        iounmap(gpio->regs);
 
  err_claimed:
-       release_resource(gpio->regs_res);
-       kfree(gpio->regs_res);
+       release_mem_region(iobase, 0x20);
 
        return ret;
 }
@@ -1095,6 +1094,7 @@ static int sm501_register_gpio(struct sm501_devdata *sm)
 static void sm501_gpio_remove(struct sm501_devdata *sm)
 {
        struct sm501_gpio *gpio = &sm->gpio;
+       resource_size_t iobase = sm->io_res->start + SM501_GPIO;
 
        if (!sm->gpio.registered)
                return;
@@ -1103,8 +1103,7 @@ static void sm501_gpio_remove(struct sm501_devdata *sm)
        gpiochip_remove(&gpio->high.gpio);
 
        iounmap(gpio->regs);
-       release_resource(gpio->regs_res);
-       kfree(gpio->regs_res);
+       release_mem_region(iobase, 0x20);
 }
 
 static inline int sm501_gpio_isregistered(struct sm501_devdata *sm)
@@ -1427,8 +1426,7 @@ static int sm501_plat_probe(struct platform_device *dev)
        return sm501_init_dev(sm);
 
  err_claim:
-       release_resource(sm->regs_claim);
-       kfree(sm->regs_claim);
+       release_mem_region(sm->io_res->start, 0x100);
  err_res:
        kfree(sm);
  err1:
@@ -1637,8 +1635,7 @@ static int sm501_pci_probe(struct pci_dev *dev,
        return 0;
 
  err4:
-       release_resource(sm->regs_claim);
-       kfree(sm->regs_claim);
+       release_mem_region(sm->io_res->start, 0x100);
  err3:
        pci_disable_device(dev);
  err2:
@@ -1673,8 +1670,7 @@ static void sm501_pci_remove(struct pci_dev *dev)
        sm501_dev_remove(sm);
        iounmap(sm->regs);
 
-       release_resource(sm->regs_claim);
-       kfree(sm->regs_claim);
+       release_mem_region(sm->io_res->start, 0x100);
 
        pci_disable_device(dev);
 }
@@ -1686,8 +1682,7 @@ static int sm501_plat_remove(struct platform_device *dev)
        sm501_dev_remove(sm);
        iounmap(sm->regs);
 
-       release_resource(sm->regs_claim);
-       kfree(sm->regs_claim);
+       release_mem_region(sm->io_res->start, 0x100);
 
        return 0;
 }
index e22197c..3a97816 100644 (file)
@@ -224,6 +224,35 @@ struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
 }
 EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle);
 
+struct regmap *syscon_regmap_lookup_by_phandle_args(struct device_node *np,
+                                       const char *property,
+                                       int arg_count,
+                                       unsigned int *out_args)
+{
+       struct device_node *syscon_np;
+       struct of_phandle_args args;
+       struct regmap *regmap;
+       unsigned int index;
+       int rc;
+
+       rc = of_parse_phandle_with_fixed_args(np, property, arg_count,
+                       0, &args);
+       if (rc)
+               return ERR_PTR(rc);
+
+       syscon_np = args.np;
+       if (!syscon_np)
+               return ERR_PTR(-ENODEV);
+
+       regmap = syscon_node_to_regmap(syscon_np);
+       for (index = 0; index < arg_count; index++)
+               out_args[index] = args.args[index];
+       of_node_put(syscon_np);
+
+       return regmap;
+}
+EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle_args);
+
 static int syscon_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
@@ -245,7 +274,7 @@ static int syscon_probe(struct platform_device *pdev)
        if (!base)
                return -ENOMEM;
 
-       syscon_config.max_register = res->end - res->start - 3;
+       syscon_config.max_register = resource_size(res) - 4;
        if (pdata)
                syscon_config.name = pdata->label;
        syscon->regmap = devm_regmap_init_mmio(dev, base, &syscon_config);
index 22d2f02..b9f48e5 100644 (file)
@@ -158,7 +158,7 @@ static int tqmx86_board_id_to_clk_rate(u8 board_id)
 
 static int tqmx86_probe(struct platform_device *pdev)
 {
-       u8 board_id, rev, i2c_det, i2c_ien, io_ext_int_val;
+       u8 board_id, rev, i2c_det, io_ext_int_val;
        struct device *dev = &pdev->dev;
        u8 gpio_irq_cfg, readback;
        const char *board_name;
@@ -196,7 +196,6 @@ static int tqmx86_probe(struct platform_device *pdev)
                 board_name, board_id, rev >> 4, rev & 0xf);
 
        i2c_det = ioread8(io_base + TQMX86_REG_I2C_DETECT);
-       i2c_ien = ioread8(io_base + TQMX86_REG_I2C_INT_EN);
 
        if (gpio_irq_cfg) {
                io_ext_int_val =
diff --git a/drivers/mfd/wcd934x.c b/drivers/mfd/wcd934x.c
new file mode 100644 (file)
index 0000000..90341f3
--- /dev/null
@@ -0,0 +1,306 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2019, Linaro Limited
+
+#include <linux/clk.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/wcd934x/registers.h>
+#include <linux/mfd/wcd934x/wcd934x.h>
+#include <linux/module.h>
+#include <linux/of_gpio.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slimbus.h>
+
+static const struct mfd_cell wcd934x_devices[] = {
+       {
+               .name = "wcd934x-codec",
+       }, {
+               .name = "wcd934x-gpio",
+               .of_compatible = "qcom,wcd9340-gpio",
+       }, {
+               .name = "wcd934x-soundwire",
+               .of_compatible = "qcom,soundwire-v1.3.0",
+       },
+};
+
+static const struct regmap_irq wcd934x_irqs[] = {
+       [WCD934X_IRQ_SLIMBUS] = {
+               .reg_offset = 0,
+               .mask = BIT(0),
+               .type = {
+                       .type_reg_offset = 0,
+                       .types_supported = IRQ_TYPE_EDGE_BOTH,
+                       .type_reg_mask  = BIT(0),
+                       .type_level_low_val = BIT(0),
+                       .type_level_high_val = BIT(0),
+                       .type_falling_val = 0,
+                       .type_rising_val = 0,
+               },
+       },
+       [WCD934X_IRQ_SOUNDWIRE] = {
+               .reg_offset = 2,
+               .mask = BIT(4),
+               .type = {
+                       .type_reg_offset = 2,
+                       .types_supported = IRQ_TYPE_EDGE_BOTH,
+                       .type_reg_mask  = BIT(4),
+                       .type_level_low_val = BIT(4),
+                       .type_level_high_val = BIT(4),
+                       .type_falling_val = 0,
+                       .type_rising_val = 0,
+               },
+       },
+};
+
+static const struct regmap_irq_chip wcd934x_regmap_irq_chip = {
+       .name = "wcd934x_irq",
+       .status_base = WCD934X_INTR_PIN1_STATUS0,
+       .mask_base = WCD934X_INTR_PIN1_MASK0,
+       .ack_base = WCD934X_INTR_PIN1_CLEAR0,
+       .type_base = WCD934X_INTR_LEVEL0,
+       .num_type_reg = 4,
+       .type_in_mask = false,
+       .num_regs = 4,
+       .irqs = wcd934x_irqs,
+       .num_irqs = ARRAY_SIZE(wcd934x_irqs),
+};
+
+static bool wcd934x_is_volatile_register(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case WCD934X_INTR_PIN1_STATUS0...WCD934X_INTR_PIN2_CLEAR3:
+       case WCD934X_SWR_AHB_BRIDGE_RD_DATA_0:
+       case WCD934X_SWR_AHB_BRIDGE_RD_DATA_1:
+       case WCD934X_SWR_AHB_BRIDGE_RD_DATA_2:
+       case WCD934X_SWR_AHB_BRIDGE_RD_DATA_3:
+       case WCD934X_SWR_AHB_BRIDGE_ACCESS_STATUS:
+       case WCD934X_ANA_MBHC_RESULT_3:
+       case WCD934X_ANA_MBHC_RESULT_2:
+       case WCD934X_ANA_MBHC_RESULT_1:
+       case WCD934X_ANA_MBHC_MECH:
+       case WCD934X_ANA_MBHC_ELECT:
+       case WCD934X_ANA_MBHC_ZDET:
+       case WCD934X_ANA_MICB2:
+       case WCD934X_ANA_RCO:
+       case WCD934X_ANA_BIAS:
+               return true;
+       default:
+               return false;
+       }
+};
+
+static const struct regmap_range_cfg wcd934x_ranges[] = {
+       {       .name = "WCD934X",
+               .range_min =  0x0,
+               .range_max =  WCD934X_MAX_REGISTER,
+               .selector_reg = WCD934X_SEL_REGISTER,
+               .selector_mask = WCD934X_SEL_MASK,
+               .selector_shift = WCD934X_SEL_SHIFT,
+               .window_start = WCD934X_WINDOW_START,
+               .window_len = WCD934X_WINDOW_LENGTH,
+       },
+};
+
+static struct regmap_config wcd934x_regmap_config = {
+       .reg_bits = 16,
+       .val_bits = 8,
+       .cache_type = REGCACHE_RBTREE,
+       .max_register = 0xffff,
+       .can_multi_write = true,
+       .ranges = wcd934x_ranges,
+       .num_ranges = ARRAY_SIZE(wcd934x_ranges),
+       .volatile_reg = wcd934x_is_volatile_register,
+};
+
+static int wcd934x_bring_up(struct wcd934x_ddata *ddata)
+{
+       struct regmap *regmap = ddata->regmap;
+       u16 id_minor, id_major;
+       int ret;
+
+       ret = regmap_bulk_read(regmap, WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0,
+                              (u8 *)&id_minor, sizeof(u16));
+       if (ret)
+               return ret;
+
+       ret = regmap_bulk_read(regmap, WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE2,
+                              (u8 *)&id_major, sizeof(u16));
+       if (ret)
+               return ret;
+
+       dev_info(ddata->dev, "WCD934x chip id major 0x%x, minor 0x%x\n",
+                id_major, id_minor);
+
+       regmap_write(regmap, WCD934X_CODEC_RPM_RST_CTL, 0x01);
+       regmap_write(regmap, WCD934X_SIDO_NEW_VOUT_A_STARTUP, 0x19);
+       regmap_write(regmap, WCD934X_SIDO_NEW_VOUT_D_STARTUP, 0x15);
+       /* Add 1msec delay for VOUT to settle */
+       usleep_range(1000, 1100);
+       regmap_write(regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x5);
+       regmap_write(regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x7);
+       regmap_write(regmap, WCD934X_CODEC_RPM_RST_CTL, 0x3);
+       regmap_write(regmap, WCD934X_CODEC_RPM_RST_CTL, 0x7);
+       regmap_write(regmap, WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL, 0x3);
+
+       return 0;
+}
+
+static int wcd934x_slim_status_up(struct slim_device *sdev)
+{
+       struct device *dev = &sdev->dev;
+       struct wcd934x_ddata *ddata;
+       int ret;
+
+       ddata = dev_get_drvdata(dev);
+
+       ddata->regmap = regmap_init_slimbus(sdev, &wcd934x_regmap_config);
+       if (IS_ERR(ddata->regmap)) {
+               dev_err(dev, "Error allocating slim regmap\n");
+               return PTR_ERR(ddata->regmap);
+       }
+
+       ret = wcd934x_bring_up(ddata);
+       if (ret) {
+               dev_err(dev, "Failed to bring up WCD934X: err = %d\n", ret);
+               return ret;
+       }
+
+       ret = devm_regmap_add_irq_chip(dev, ddata->regmap, ddata->irq,
+                                      IRQF_TRIGGER_HIGH, 0,
+                                      &wcd934x_regmap_irq_chip,
+                                      &ddata->irq_data);
+       if (ret) {
+               dev_err(dev, "Failed to add IRQ chip: err = %d\n", ret);
+               return ret;
+       }
+
+       ret = mfd_add_devices(dev, PLATFORM_DEVID_AUTO, wcd934x_devices,
+                             ARRAY_SIZE(wcd934x_devices), NULL, 0, NULL);
+       if (ret) {
+               dev_err(dev, "Failed to add child devices: err = %d\n",
+                       ret);
+               return ret;
+       }
+
+       return ret;
+}
+
+static int wcd934x_slim_status(struct slim_device *sdev,
+                              enum slim_device_status status)
+{
+       switch (status) {
+       case SLIM_DEVICE_STATUS_UP:
+               return wcd934x_slim_status_up(sdev);
+       case SLIM_DEVICE_STATUS_DOWN:
+               mfd_remove_devices(&sdev->dev);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int wcd934x_slim_probe(struct slim_device *sdev)
+{
+       struct device *dev = &sdev->dev;
+       struct device_node *np = dev->of_node;
+       struct wcd934x_ddata *ddata;
+       int reset_gpio, ret;
+
+       ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
+       if (!ddata)
+               return  -ENOMEM;
+
+       ddata->irq = of_irq_get(np, 0);
+       if (ddata->irq < 0) {
+               if (ddata->irq != -EPROBE_DEFER)
+                       dev_err(ddata->dev, "Failed to get IRQ: err = %d\n",
+                               ddata->irq);
+               return ddata->irq;
+       }
+
+       reset_gpio = of_get_named_gpio(np, "reset-gpios", 0);
+       if (reset_gpio < 0) {
+               dev_err(dev, "Failed to get reset gpio: err = %d\n",
+                       reset_gpio);
+               return reset_gpio;
+       }
+
+       ddata->extclk = devm_clk_get(dev, "extclk");
+       if (IS_ERR(ddata->extclk)) {
+               dev_err(dev, "Failed to get extclk");
+               return PTR_ERR(ddata->extclk);
+       }
+
+       ddata->supplies[0].supply = "vdd-buck";
+       ddata->supplies[1].supply = "vdd-buck-sido";
+       ddata->supplies[2].supply = "vdd-tx";
+       ddata->supplies[3].supply = "vdd-rx";
+       ddata->supplies[4].supply = "vdd-io";
+
+       ret = regulator_bulk_get(dev, WCD934X_MAX_SUPPLY, ddata->supplies);
+       if (ret) {
+               dev_err(dev, "Failed to get supplies: err = %d\n", ret);
+               return ret;
+       }
+
+       ret = regulator_bulk_enable(WCD934X_MAX_SUPPLY, ddata->supplies);
+       if (ret) {
+               dev_err(dev, "Failed to enable supplies: err = %d\n", ret);
+               return ret;
+       }
+
+       /*
+        * For WCD934X, it takes about 600us for the Vout_A and
+        * Vout_D to be ready after BUCK_SIDO is powered up.
+        * SYS_RST_N shouldn't be pulled high during this time
+        */
+       usleep_range(600, 650);
+       gpio_direction_output(reset_gpio, 0);
+       msleep(20);
+       gpio_set_value(reset_gpio, 1);
+       msleep(20);
+
+       ddata->dev = dev;
+       dev_set_drvdata(dev, ddata);
+
+       return 0;
+}
+
+static void wcd934x_slim_remove(struct slim_device *sdev)
+{
+       struct wcd934x_ddata *ddata = dev_get_drvdata(&sdev->dev);
+
+       regulator_bulk_disable(WCD934X_MAX_SUPPLY, ddata->supplies);
+       mfd_remove_devices(&sdev->dev);
+       kfree(ddata);
+}
+
+static const struct slim_device_id wcd934x_slim_id[] = {
+       { SLIM_MANF_ID_QCOM, SLIM_PROD_CODE_WCD9340,
+         SLIM_DEV_IDX_WCD9340, SLIM_DEV_INSTANCE_ID_WCD9340 },
+       {}
+};
+
+static struct slim_driver wcd934x_slim_driver = {
+       .driver = {
+               .name = "wcd934x-slim",
+       },
+       .probe = wcd934x_slim_probe,
+       .remove = wcd934x_slim_remove,
+       .device_status = wcd934x_slim_status,
+       .id_table = wcd934x_slim_id,
+};
+
+module_slim_driver(wcd934x_slim_driver);
+MODULE_DESCRIPTION("WCD934X slim driver");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("slim:217:250:*");
+MODULE_AUTHOR("Srinivas Kandagatla <srinivas.kandagatla@linaro.org>");
index 0681d5f..031eb64 100644 (file)
@@ -1,4 +1,4 @@
-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0-or-later
 /*
  * at24.c - handle most I2C EEPROMs
  *
@@ -6,23 +6,23 @@
  * Copyright (C) 2008 Wolfram Sang, Pengutronix
  */
 
-#include <linux/kernel.h>
+#include <linux/acpi.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/i2c.h>
 #include <linux/init.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/mod_devicetable.h>
 #include <linux/module.h>
-#include <linux/of_device.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/mutex.h>
-#include <linux/mod_devicetable.h>
-#include <linux/bitops.h>
-#include <linux/jiffies.h>
-#include <linux/property.h>
-#include <linux/acpi.h>
-#include <linux/i2c.h>
 #include <linux/nvmem-provider.h>
-#include <linux/regmap.h>
+#include <linux/of_device.h>
 #include <linux/pm_runtime.h>
-#include <linux/gpio/consumer.h>
+#include <linux/property.h>
+#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
+#include <linux/slab.h>
 
 /* Address pointer is 16 bit. */
 #define AT24_FLAG_ADDR16       BIT(7)
@@ -88,8 +88,7 @@ struct at24_data {
        u8 flags;
 
        struct nvmem_device *nvmem;
-
-       struct gpio_desc *wp_gpio;
+       struct regulator *vcc_reg;
 
        /*
         * Some chips tie up multiple I2C addresses; dummy devices reserve
@@ -457,12 +456,10 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
         * from this host, but not from other I2C masters.
         */
        mutex_lock(&at24->lock);
-       gpiod_set_value_cansleep(at24->wp_gpio, 0);
 
        while (count) {
                ret = at24_regmap_write(at24, buf, off, count);
                if (ret < 0) {
-                       gpiod_set_value_cansleep(at24->wp_gpio, 1);
                        mutex_unlock(&at24->lock);
                        pm_runtime_put(dev);
                        return ret;
@@ -472,7 +469,6 @@ static int at24_write(void *priv, unsigned int off, void *val, size_t count)
                count -= ret;
        }
 
-       gpiod_set_value_cansleep(at24->wp_gpio, 1);
        mutex_unlock(&at24->lock);
 
        pm_runtime_put(dev);
@@ -662,9 +658,9 @@ static int at24_probe(struct i2c_client *client)
        at24->client[0].client = client;
        at24->client[0].regmap = regmap;
 
-       at24->wp_gpio = devm_gpiod_get_optional(dev, "wp", GPIOD_OUT_HIGH);
-       if (IS_ERR(at24->wp_gpio))
-               return PTR_ERR(at24->wp_gpio);
+       at24->vcc_reg = devm_regulator_get(dev, "vcc");
+       if (IS_ERR(at24->vcc_reg))
+               return PTR_ERR(at24->vcc_reg);
 
        writable = !(flags & AT24_FLAG_READONLY);
        if (writable) {
@@ -701,6 +697,12 @@ static int at24_probe(struct i2c_client *client)
 
        i2c_set_clientdata(client, at24);
 
+       err = regulator_enable(at24->vcc_reg);
+       if (err) {
+               dev_err(dev, "Failed to enable vcc regulator\n");
+               return err;
+       }
+
        /* enable runtime pm */
        pm_runtime_set_active(dev);
        pm_runtime_enable(dev);
@@ -713,6 +715,7 @@ static int at24_probe(struct i2c_client *client)
        pm_runtime_idle(dev);
        if (err) {
                pm_runtime_disable(dev);
+               regulator_disable(at24->vcc_reg);
                return -ENODEV;
        }
 
@@ -728,15 +731,42 @@ static int at24_probe(struct i2c_client *client)
 
 static int at24_remove(struct i2c_client *client)
 {
+       struct at24_data *at24 = i2c_get_clientdata(client);
+
        pm_runtime_disable(&client->dev);
+       if (!pm_runtime_status_suspended(&client->dev))
+               regulator_disable(at24->vcc_reg);
        pm_runtime_set_suspended(&client->dev);
 
        return 0;
 }
 
+static int __maybe_unused at24_suspend(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct at24_data *at24 = i2c_get_clientdata(client);
+
+       return regulator_disable(at24->vcc_reg);
+}
+
+static int __maybe_unused at24_resume(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct at24_data *at24 = i2c_get_clientdata(client);
+
+       return regulator_enable(at24->vcc_reg);
+}
+
+static const struct dev_pm_ops at24_pm_ops = {
+       SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+                               pm_runtime_force_resume)
+       SET_RUNTIME_PM_OPS(at24_suspend, at24_resume, NULL)
+};
+
 static struct i2c_driver at24_driver = {
        .driver = {
                .name = "at24",
+               .pm = &at24_pm_ops,
                .of_match_table = at24_of_match,
                .acpi_match_table = ACPI_PTR(at24_acpi_ids),
        },
index 1916fa6..2d2266c 100644 (file)
@@ -11,6 +11,7 @@ config OCXL
        tristate "OpenCAPI coherent accelerator support"
        depends on PPC_POWERNV && PCI && EEH
        select OCXL_BASE
+       select HOTPLUG_PCI_POWERNV
        default m
        help
          Select this option to enable the ocxl driver for Open
index 2817f47..97b8b38 100644 (file)
@@ -255,28 +255,28 @@ static int options_open(struct inode *inode, struct file *file)
 }
 
 /* *INDENT-OFF* */
-static const struct file_operations statistics_fops = {
-       .open           = statistics_open,
-       .read           = seq_read,
-       .write          = statistics_write,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops statistics_proc_ops = {
+       .proc_open      = statistics_open,
+       .proc_read      = seq_read,
+       .proc_write     = statistics_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
-static const struct file_operations mcs_statistics_fops = {
-       .open           = mcs_statistics_open,
-       .read           = seq_read,
-       .write          = mcs_statistics_write,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops mcs_statistics_proc_ops = {
+       .proc_open      = mcs_statistics_open,
+       .proc_read      = seq_read,
+       .proc_write     = mcs_statistics_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
-static const struct file_operations options_fops = {
-       .open           = options_open,
-       .read           = seq_read,
-       .write          = options_write,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops options_proc_ops = {
+       .proc_open      = options_open,
+       .proc_read      = seq_read,
+       .proc_write     = options_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 static struct proc_dir_entry *proc_gru __read_mostly;
@@ -286,11 +286,11 @@ int gru_proc_init(void)
        proc_gru = proc_mkdir("sgi_uv/gru", NULL);
        if (!proc_gru)
                return -1;
-       if (!proc_create("statistics", 0644, proc_gru, &statistics_fops))
+       if (!proc_create("statistics", 0644, proc_gru, &statistics_proc_ops))
                goto err;
-       if (!proc_create("mcs_statistics", 0644, proc_gru, &mcs_statistics_fops))
+       if (!proc_create("mcs_statistics", 0644, proc_gru, &mcs_statistics_proc_ops))
                goto err;
-       if (!proc_create("debug_options", 0644, proc_gru, &options_fops))
+       if (!proc_create("debug_options", 0644, proc_gru, &options_proc_ops))
                goto err;
        if (!proc_create_seq("cch_status", 0444, proc_gru, &cch_seq_ops))
                goto err;
index 25fb72b..2f93c25 100644 (file)
@@ -1180,7 +1180,7 @@ static struct mtd_info * __init open_mtd_device(const char *mtd_dev)
                 * MTD device name.
                 */
                mtd = get_mtd_device_nm(mtd_dev);
-               if (IS_ERR(mtd) && PTR_ERR(mtd) == -ENODEV)
+               if (PTR_ERR(mtd) == -ENODEV)
                        /* Probably this is an MTD character device node path */
                        mtd = open_mtd_by_chdev(mtd_dev);
        } else
index 4f2e691..1cc2cd8 100644 (file)
@@ -1383,26 +1383,31 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
        bool do_tx_balance = true;
        u32 hash_index = 0;
        const u8 *hash_start = NULL;
-       struct ipv6hdr *ip6hdr;
 
        skb_reset_mac_header(skb);
        eth_data = eth_hdr(skb);
 
        switch (ntohs(skb->protocol)) {
        case ETH_P_IP: {
-               const struct iphdr *iph = ip_hdr(skb);
+               const struct iphdr *iph;
 
                if (is_broadcast_ether_addr(eth_data->h_dest) ||
-                   iph->daddr == ip_bcast ||
-                   iph->protocol == IPPROTO_IGMP) {
+                   !pskb_network_may_pull(skb, sizeof(*iph))) {
+                       do_tx_balance = false;
+                       break;
+               }
+               iph = ip_hdr(skb);
+               if (iph->daddr == ip_bcast || iph->protocol == IPPROTO_IGMP) {
                        do_tx_balance = false;
                        break;
                }
                hash_start = (char *)&(iph->daddr);
                hash_size = sizeof(iph->daddr);
-       }
                break;
-       case ETH_P_IPV6:
+       }
+       case ETH_P_IPV6: {
+               const struct ipv6hdr *ip6hdr;
+
                /* IPv6 doesn't really use broadcast mac address, but leave
                 * that here just in case.
                 */
@@ -1419,7 +1424,11 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
                        break;
                }
 
-               /* Additianally, DAD probes should not be tx-balanced as that
+               if (!pskb_network_may_pull(skb, sizeof(*ip6hdr))) {
+                       do_tx_balance = false;
+                       break;
+               }
+               /* Additionally, DAD probes should not be tx-balanced as that
                 * will lead to false positives for duplicate addresses and
                 * prevent address configuration from working.
                 */
@@ -1429,17 +1438,26 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
                        break;
                }
 
-               hash_start = (char *)&(ipv6_hdr(skb)->daddr);
-               hash_size = sizeof(ipv6_hdr(skb)->daddr);
+               hash_start = (char *)&ip6hdr->daddr;
+               hash_size = sizeof(ip6hdr->daddr);
                break;
-       case ETH_P_IPX:
-               if (ipx_hdr(skb)->ipx_checksum != IPX_NO_CHECKSUM) {
+       }
+       case ETH_P_IPX: {
+               const struct ipxhdr *ipxhdr;
+
+               if (pskb_network_may_pull(skb, sizeof(*ipxhdr))) {
+                       do_tx_balance = false;
+                       break;
+               }
+               ipxhdr = (struct ipxhdr *)skb_network_header(skb);
+
+               if (ipxhdr->ipx_checksum != IPX_NO_CHECKSUM) {
                        /* something is wrong with this packet */
                        do_tx_balance = false;
                        break;
                }
 
-               if (ipx_hdr(skb)->ipx_type != IPX_TYPE_NCP) {
+               if (ipxhdr->ipx_type != IPX_TYPE_NCP) {
                        /* The only protocol worth balancing in
                         * this family since it has an "ARP" like
                         * mechanism
@@ -1448,9 +1466,11 @@ netdev_tx_t bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
                        break;
                }
 
+               eth_data = eth_hdr(skb);
                hash_start = (char *)eth_data->h_dest;
                hash_size = ETH_ALEN;
                break;
+       }
        case ETH_P_ARP:
                do_tx_balance = false;
                if (bond_info->rlb_enabled)
index 0604975..449a221 100644 (file)
@@ -693,7 +693,7 @@ int b53_configure_vlan(struct dsa_switch *ds)
                b53_do_vlan_op(dev, VTA_CMD_CLEAR);
        }
 
-       b53_enable_vlan(dev, false, ds->vlan_filtering);
+       b53_enable_vlan(dev, dev->vlan_enabled, ds->vlan_filtering);
 
        b53_for_each_port(dev, i)
                b53_write16(dev, B53_VLAN_PAGE,
index 3e86353..d195554 100644 (file)
@@ -68,7 +68,9 @@ static void bcm_sf2_imp_setup(struct dsa_switch *ds, int port)
 
                /* Force link status for IMP port */
                reg = core_readl(priv, offset);
-               reg |= (MII_SW_OR | LINK_STS | GMII_SPEED_UP_2G);
+               reg |= (MII_SW_OR | LINK_STS);
+               if (priv->type == BCM7278_DEVICE_ID)
+                       reg |= GMII_SPEED_UP_2G;
                core_writel(priv, reg, offset);
 
                /* Enable Broadcast, Multicast, Unicast forwarding to IMP port */
index c5f6495..1142768 100644 (file)
@@ -101,6 +101,12 @@ static struct spi_driver ksz9477_spi_driver = {
 
 module_spi_driver(ksz9477_spi_driver);
 
+MODULE_ALIAS("spi:ksz9477");
+MODULE_ALIAS("spi:ksz9897");
+MODULE_ALIAS("spi:ksz9893");
+MODULE_ALIAS("spi:ksz9563");
+MODULE_ALIAS("spi:ksz8563");
+MODULE_ALIAS("spi:ksz9567");
 MODULE_AUTHOR("Woojung Huh <Woojung.Huh@microchip.com>");
 MODULE_DESCRIPTION("Microchip KSZ9477 Series Switch SPI access Driver");
 MODULE_LICENSE("GPL");
index f07ac0e..e0611cb 100644 (file)
@@ -2736,6 +2736,9 @@ static int __maybe_unused bcm_sysport_resume(struct device *d)
 
        umac_reset(priv);
 
+       /* Disable the UniMAC RX/TX */
+       umac_enable_set(priv, CMD_RX_EN | CMD_TX_EN, 0);
+
        /* We may have been suspended and never received a WOL event that
         * would turn off MPD detection, take care of that now
         */
index 483935b..597e6fd 100644 (file)
@@ -7893,7 +7893,7 @@ static void bnxt_setup_msix(struct bnxt *bp)
        int tcs, i;
 
        tcs = netdev_get_num_tc(dev);
-       if (tcs > 1) {
+       if (tcs) {
                int i, off, count;
 
                for (i = 0; i < tcs; i++) {
@@ -9241,6 +9241,17 @@ void bnxt_half_close_nic(struct bnxt *bp)
        bnxt_free_mem(bp, false);
 }
 
+static void bnxt_reenable_sriov(struct bnxt *bp)
+{
+       if (BNXT_PF(bp)) {
+               struct bnxt_pf_info *pf = &bp->pf;
+               int n = pf->active_vfs;
+
+               if (n)
+                       bnxt_cfg_hw_sriov(bp, &n, true);
+       }
+}
+
 static int bnxt_open(struct net_device *dev)
 {
        struct bnxt *bp = netdev_priv(dev);
@@ -9259,15 +9270,10 @@ static int bnxt_open(struct net_device *dev)
                bnxt_hwrm_if_change(bp, false);
        } else {
                if (test_and_clear_bit(BNXT_STATE_FW_RESET_DET, &bp->state)) {
-                       if (BNXT_PF(bp)) {
-                               struct bnxt_pf_info *pf = &bp->pf;
-                               int n = pf->active_vfs;
-
-                               if (n)
-                                       bnxt_cfg_hw_sriov(bp, &n, true);
-                       }
-                       if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state))
+                       if (!test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
                                bnxt_ulp_start(bp, 0);
+                               bnxt_reenable_sriov(bp);
+                       }
                }
                bnxt_hwmon_open(bp);
        }
@@ -9307,10 +9313,6 @@ static void __bnxt_close_nic(struct bnxt *bp, bool irq_re_init,
        bnxt_debug_dev_exit(bp);
        bnxt_disable_napi(bp);
        del_timer_sync(&bp->timer);
-       if (test_bit(BNXT_STATE_IN_FW_RESET, &bp->state) &&
-           pci_is_enabled(bp->pdev))
-               pci_disable_device(bp->pdev);
-
        bnxt_free_skbs(bp);
 
        /* Save ring stats before shutdown */
@@ -10096,9 +10098,16 @@ static void bnxt_reset(struct bnxt *bp, bool silent)
 static void bnxt_fw_reset_close(struct bnxt *bp)
 {
        bnxt_ulp_stop(bp);
+       /* When firmware is fatal state, disable PCI device to prevent
+        * any potential bad DMAs before freeing kernel memory.
+        */
+       if (test_bit(BNXT_STATE_FW_FATAL_COND, &bp->state))
+               pci_disable_device(bp->pdev);
        __bnxt_close_nic(bp, true, false);
        bnxt_clear_int_mode(bp);
        bnxt_hwrm_func_drv_unrgtr(bp);
+       if (pci_is_enabled(bp->pdev))
+               pci_disable_device(bp->pdev);
        bnxt_free_ctx_mem(bp);
        kfree(bp->ctx);
        bp->ctx = NULL;
@@ -10831,6 +10840,8 @@ static void bnxt_fw_reset_task(struct work_struct *work)
                smp_mb__before_atomic();
                clear_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
                bnxt_ulp_start(bp, rc);
+               if (!rc)
+                       bnxt_reenable_sriov(bp);
                bnxt_dl_health_recovery_done(bp);
                bnxt_dl_health_status_update(bp, true);
                rtnl_unlock();
index 7a2fe63..4508f0d 100644 (file)
@@ -73,7 +73,11 @@ struct sifive_fu540_macb_mgmt {
 /* Max length of transmit frame must be a multiple of 8 bytes */
 #define MACB_TX_LEN_ALIGN      8
 #define MACB_MAX_TX_LEN                ((unsigned int)((1 << MACB_TX_FRMLEN_SIZE) - 1) & ~((unsigned int)(MACB_TX_LEN_ALIGN - 1)))
-#define GEM_MAX_TX_LEN         ((unsigned int)((1 << GEM_TX_FRMLEN_SIZE) - 1) & ~((unsigned int)(MACB_TX_LEN_ALIGN - 1)))
+/* Limit maximum TX length as per Cadence TSO errata. This is to avoid a
+ * false amba_error in TX path from the DMA assuming there is not enough
+ * space in the SRAM (16KB) even when there is.
+ */
+#define GEM_MAX_TX_LEN         (unsigned int)(0x3FC0)
 
 #define GEM_MTU_MIN_SIZE       ETH_MIN_MTU
 #define MACB_NETIF_LSO         NETIF_F_TSO
@@ -1791,16 +1795,14 @@ static netdev_features_t macb_features_check(struct sk_buff *skb,
 
        /* Validate LSO compatibility */
 
-       /* there is only one buffer */
-       if (!skb_is_nonlinear(skb))
+       /* there is only one buffer or protocol is not UDP */
+       if (!skb_is_nonlinear(skb) || (ip_hdr(skb)->protocol != IPPROTO_UDP))
                return features;
 
        /* length of header */
        hdrlen = skb_transport_offset(skb);
-       if (ip_hdr(skb)->protocol == IPPROTO_TCP)
-               hdrlen += tcp_hdrlen(skb);
 
-       /* For LSO:
+       /* For UFO only:
         * When software supplies two or more payload buffers all payload buffers
         * apart from the last must be a multiple of 8 bytes in size.
         */
index c4f6ec0..17a4110 100644 (file)
@@ -1039,7 +1039,7 @@ static int phy_interface_mode(u8 lmac_type)
        if (lmac_type == BGX_MODE_QSGMII)
                return PHY_INTERFACE_MODE_QSGMII;
        if (lmac_type == BGX_MODE_RGMII)
-               return PHY_INTERFACE_MODE_RGMII;
+               return PHY_INTERFACE_MODE_RGMII_RXID;
 
        return PHY_INTERFACE_MODE_SGMII;
 }
index 9d1f2f8..de30d61 100644 (file)
@@ -3403,6 +3403,13 @@ static int chcr_stats_show(struct seq_file *seq, void *v)
                   atomic_read(&adap->chcr_stats.fallback));
        seq_printf(seq, "IPSec PDU: %10u\n",
                   atomic_read(&adap->chcr_stats.ipsec_cnt));
+       seq_printf(seq, "TLS PDU Tx: %10u\n",
+                  atomic_read(&adap->chcr_stats.tls_pdu_tx));
+       seq_printf(seq, "TLS PDU Rx: %10u\n",
+                  atomic_read(&adap->chcr_stats.tls_pdu_rx));
+       seq_printf(seq, "TLS Keys (DDR) Count: %10u\n",
+                  atomic_read(&adap->chcr_stats.tls_key));
+
        return 0;
 }
 DEFINE_SHOW_ATTRIBUTE(chcr_stats);
index d305d1b..42b798a 100644 (file)
@@ -417,7 +417,10 @@ static void de_rx (struct de_private *de)
                if (status & DescOwn)
                        break;
 
-               len = ((status >> 16) & 0x7ff) - 4;
+               /* the length is actually a 15 bit value here according
+                * to Table 4-1 in the DE2104x spec so mask is 0x7fff
+                */
+               len = ((status >> 16) & 0x7fff) - 4;
                mapping = de->rx_skb[rx_tail].mapping;
 
                if (unlikely(drop)) {
index 6a7e899..2bd7ace 100644 (file)
@@ -74,7 +74,7 @@ config FSL_XGMAC_MDIO
 
 config UCC_GETH
        tristate "Freescale QE Gigabit Ethernet"
-       depends on QUICC_ENGINE
+       depends on QUICC_ENGINE && PPC32
        select FSL_PQ_MDIO
        select PHYLIB
        ---help---
index 09dbcd8..fd93d54 100644 (file)
@@ -2453,6 +2453,9 @@ static void dpaa_adjust_link(struct net_device *net_dev)
        mac_dev->adjust_link(mac_dev);
 }
 
+/* The Aquantia PHYs are capable of performing rate adaptation */
+#define PHY_VEND_AQUANTIA      0x03a1b400
+
 static int dpaa_phy_init(struct net_device *net_dev)
 {
        __ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
@@ -2471,9 +2474,14 @@ static int dpaa_phy_init(struct net_device *net_dev)
                return -ENODEV;
        }
 
-       /* Remove any features not supported by the controller */
-       ethtool_convert_legacy_u32_to_link_mode(mask, mac_dev->if_support);
-       linkmode_and(phy_dev->supported, phy_dev->supported, mask);
+       /* Unless the PHY is capable of rate adaptation */
+       if (mac_dev->phy_if != PHY_INTERFACE_MODE_XGMII ||
+           ((phy_dev->drv->phy_id & GENMASK(31, 10)) != PHY_VEND_AQUANTIA)) {
+               /* remove any features not supported by the controller */
+               ethtool_convert_legacy_u32_to_link_mode(mask,
+                                                       mac_dev->if_support);
+               linkmode_and(phy_dev->supported, phy_dev->supported, mask);
+       }
 
        phy_support_asym_pause(phy_dev);
 
index 42058fa..0b7d291 100644 (file)
@@ -791,7 +791,7 @@ int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags)
        struct i40e_ring *ring;
 
        if (test_bit(__I40E_CONFIG_BUSY, pf->state))
-               return -ENETDOWN;
+               return -EAGAIN;
 
        if (test_bit(__I40E_VSI_DOWN, vsi->state))
                return -ENETDOWN;
index 037e054..98017e7 100644 (file)
@@ -401,6 +401,8 @@ struct mvneta_pcpu_stats {
        struct  u64_stats_sync syncp;
        u64     rx_packets;
        u64     rx_bytes;
+       u64     rx_dropped;
+       u64     rx_errors;
        u64     tx_packets;
        u64     tx_bytes;
 };
@@ -738,6 +740,8 @@ mvneta_get_stats64(struct net_device *dev,
                struct mvneta_pcpu_stats *cpu_stats;
                u64 rx_packets;
                u64 rx_bytes;
+               u64 rx_dropped;
+               u64 rx_errors;
                u64 tx_packets;
                u64 tx_bytes;
 
@@ -746,19 +750,20 @@ mvneta_get_stats64(struct net_device *dev,
                        start = u64_stats_fetch_begin_irq(&cpu_stats->syncp);
                        rx_packets = cpu_stats->rx_packets;
                        rx_bytes   = cpu_stats->rx_bytes;
+                       rx_dropped = cpu_stats->rx_dropped;
+                       rx_errors  = cpu_stats->rx_errors;
                        tx_packets = cpu_stats->tx_packets;
                        tx_bytes   = cpu_stats->tx_bytes;
                } while (u64_stats_fetch_retry_irq(&cpu_stats->syncp, start));
 
                stats->rx_packets += rx_packets;
                stats->rx_bytes   += rx_bytes;
+               stats->rx_dropped += rx_dropped;
+               stats->rx_errors  += rx_errors;
                stats->tx_packets += tx_packets;
                stats->tx_bytes   += tx_bytes;
        }
 
-       stats->rx_errors        = dev->stats.rx_errors;
-       stats->rx_dropped       = dev->stats.rx_dropped;
-
        stats->tx_dropped       = dev->stats.tx_dropped;
 }
 
@@ -1736,8 +1741,14 @@ static u32 mvneta_txq_desc_csum(int l3_offs, int l3_proto,
 static void mvneta_rx_error(struct mvneta_port *pp,
                            struct mvneta_rx_desc *rx_desc)
 {
+       struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats);
        u32 status = rx_desc->status;
 
+       /* update per-cpu counter */
+       u64_stats_update_begin(&stats->syncp);
+       stats->rx_errors++;
+       u64_stats_update_end(&stats->syncp);
+
        switch (status & MVNETA_RXD_ERR_CODE_MASK) {
        case MVNETA_RXD_ERR_CRC:
                netdev_err(pp->dev, "bad rx status %08x (crc error), size=%d\n",
@@ -2179,11 +2190,15 @@ mvneta_swbm_rx_frame(struct mvneta_port *pp,
 
        rxq->skb = build_skb(xdp->data_hard_start, PAGE_SIZE);
        if (unlikely(!rxq->skb)) {
-               netdev_err(dev,
-                          "Can't allocate skb on queue %d\n",
-                          rxq->id);
-               dev->stats.rx_dropped++;
+               struct mvneta_pcpu_stats *stats = this_cpu_ptr(pp->stats);
+
+               netdev_err(dev, "Can't allocate skb on queue %d\n", rxq->id);
                rxq->skb_alloc_err++;
+
+               u64_stats_update_begin(&stats->syncp);
+               stats->rx_dropped++;
+               u64_stats_update_end(&stats->syncp);
+
                return -ENOMEM;
        }
        page_pool_release_page(rxq->page_pool, page);
@@ -2270,7 +2285,6 @@ static int mvneta_rx_swbm(struct napi_struct *napi,
                        /* Check errors only for FIRST descriptor */
                        if (rx_status & MVNETA_RXD_ERR_SUMMARY) {
                                mvneta_rx_error(pp, rx_desc);
-                               dev->stats.rx_errors++;
                                /* leave the descriptor untouched */
                                continue;
                        }
@@ -2372,7 +2386,6 @@ err_drop_frame_ret_pool:
                        mvneta_bm_pool_put_bp(pp->bm_priv, bm_pool,
                                              rx_desc->buf_phys_addr);
 err_drop_frame:
-                       dev->stats.rx_errors++;
                        mvneta_rx_error(pp, rx_desc);
                        /* leave the descriptor untouched */
                        continue;
index 8247d21..b945bd3 100644 (file)
@@ -171,9 +171,9 @@ static int otx2_hw_get_mac_addr(struct otx2_nic *pfvf,
        }
 
        msghdr = otx2_mbox_get_rsp(&pfvf->mbox.mbox, 0, &req->hdr);
-       if (!msghdr) {
+       if (IS_ERR(msghdr)) {
                otx2_mbox_unlock(&pfvf->mbox);
-               return -ENOMEM;
+               return PTR_ERR(msghdr);
        }
        rsp = (struct nix_get_mac_addr_rsp *)msghdr;
        ether_addr_copy(netdev->dev_addr, rsp->mac_addr);
index d787bc0..e09bc38 100644 (file)
@@ -45,7 +45,7 @@ void mlx5_ktls_destroy_key(struct mlx5_core_dev *mdev, u32 key_id);
 
 static inline bool mlx5_accel_is_ktls_device(struct mlx5_core_dev *mdev)
 {
-       if (!MLX5_CAP_GEN(mdev, tls))
+       if (!MLX5_CAP_GEN(mdev, tls_tx))
                return false;
 
        if (!MLX5_CAP_GEN(mdev, log_max_dek))
index 71384ad..ef1ed15 100644 (file)
@@ -269,7 +269,7 @@ struct sk_buff *mlx5e_tls_handle_tx_skb(struct net_device *netdev,
        int datalen;
        u32 skb_seq;
 
-       if (MLX5_CAP_GEN(sq->channel->mdev, tls)) {
+       if (MLX5_CAP_GEN(sq->channel->mdev, tls_tx)) {
                skb = mlx5e_ktls_handle_tx_skb(netdev, sq, skb, wqe, pi);
                goto out;
        }
index 9e99601..1c3ab69 100644 (file)
@@ -613,13 +613,6 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
 
                wqe_counter = be16_to_cpu(cqe->wqe_counter);
 
-               if (unlikely(get_cqe_opcode(cqe) != MLX5_CQE_REQ)) {
-                       netdev_WARN_ONCE(cq->channel->netdev,
-                                        "Bad OP in ICOSQ CQE: 0x%x\n", get_cqe_opcode(cqe));
-                       if (!test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state))
-                               queue_work(cq->channel->priv->wq, &sq->recover_work);
-                       break;
-               }
                do {
                        struct mlx5e_sq_wqe_info *wi;
                        u16 ci;
@@ -629,6 +622,15 @@ void mlx5e_poll_ico_cq(struct mlx5e_cq *cq)
                        ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc);
                        wi = &sq->db.ico_wqe[ci];
 
+                       if (last_wqe && unlikely(get_cqe_opcode(cqe) != MLX5_CQE_REQ)) {
+                               netdev_WARN_ONCE(cq->channel->netdev,
+                                                "Bad OP in ICOSQ CQE: 0x%x\n",
+                                                get_cqe_opcode(cqe));
+                               if (!test_and_set_bit(MLX5E_SQ_STATE_RECOVERING, &sq->state))
+                                       queue_work(cq->channel->priv->wq, &sq->recover_work);
+                               break;
+                       }
+
                        if (likely(wi->opcode == MLX5_OPCODE_UMR)) {
                                sqcc += MLX5E_UMR_WQEBBS;
                                wi->umr.rq->mpwqe.umr_completed++;
index 2565ba8..ee60383 100644 (file)
@@ -451,34 +451,17 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
 
        i = 0;
        do {
+               struct mlx5e_tx_wqe_info *wi;
                u16 wqe_counter;
                bool last_wqe;
+               u16 ci;
 
                mlx5_cqwq_pop(&cq->wq);
 
                wqe_counter = be16_to_cpu(cqe->wqe_counter);
 
-               if (unlikely(get_cqe_opcode(cqe) == MLX5_CQE_REQ_ERR)) {
-                       if (!test_and_set_bit(MLX5E_SQ_STATE_RECOVERING,
-                                             &sq->state)) {
-                               struct mlx5e_tx_wqe_info *wi;
-                               u16 ci;
-
-                               ci = mlx5_wq_cyc_ctr2ix(&sq->wq, sqcc);
-                               wi = &sq->db.wqe_info[ci];
-                               mlx5e_dump_error_cqe(sq,
-                                                    (struct mlx5_err_cqe *)cqe);
-                               mlx5_wq_cyc_wqe_dump(&sq->wq, ci, wi->num_wqebbs);
-                               queue_work(cq->channel->priv->wq,
-                                          &sq->recover_work);
-                       }
-                       stats->cqe_err++;
-               }
-
                do {
-                       struct mlx5e_tx_wqe_info *wi;
                        struct sk_buff *skb;
-                       u16 ci;
                        int j;
 
                        last_wqe = (sqcc == wqe_counter);
@@ -516,6 +499,18 @@ bool mlx5e_poll_tx_cq(struct mlx5e_cq *cq, int napi_budget)
                        napi_consume_skb(skb, napi_budget);
                } while (!last_wqe);
 
+               if (unlikely(get_cqe_opcode(cqe) == MLX5_CQE_REQ_ERR)) {
+                       if (!test_and_set_bit(MLX5E_SQ_STATE_RECOVERING,
+                                             &sq->state)) {
+                               mlx5e_dump_error_cqe(sq,
+                                                    (struct mlx5_err_cqe *)cqe);
+                               mlx5_wq_cyc_wqe_dump(&sq->wq, ci, wi->num_wqebbs);
+                               queue_work(cq->channel->priv->wq,
+                                          &sq->recover_work);
+                       }
+                       stats->cqe_err++;
+               }
+
        } while ((++i < MLX5E_TX_CQ_POLL_BUDGET) && (cqe = mlx5_cqwq_get_cqe(&cq->wq)));
 
        stats->cqes += i;
index e4ec0e0..4c61d25 100644 (file)
@@ -850,6 +850,7 @@ void mlx5_fpga_ipsec_delete_sa_ctx(void *context)
        mutex_lock(&fpga_xfrm->lock);
        if (!--fpga_xfrm->num_rules) {
                mlx5_fpga_ipsec_release_sa_ctx(fpga_xfrm->sa_ctx);
+               kfree(fpga_xfrm->sa_ctx);
                fpga_xfrm->sa_ctx = NULL;
        }
        mutex_unlock(&fpga_xfrm->lock);
@@ -1478,7 +1479,7 @@ int mlx5_fpga_esp_modify_xfrm(struct mlx5_accel_esp_xfrm *xfrm,
        if (!memcmp(&xfrm->attrs, attrs, sizeof(xfrm->attrs)))
                return 0;
 
-       if (!mlx5_fpga_esp_validate_xfrm_attrs(mdev, attrs)) {
+       if (mlx5_fpga_esp_validate_xfrm_attrs(mdev, attrs)) {
                mlx5_core_warn(mdev, "Tried to create an esp with unsupported attrs\n");
                return -EOPNOTSUPP;
        }
index c7a16ae..9dc2424 100644 (file)
@@ -1582,16 +1582,16 @@ struct match_list_head {
        struct match_list first;
 };
 
-static void free_match_list(struct match_list_head *head)
+static void free_match_list(struct match_list_head *head, bool ft_locked)
 {
        if (!list_empty(&head->list)) {
                struct match_list *iter, *match_tmp;
 
                list_del(&head->first.list);
-               tree_put_node(&head->first.g->node, false);
+               tree_put_node(&head->first.g->node, ft_locked);
                list_for_each_entry_safe(iter, match_tmp, &head->list,
                                         list) {
-                       tree_put_node(&iter->g->node, false);
+                       tree_put_node(&iter->g->node, ft_locked);
                        list_del(&iter->list);
                        kfree(iter);
                }
@@ -1600,7 +1600,8 @@ static void free_match_list(struct match_list_head *head)
 
 static int build_match_list(struct match_list_head *match_head,
                            struct mlx5_flow_table *ft,
-                           const struct mlx5_flow_spec *spec)
+                           const struct mlx5_flow_spec *spec,
+                           bool ft_locked)
 {
        struct rhlist_head *tmp, *list;
        struct mlx5_flow_group *g;
@@ -1625,7 +1626,7 @@ static int build_match_list(struct match_list_head *match_head,
 
                curr_match = kmalloc(sizeof(*curr_match), GFP_ATOMIC);
                if (!curr_match) {
-                       free_match_list(match_head);
+                       free_match_list(match_head, ft_locked);
                        err = -ENOMEM;
                        goto out;
                }
@@ -1805,7 +1806,7 @@ search_again_locked:
        version = atomic_read(&ft->node.version);
 
        /* Collect all fgs which has a matching match_criteria */
-       err = build_match_list(&match_head, ft, spec);
+       err = build_match_list(&match_head, ft, spec, take_write);
        if (err) {
                if (take_write)
                        up_write_ref_node(&ft->node, false);
@@ -1819,7 +1820,7 @@ search_again_locked:
 
        rule = try_add_to_existing_fg(ft, &match_head.list, spec, flow_act, dest,
                                      dest_num, version);
-       free_match_list(&match_head);
+       free_match_list(&match_head, take_write);
        if (!IS_ERR(rule) ||
            (PTR_ERR(rule) != -ENOENT && PTR_ERR(rule) != -EAGAIN)) {
                if (take_write)
index d89ff1d..909a7f2 100644 (file)
@@ -242,7 +242,7 @@ int mlx5_query_hca_caps(struct mlx5_core_dev *dev)
                        return err;
        }
 
-       if (MLX5_CAP_GEN(dev, tls)) {
+       if (MLX5_CAP_GEN(dev, tls_tx)) {
                err = mlx5_core_get_caps(dev, MLX5_CAP_TLS);
                if (err)
                        return err;
index 9bf8da5..3fe878d 100644 (file)
@@ -573,6 +573,7 @@ static int mlxsw_hwmon_module_init(struct mlxsw_hwmon *mlxsw_hwmon)
 
 static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
 {
+       enum mlxsw_reg_mgpir_device_type device_type;
        int index, max_index, sensor_index;
        char mgpir_pl[MLXSW_REG_MGPIR_LEN];
        char mtmp_pl[MLXSW_REG_MTMP_LEN];
@@ -584,8 +585,9 @@ static int mlxsw_hwmon_gearbox_init(struct mlxsw_hwmon *mlxsw_hwmon)
        if (err)
                return err;
 
-       mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, NULL, NULL, NULL);
-       if (!gbox_num)
+       mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL, NULL);
+       if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
+           !gbox_num)
                return 0;
 
        index = mlxsw_hwmon->module_sensor_max;
index c721b17..ce0a683 100644 (file)
@@ -895,8 +895,10 @@ static int
 mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
                             struct mlxsw_thermal *thermal)
 {
+       enum mlxsw_reg_mgpir_device_type device_type;
        struct mlxsw_thermal_module *gearbox_tz;
        char mgpir_pl[MLXSW_REG_MGPIR_LEN];
+       u8 gbox_num;
        int i;
        int err;
 
@@ -908,11 +910,13 @@ mlxsw_thermal_gearboxes_init(struct device *dev, struct mlxsw_core *core,
        if (err)
                return err;
 
-       mlxsw_reg_mgpir_unpack(mgpir_pl, &thermal->tz_gearbox_num, NULL, NULL,
+       mlxsw_reg_mgpir_unpack(mgpir_pl, &gbox_num, &device_type, NULL,
                               NULL);
-       if (!thermal->tz_gearbox_num)
+       if (device_type != MLXSW_REG_MGPIR_DEVICE_TYPE_GEARBOX_DIE ||
+           !gbox_num)
                return 0;
 
+       thermal->tz_gearbox_num = gbox_num;
        thermal->tz_gearbox_arr = kcalloc(thermal->tz_gearbox_num,
                                          sizeof(*thermal->tz_gearbox_arr),
                                          GFP_KERNEL);
index 4993381..2dc0978 100644 (file)
@@ -215,7 +215,7 @@ mlxsw_sp_dpipe_table_erif_entries_dump(void *priv, bool counters_enabled,
 start_again:
        err = devlink_dpipe_entry_ctx_prepare(dump_ctx);
        if (err)
-               return err;
+               goto err_ctx_prepare;
        j = 0;
        for (; i < rif_count; i++) {
                struct mlxsw_sp_rif *rif = mlxsw_sp_rif_by_index(mlxsw_sp, i);
@@ -247,6 +247,7 @@ start_again:
        return 0;
 err_entry_append:
 err_entry_get:
+err_ctx_prepare:
        rtnl_unlock();
        devlink_dpipe_entry_clear(&entry);
        return err;
index 79a2801..02526c5 100644 (file)
@@ -614,7 +614,7 @@ mlxsw_sp_qdisc_tbf_rate_kbps(struct tc_tbf_qopt_offload_replace_params *p)
        /* TBF interface is in bytes/s, whereas Spectrum ASIC is configured in
         * Kbits/s.
         */
-       return p->rate.rate_bytes_ps / 1000 * 8;
+       return div_u64(p->rate.rate_bytes_ps, 1000) * 8;
 }
 
 static int
index ce70772..4a77b51 100644 (file)
@@ -4844,6 +4844,23 @@ mlxsw_sp_fib_node_entry_unlink(struct mlxsw_sp *mlxsw_sp,
        fib_node->fib_entry = NULL;
 }
 
+static bool mlxsw_sp_fib4_allow_replace(struct mlxsw_sp_fib4_entry *fib4_entry)
+{
+       struct mlxsw_sp_fib_node *fib_node = fib4_entry->common.fib_node;
+       struct mlxsw_sp_fib4_entry *fib4_replaced;
+
+       if (!fib_node->fib_entry)
+               return true;
+
+       fib4_replaced = container_of(fib_node->fib_entry,
+                                    struct mlxsw_sp_fib4_entry, common);
+       if (fib4_entry->tb_id == RT_TABLE_MAIN &&
+           fib4_replaced->tb_id == RT_TABLE_LOCAL)
+               return false;
+
+       return true;
+}
+
 static int
 mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
                             const struct fib_entry_notifier_info *fen_info)
@@ -4872,6 +4889,12 @@ mlxsw_sp_router_fib4_replace(struct mlxsw_sp *mlxsw_sp,
                goto err_fib4_entry_create;
        }
 
+       if (!mlxsw_sp_fib4_allow_replace(fib4_entry)) {
+               mlxsw_sp_fib4_entry_destroy(mlxsw_sp, fib4_entry);
+               mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
+               return 0;
+       }
+
        replaced = fib_node->fib_entry;
        err = mlxsw_sp_fib_node_entry_link(mlxsw_sp, &fib4_entry->common);
        if (err) {
@@ -4908,7 +4931,7 @@ static void mlxsw_sp_router_fib4_del(struct mlxsw_sp *mlxsw_sp,
                return;
 
        fib4_entry = mlxsw_sp_fib4_entry_lookup(mlxsw_sp, fen_info);
-       if (WARN_ON(!fib4_entry))
+       if (!fib4_entry)
                return;
        fib_node = fib4_entry->common.fib_node;
 
@@ -4970,6 +4993,9 @@ static void mlxsw_sp_rt6_release(struct fib6_info *rt)
 
 static void mlxsw_sp_rt6_destroy(struct mlxsw_sp_rt6 *mlxsw_sp_rt6)
 {
+       struct fib6_nh *fib6_nh = mlxsw_sp_rt6->rt->fib6_nh;
+
+       fib6_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
        mlxsw_sp_rt6_release(mlxsw_sp_rt6->rt);
        kfree(mlxsw_sp_rt6);
 }
@@ -5408,6 +5434,27 @@ mlxsw_sp_fib6_entry_lookup(struct mlxsw_sp *mlxsw_sp,
        return NULL;
 }
 
+static bool mlxsw_sp_fib6_allow_replace(struct mlxsw_sp_fib6_entry *fib6_entry)
+{
+       struct mlxsw_sp_fib_node *fib_node = fib6_entry->common.fib_node;
+       struct mlxsw_sp_fib6_entry *fib6_replaced;
+       struct fib6_info *rt, *rt_replaced;
+
+       if (!fib_node->fib_entry)
+               return true;
+
+       fib6_replaced = container_of(fib_node->fib_entry,
+                                    struct mlxsw_sp_fib6_entry,
+                                    common);
+       rt = mlxsw_sp_fib6_entry_rt(fib6_entry);
+       rt_replaced = mlxsw_sp_fib6_entry_rt(fib6_replaced);
+       if (rt->fib6_table->tb6_id == RT_TABLE_MAIN &&
+           rt_replaced->fib6_table->tb6_id == RT_TABLE_LOCAL)
+               return false;
+
+       return true;
+}
+
 static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
                                        struct fib6_info **rt_arr,
                                        unsigned int nrt6)
@@ -5442,6 +5489,12 @@ static int mlxsw_sp_router_fib6_replace(struct mlxsw_sp *mlxsw_sp,
                goto err_fib6_entry_create;
        }
 
+       if (!mlxsw_sp_fib6_allow_replace(fib6_entry)) {
+               mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
+               mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
+               return 0;
+       }
+
        replaced = fib_node->fib_entry;
        err = mlxsw_sp_fib_node_entry_link(mlxsw_sp, &fib6_entry->common);
        if (err)
index f131ada..ce07c29 100644 (file)
@@ -866,7 +866,7 @@ struct ionic_rxq_comp {
 #define IONIC_RXQ_COMP_CSUM_F_VLAN     0x40
 #define IONIC_RXQ_COMP_CSUM_F_CALC     0x80
        u8     pkt_type_color;
-#define IONIC_RXQ_COMP_PKT_TYPE_MASK   0x0f
+#define IONIC_RXQ_COMP_PKT_TYPE_MASK   0x7f
 };
 
 enum ionic_pkt_type {
index fbfff2b..1a636ba 100644 (file)
@@ -1398,14 +1398,11 @@ void qed_qm_init_pf(struct qed_hwfn *p_hwfn,
 {
        struct qed_qm_info *qm_info = &p_hwfn->qm_info;
        struct qed_qm_pf_rt_init_params params;
-       struct qed_mcp_link_state *p_link;
        struct qed_qm_iids iids;
 
        memset(&iids, 0, sizeof(iids));
        qed_cxt_qm_iids(p_hwfn, &iids);
 
-       p_link = &QED_LEADING_HWFN(p_hwfn->cdev)->mcp_info->link_output;
-
        memset(&params, 0, sizeof(params));
        params.port_id = p_hwfn->port_id;
        params.pf_id = p_hwfn->rel_pf_id;
index 7912911..03bdd2e 100644 (file)
@@ -3114,6 +3114,7 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
                if (!p_hwfn->fw_overlay_mem) {
                        DP_NOTICE(p_hwfn,
                                  "Failed to allocate fw overlay memory\n");
+                       rc = -ENOMEM;
                        goto load_err;
                }
 
index 0dacf2c..3e61305 100644 (file)
@@ -44,8 +44,8 @@
 /* Add/subtract the Adjustment_Value when making a Drift adjustment */
 #define QED_DRIFT_CNTR_DIRECTION_SHIFT         31
 #define QED_TIMESTAMP_MASK                     BIT(16)
-/* Param mask for Hardware to detect/timestamp the unicast PTP packets */
-#define QED_PTP_UCAST_PARAM_MASK               0xF
+/* Param mask for Hardware to detect/timestamp the L2/L4 unicast PTP packets */
+#define QED_PTP_UCAST_PARAM_MASK              0x70F
 
 static enum qed_resc_lock qed_ptcdev_to_resc(struct qed_hwfn *p_hwfn)
 {
index aaa316b..a2168a1 100644 (file)
@@ -2477,15 +2477,18 @@ static void rtl_hw_jumbo_enable(struct rtl8169_private *tp)
        switch (tp->mac_version) {
        case RTL_GIGA_MAC_VER_12:
        case RTL_GIGA_MAC_VER_17:
+               pcie_set_readrq(tp->pci_dev, 512);
                r8168b_1_hw_jumbo_enable(tp);
                break;
        case RTL_GIGA_MAC_VER_18 ... RTL_GIGA_MAC_VER_26:
+               pcie_set_readrq(tp->pci_dev, 512);
                r8168c_hw_jumbo_enable(tp);
                break;
        case RTL_GIGA_MAC_VER_27 ... RTL_GIGA_MAC_VER_28:
                r8168dp_hw_jumbo_enable(tp);
                break;
        case RTL_GIGA_MAC_VER_31 ... RTL_GIGA_MAC_VER_33:
+               pcie_set_readrq(tp->pci_dev, 512);
                r8168e_hw_jumbo_enable(tp);
                break;
        default:
@@ -2515,6 +2518,9 @@ static void rtl_hw_jumbo_disable(struct rtl8169_private *tp)
                break;
        }
        rtl_lock_config_regs(tp);
+
+       if (pci_is_pcie(tp->pci_dev) && tp->supports_gmii)
+               pcie_set_readrq(tp->pci_dev, 4096);
 }
 
 static void rtl_jumbo_config(struct rtl8169_private *tp, int mtu)
index e61eb89..db6b298 100644 (file)
@@ -823,7 +823,6 @@ static int ioc3_close(struct net_device *dev)
        netif_stop_queue(dev);
 
        ioc3_stop(ip);
-       free_irq(dev->irq, dev);
 
        ioc3_free_rx_bufs(ip);
        ioc3_clean_tx_ring(ip);
index 7ec8954..e0a5fe8 100644 (file)
@@ -413,6 +413,7 @@ static int ethqos_configure(struct qcom_ethqos *ethqos)
                        dll_lock = rgmii_readl(ethqos, SDC4_STATUS);
                        if (dll_lock & SDC4_STATUS_DLL_LOCK)
                                break;
+                       retry--;
                } while (retry > 0);
                if (!retry)
                        dev_err(&ethqos->pdev->dev,
index f0c0ea6..dc09d21 100644 (file)
@@ -420,7 +420,7 @@ static void dwmac4_set_filter(struct mac_device_info *hw,
                value |= GMAC_PACKET_FILTER_PM;
                /* Set all the bits of the HASH tab */
                memset(mc_filter, 0xff, sizeof(mc_filter));
-       } else if (!netdev_mc_empty(dev)) {
+       } else if (!netdev_mc_empty(dev) && (dev->flags & IFF_MULTICAST)) {
                struct netdev_hw_addr *ha;
 
                /* Hash filter for multicast */
@@ -736,11 +736,14 @@ static void dwmac4_update_vlan_hash(struct mac_device_info *hw, u32 hash,
                                    __le16 perfect_match, bool is_double)
 {
        void __iomem *ioaddr = hw->pcsr;
+       u32 value;
 
        writel(hash, ioaddr + GMAC_VLAN_HASH_TABLE);
 
+       value = readl(ioaddr + GMAC_VLAN_TAG);
+
        if (hash) {
-               u32 value = GMAC_VLAN_VTHM | GMAC_VLAN_ETV;
+               value |= GMAC_VLAN_VTHM | GMAC_VLAN_ETV;
                if (is_double) {
                        value |= GMAC_VLAN_EDVLP;
                        value |= GMAC_VLAN_ESVL;
@@ -759,8 +762,6 @@ static void dwmac4_update_vlan_hash(struct mac_device_info *hw, u32 hash,
 
                writel(value | perfect_match, ioaddr + GMAC_VLAN_TAG);
        } else {
-               u32 value = readl(ioaddr + GMAC_VLAN_TAG);
-
                value &= ~(GMAC_VLAN_VTHM | GMAC_VLAN_ETV);
                value &= ~(GMAC_VLAN_EDVLP | GMAC_VLAN_ESVL);
                value &= ~GMAC_VLAN_DOVLTC;
index 2af3ac5..67b754a 100644 (file)
@@ -458,7 +458,7 @@ static void dwxgmac2_set_filter(struct mac_device_info *hw,
 
                for (i = 0; i < XGMAC_MAX_HASH_TABLE; i++)
                        writel(~0x0, ioaddr + XGMAC_HASH_TABLE(i));
-       } else if (!netdev_mc_empty(dev)) {
+       } else if (!netdev_mc_empty(dev) && (dev->flags & IFF_MULTICAST)) {
                struct netdev_hw_addr *ha;
 
                value |= XGMAC_FILTER_HMC;
@@ -569,7 +569,9 @@ static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash,
 
                writel(value, ioaddr + XGMAC_PACKET_FILTER);
 
-               value = XGMAC_VLAN_VTHM | XGMAC_VLAN_ETV;
+               value = readl(ioaddr + XGMAC_VLAN_TAG);
+
+               value |= XGMAC_VLAN_VTHM | XGMAC_VLAN_ETV;
                if (is_double) {
                        value |= XGMAC_VLAN_EDVLP;
                        value |= XGMAC_VLAN_ESVL;
@@ -584,7 +586,9 @@ static void dwxgmac2_update_vlan_hash(struct mac_device_info *hw, u32 hash,
 
                writel(value, ioaddr + XGMAC_PACKET_FILTER);
 
-               value = XGMAC_VLAN_ETV;
+               value = readl(ioaddr + XGMAC_VLAN_TAG);
+
+               value |= XGMAC_VLAN_ETV;
                if (is_double) {
                        value |= XGMAC_VLAN_EDVLP;
                        value |= XGMAC_VLAN_ESVL;
index ff1cbfc..5836b21 100644 (file)
@@ -4974,6 +4974,7 @@ int stmmac_suspend(struct device *dev)
 {
        struct net_device *ndev = dev_get_drvdata(dev);
        struct stmmac_priv *priv = netdev_priv(ndev);
+       u32 chan;
 
        if (!ndev || !netif_running(ndev))
                return 0;
@@ -4987,6 +4988,9 @@ int stmmac_suspend(struct device *dev)
 
        stmmac_disable_all_queues(priv);
 
+       for (chan = 0; chan < priv->plat->tx_queues_to_use; chan++)
+               del_timer_sync(&priv->tx_queue[chan].txtimer);
+
        /* Stop TX/RX DMA */
        stmmac_stop_all_dma(priv);
 
index 6235210..fe2c9fa 100644 (file)
@@ -95,7 +95,7 @@ static int stmmac_default_data(struct pci_dev *pdev,
 
        plat->bus_id = 1;
        plat->phy_addr = 0;
-       plat->interface = PHY_INTERFACE_MODE_GMII;
+       plat->phy_interface = PHY_INTERFACE_MODE_GMII;
 
        plat->dma_cfg->pbl = 32;
        plat->dma_cfg->pblx8 = true;
@@ -217,7 +217,8 @@ static int ehl_sgmii_data(struct pci_dev *pdev,
 {
        plat->bus_id = 1;
        plat->phy_addr = 0;
-       plat->interface = PHY_INTERFACE_MODE_SGMII;
+       plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
+
        return ehl_common_data(pdev, plat);
 }
 
@@ -230,7 +231,8 @@ static int ehl_rgmii_data(struct pci_dev *pdev,
 {
        plat->bus_id = 1;
        plat->phy_addr = 0;
-       plat->interface = PHY_INTERFACE_MODE_RGMII;
+       plat->phy_interface = PHY_INTERFACE_MODE_RGMII;
+
        return ehl_common_data(pdev, plat);
 }
 
@@ -258,7 +260,7 @@ static int tgl_sgmii_data(struct pci_dev *pdev,
 {
        plat->bus_id = 1;
        plat->phy_addr = 0;
-       plat->interface = PHY_INTERFACE_MODE_SGMII;
+       plat->phy_interface = PHY_INTERFACE_MODE_SGMII;
        return tgl_common_data(pdev, plat);
 }
 
@@ -358,7 +360,7 @@ static int quark_default_data(struct pci_dev *pdev,
 
        plat->bus_id = pci_dev_id(pdev);
        plat->phy_addr = ret;
-       plat->interface = PHY_INTERFACE_MODE_RMII;
+       plat->phy_interface = PHY_INTERFACE_MODE_RMII;
 
        plat->dma_cfg->pbl = 16;
        plat->dma_cfg->pblx8 = true;
@@ -415,7 +417,7 @@ static int snps_gmac5_default_data(struct pci_dev *pdev,
 
        plat->bus_id = 1;
        plat->phy_addr = -1;
-       plat->interface = PHY_INTERFACE_MODE_GMII;
+       plat->phy_interface = PHY_INTERFACE_MODE_GMII;
 
        plat->dma_cfg->pbl = 32;
        plat->dma_cfg->pblx8 = true;
index 7032a24..af07ea7 100644 (file)
@@ -767,12 +767,12 @@ static int gtp_hashtable_new(struct gtp_dev *gtp, int hsize)
        int i;
 
        gtp->addr_hash = kmalloc_array(hsize, sizeof(struct hlist_head),
-                                      GFP_KERNEL);
+                                      GFP_KERNEL | __GFP_NOWARN);
        if (gtp->addr_hash == NULL)
                return -ENOMEM;
 
        gtp->tid_hash = kmalloc_array(hsize, sizeof(struct hlist_head),
-                                     GFP_KERNEL);
+                                     GFP_KERNEL | __GFP_NOWARN);
        if (gtp->tid_hash == NULL)
                goto err1;
 
index 20adfe5..b866110 100644 (file)
@@ -120,7 +120,7 @@ int netvsc_xdp_set(struct net_device *dev, struct bpf_prog *prog,
        }
 
        if (prog)
-               bpf_prog_add(prog, nvdev->num_chn);
+               bpf_prog_add(prog, nvdev->num_chn - 1);
 
        for (i = 0; i < nvdev->num_chn; i++)
                rcu_assign_pointer(nvdev->chan_table[i].bpf_prog, prog);
@@ -136,6 +136,7 @@ int netvsc_vf_setxdp(struct net_device *vf_netdev, struct bpf_prog *prog)
 {
        struct netdev_bpf xdp;
        bpf_op_t ndo_bpf;
+       int ret;
 
        ASSERT_RTNL();
 
@@ -148,10 +149,18 @@ int netvsc_vf_setxdp(struct net_device *vf_netdev, struct bpf_prog *prog)
 
        memset(&xdp, 0, sizeof(xdp));
 
+       if (prog)
+               bpf_prog_inc(prog);
+
        xdp.command = XDP_SETUP_PROG;
        xdp.prog = prog;
 
-       return ndo_bpf(vf_netdev, &xdp);
+       ret = ndo_bpf(vf_netdev, &xdp);
+
+       if (ret && prog)
+               bpf_prog_put(prog);
+
+       return ret;
 }
 
 static u32 netvsc_xdp_query(struct netvsc_device *nvdev)
index 8fc71bd..65e12cb 100644 (file)
@@ -1059,9 +1059,12 @@ static int netvsc_attach(struct net_device *ndev,
 
        prog = dev_info->bprog;
        if (prog) {
+               bpf_prog_inc(prog);
                ret = netvsc_xdp_set(ndev, prog, NULL, nvdev);
-               if (ret)
+               if (ret) {
+                       bpf_prog_put(prog);
                        goto err1;
+               }
        }
 
        /* In any case device is now ready */
index 2b74425..0b362b8 100644 (file)
@@ -218,6 +218,7 @@ static int nsim_bpf_create_prog(struct nsim_dev *nsim_dev,
 {
        struct nsim_bpf_bound_prog *state;
        char name[16];
+       int ret;
 
        state = kzalloc(sizeof(*state), GFP_KERNEL);
        if (!state)
@@ -230,9 +231,10 @@ static int nsim_bpf_create_prog(struct nsim_dev *nsim_dev,
        /* Program id is not populated yet when we create the state. */
        sprintf(name, "%u", nsim_dev->prog_id_gen++);
        state->ddir = debugfs_create_dir(name, nsim_dev->ddir_bpf_bound_progs);
-       if (IS_ERR_OR_NULL(state->ddir)) {
+       if (IS_ERR(state->ddir)) {
+               ret = PTR_ERR(state->ddir);
                kfree(state);
-               return -ENOMEM;
+               return ret;
        }
 
        debugfs_create_u32("id", 0400, state->ddir, &prog->aux->id);
@@ -587,8 +589,8 @@ int nsim_bpf_dev_init(struct nsim_dev *nsim_dev)
 
        nsim_dev->ddir_bpf_bound_progs = debugfs_create_dir("bpf_bound_progs",
                                                            nsim_dev->ddir);
-       if (IS_ERR_OR_NULL(nsim_dev->ddir_bpf_bound_progs))
-               return -ENOMEM;
+       if (IS_ERR(nsim_dev->ddir_bpf_bound_progs))
+               return PTR_ERR(nsim_dev->ddir_bpf_bound_progs);
 
        nsim_dev->bpf_dev = bpf_offload_dev_create(&nsim_bpf_dev_ops, nsim_dev);
        err = PTR_ERR_OR_ZERO(nsim_dev->bpf_dev);
index 6aeed0c..7971dc4 100644 (file)
@@ -17,6 +17,7 @@
 static DEFINE_IDA(nsim_bus_dev_ids);
 static LIST_HEAD(nsim_bus_dev_list);
 static DEFINE_MUTEX(nsim_bus_dev_list_lock);
+static bool nsim_bus_enable;
 
 static struct nsim_bus_dev *to_nsim_bus_dev(struct device *dev)
 {
@@ -28,7 +29,7 @@ static int nsim_bus_dev_vfs_enable(struct nsim_bus_dev *nsim_bus_dev,
 {
        nsim_bus_dev->vfconfigs = kcalloc(num_vfs,
                                          sizeof(struct nsim_vf_config),
-                                         GFP_KERNEL);
+                                         GFP_KERNEL | __GFP_NOWARN);
        if (!nsim_bus_dev->vfconfigs)
                return -ENOMEM;
        nsim_bus_dev->num_vfs = num_vfs;
@@ -96,13 +97,25 @@ new_port_store(struct device *dev, struct device_attribute *attr,
               const char *buf, size_t count)
 {
        struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
+       struct nsim_dev *nsim_dev = dev_get_drvdata(dev);
+       struct devlink *devlink;
        unsigned int port_index;
        int ret;
 
+       /* Prevent to use nsim_bus_dev before initialization. */
+       if (!smp_load_acquire(&nsim_bus_dev->init))
+               return -EBUSY;
        ret = kstrtouint(buf, 0, &port_index);
        if (ret)
                return ret;
+
+       devlink = priv_to_devlink(nsim_dev);
+
+       mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock);
+       devlink_reload_disable(devlink);
        ret = nsim_dev_port_add(nsim_bus_dev, port_index);
+       devlink_reload_enable(devlink);
+       mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
        return ret ? ret : count;
 }
 
@@ -113,13 +126,25 @@ del_port_store(struct device *dev, struct device_attribute *attr,
               const char *buf, size_t count)
 {
        struct nsim_bus_dev *nsim_bus_dev = to_nsim_bus_dev(dev);
+       struct nsim_dev *nsim_dev = dev_get_drvdata(dev);
+       struct devlink *devlink;
        unsigned int port_index;
        int ret;
 
+       /* Prevent to use nsim_bus_dev before initialization. */
+       if (!smp_load_acquire(&nsim_bus_dev->init))
+               return -EBUSY;
        ret = kstrtouint(buf, 0, &port_index);
        if (ret)
                return ret;
+
+       devlink = priv_to_devlink(nsim_dev);
+
+       mutex_lock(&nsim_bus_dev->nsim_bus_reload_lock);
+       devlink_reload_disable(devlink);
        ret = nsim_dev_port_del(nsim_bus_dev, port_index);
+       devlink_reload_enable(devlink);
+       mutex_unlock(&nsim_bus_dev->nsim_bus_reload_lock);
        return ret ? ret : count;
 }
 
@@ -179,15 +204,30 @@ new_device_store(struct bus_type *bus, const char *buf, size_t count)
                pr_err("Format for adding new device is \"id port_count\" (uint uint).\n");
                return -EINVAL;
        }
-       nsim_bus_dev = nsim_bus_dev_new(id, port_count);
-       if (IS_ERR(nsim_bus_dev))
-               return PTR_ERR(nsim_bus_dev);
 
        mutex_lock(&nsim_bus_dev_list_lock);
+       /* Prevent to use resource before initialization. */
+       if (!smp_load_acquire(&nsim_bus_enable)) {
+               err = -EBUSY;
+               goto err;
+       }
+
+       nsim_bus_dev = nsim_bus_dev_new(id, port_count);
+       if (IS_ERR(nsim_bus_dev)) {
+               err = PTR_ERR(nsim_bus_dev);
+               goto err;
+       }
+
+       /* Allow using nsim_bus_dev */
+       smp_store_release(&nsim_bus_dev->init, true);
+
        list_add_tail(&nsim_bus_dev->list, &nsim_bus_dev_list);
        mutex_unlock(&nsim_bus_dev_list_lock);
 
        return count;
+err:
+       mutex_unlock(&nsim_bus_dev_list_lock);
+       return err;
 }
 static BUS_ATTR_WO(new_device);
 
@@ -215,6 +255,11 @@ del_device_store(struct bus_type *bus, const char *buf, size_t count)
 
        err = -ENOENT;
        mutex_lock(&nsim_bus_dev_list_lock);
+       /* Prevent to use resource before initialization. */
+       if (!smp_load_acquire(&nsim_bus_enable)) {
+               mutex_unlock(&nsim_bus_dev_list_lock);
+               return -EBUSY;
+       }
        list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
                if (nsim_bus_dev->dev.id != id)
                        continue;
@@ -284,6 +329,9 @@ nsim_bus_dev_new(unsigned int id, unsigned int port_count)
        nsim_bus_dev->dev.type = &nsim_bus_dev_type;
        nsim_bus_dev->port_count = port_count;
        nsim_bus_dev->initial_net = current->nsproxy->net_ns;
+       mutex_init(&nsim_bus_dev->nsim_bus_reload_lock);
+       /* Disallow using nsim_bus_dev */
+       smp_store_release(&nsim_bus_dev->init, false);
 
        err = device_register(&nsim_bus_dev->dev);
        if (err)
@@ -299,6 +347,8 @@ err_nsim_bus_dev_free:
 
 static void nsim_bus_dev_del(struct nsim_bus_dev *nsim_bus_dev)
 {
+       /* Disallow using nsim_bus_dev */
+       smp_store_release(&nsim_bus_dev->init, false);
        device_unregister(&nsim_bus_dev->dev);
        ida_free(&nsim_bus_dev_ids, nsim_bus_dev->dev.id);
        kfree(nsim_bus_dev);
@@ -320,6 +370,8 @@ int nsim_bus_init(void)
        err = driver_register(&nsim_driver);
        if (err)
                goto err_bus_unregister;
+       /* Allow using resources */
+       smp_store_release(&nsim_bus_enable, true);
        return 0;
 
 err_bus_unregister:
@@ -331,12 +383,16 @@ void nsim_bus_exit(void)
 {
        struct nsim_bus_dev *nsim_bus_dev, *tmp;
 
+       /* Disallow using resources */
+       smp_store_release(&nsim_bus_enable, false);
+
        mutex_lock(&nsim_bus_dev_list_lock);
        list_for_each_entry_safe(nsim_bus_dev, tmp, &nsim_bus_dev_list, list) {
                list_del(&nsim_bus_dev->list);
                nsim_bus_dev_del(nsim_bus_dev);
        }
        mutex_unlock(&nsim_bus_dev_list_lock);
+
        driver_unregister(&nsim_driver);
        bus_unregister(&nsim_bus);
 }
index b53fbc0..d7706a0 100644 (file)
@@ -73,23 +73,26 @@ static const struct file_operations nsim_dev_take_snapshot_fops = {
 
 static int nsim_dev_debugfs_init(struct nsim_dev *nsim_dev)
 {
-       char dev_ddir_name[16];
+       char dev_ddir_name[sizeof(DRV_NAME) + 10];
 
        sprintf(dev_ddir_name, DRV_NAME "%u", nsim_dev->nsim_bus_dev->dev.id);
        nsim_dev->ddir = debugfs_create_dir(dev_ddir_name, nsim_dev_ddir);
-       if (IS_ERR_OR_NULL(nsim_dev->ddir))
-               return PTR_ERR_OR_ZERO(nsim_dev->ddir) ?: -EINVAL;
+       if (IS_ERR(nsim_dev->ddir))
+               return PTR_ERR(nsim_dev->ddir);
        nsim_dev->ports_ddir = debugfs_create_dir("ports", nsim_dev->ddir);
-       if (IS_ERR_OR_NULL(nsim_dev->ports_ddir))
-               return PTR_ERR_OR_ZERO(nsim_dev->ports_ddir) ?: -EINVAL;
+       if (IS_ERR(nsim_dev->ports_ddir))
+               return PTR_ERR(nsim_dev->ports_ddir);
        debugfs_create_bool("fw_update_status", 0600, nsim_dev->ddir,
                            &nsim_dev->fw_update_status);
        debugfs_create_u32("max_macs", 0600, nsim_dev->ddir,
                           &nsim_dev->max_macs);
        debugfs_create_bool("test1", 0600, nsim_dev->ddir,
                            &nsim_dev->test1);
-       debugfs_create_file("take_snapshot", 0200, nsim_dev->ddir, nsim_dev,
-                           &nsim_dev_take_snapshot_fops);
+       nsim_dev->take_snapshot = debugfs_create_file("take_snapshot",
+                                                     0200,
+                                                     nsim_dev->ddir,
+                                                     nsim_dev,
+                                               &nsim_dev_take_snapshot_fops);
        debugfs_create_bool("dont_allow_reload", 0600, nsim_dev->ddir,
                            &nsim_dev->dont_allow_reload);
        debugfs_create_bool("fail_reload", 0600, nsim_dev->ddir,
@@ -112,8 +115,8 @@ static int nsim_dev_port_debugfs_init(struct nsim_dev *nsim_dev,
        sprintf(port_ddir_name, "%u", nsim_dev_port->port_index);
        nsim_dev_port->ddir = debugfs_create_dir(port_ddir_name,
                                                 nsim_dev->ports_ddir);
-       if (IS_ERR_OR_NULL(nsim_dev_port->ddir))
-               return -ENOMEM;
+       if (IS_ERR(nsim_dev_port->ddir))
+               return PTR_ERR(nsim_dev_port->ddir);
 
        sprintf(dev_link_name, "../../../" DRV_NAME "%u",
                nsim_dev->nsim_bus_dev->dev.id);
@@ -740,6 +743,11 @@ static int nsim_dev_reload_create(struct nsim_dev *nsim_dev,
        if (err)
                goto err_health_exit;
 
+       nsim_dev->take_snapshot = debugfs_create_file("take_snapshot",
+                                                     0200,
+                                                     nsim_dev->ddir,
+                                                     nsim_dev,
+                                               &nsim_dev_take_snapshot_fops);
        return 0;
 
 err_health_exit:
@@ -853,6 +861,7 @@ static void nsim_dev_reload_destroy(struct nsim_dev *nsim_dev)
 
        if (devlink_is_reload_failed(devlink))
                return;
+       debugfs_remove(nsim_dev->take_snapshot);
        nsim_dev_port_del_all(nsim_dev);
        nsim_dev_health_exit(nsim_dev);
        nsim_dev_traps_exit(devlink);
@@ -925,9 +934,7 @@ int nsim_dev_port_del(struct nsim_bus_dev *nsim_bus_dev,
 int nsim_dev_init(void)
 {
        nsim_dev_ddir = debugfs_create_dir(DRV_NAME, NULL);
-       if (IS_ERR_OR_NULL(nsim_dev_ddir))
-               return -ENOMEM;
-       return 0;
+       return PTR_ERR_OR_ZERO(nsim_dev_ddir);
 }
 
 void nsim_dev_exit(void)
index 9aa637d..ba8d9ad 100644 (file)
@@ -82,7 +82,7 @@ static int nsim_dev_dummy_fmsg_put(struct devlink_fmsg *fmsg, u32 binary_len)
        if (err)
                return err;
 
-       binary = kmalloc(binary_len, GFP_KERNEL);
+       binary = kmalloc(binary_len, GFP_KERNEL | __GFP_NOWARN);
        if (!binary)
                return -ENOMEM;
        get_random_bytes(binary, binary_len);
@@ -285,8 +285,8 @@ int nsim_dev_health_init(struct nsim_dev *nsim_dev, struct devlink *devlink)
        }
 
        health->ddir = debugfs_create_dir("health", nsim_dev->ddir);
-       if (IS_ERR_OR_NULL(health->ddir)) {
-               err = PTR_ERR_OR_ZERO(health->ddir) ?: -EINVAL;
+       if (IS_ERR(health->ddir)) {
+               err = PTR_ERR(health->ddir);
                goto err_dummy_reporter_destroy;
        }
 
index 94df795..2eb7b0d 100644 (file)
@@ -160,6 +160,7 @@ struct nsim_dev {
        struct nsim_trap_data *trap_data;
        struct dentry *ddir;
        struct dentry *ports_ddir;
+       struct dentry *take_snapshot;
        struct bpf_offload_dev *bpf_dev;
        bool bpf_bind_accept;
        u32 bpf_bind_verifier_delay;
@@ -240,6 +241,9 @@ struct nsim_bus_dev {
                                  */
        unsigned int num_vfs;
        struct nsim_vf_config *vfconfigs;
+       /* Lock for devlink->reload_enabled in netdevsim module */
+       struct mutex nsim_bus_reload_lock;
+       bool init;
 };
 
 int nsim_bus_init(void);
diff --git a/drivers/net/netdevsim/sdev.c b/drivers/net/netdevsim/sdev.c
deleted file mode 100644 (file)
index 6712da3..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/* Copyright (c) 2019 Mellanox Technologies. All rights reserved */
-
-#include <linux/debugfs.h>
-#include <linux/err.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-
-#include "netdevsim.h"
-
-static struct dentry *nsim_sdev_ddir;
-
-static u32 nsim_sdev_id;
-
-struct netdevsim_shared_dev *nsim_sdev_get(struct netdevsim *joinns)
-{
-       struct netdevsim_shared_dev *sdev;
-       char sdev_ddir_name[10];
-       int err;
-
-       if (joinns) {
-               if (WARN_ON(!joinns->sdev))
-                       return ERR_PTR(-EINVAL);
-               sdev = joinns->sdev;
-               sdev->refcnt++;
-               return sdev;
-       }
-
-       sdev = kzalloc(sizeof(*sdev), GFP_KERNEL);
-       if (!sdev)
-               return ERR_PTR(-ENOMEM);
-       sdev->refcnt = 1;
-       sdev->switch_id = nsim_sdev_id++;
-
-       sprintf(sdev_ddir_name, "%u", sdev->switch_id);
-       sdev->ddir = debugfs_create_dir(sdev_ddir_name, nsim_sdev_ddir);
-       if (IS_ERR_OR_NULL(sdev->ddir)) {
-               err = PTR_ERR_OR_ZERO(sdev->ddir) ?: -EINVAL;
-               goto err_sdev_free;
-       }
-
-       return sdev;
-
-err_sdev_free:
-       nsim_sdev_id--;
-       kfree(sdev);
-       return ERR_PTR(err);
-}
-
-void nsim_sdev_put(struct netdevsim_shared_dev *sdev)
-{
-       if (--sdev->refcnt)
-               return;
-       debugfs_remove_recursive(sdev->ddir);
-       kfree(sdev);
-}
-
-int nsim_sdev_init(void)
-{
-       nsim_sdev_ddir = debugfs_create_dir(DRV_NAME "_sdev", NULL);
-       if (IS_ERR_OR_NULL(nsim_sdev_ddir))
-               return -ENOMEM;
-       return 0;
-}
-
-void nsim_sdev_exit(void)
-{
-       debugfs_remove_recursive(nsim_sdev_ddir);
-}
index aee6261..481cf48 100644 (file)
@@ -489,6 +489,14 @@ static int at803x_probe(struct phy_device *phydev)
        return at803x_parse_dt(phydev);
 }
 
+static void at803x_remove(struct phy_device *phydev)
+{
+       struct at803x_priv *priv = phydev->priv;
+
+       if (priv->vddio)
+               regulator_disable(priv->vddio);
+}
+
 static int at803x_clk_out_config(struct phy_device *phydev)
 {
        struct at803x_priv *priv = phydev->priv;
@@ -711,6 +719,7 @@ static struct phy_driver at803x_driver[] = {
        .name                   = "Qualcomm Atheros AR8035",
        .phy_id_mask            = AT803X_PHY_ID_MASK,
        .probe                  = at803x_probe,
+       .remove                 = at803x_remove,
        .config_init            = at803x_config_init,
        .set_wol                = at803x_set_wol,
        .get_wol                = at803x_get_wol,
@@ -726,6 +735,7 @@ static struct phy_driver at803x_driver[] = {
        .name                   = "Qualcomm Atheros AR8030",
        .phy_id_mask            = AT803X_PHY_ID_MASK,
        .probe                  = at803x_probe,
+       .remove                 = at803x_remove,
        .config_init            = at803x_config_init,
        .link_change_notify     = at803x_link_change_notify,
        .set_wol                = at803x_set_wol,
@@ -741,6 +751,7 @@ static struct phy_driver at803x_driver[] = {
        .name                   = "Qualcomm Atheros AR8031/AR8033",
        .phy_id_mask            = AT803X_PHY_ID_MASK,
        .probe                  = at803x_probe,
+       .remove                 = at803x_remove,
        .config_init            = at803x_config_init,
        .set_wol                = at803x_set_wol,
        .get_wol                = at803x_get_wol,
index 7a9ad54..bf86c9c 100644 (file)
@@ -123,7 +123,7 @@ static int g12a_ephy_pll_is_enabled(struct clk_hw *hw)
        return (val & PLL_CTL0_LOCK_DIG) ? 1 : 0;
 }
 
-static void g12a_ephy_pll_init(struct clk_hw *hw)
+static int g12a_ephy_pll_init(struct clk_hw *hw)
 {
        struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
 
@@ -136,6 +136,8 @@ static void g12a_ephy_pll_init(struct clk_hw *hw)
        writel(0x20200000, pll->base + ETH_PLL_CTL5);
        writel(0x0000c002, pll->base + ETH_PLL_CTL6);
        writel(0x00000023, pll->base + ETH_PLL_CTL7);
+
+       return 0;
 }
 
 static const struct clk_ops g12a_ephy_pll_ops = {
index 2f12c5d..b71b745 100644 (file)
@@ -111,6 +111,13 @@ void unregister_mii_timestamper(struct mii_timestamper *mii_ts)
        struct mii_timestamping_desc *desc;
        struct list_head *this;
 
+       /* mii_timestamper statically registered by the PHY driver won't use the
+        * register_mii_timestamper() and thus don't have ->device set. Don't
+        * try to unregister these.
+        */
+       if (!mii_ts->device)
+               return;
+
        mutex_lock(&tstamping_devices_lock);
        list_for_each(this, &mii_timestamping_devices) {
                desc = list_entry(this, struct mii_timestamping_desc, list);
index e8cd8c0..78ddbaf 100644 (file)
@@ -698,6 +698,9 @@ enum rtl8152_flags {
 #define VENDOR_ID_NVIDIA               0x0955
 #define VENDOR_ID_TPLINK               0x2357
 
+#define DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2      0x3082
+#define DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2             0xa387
+
 #define MCU_TYPE_PLA                   0x0100
 #define MCU_TYPE_USB                   0x0000
 
@@ -6759,9 +6762,13 @@ static int rtl8152_probe(struct usb_interface *intf,
                netdev->hw_features &= ~NETIF_F_RXCSUM;
        }
 
-       if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO &&
-           le16_to_cpu(udev->descriptor.idProduct) == 0x3082)
-               set_bit(LENOVO_MACPASSTHRU, &tp->flags);
+       if (le16_to_cpu(udev->descriptor.idVendor) == VENDOR_ID_LENOVO) {
+               switch (le16_to_cpu(udev->descriptor.idProduct)) {
+               case DEVICE_ID_THINKPAD_THUNDERBOLT3_DOCK_GEN2:
+               case DEVICE_ID_THINKPAD_USB_C_DOCK_GEN2:
+                       set_bit(LENOVO_MACPASSTHRU, &tp->flags);
+               }
+       }
 
        if (le16_to_cpu(udev->descriptor.bcdDevice) == 0x3011 && udev->serial &&
            (!strcmp(udev->serial, "000001000000") ||
index 3998cac..9edd946 100644 (file)
@@ -84,8 +84,8 @@ static int uhdlc_init(struct ucc_hdlc_private *priv)
        int ret, i;
        void *bd_buffer;
        dma_addr_t bd_dma_addr;
-       u32 riptr;
-       u32 tiptr;
+       s32 riptr;
+       s32 tiptr;
        u32 gumr;
 
        ut_info = priv->ut_info;
@@ -195,7 +195,7 @@ static int uhdlc_init(struct ucc_hdlc_private *priv)
        priv->ucc_pram_offset = qe_muram_alloc(sizeof(struct ucc_hdlc_param),
                                ALIGNMENT_OF_UCC_HDLC_PRAM);
 
-       if (IS_ERR_VALUE(priv->ucc_pram_offset)) {
+       if (priv->ucc_pram_offset < 0) {
                dev_err(priv->dev, "Can not allocate MURAM for hdlc parameter.\n");
                ret = -ENOMEM;
                goto free_tx_bd;
@@ -233,18 +233,23 @@ static int uhdlc_init(struct ucc_hdlc_private *priv)
 
        /* Alloc riptr, tiptr */
        riptr = qe_muram_alloc(32, 32);
-       if (IS_ERR_VALUE(riptr)) {
+       if (riptr < 0) {
                dev_err(priv->dev, "Cannot allocate MURAM mem for Receive internal temp data pointer\n");
                ret = -ENOMEM;
                goto free_tx_skbuff;
        }
 
        tiptr = qe_muram_alloc(32, 32);
-       if (IS_ERR_VALUE(tiptr)) {
+       if (tiptr < 0) {
                dev_err(priv->dev, "Cannot allocate MURAM mem for Transmit internal temp data pointer\n");
                ret = -ENOMEM;
                goto free_riptr;
        }
+       if (riptr != (u16)riptr || tiptr != (u16)tiptr) {
+               dev_err(priv->dev, "MURAM allocation out of addressable range\n");
+               ret = -ENOMEM;
+               goto free_tiptr;
+       }
 
        /* Set RIPTR, TIPTR */
        iowrite16be(riptr, &priv->ucc_pram->riptr);
@@ -623,8 +628,8 @@ static int ucc_hdlc_poll(struct napi_struct *napi, int budget)
 
        if (howmany < budget) {
                napi_complete_done(napi, howmany);
-               qe_setbits32(priv->uccf->p_uccm,
-                            (UCCE_HDLC_RX_EVENTS | UCCE_HDLC_TX_EVENTS) << 16);
+               qe_setbits_be32(priv->uccf->p_uccm,
+                               (UCCE_HDLC_RX_EVENTS | UCCE_HDLC_TX_EVENTS) << 16);
        }
 
        return howmany;
@@ -730,8 +735,8 @@ static int uhdlc_open(struct net_device *dev)
 
 static void uhdlc_memclean(struct ucc_hdlc_private *priv)
 {
-       qe_muram_free(priv->ucc_pram->riptr);
-       qe_muram_free(priv->ucc_pram->tiptr);
+       qe_muram_free(ioread16be(&priv->ucc_pram->riptr));
+       qe_muram_free(ioread16be(&priv->ucc_pram->tiptr));
 
        if (priv->rx_bd_base) {
                dma_free_coherent(priv->dev,
index 8b3507a..71d5ad0 100644 (file)
@@ -98,7 +98,7 @@ struct ucc_hdlc_private {
 
        unsigned short tx_ring_size;
        unsigned short rx_ring_size;
-       u32 ucc_pram_offset;
+       s32 ucc_pram_offset;
 
        unsigned short encoding;
        unsigned short parity;
index 121d9ea..3725e9c 100644 (file)
@@ -263,6 +263,7 @@ static int add(struct allowedips_node __rcu **trie, u8 bits, const u8 *key,
        } else {
                node = kzalloc(sizeof(*node), GFP_KERNEL);
                if (unlikely(!node)) {
+                       list_del(&newnode->peer_list);
                        kfree(newnode);
                        return -ENOMEM;
                }
index 0fdbd1c..bda2640 100644 (file)
@@ -569,10 +569,8 @@ static int wg_set_device(struct sk_buff *skb, struct genl_info *info)
                                                         private_key);
                list_for_each_entry_safe(peer, temp, &wg->peer_list,
                                         peer_list) {
-                       if (wg_noise_precompute_static_static(peer))
-                               wg_noise_expire_current_peer_keypairs(peer);
-                       else
-                               wg_peer_remove(peer);
+                       BUG_ON(!wg_noise_precompute_static_static(peer));
+                       wg_noise_expire_current_peer_keypairs(peer);
                }
                wg_cookie_checker_precompute_device_keys(&wg->cookie_checker);
                up_write(&wg->static_identity.lock);
index d71c8db..919d9d8 100644 (file)
@@ -46,17 +46,21 @@ void __init wg_noise_init(void)
 /* Must hold peer->handshake.static_identity->lock */
 bool wg_noise_precompute_static_static(struct wg_peer *peer)
 {
-       bool ret = true;
+       bool ret;
 
        down_write(&peer->handshake.lock);
-       if (peer->handshake.static_identity->has_identity)
+       if (peer->handshake.static_identity->has_identity) {
                ret = curve25519(
                        peer->handshake.precomputed_static_static,
                        peer->handshake.static_identity->static_private,
                        peer->handshake.remote_static);
-       else
+       } else {
+               u8 empty[NOISE_PUBLIC_KEY_LEN] = { 0 };
+
+               ret = curve25519(empty, empty, peer->handshake.remote_static);
                memset(peer->handshake.precomputed_static_static, 0,
                       NOISE_PUBLIC_KEY_LEN);
+       }
        up_write(&peer->handshake.lock);
        return ret;
 }
index c4c8f1b..8363f91 100644 (file)
@@ -4420,73 +4420,65 @@ static int proc_BSSList_open( struct inode *inode, struct file *file );
 static int proc_config_open( struct inode *inode, struct file *file );
 static int proc_wepkey_open( struct inode *inode, struct file *file );
 
-static const struct file_operations proc_statsdelta_ops = {
-       .owner          = THIS_MODULE,
-       .read           = proc_read,
-       .open           = proc_statsdelta_open,
-       .release        = proc_close,
-       .llseek         = default_llseek,
+static const struct proc_ops proc_statsdelta_ops = {
+       .proc_read      = proc_read,
+       .proc_open      = proc_statsdelta_open,
+       .proc_release   = proc_close,
+       .proc_lseek     = default_llseek,
 };
 
-static const struct file_operations proc_stats_ops = {
-       .owner          = THIS_MODULE,
-       .read           = proc_read,
-       .open           = proc_stats_open,
-       .release        = proc_close,
-       .llseek         = default_llseek,
+static const struct proc_ops proc_stats_ops = {
+       .proc_read      = proc_read,
+       .proc_open      = proc_stats_open,
+       .proc_release   = proc_close,
+       .proc_lseek     = default_llseek,
 };
 
-static const struct file_operations proc_status_ops = {
-       .owner          = THIS_MODULE,
-       .read           = proc_read,
-       .open           = proc_status_open,
-       .release        = proc_close,
-       .llseek         = default_llseek,
+static const struct proc_ops proc_status_ops = {
+       .proc_read      = proc_read,
+       .proc_open      = proc_status_open,
+       .proc_release   = proc_close,
+       .proc_lseek     = default_llseek,
 };
 
-static const struct file_operations proc_SSID_ops = {
-       .owner          = THIS_MODULE,
-       .read           = proc_read,
-       .write          = proc_write,
-       .open           = proc_SSID_open,
-       .release        = proc_close,
-       .llseek         = default_llseek,
+static const struct proc_ops proc_SSID_ops = {
+       .proc_read      = proc_read,
+       .proc_write     = proc_write,
+       .proc_open      = proc_SSID_open,
+       .proc_release   = proc_close,
+       .proc_lseek     = default_llseek,
 };
 
-static const struct file_operations proc_BSSList_ops = {
-       .owner          = THIS_MODULE,
-       .read           = proc_read,
-       .write          = proc_write,
-       .open           = proc_BSSList_open,
-       .release        = proc_close,
-       .llseek         = default_llseek,
+static const struct proc_ops proc_BSSList_ops = {
+       .proc_read      = proc_read,
+       .proc_write     = proc_write,
+       .proc_open      = proc_BSSList_open,
+       .proc_release   = proc_close,
+       .proc_lseek     = default_llseek,
 };
 
-static const struct file_operations proc_APList_ops = {
-       .owner          = THIS_MODULE,
-       .read           = proc_read,
-       .write          = proc_write,
-       .open           = proc_APList_open,
-       .release        = proc_close,
-       .llseek         = default_llseek,
+static const struct proc_ops proc_APList_ops = {
+       .proc_read      = proc_read,
+       .proc_write     = proc_write,
+       .proc_open      = proc_APList_open,
+       .proc_release   = proc_close,
+       .proc_lseek     = default_llseek,
 };
 
-static const struct file_operations proc_config_ops = {
-       .owner          = THIS_MODULE,
-       .read           = proc_read,
-       .write          = proc_write,
-       .open           = proc_config_open,
-       .release        = proc_close,
-       .llseek         = default_llseek,
+static const struct proc_ops proc_config_ops = {
+       .proc_read      = proc_read,
+       .proc_write     = proc_write,
+       .proc_open      = proc_config_open,
+       .proc_release   = proc_close,
+       .proc_lseek     = default_llseek,
 };
 
-static const struct file_operations proc_wepkey_ops = {
-       .owner          = THIS_MODULE,
-       .read           = proc_read,
-       .write          = proc_write,
-       .open           = proc_wepkey_open,
-       .release        = proc_close,
-       .llseek         = default_llseek,
+static const struct proc_ops proc_wepkey_ops = {
+       .proc_read      = proc_read,
+       .proc_write     = proc_write,
+       .proc_open      = proc_wepkey_open,
+       .proc_release   = proc_close,
+       .proc_lseek     = default_llseek,
 };
 
 static struct proc_dir_entry *airo_entry;
index 436b819..43bab92 100644 (file)
@@ -240,13 +240,12 @@ static ssize_t debug_level_proc_write(struct file *file,
        return strnlen(buf, len);
 }
 
-static const struct file_operations debug_level_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = debug_level_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = debug_level_proc_write,
+static const struct proc_ops debug_level_proc_ops = {
+       .proc_open      = debug_level_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = debug_level_proc_write,
 };
 #endif                         /* CONFIG_LIBIPW_DEBUG */
 
@@ -263,7 +262,7 @@ static int __init libipw_init(void)
                return -EIO;
        }
        e = proc_create("debug_level", 0644, libipw_proc,
-                       &debug_level_proc_fops);
+                       &debug_level_proc_ops);
        if (!e) {
                remove_proc_entry(DRV_PROCNAME, init_net.proc_net);
                libipw_proc = NULL;
index 8878409..22a32eb 100644 (file)
@@ -1897,27 +1897,55 @@ static void iwl_mvm_d3_disconnect_iter(void *data, u8 *mac,
                ieee80211_resume_disconnect(vif);
 }
 
-static int iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
-                                  struct ieee80211_vif *vif)
+static bool iwl_mvm_rt_status(struct iwl_trans *trans, u32 base, u32 *err_id)
 {
-       u32 base = mvm->trans->dbg.lmac_error_event_table[0];
        struct error_table_start {
                /* cf. struct iwl_error_event_table */
                u32 valid;
-               u32 error_id;
+               __le32 err_id;
        } err_info;
 
-       iwl_trans_read_mem_bytes(mvm->trans, base,
+       if (!base)
+               return false;
+
+       iwl_trans_read_mem_bytes(trans, base,
                                 &err_info, sizeof(err_info));
+       if (err_info.valid && err_id)
+               *err_id = le32_to_cpu(err_info.err_id);
 
-       if (err_info.valid &&
-           err_info.error_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
-               struct cfg80211_wowlan_wakeup wakeup = {
-                       .rfkill_release = true,
-               };
-               ieee80211_report_wowlan_wakeup(vif, &wakeup, GFP_KERNEL);
+       return !!err_info.valid;
+}
+
+static bool iwl_mvm_check_rt_status(struct iwl_mvm *mvm,
+                                  struct ieee80211_vif *vif)
+{
+       u32 err_id;
+
+       /* check for lmac1 error */
+       if (iwl_mvm_rt_status(mvm->trans,
+                             mvm->trans->dbg.lmac_error_event_table[0],
+                             &err_id)) {
+               if (err_id == RF_KILL_INDICATOR_FOR_WOWLAN) {
+                       struct cfg80211_wowlan_wakeup wakeup = {
+                               .rfkill_release = true,
+                       };
+                       ieee80211_report_wowlan_wakeup(vif, &wakeup,
+                                                      GFP_KERNEL);
+               }
+               return true;
        }
-       return err_info.valid;
+
+       /* check if we have lmac2 set and check for error */
+       if (iwl_mvm_rt_status(mvm->trans,
+                             mvm->trans->dbg.lmac_error_event_table[1], NULL))
+               return true;
+
+       /* check for umac error */
+       if (iwl_mvm_rt_status(mvm->trans,
+                             mvm->trans->dbg.umac_error_event_table, NULL))
+               return true;
+
+       return false;
 }
 
 static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
index f783d6d..6e1ea92 100644 (file)
@@ -8,6 +8,7 @@
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
  * Copyright (C) 2018 Intel Corporation
  * Copyright (C) 2019 Intel Corporation
+ * Copyright (C) 2020 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -30,6 +31,7 @@
  * Copyright(c) 2015 - 2017 Intel Deutschland GmbH
  * Copyright (C) 2018 Intel Corporation
  * Copyright (C) 2019 Intel Corporation
+ * Copyright (C) 2020 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -528,6 +530,8 @@ void iwl_mvm_ftm_abort(struct iwl_mvm *mvm, struct cfg80211_pmsr_request *req)
        if (req != mvm->ftm_initiator.req)
                return;
 
+       iwl_mvm_ftm_reset(mvm);
+
        if (iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(TOF_RANGE_ABORT_CMD,
                                                 LOCATION_GROUP, 0),
                                 0, sizeof(cmd), &cmd))
@@ -641,7 +645,6 @@ void iwl_mvm_ftm_range_resp(struct iwl_mvm *mvm, struct iwl_rx_cmd_buffer *rxb)
        lockdep_assert_held(&mvm->mutex);
 
        if (!mvm->ftm_initiator.req) {
-               IWL_ERR(mvm, "Got FTM response but have no request?\n");
                return;
        }
 
index 6717f25..02df603 100644 (file)
@@ -5,10 +5,9 @@
  *
  * GPL LICENSE SUMMARY
  *
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
  *
  * BSD LICENSE
  *
- * Copyright(c) 2012 - 2014 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2015 Intel Mobile Communications GmbH
  * Copyright(c) 2016 - 2017 Intel Deutschland GmbH
- * Copyright(c) 2018 - 2019 Intel Corporation
+ * Copyright(c) 2012 - 2014, 2018 - 2020 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -2037,7 +2035,7 @@ static void iwl_mvm_cfg_he_sta(struct iwl_mvm *mvm,
        rcu_read_lock();
 
        sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_ctxt_cmd.sta_id]);
-       if (IS_ERR(sta)) {
+       if (IS_ERR_OR_NULL(sta)) {
                rcu_read_unlock();
                WARN(1, "Can't find STA to configure HE\n");
                return;
@@ -3293,7 +3291,7 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
        if (fw_has_capa(&mvm->fw->ucode_capa,
                        IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
                iwl_mvm_schedule_session_protection(mvm, vif, 900,
-                                                   min_duration);
+                                                   min_duration, false);
        else
                iwl_mvm_protect_session(mvm, vif, duration,
                                        min_duration, 500, false);
index 7b35f41..64ef3f3 100644 (file)
@@ -3320,6 +3320,10 @@ static int iwl_mvm_send_sta_igtk(struct iwl_mvm *mvm,
        igtk_cmd.sta_id = cpu_to_le32(sta_id);
 
        if (remove_key) {
+               /* This is a valid situation for IGTK */
+               if (sta_id == IWL_MVM_INVALID_STA)
+                       return 0;
+
                igtk_cmd.ctrl_flags |= cpu_to_le32(STA_KEY_NOT_VALID);
        } else {
                struct ieee80211_key_seq seq;
@@ -3574,9 +3578,9 @@ int iwl_mvm_remove_sta_key(struct iwl_mvm *mvm,
        IWL_DEBUG_WEP(mvm, "mvm remove dynamic key: idx=%d sta=%d\n",
                      keyconf->keyidx, sta_id);
 
-       if (mvm_sta && (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
-                       keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
-                       keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256))
+       if (keyconf->cipher == WLAN_CIPHER_SUITE_AES_CMAC ||
+           keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_128 ||
+           keyconf->cipher == WLAN_CIPHER_SUITE_BIP_GMAC_256)
                return iwl_mvm_send_sta_igtk(mvm, keyconf, sta_id, true);
 
        if (!__test_and_clear_bit(keyconf->hw_key_idx, mvm->fw_key_table)) {
index 1851719..d781777 100644 (file)
@@ -205,9 +205,15 @@ void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
        struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
        u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
 
-       mutex_lock(&mvm->mutex);
        /* Protect the session to hear the TDLS setup response on the channel */
-       iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
+       mutex_lock(&mvm->mutex);
+       if (fw_has_capa(&mvm->fw->ucode_capa,
+                       IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD))
+               iwl_mvm_schedule_session_protection(mvm, vif, duration,
+                                                   duration, true);
+       else
+               iwl_mvm_protect_session(mvm, vif, duration,
+                                       duration, 100, true);
        mutex_unlock(&mvm->mutex);
 }
 
index 51b1386..c0b420f 100644 (file)
@@ -1056,13 +1056,42 @@ int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
        return iwl_mvm_time_event_send_add(mvm, vif, te_data, &time_cmd);
 }
 
+static bool iwl_mvm_session_prot_notif(struct iwl_notif_wait_data *notif_wait,
+                                      struct iwl_rx_packet *pkt, void *data)
+{
+       struct iwl_mvm *mvm =
+               container_of(notif_wait, struct iwl_mvm, notif_wait);
+       struct iwl_mvm_session_prot_notif *resp;
+       int resp_len = iwl_rx_packet_payload_len(pkt);
+
+       if (WARN_ON(pkt->hdr.cmd != SESSION_PROTECTION_NOTIF ||
+                   pkt->hdr.group_id != MAC_CONF_GROUP))
+               return true;
+
+       if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {
+               IWL_ERR(mvm, "Invalid SESSION_PROTECTION_NOTIF response\n");
+               return true;
+       }
+
+       resp = (void *)pkt->data;
+
+       if (!resp->status)
+               IWL_ERR(mvm,
+                       "TIME_EVENT_NOTIFICATION received but not executed\n");
+
+       return true;
+}
+
 void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
                                         struct ieee80211_vif *vif,
-                                        u32 duration, u32 min_duration)
+                                        u32 duration, u32 min_duration,
+                                        bool wait_for_notif)
 {
        struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
        struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
-
+       const u16 notif[] = { iwl_cmd_id(SESSION_PROTECTION_NOTIF,
+                                        MAC_CONF_GROUP, 0) };
+       struct iwl_notification_wait wait_notif;
        struct iwl_mvm_session_prot_cmd cmd = {
                .id_and_color =
                        cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id,
@@ -1071,7 +1100,6 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
                .conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC),
                .duration_tu = cpu_to_le32(MSEC_TO_TU(duration)),
        };
-       int ret;
 
        lockdep_assert_held(&mvm->mutex);
 
@@ -1092,14 +1120,35 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
        IWL_DEBUG_TE(mvm, "Add new session protection, duration %d TU\n",
                     le32_to_cpu(cmd.duration_tu));
 
-       ret = iwl_mvm_send_cmd_pdu(mvm, iwl_cmd_id(SESSION_PROTECTION_CMD,
-                                                  MAC_CONF_GROUP, 0),
-                                  0, sizeof(cmd), &cmd);
-       if (ret) {
+       if (!wait_for_notif) {
+               if (iwl_mvm_send_cmd_pdu(mvm,
+                                        iwl_cmd_id(SESSION_PROTECTION_CMD,
+                                                   MAC_CONF_GROUP, 0),
+                                        0, sizeof(cmd), &cmd)) {
+                       IWL_ERR(mvm,
+                               "Couldn't send the SESSION_PROTECTION_CMD\n");
+                       spin_lock_bh(&mvm->time_event_lock);
+                       iwl_mvm_te_clear_data(mvm, te_data);
+                       spin_unlock_bh(&mvm->time_event_lock);
+               }
+
+               return;
+       }
+
+       iwl_init_notification_wait(&mvm->notif_wait, &wait_notif,
+                                  notif, ARRAY_SIZE(notif),
+                                  iwl_mvm_session_prot_notif, NULL);
+
+       if (iwl_mvm_send_cmd_pdu(mvm,
+                                iwl_cmd_id(SESSION_PROTECTION_CMD,
+                                           MAC_CONF_GROUP, 0),
+                                0, sizeof(cmd), &cmd)) {
                IWL_ERR(mvm,
-                       "Couldn't send the SESSION_PROTECTION_CMD: %d\n", ret);
-               spin_lock_bh(&mvm->time_event_lock);
-               iwl_mvm_te_clear_data(mvm, te_data);
-               spin_unlock_bh(&mvm->time_event_lock);
+                       "Couldn't send the SESSION_PROTECTION_CMD\n");
+               iwl_remove_notification(&mvm->notif_wait, &wait_notif);
+       } else if (iwl_wait_notification(&mvm->notif_wait, &wait_notif,
+                                        TU_TO_JIFFIES(100))) {
+               IWL_ERR(mvm,
+                       "Failed to protect session until session protection\n");
        }
 }
index df6832b..3186d7e 100644 (file)
@@ -250,10 +250,12 @@ iwl_mvm_te_scheduled(struct iwl_mvm_time_event_data *te_data)
  * @mvm: the mvm component
  * @vif: the virtual interface for which the protection issued
  * @duration: the duration of the protection
+ * @wait_for_notif: if true, will block until the start of the protection
  */
 void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm,
                                         struct ieee80211_vif *vif,
-                                        u32 duration, u32 min_duration);
+                                        u32 duration, u32 min_duration,
+                                        bool wait_for_notif);
 
 /**
  * iwl_mvm_rx_session_protect_notif - handles %SESSION_PROTECTION_NOTIF
index b5a16f0..418e59b 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright(c) 2013 - 2014, 2019 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
- * Copyright(c) 2019 Intel Corporation
+ * Copyright(c) 2019 - 2020 Intel Corporation
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of version 2 of the GNU General Public License as
@@ -31,7 +31,7 @@
  * Copyright(c) 2012 - 2014, 2019 Intel Corporation. All rights reserved.
  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
  * Copyright(c) 2015 - 2016 Intel Deutschland GmbH
- * Copyright(c) 2019 Intel Corporation
+ * Copyright(c) 2019 - 2020 Intel Corporation
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -234,7 +234,7 @@ static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
                .flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
        };
        struct iwl_ext_dts_measurement_cmd extcmd = {
-               .control_mode = cpu_to_le32(DTS_AUTOMATIC),
+               .control_mode = cpu_to_le32(DTS_DIRECT_WITHOUT_MEASURE),
        };
        u32 cmdid;
 
@@ -734,7 +734,8 @@ static  struct thermal_zone_device_ops tzone_ops = {
 static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
 {
        int i;
-       char name[] = "iwlwifi";
+       char name[16];
+       static atomic_t counter = ATOMIC_INIT(0);
 
        if (!iwl_mvm_is_tt_in_fw(mvm)) {
                mvm->tz_device.tzone = NULL;
@@ -744,6 +745,7 @@ static void iwl_mvm_thermal_zone_register(struct iwl_mvm *mvm)
 
        BUILD_BUG_ON(ARRAY_SIZE(name) >= THERMAL_NAME_LENGTH);
 
+       sprintf(name, "iwlwifi_%u", atomic_inc_return(&counter) & 0xFF);
        mvm->tz_device.tzone = thermal_zone_device_register(name,
                                                        IWL_MAX_DTS_TRIPS,
                                                        IWL_WRITABLE_TRIPS_MSK,
index e323e9a..58212c5 100644 (file)
@@ -126,7 +126,7 @@ static void prism2_check_sta_fw_version(local_info_t *local);
 
 #ifdef PRISM2_DOWNLOAD_SUPPORT
 /* hostap_download.c */
-static const struct file_operations prism2_download_aux_dump_proc_fops;
+static const struct proc_ops prism2_download_aux_dump_proc_ops;
 static u8 * prism2_read_pda(struct net_device *dev);
 static int prism2_download(local_info_t *local,
                           struct prism2_download_param *param);
@@ -3094,7 +3094,7 @@ prism2_init_local_data(struct prism2_helper_functions *funcs, int card_idx,
        local->func->reset_port = prism2_reset_port;
        local->func->schedule_reset = prism2_schedule_reset;
 #ifdef PRISM2_DOWNLOAD_SUPPORT
-       local->func->read_aux_fops = &prism2_download_aux_dump_proc_fops;
+       local->func->read_aux_proc_ops = &prism2_download_aux_dump_proc_ops;
        local->func->download = prism2_download;
 #endif /* PRISM2_DOWNLOAD_SUPPORT */
        local->func->tx = prism2_tx_80211;
index 6151d8d..a2ee469 100644 (file)
@@ -211,9 +211,9 @@ static ssize_t prism2_pda_proc_read(struct file *file, char __user *buf,
        return count;
 }
 
-static const struct file_operations prism2_pda_proc_fops = {
-       .read           = prism2_pda_proc_read,
-       .llseek         = generic_file_llseek,
+static const struct proc_ops prism2_pda_proc_ops = {
+       .proc_read      = prism2_pda_proc_read,
+       .proc_lseek     = generic_file_llseek,
 };
 
 
@@ -223,8 +223,8 @@ static ssize_t prism2_aux_dump_proc_no_read(struct file *file, char __user *buf,
        return 0;
 }
 
-static const struct file_operations prism2_aux_dump_proc_fops = {
-       .read           = prism2_aux_dump_proc_no_read,
+static const struct proc_ops prism2_aux_dump_proc_ops = {
+       .proc_read      = prism2_aux_dump_proc_no_read,
 };
 
 
@@ -379,9 +379,9 @@ void hostap_init_proc(local_info_t *local)
        proc_create_seq_data("wds", 0, local->proc,
                        &prism2_wds_proc_seqops, local);
        proc_create_data("pda", 0, local->proc,
-                        &prism2_pda_proc_fops, local);
+                        &prism2_pda_proc_ops, local);
        proc_create_data("aux_dump", 0, local->proc,
-                        local->func->read_aux_fops ?: &prism2_aux_dump_proc_fops,
+                        local->func->read_aux_proc_ops ?: &prism2_aux_dump_proc_ops,
                         local);
        proc_create_seq_data("bss_list", 0, local->proc,
                        &prism2_bss_list_proc_seqops, local);
index a8c4c1a..487883f 100644 (file)
@@ -599,7 +599,7 @@ struct prism2_helper_functions {
                        struct prism2_download_param *param);
        int (*tx)(struct sk_buff *skb, struct net_device *dev);
        int (*set_tim)(struct net_device *dev, int aid, int set);
-       const struct file_operations *read_aux_fops;
+       const struct proc_ops *read_aux_proc_ops;
 
        int need_tx_headroom; /* number of bytes of headroom needed before
                               * IEEE 802.11 header */
index c9401c1..4e3de68 100644 (file)
@@ -1785,6 +1785,8 @@ static int lbs_ibss_join_existing(struct lbs_private *priv,
                rates_max = rates_eid[1];
                if (rates_max > MAX_RATES) {
                        lbs_deb_join("invalid rates");
+                       rcu_read_unlock();
+                       ret = -EINVAL;
                        goto out;
                }
                rates = cmd.bss.rates;
index 98f942b..a7968a8 100644 (file)
@@ -2884,6 +2884,13 @@ mwifiex_cmd_append_vsie_tlv(struct mwifiex_private *priv,
                        vs_param_set->header.len =
                                cpu_to_le16((((u16) priv->vs_ie[id].ie[1])
                                & 0x00FF) + 2);
+                       if (le16_to_cpu(vs_param_set->header.len) >
+                               MWIFIEX_MAX_VSIE_LEN) {
+                               mwifiex_dbg(priv->adapter, ERROR,
+                                           "Invalid param length!\n");
+                               break;
+                       }
+
                        memcpy(vs_param_set->ie, priv->vs_ie[id].ie,
                               le16_to_cpu(vs_param_set->header.len));
                        *buffer += le16_to_cpu(vs_param_set->header.len) +
index 6dd835f..fbfa0b1 100644 (file)
@@ -232,6 +232,7 @@ static int mwifiex_process_country_ie(struct mwifiex_private *priv,
 
        if (country_ie_len >
            (IEEE80211_COUNTRY_STRING_LEN + MWIFIEX_MAX_TRIPLET_802_11D)) {
+               rcu_read_unlock();
                mwifiex_dbg(priv->adapter, ERROR,
                            "11D: country_ie_len overflow!, deauth AP\n");
                return -EINVAL;
index 41f0231..132f9e8 100644 (file)
@@ -970,6 +970,10 @@ int mwifiex_ret_wmm_get_status(struct mwifiex_private *priv,
                                    "WMM Parameter Set Count: %d\n",
                                    wmm_param_ie->qos_info_bitmap & mask);
 
+                       if (wmm_param_ie->vend_hdr.len + 2 >
+                               sizeof(struct ieee_types_wmm_parameter))
+                               break;
+
                        memcpy((u8 *) &priv->curr_bss_params.bss_descriptor.
                               wmm_ie, wmm_param_ie,
                               wmm_param_ie->vend_hdr.len + 2);
index eccad49..17e277b 100644 (file)
@@ -92,8 +92,9 @@ static int mt7615_check_eeprom(struct mt76_dev *dev)
 
 static void mt7615_eeprom_parse_hw_cap(struct mt7615_dev *dev)
 {
-       u8 val, *eeprom = dev->mt76.eeprom.data;
+       u8 *eeprom = dev->mt76.eeprom.data;
        u8 tx_mask, rx_mask, max_nss;
+       u32 val;
 
        val = FIELD_GET(MT_EE_NIC_WIFI_CONF_BAND_SEL,
                        eeprom[MT_EE_WIFI_CONF]);
index cf37268..c1d542b 100644 (file)
@@ -2717,10 +2717,9 @@ static ssize_t ray_cs_essid_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations ray_cs_essid_proc_fops = {
-       .owner          = THIS_MODULE,
-       .write          = ray_cs_essid_proc_write,
-       .llseek         = noop_llseek,
+static const struct proc_ops ray_cs_essid_proc_ops = {
+       .proc_write     = ray_cs_essid_proc_write,
+       .proc_lseek     = noop_llseek,
 };
 
 static ssize_t int_proc_write(struct file *file, const char __user *buffer,
@@ -2751,10 +2750,9 @@ static ssize_t int_proc_write(struct file *file, const char __user *buffer,
        return count;
 }
 
-static const struct file_operations int_proc_fops = {
-       .owner          = THIS_MODULE,
-       .write          = int_proc_write,
-       .llseek         = noop_llseek,
+static const struct proc_ops int_proc_ops = {
+       .proc_write     = int_proc_write,
+       .proc_lseek     = noop_llseek,
 };
 #endif
 
@@ -2790,10 +2788,10 @@ static int __init init_ray_cs(void)
        proc_mkdir("driver/ray_cs", NULL);
 
        proc_create_single("driver/ray_cs/ray_cs", 0, NULL, ray_cs_proc_show);
-       proc_create("driver/ray_cs/essid", 0200, NULL, &ray_cs_essid_proc_fops);
-       proc_create_data("driver/ray_cs/net_type", 0200, NULL, &int_proc_fops,
+       proc_create("driver/ray_cs/essid", 0200, NULL, &ray_cs_essid_proc_ops);
+       proc_create_data("driver/ray_cs/net_type", 0200, NULL, &int_proc_ops,
                         &net_type);
-       proc_create_data("driver/ray_cs/translate", 0200, NULL, &int_proc_fops,
+       proc_create_data("driver/ray_cs/translate", 0200, NULL, &int_proc_ops,
                         &translate);
 #endif
        if (translate != 0)
index af5c27e..4820dca 100644 (file)
@@ -281,27 +281,26 @@ static void rtw_wow_rx_dma_start(struct rtw_dev *rtwdev)
        rtw_write32_clr(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE);
 }
 
-static bool rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable)
+static int rtw_wow_check_fw_status(struct rtw_dev *rtwdev, bool wow_enable)
 {
-       bool ret;
-
        /* wait 100ms for wow firmware to finish work */
        msleep(100);
 
        if (wow_enable) {
-               if (!rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON))
-                       ret = 0;
+               if (rtw_read8(rtwdev, REG_WOWLAN_WAKE_REASON))
+                       goto wow_fail;
        } else {
-               if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) == 0 &&
-                   rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE) == 0)
-                       ret = 0;
+               if (rtw_read32_mask(rtwdev, REG_FE1IMR, BIT_FS_RXDONE) ||
+                   rtw_read32_mask(rtwdev, REG_RXPKT_NUM, BIT_RW_RELEASE))
+                       goto wow_fail;
        }
 
-       if (ret)
-               rtw_err(rtwdev, "failed to check wow status %s\n",
-                       wow_enable ? "enabled" : "disabled");
+       return 0;
 
-       return ret;
+wow_fail:
+       rtw_err(rtwdev, "failed to check wow status %s\n",
+               wow_enable ? "enabled" : "disabled");
+       return -EBUSY;
 }
 
 static void rtw_wow_fw_security_type_iter(struct ieee80211_hw *hw,
index 365a2dd..da392b5 100644 (file)
@@ -167,7 +167,6 @@ struct nvme_queue {
         /* only used for poll queues: */
        spinlock_t cq_poll_lock ____cacheline_aligned_in_smp;
        volatile struct nvme_completion *cqes;
-       struct blk_mq_tags **tags;
        dma_addr_t sq_dma_addr;
        dma_addr_t cq_dma_addr;
        u32 __iomem *q_db;
@@ -376,29 +375,17 @@ static int nvme_admin_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
 
        WARN_ON(hctx_idx != 0);
        WARN_ON(dev->admin_tagset.tags[0] != hctx->tags);
-       WARN_ON(nvmeq->tags);
 
        hctx->driver_data = nvmeq;
-       nvmeq->tags = &dev->admin_tagset.tags[0];
        return 0;
 }
 
-static void nvme_admin_exit_hctx(struct blk_mq_hw_ctx *hctx, unsigned int hctx_idx)
-{
-       struct nvme_queue *nvmeq = hctx->driver_data;
-
-       nvmeq->tags = NULL;
-}
-
 static int nvme_init_hctx(struct blk_mq_hw_ctx *hctx, void *data,
                          unsigned int hctx_idx)
 {
        struct nvme_dev *dev = data;
        struct nvme_queue *nvmeq = &dev->queues[hctx_idx + 1];
 
-       if (!nvmeq->tags)
-               nvmeq->tags = &dev->tagset.tags[hctx_idx];
-
        WARN_ON(dev->tagset.tags[hctx_idx] != hctx->tags);
        hctx->driver_data = nvmeq;
        return 0;
@@ -948,6 +935,13 @@ static inline void nvme_ring_cq_doorbell(struct nvme_queue *nvmeq)
                writel(head, nvmeq->q_db + nvmeq->dev->db_stride);
 }
 
+static inline struct blk_mq_tags *nvme_queue_tagset(struct nvme_queue *nvmeq)
+{
+       if (!nvmeq->qid)
+               return nvmeq->dev->admin_tagset.tags[0];
+       return nvmeq->dev->tagset.tags[nvmeq->qid - 1];
+}
+
 static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx)
 {
        volatile struct nvme_completion *cqe = &nvmeq->cqes[idx];
@@ -972,7 +966,7 @@ static inline void nvme_handle_cqe(struct nvme_queue *nvmeq, u16 idx)
                return;
        }
 
-       req = blk_mq_tag_to_rq(*nvmeq->tags, cqe->command_id);
+       req = blk_mq_tag_to_rq(nvme_queue_tagset(nvmeq), cqe->command_id);
        trace_nvme_sq(req, cqe->sq_head, nvmeq->sq_tail);
        nvme_end_request(req, cqe->status, cqe->result);
 }
@@ -1572,7 +1566,6 @@ static const struct blk_mq_ops nvme_mq_admin_ops = {
        .queue_rq       = nvme_queue_rq,
        .complete       = nvme_pci_complete_rq,
        .init_hctx      = nvme_admin_init_hctx,
-       .exit_hctx      = nvme_admin_exit_hctx,
        .init_request   = nvme_init_request,
        .timeout        = nvme_timeout,
 };
index 28438b8..576de77 100644 (file)
@@ -129,27 +129,8 @@ static u32 nvmet_async_event_result(struct nvmet_async_event *aen)
        return aen->event_type | (aen->event_info << 8) | (aen->log_page << 16);
 }
 
-static void nvmet_async_events_free(struct nvmet_ctrl *ctrl)
-{
-       struct nvmet_req *req;
-
-       while (1) {
-               mutex_lock(&ctrl->lock);
-               if (!ctrl->nr_async_event_cmds) {
-                       mutex_unlock(&ctrl->lock);
-                       return;
-               }
-
-               req = ctrl->async_event_cmds[--ctrl->nr_async_event_cmds];
-               mutex_unlock(&ctrl->lock);
-               nvmet_req_complete(req, NVME_SC_INTERNAL | NVME_SC_DNR);
-       }
-}
-
-static void nvmet_async_event_work(struct work_struct *work)
+static void nvmet_async_events_process(struct nvmet_ctrl *ctrl, u16 status)
 {
-       struct nvmet_ctrl *ctrl =
-               container_of(work, struct nvmet_ctrl, async_event_work);
        struct nvmet_async_event *aen;
        struct nvmet_req *req;
 
@@ -159,18 +140,41 @@ static void nvmet_async_event_work(struct work_struct *work)
                                struct nvmet_async_event, entry);
                if (!aen || !ctrl->nr_async_event_cmds) {
                        mutex_unlock(&ctrl->lock);
-                       return;
+                       break;
                }
 
                req = ctrl->async_event_cmds[--ctrl->nr_async_event_cmds];
-               nvmet_set_result(req, nvmet_async_event_result(aen));
+               if (status == 0)
+                       nvmet_set_result(req, nvmet_async_event_result(aen));
 
                list_del(&aen->entry);
                kfree(aen);
 
                mutex_unlock(&ctrl->lock);
-               nvmet_req_complete(req, 0);
+               nvmet_req_complete(req, status);
+       }
+}
+
+static void nvmet_async_events_free(struct nvmet_ctrl *ctrl)
+{
+       struct nvmet_req *req;
+
+       mutex_lock(&ctrl->lock);
+       while (ctrl->nr_async_event_cmds) {
+               req = ctrl->async_event_cmds[--ctrl->nr_async_event_cmds];
+               mutex_unlock(&ctrl->lock);
+               nvmet_req_complete(req, NVME_SC_INTERNAL | NVME_SC_DNR);
+               mutex_lock(&ctrl->lock);
        }
+       mutex_unlock(&ctrl->lock);
+}
+
+static void nvmet_async_event_work(struct work_struct *work)
+{
+       struct nvmet_ctrl *ctrl =
+               container_of(work, struct nvmet_ctrl, async_event_work);
+
+       nvmet_async_events_process(ctrl, 0);
 }
 
 void nvmet_add_async_event(struct nvmet_ctrl *ctrl, u8 event_type,
@@ -555,7 +559,8 @@ int nvmet_ns_enable(struct nvmet_ns *ns)
        } else {
                struct nvmet_ns *old;
 
-               list_for_each_entry_rcu(old, &subsys->namespaces, dev_link) {
+               list_for_each_entry_rcu(old, &subsys->namespaces, dev_link,
+                                       lockdep_is_held(&subsys->lock)) {
                        BUG_ON(ns->nsid == old->nsid);
                        if (ns->nsid < old->nsid)
                                break;
@@ -752,19 +757,24 @@ static void nvmet_confirm_sq(struct percpu_ref *ref)
 
 void nvmet_sq_destroy(struct nvmet_sq *sq)
 {
+       u16 status = NVME_SC_INTERNAL | NVME_SC_DNR;
+       struct nvmet_ctrl *ctrl = sq->ctrl;
+
        /*
         * If this is the admin queue, complete all AERs so that our
         * queue doesn't have outstanding requests on it.
         */
-       if (sq->ctrl && sq->ctrl->sqs && sq->ctrl->sqs[0] == sq)
-               nvmet_async_events_free(sq->ctrl);
+       if (ctrl && ctrl->sqs && ctrl->sqs[0] == sq) {
+               nvmet_async_events_process(ctrl, status);
+               nvmet_async_events_free(ctrl);
+       }
        percpu_ref_kill_and_confirm(&sq->ref, nvmet_confirm_sq);
        wait_for_completion(&sq->confirm_done);
        wait_for_completion(&sq->free_done);
        percpu_ref_exit(&sq->ref);
 
-       if (sq->ctrl) {
-               nvmet_ctrl_put(sq->ctrl);
+       if (ctrl) {
+               nvmet_ctrl_put(ctrl);
                sq->ctrl = NULL; /* allows reusing the queue later */
        }
 }
@@ -938,6 +948,17 @@ bool nvmet_check_data_len(struct nvmet_req *req, size_t data_len)
 }
 EXPORT_SYMBOL_GPL(nvmet_check_data_len);
 
+bool nvmet_check_data_len_lte(struct nvmet_req *req, size_t data_len)
+{
+       if (unlikely(data_len > req->transfer_len)) {
+               req->error_loc = offsetof(struct nvme_common_command, dptr);
+               nvmet_req_complete(req, NVME_SC_SGL_INVALID_DATA | NVME_SC_DNR);
+               return false;
+       }
+
+       return true;
+}
+
 int nvmet_req_alloc_sgl(struct nvmet_req *req)
 {
        struct pci_dev *p2p_dev = NULL;
@@ -1172,7 +1193,8 @@ static void nvmet_setup_p2p_ns_map(struct nvmet_ctrl *ctrl,
 
        ctrl->p2p_client = get_device(req->p2p_client);
 
-       list_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link)
+       list_for_each_entry_rcu(ns, &ctrl->subsys->namespaces, dev_link,
+                               lockdep_is_held(&ctrl->subsys->lock))
                nvmet_p2pmem_ns_add_p2p(ctrl, ns);
 }
 
index f729747..feef15c 100644 (file)
@@ -109,6 +109,7 @@ static u16 nvmet_install_queue(struct nvmet_ctrl *ctrl, struct nvmet_req *req)
        u16 qid = le16_to_cpu(c->qid);
        u16 sqsize = le16_to_cpu(c->sqsize);
        struct nvmet_ctrl *old;
+       u16 ret;
 
        old = cmpxchg(&req->sq->ctrl, NULL, ctrl);
        if (old) {
@@ -119,7 +120,8 @@ static u16 nvmet_install_queue(struct nvmet_ctrl *ctrl, struct nvmet_req *req)
        if (!sqsize) {
                pr_warn("queue size zero!\n");
                req->error_loc = offsetof(struct nvmf_connect_command, sqsize);
-               return NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR;
+               ret = NVME_SC_CONNECT_INVALID_PARAM | NVME_SC_DNR;
+               goto err;
        }
 
        /* note: convert queue size from 0's-based value to 1's-based value */
@@ -132,16 +134,19 @@ static u16 nvmet_install_queue(struct nvmet_ctrl *ctrl, struct nvmet_req *req)
        }
 
        if (ctrl->ops->install_queue) {
-               u16 ret = ctrl->ops->install_queue(req->sq);
-
+               ret = ctrl->ops->install_queue(req->sq);
                if (ret) {
                        pr_err("failed to install queue %d cntlid %d ret %x\n",
-                               qid, ret, ctrl->cntlid);
-                       return ret;
+                               qid, ctrl->cntlid, ret);
+                       goto err;
                }
        }
 
        return 0;
+
+err:
+       req->sq->ctrl = NULL;
+       return ret;
 }
 
 static void nvmet_execute_admin_connect(struct nvmet_req *req)
index b6fca0e..ea0e596 100644 (file)
@@ -280,7 +280,7 @@ static void nvmet_bdev_execute_discard(struct nvmet_req *req)
 
 static void nvmet_bdev_execute_dsm(struct nvmet_req *req)
 {
-       if (!nvmet_check_data_len(req, nvmet_dsm_len(req)))
+       if (!nvmet_check_data_len_lte(req, nvmet_dsm_len(req)))
                return;
 
        switch (le32_to_cpu(req->cmd->dsm.attributes)) {
index caebfce..cd5670b 100644 (file)
@@ -336,7 +336,7 @@ static void nvmet_file_dsm_work(struct work_struct *w)
 
 static void nvmet_file_execute_dsm(struct nvmet_req *req)
 {
-       if (!nvmet_check_data_len(req, nvmet_dsm_len(req)))
+       if (!nvmet_check_data_len_lte(req, nvmet_dsm_len(req)))
                return;
        INIT_WORK(&req->f.work, nvmet_file_dsm_work);
        schedule_work(&req->f.work);
index 46df45e..eda28b2 100644 (file)
@@ -374,6 +374,7 @@ bool nvmet_req_init(struct nvmet_req *req, struct nvmet_cq *cq,
                struct nvmet_sq *sq, const struct nvmet_fabrics_ops *ops);
 void nvmet_req_uninit(struct nvmet_req *req);
 bool nvmet_check_data_len(struct nvmet_req *req, size_t data_len);
+bool nvmet_check_data_len_lte(struct nvmet_req *req, size_t data_len);
 void nvmet_req_complete(struct nvmet_req *req, u16 status);
 int nvmet_req_alloc_sgl(struct nvmet_req *req);
 void nvmet_req_free_sgl(struct nvmet_req *req);
index 1e4a798..ef326f2 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/module.h>
 #include <linux/nvmem-consumer.h>
 #include <linux/nvmem-provider.h>
+#include <linux/gpio/consumer.h>
 #include <linux/of.h>
 #include <linux/slab.h>
 #include "nvmem.h"
@@ -54,8 +55,14 @@ static int nvmem_reg_read(struct nvmem_device *nvmem, unsigned int offset,
 static int nvmem_reg_write(struct nvmem_device *nvmem, unsigned int offset,
                           void *val, size_t bytes)
 {
-       if (nvmem->reg_write)
-               return nvmem->reg_write(nvmem->priv, offset, val, bytes);
+       int ret;
+
+       if (nvmem->reg_write) {
+               gpiod_set_value_cansleep(nvmem->wp_gpio, 0);
+               ret = nvmem->reg_write(nvmem->priv, offset, val, bytes);
+               gpiod_set_value_cansleep(nvmem->wp_gpio, 1);
+               return ret;
+       }
 
        return -EINVAL;
 }
@@ -340,6 +347,14 @@ struct nvmem_device *nvmem_register(const struct nvmem_config *config)
                kfree(nvmem);
                return ERR_PTR(rval);
        }
+       if (config->wp_gpio)
+               nvmem->wp_gpio = config->wp_gpio;
+       else
+               nvmem->wp_gpio = gpiod_get_optional(config->dev, "wp",
+                                                   GPIOD_OUT_HIGH);
+       if (IS_ERR(nvmem->wp_gpio))
+               return ERR_CAST(nvmem->wp_gpio);
+
 
        kref_init(&nvmem->refcnt);
        INIT_LIST_HEAD(&nvmem->cells);
index eb8ed71..be0d66d 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/list.h>
 #include <linux/nvmem-consumer.h>
 #include <linux/nvmem-provider.h>
+#include <linux/gpio/consumer.h>
 
 struct nvmem_device {
        struct module           *owner;
@@ -26,6 +27,7 @@ struct nvmem_device {
        struct list_head        cells;
        nvmem_reg_read_t        reg_read;
        nvmem_reg_write_t       reg_write;
+       struct gpio_desc        *wp_gpio;
        void *priv;
 };
 
index 8d173fb..ae03b12 100644 (file)
@@ -416,6 +416,42 @@ int of_cpu_node_to_id(struct device_node *cpu_node)
 EXPORT_SYMBOL(of_cpu_node_to_id);
 
 /**
+ * of_get_cpu_state_node - Get CPU's idle state node at the given index
+ *
+ * @cpu_node: The device node for the CPU
+ * @index: The index in the list of the idle states
+ *
+ * Two generic methods can be used to describe a CPU's idle states, either via
+ * a flattened description through the "cpu-idle-states" binding or via the
+ * hierarchical layout, using the "power-domains" and the "domain-idle-states"
+ * bindings. This function check for both and returns the idle state node for
+ * the requested index.
+ *
+ * In case an idle state node is found at @index, the refcount is incremented
+ * for it, so call of_node_put() on it when done. Returns NULL if not found.
+ */
+struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
+                                         int index)
+{
+       struct of_phandle_args args;
+       int err;
+
+       err = of_parse_phandle_with_args(cpu_node, "power-domains",
+                                       "#power-domain-cells", 0, &args);
+       if (!err) {
+               struct device_node *state_node =
+                       of_parse_phandle(args.np, "domain-idle-states", index);
+
+               of_node_put(args.np);
+               if (state_node)
+                       return state_node;
+       }
+
+       return of_parse_phandle(cpu_node, "cpu-idle-states", index);
+}
+EXPORT_SYMBOL(of_get_cpu_state_node);
+
+/**
  * __of_device_is_compatible() - Check if the node matches given constraints
  * @device: pointer to node
  * @compat: required compatible string, NULL or "" for any match
index e9127db..27203bf 100644 (file)
@@ -161,7 +161,7 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma)
                coherent ? " " : " not ");
 
        iommu = of_iommu_configure(dev, np);
-       if (IS_ERR(iommu) && PTR_ERR(iommu) == -EPROBE_DEFER)
+       if (PTR_ERR(iommu) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
        dev_dbg(dev, "device is%sbehind an iommu\n",
index f5c2a54..8270bbf 100644 (file)
@@ -81,13 +81,15 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
        else
                phy = get_phy_device(mdio, addr, is_c45);
        if (IS_ERR(phy)) {
-               unregister_mii_timestamper(mii_ts);
+               if (mii_ts)
+                       unregister_mii_timestamper(mii_ts);
                return PTR_ERR(phy);
        }
 
        rc = of_irq_get(child, 0);
        if (rc == -EPROBE_DEFER) {
-               unregister_mii_timestamper(mii_ts);
+               if (mii_ts)
+                       unregister_mii_timestamper(mii_ts);
                phy_device_free(phy);
                return rc;
        }
@@ -116,12 +118,19 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
         * register it */
        rc = phy_device_register(phy);
        if (rc) {
-               unregister_mii_timestamper(mii_ts);
+               if (mii_ts)
+                       unregister_mii_timestamper(mii_ts);
                phy_device_free(phy);
                of_node_put(child);
                return rc;
        }
-       phy->mii_ts = mii_ts;
+
+       /* phy->mii_ts may already be defined by the PHY driver. A
+        * mii_timestamper probed via the device tree will still have
+        * precedence.
+        */
+       if (mii_ts)
+               phy->mii_ts = mii_ts;
 
        dev_dbg(&mdio->dev, "registered phy %pOFn at address %i\n",
                child, addr);
index eda2633..9210a95 100644 (file)
@@ -32,7 +32,7 @@
 
 #define OP_BUFFER_FLAGS        0
 
-static struct ring_buffer *op_ring_buffer;
+static struct trace_buffer *op_ring_buffer;
 DEFINE_PER_CPU(struct oprofile_cpu_buffer, op_cpu_buffer);
 
 static void wq_sync_buffer(struct work_struct *work);
index 73e37bb..36c6613 100644 (file)
@@ -230,13 +230,12 @@ parse_error:
        return -EINVAL;
 }
 
-static const struct file_operations led_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = led_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = led_proc_write,
+static const struct proc_ops led_proc_ops = {
+       .proc_open      = led_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = led_proc_write,
 };
 
 static int __init led_create_procfs(void)
@@ -252,14 +251,14 @@ static int __init led_create_procfs(void)
        if (!lcd_no_led_support)
        {
                ent = proc_create_data("led", S_IRUGO|S_IWUSR, proc_pdc_root,
-                                       &led_proc_fops, (void *)LED_NOLCD); /* LED */
+                                       &led_proc_ops, (void *)LED_NOLCD); /* LED */
                if (!ent) return -1;
        }
 
        if (led_type == LED_HASLCD)
        {
                ent = proc_create_data("lcd", S_IRUGO|S_IWUSR, proc_pdc_root,
-                                       &led_proc_fops, (void *)LED_HASLCD); /* LCD */
+                                       &led_proc_ops, (void *)LED_HASLCD); /* LCD */
                if (!ent) return -1;
        }
 
index 982b46f..3ef0bb2 100644 (file)
@@ -69,6 +69,7 @@ int pci_enable_ats(struct pci_dev *dev, int ps)
        dev->ats_enabled = 1;
        return 0;
 }
+EXPORT_SYMBOL_GPL(pci_enable_ats);
 
 /**
  * pci_disable_ats - disable the ATS capability
@@ -87,6 +88,7 @@ void pci_disable_ats(struct pci_dev *dev)
 
        dev->ats_enabled = 0;
 }
+EXPORT_SYMBOL_GPL(pci_disable_ats);
 
 void pci_restore_ats_state(struct pci_dev *dev)
 {
@@ -424,11 +426,12 @@ void pci_restore_pasid_state(struct pci_dev *pdev)
 int pci_pasid_features(struct pci_dev *pdev)
 {
        u16 supported;
-       int pasid = pdev->pasid_cap;
+       int pasid;
 
        if (pdev->is_virtfn)
                pdev = pci_physfn(pdev);
 
+       pasid = pdev->pasid_cap;
        if (!pasid)
                return -EINVAL;
 
@@ -451,11 +454,12 @@ int pci_pasid_features(struct pci_dev *pdev)
 int pci_max_pasids(struct pci_dev *pdev)
 {
        u16 supported;
-       int pasid = pdev->pasid_cap;
+       int pasid;
 
        if (pdev->is_virtfn)
                pdev = pci_physfn(pdev);
 
+       pasid = pdev->pasid_cap;
        if (!pasid)
                return -EINVAL;
 
index ac93f5a..0e03cef 100644 (file)
@@ -1406,7 +1406,7 @@ static struct phy *devm_of_phy_optional_get_index(struct device *dev,
        phy = devm_of_phy_get(dev, np, name);
        kfree(name);
 
-       if (IS_ERR(phy) && PTR_ERR(phy) == -ENODEV)
+       if (PTR_ERR(phy) == -ENODEV)
                phy = NULL;
 
        return phy;
index d7b2b47..0456516 100644 (file)
@@ -18,6 +18,9 @@
 #define DRIVER_AUTHOR  "Gavin Shan, IBM Corporation"
 #define DRIVER_DESC    "PowerPC PowerNV PCI Hotplug Driver"
 
+#define SLOT_WARN(sl, x...) \
+       ((sl)->pdev ? pci_warn((sl)->pdev, x) : dev_warn(&(sl)->bus->dev, x))
+
 struct pnv_php_event {
        bool                    added;
        struct pnv_php_slot     *php_slot;
@@ -151,17 +154,11 @@ static void pnv_php_rmv_pdns(struct device_node *dn)
 static void pnv_php_detach_device_nodes(struct device_node *parent)
 {
        struct device_node *dn;
-       int refcount;
 
        for_each_child_of_node(parent, dn) {
                pnv_php_detach_device_nodes(dn);
 
                of_node_put(dn);
-               refcount = kref_read(&dn->kobj.kref);
-               if (refcount != 1)
-                       pr_warn("Invalid refcount %d on <%pOF>\n",
-                               refcount, dn);
-
                of_detach_node(dn);
        }
 }
@@ -271,7 +268,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
 
        ret = pnv_pci_get_device_tree(php_slot->dn->phandle, fdt1, 0x10000);
        if (ret) {
-               pci_warn(php_slot->pdev, "Error %d getting FDT blob\n", ret);
+               SLOT_WARN(php_slot, "Error %d getting FDT blob\n", ret);
                goto free_fdt1;
        }
 
@@ -285,7 +282,7 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
        dt = of_fdt_unflatten_tree(fdt, php_slot->dn, NULL);
        if (!dt) {
                ret = -EINVAL;
-               pci_warn(php_slot->pdev, "Cannot unflatten FDT\n");
+               SLOT_WARN(php_slot, "Cannot unflatten FDT\n");
                goto free_fdt;
        }
 
@@ -295,15 +292,15 @@ static int pnv_php_add_devtree(struct pnv_php_slot *php_slot)
        ret = pnv_php_populate_changeset(&php_slot->ocs, php_slot->dn);
        if (ret) {
                pnv_php_reverse_nodes(php_slot->dn);
-               pci_warn(php_slot->pdev, "Error %d populating changeset\n",
-                        ret);
+               SLOT_WARN(php_slot, "Error %d populating changeset\n",
+                         ret);
                goto free_dt;
        }
 
        php_slot->dn->child = NULL;
        ret = of_changeset_apply(&php_slot->ocs);
        if (ret) {
-               pci_warn(php_slot->pdev, "Error %d applying changeset\n", ret);
+               SLOT_WARN(php_slot, "Error %d applying changeset\n", ret);
                goto destroy_changeset;
        }
 
@@ -342,18 +339,19 @@ int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
        ret = pnv_pci_set_power_state(php_slot->id, state, &msg);
        if (ret > 0) {
                if (be64_to_cpu(msg.params[1]) != php_slot->dn->phandle ||
-                   be64_to_cpu(msg.params[2]) != state                 ||
-                   be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) {
-                       pci_warn(php_slot->pdev, "Wrong msg (%lld, %lld, %lld)\n",
-                                be64_to_cpu(msg.params[1]),
-                                be64_to_cpu(msg.params[2]),
-                                be64_to_cpu(msg.params[3]));
+                   be64_to_cpu(msg.params[2]) != state) {
+                       SLOT_WARN(php_slot, "Wrong msg (%lld, %lld, %lld)\n",
+                                 be64_to_cpu(msg.params[1]),
+                                 be64_to_cpu(msg.params[2]),
+                                 be64_to_cpu(msg.params[3]));
                        return -ENOMSG;
                }
+               if (be64_to_cpu(msg.params[3]) != OPAL_SUCCESS) {
+                       ret = -ENODEV;
+                       goto error;
+               }
        } else if (ret < 0) {
-               pci_warn(php_slot->pdev, "Error %d powering %s\n",
-                        ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off");
-               return ret;
+               goto error;
        }
 
        if (state == OPAL_PCI_SLOT_POWER_OFF || state == OPAL_PCI_SLOT_OFFLINE)
@@ -362,6 +360,11 @@ int pnv_php_set_slot_power_state(struct hotplug_slot *slot,
                ret = pnv_php_add_devtree(php_slot);
 
        return ret;
+
+error:
+       SLOT_WARN(php_slot, "Error %d powering %s\n",
+                 ret, (state == OPAL_PCI_SLOT_POWER_ON) ? "on" : "off");
+       return ret;
 }
 EXPORT_SYMBOL_GPL(pnv_php_set_slot_power_state);
 
@@ -378,8 +381,8 @@ static int pnv_php_get_power_state(struct hotplug_slot *slot, u8 *state)
         */
        ret = pnv_pci_get_power_state(php_slot->id, &power_state);
        if (ret) {
-               pci_warn(php_slot->pdev, "Error %d getting power status\n",
-                        ret);
+               SLOT_WARN(php_slot, "Error %d getting power status\n",
+                         ret);
        } else {
                *state = power_state;
        }
@@ -402,7 +405,7 @@ static int pnv_php_get_adapter_state(struct hotplug_slot *slot, u8 *state)
                *state = presence;
                ret = 0;
        } else {
-               pci_warn(php_slot->pdev, "Error %d getting presence\n", ret);
+               SLOT_WARN(php_slot, "Error %d getting presence\n", ret);
        }
 
        return ret;
@@ -566,7 +569,13 @@ static int pnv_php_disable_slot(struct hotplug_slot *slot)
        struct pnv_php_slot *php_slot = to_pnv_php_slot(slot);
        int ret;
 
-       if (php_slot->state != PNV_PHP_STATE_POPULATED)
+       /*
+        * Allow to disable a slot already in the registered state to
+        * cover cases where the slot couldn't be enabled and never
+        * reached the populated state
+        */
+       if (php_slot->state != PNV_PHP_STATE_POPULATED &&
+           php_slot->state != PNV_PHP_STATE_REGISTERED)
                return 0;
 
        /* Remove all devices behind the slot */
@@ -675,7 +684,7 @@ static int pnv_php_register_slot(struct pnv_php_slot *php_slot)
        ret = pci_hp_register(&php_slot->slot, php_slot->bus,
                              php_slot->slot_no, php_slot->name);
        if (ret) {
-               pci_warn(php_slot->pdev, "Error %d registering slot\n", ret);
+               SLOT_WARN(php_slot, "Error %d registering slot\n", ret);
                return ret;
        }
 
@@ -728,7 +737,7 @@ static int pnv_php_enable_msix(struct pnv_php_slot *php_slot)
        /* Enable MSIx */
        ret = pci_enable_msix_exact(pdev, &entry, 1);
        if (ret) {
-               pci_warn(pdev, "Error %d enabling MSIx\n", ret);
+               SLOT_WARN(php_slot, "Error %d enabling MSIx\n", ret);
                return ret;
        }
 
@@ -778,8 +787,9 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
                   (sts & PCI_EXP_SLTSTA_PDC)) {
                ret = pnv_pci_get_presence_state(php_slot->id, &presence);
                if (ret) {
-                       pci_warn(pdev, "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
-                                php_slot->name, ret, sts);
+                       SLOT_WARN(php_slot,
+                                 "PCI slot [%s] error %d getting presence (0x%04x), to retry the operation.\n",
+                                 php_slot->name, ret, sts);
                        return IRQ_HANDLED;
                }
 
@@ -809,8 +819,9 @@ static irqreturn_t pnv_php_interrupt(int irq, void *data)
         */
        event = kzalloc(sizeof(*event), GFP_ATOMIC);
        if (!event) {
-               pci_warn(pdev, "PCI slot [%s] missed hotplug event 0x%04x\n",
-                        php_slot->name, sts);
+               SLOT_WARN(php_slot,
+                         "PCI slot [%s] missed hotplug event 0x%04x\n",
+                         php_slot->name, sts);
                return IRQ_HANDLED;
        }
 
@@ -834,7 +845,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
        /* Allocate workqueue */
        php_slot->wq = alloc_workqueue("pciehp-%s", 0, 0, php_slot->name);
        if (!php_slot->wq) {
-               pci_warn(pdev, "Cannot alloc workqueue\n");
+               SLOT_WARN(php_slot, "Cannot alloc workqueue\n");
                pnv_php_disable_irq(php_slot, true);
                return;
        }
@@ -858,7 +869,7 @@ static void pnv_php_init_irq(struct pnv_php_slot *php_slot, int irq)
                          php_slot->name, php_slot);
        if (ret) {
                pnv_php_disable_irq(php_slot, true);
-               pci_warn(pdev, "Error %d enabling IRQ %d\n", ret, irq);
+               SLOT_WARN(php_slot, "Error %d enabling IRQ %d\n", ret, irq);
                return;
        }
 
@@ -894,7 +905,7 @@ static void pnv_php_enable_irq(struct pnv_php_slot *php_slot)
 
        ret = pci_enable_device(pdev);
        if (ret) {
-               pci_warn(pdev, "Error %d enabling device\n", ret);
+               SLOT_WARN(php_slot, "Error %d enabling device\n", ret);
                return;
        }
 
@@ -1009,6 +1020,8 @@ static int __init pnv_php_init(void)
        for_each_compatible_node(dn, NULL, "ibm,ioda3-phb")
                pnv_php_register(dn);
 
+       for_each_compatible_node(dn, NULL, "ibm,ioda2-npu2-opencapi-phb")
+               pnv_php_register_one(dn); /* slot directly under the PHB */
        return 0;
 }
 
@@ -1021,6 +1034,9 @@ static void __exit pnv_php_exit(void)
 
        for_each_compatible_node(dn, NULL, "ibm,ioda3-phb")
                pnv_php_unregister(dn);
+
+       for_each_compatible_node(dn, NULL, "ibm,ioda2-npu2-opencapi-phb")
+               pnv_php_unregister_one(dn); /* slot directly under the PHB */
 }
 
 module_init(pnv_php_init);
index 3c30e72..d828ca8 100644 (file)
@@ -131,6 +131,7 @@ bool pci_ats_disabled(void)
 {
        return pcie_ats_disabled;
 }
+EXPORT_SYMBOL_GPL(pci_ats_disabled);
 
 /* Disable bridge_d3 for all PCIe ports */
 static bool pci_bridge_d3_disable;
index 6ef74bf..bd2b691 100644 (file)
@@ -306,19 +306,20 @@ static int proc_bus_pci_release(struct inode *inode, struct file *file)
 }
 #endif /* HAVE_PCI_MMAP */
 
-static const struct file_operations proc_bus_pci_operations = {
-       .owner          = THIS_MODULE,
-       .llseek         = proc_bus_pci_lseek,
-       .read           = proc_bus_pci_read,
-       .write          = proc_bus_pci_write,
-       .unlocked_ioctl = proc_bus_pci_ioctl,
-       .compat_ioctl   = proc_bus_pci_ioctl,
+static const struct proc_ops proc_bus_pci_ops = {
+       .proc_lseek     = proc_bus_pci_lseek,
+       .proc_read      = proc_bus_pci_read,
+       .proc_write     = proc_bus_pci_write,
+       .proc_ioctl     = proc_bus_pci_ioctl,
+#ifdef CONFIG_COMPAT
+       .proc_compat_ioctl = proc_bus_pci_ioctl,
+#endif
 #ifdef HAVE_PCI_MMAP
-       .open           = proc_bus_pci_open,
-       .release        = proc_bus_pci_release,
-       .mmap           = proc_bus_pci_mmap,
+       .proc_open      = proc_bus_pci_open,
+       .proc_release   = proc_bus_pci_release,
+       .proc_mmap      = proc_bus_pci_mmap,
 #ifdef HAVE_ARCH_PCI_GET_UNMAPPED_AREA
-       .get_unmapped_area = get_pci_unmapped_area,
+       .proc_get_unmapped_area = get_pci_unmapped_area,
 #endif /* HAVE_ARCH_PCI_GET_UNMAPPED_AREA */
 #endif /* HAVE_PCI_MMAP */
 };
@@ -424,7 +425,7 @@ int pci_proc_attach_device(struct pci_dev *dev)
 
        sprintf(name, "%02x.%x", PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
        e = proc_create_data(name, S_IFREG | S_IRUGO | S_IWUSR, bus->procdir,
-                            &proc_bus_pci_operations, dev);
+                            &proc_bus_pci_ops, dev);
        if (!e)
                return -ENOMEM;
        proc_set_size(e, dev->cfg_size);
index aad8a46..85887d8 100644 (file)
@@ -1,5 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0-only
-/* 
+/*
  * Driver for Intel I82092AA PCI-PCMCIA bridge.
  *
  * (C) 2001 Red Hat, Inc.
@@ -18,7 +18,7 @@
 
 #include <pcmcia/ss.h>
 
-#include <asm/io.h>
+#include <linux/io.h>
 
 #include "i82092aa.h"
 #include "i82365.h"
@@ -33,16 +33,16 @@ static const struct pci_device_id i82092aa_pci_ids[] = {
 MODULE_DEVICE_TABLE(pci, i82092aa_pci_ids);
 
 static struct pci_driver i82092aa_pci_driver = {
-       .name           = "i82092aa",
-       .id_table       = i82092aa_pci_ids,
-       .probe          = i82092aa_pci_probe,
-       .remove         = i82092aa_pci_remove,
+       .name           = "i82092aa",
+       .id_table       = i82092aa_pci_ids,
+       .probe          = i82092aa_pci_probe,
+       .remove = i82092aa_pci_remove,
 };
 
 
 /* the pccard structure and its functions */
 static struct pccard_operations i82092aa_operations = {
-       .init                   = i82092aa_init,
+       .init                   = i82092aa_init,
        .get_status             = i82092aa_get_status,
        .set_socket             = i82092aa_set_socket,
        .set_io_map             = i82092aa_set_io_map,
@@ -53,57 +53,63 @@ static struct pccard_operations i82092aa_operations = {
 
 struct socket_info {
        int     number;
-       int     card_state;     /*  0 = no socket,
-                                   1 = empty socket, 
-                                   2 = card but not initialized,
-                                   3 = operational card */
-       unsigned int io_base;   /* base io address of the socket */
-       
+       int     card_state;
+               /* 0 = no socket,
+                * 1 = empty socket,
+                * 2 = card but not initialized,
+                * 3 = operational card
+                */
+       unsigned int io_base;   /* base io address of the socket */
+
        struct pcmcia_socket socket;
        struct pci_dev *dev;    /* The PCI device for the socket */
 };
 
 #define MAX_SOCKETS 4
 static struct socket_info sockets[MAX_SOCKETS];
-static int socket_count;  /* shortcut */                                                                               
+static int socket_count;       /* shortcut */
 
 
-static int i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
+static int i82092aa_pci_probe(struct pci_dev *dev,
+                             const struct pci_device_id *id)
 {
        unsigned char configbyte;
        int i, ret;
-       
-       enter("i82092aa_pci_probe");
-       
-       if ((ret = pci_enable_device(dev)))
+
+       ret = pci_enable_device(dev);
+       if (ret)
                return ret;
-               
-       pci_read_config_byte(dev, 0x40, &configbyte);  /* PCI Configuration Control */
-       switch(configbyte&6) {
-               case 0:
-                       socket_count = 2;
-                       break;
-               case 2:
-                       socket_count = 1;
-                       break;
-               case 4:
-               case 6:
-                       socket_count = 4;
-                       break;
-                       
-               default:
-                       printk(KERN_ERR "i82092aa: Oops, you did something we didn't think of.\n");
-                       ret = -EIO;
-                       goto err_out_disable;
+
+       /* PCI Configuration Control */
+       pci_read_config_byte(dev, 0x40, &configbyte);
+
+       switch (configbyte&6) {
+       case 0:
+               socket_count = 2;
+               break;
+       case 2:
+               socket_count = 1;
+               break;
+       case 4:
+       case 6:
+               socket_count = 4;
+               break;
+
+       default:
+               dev_err(&dev->dev,
+                       "Oops, you did something we didn't think of.\n");
+               ret = -EIO;
+               goto err_out_disable;
        }
-       printk(KERN_INFO "i82092aa: configured as a %d socket device.\n", socket_count);
+       dev_info(&dev->dev, "configured as a %d socket device.\n",
+                socket_count);
 
        if (!request_region(pci_resource_start(dev, 0), 2, "i82092aa")) {
                ret = -EBUSY;
                goto err_out_disable;
        }
-       
-       for (i = 0;i<socket_count;i++) {
+
+       for (i = 0; i < socket_count; i++) {
                sockets[i].card_state = 1; /* 1 = present but empty */
                sockets[i].io_base = pci_resource_start(dev, 0);
                sockets[i].socket.features |= SS_CAP_PCCARD;
@@ -114,65 +120,65 @@ static int i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *i
                sockets[i].socket.owner = THIS_MODULE;
 
                sockets[i].number = i;
-               
+
                if (card_present(i)) {
                        sockets[i].card_state = 3;
-                       dev_dbg(&dev->dev, "i82092aa: slot %i is occupied\n", i);
+                       dev_dbg(&dev->dev, "slot %i is occupied\n", i);
                } else {
-                       dev_dbg(&dev->dev, "i82092aa: slot %i is vacant\n", i);
+                       dev_dbg(&dev->dev, "slot %i is vacant\n", i);
                }
        }
-               
-       /* Now, specifiy that all interrupts are to be done as PCI interrupts */
-       configbyte = 0xFF; /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */
-       pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */
+
+       /* Now, specifiy that all interrupts are to be done as PCI interrupts
+        * bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt
+        */
+       configbyte = 0xFF;
+
+       /* PCI Interrupt Routing Register */
+       pci_write_config_byte(dev, 0x50, configbyte);
 
        /* Register the interrupt handler */
        dev_dbg(&dev->dev, "Requesting interrupt %i\n", dev->irq);
-       if ((ret = request_irq(dev->irq, i82092aa_interrupt, IRQF_SHARED, "i82092aa", i82092aa_interrupt))) {
-               printk(KERN_ERR "i82092aa: Failed to register IRQ %d, aborting\n", dev->irq);
+       ret = request_irq(dev->irq, i82092aa_interrupt, IRQF_SHARED,
+                         "i82092aa", i82092aa_interrupt);
+       if (ret) {
+               dev_err(&dev->dev, "Failed to register IRQ %d, aborting\n",
+                       dev->irq);
                goto err_out_free_res;
        }
 
-       for (i = 0; i<socket_count; i++) {
+       for (i = 0; i < socket_count; i++) {
                sockets[i].socket.dev.parent = &dev->dev;
                sockets[i].socket.ops = &i82092aa_operations;
                sockets[i].socket.resource_ops = &pccard_nonstatic_ops;
                ret = pcmcia_register_socket(&sockets[i].socket);
-               if (ret) {
+               if (ret)
                        goto err_out_free_sockets;
-               }
        }
 
-       leave("i82092aa_pci_probe");
        return 0;
 
 err_out_free_sockets:
        if (i) {
-               for (i--;i>=0;i--) {
+               for (i--; i >= 0; i--)
                        pcmcia_unregister_socket(&sockets[i].socket);
-               }
        }
        free_irq(dev->irq, i82092aa_interrupt);
 err_out_free_res:
        release_region(pci_resource_start(dev, 0), 2);
 err_out_disable:
        pci_disable_device(dev);
-       return ret;                     
+       return ret;
 }
 
 static void i82092aa_pci_remove(struct pci_dev *dev)
 {
        int i;
 
-       enter("i82092aa_pci_remove");
-       
        free_irq(dev->irq, i82092aa_interrupt);
 
        for (i = 0; i < socket_count; i++)
                pcmcia_unregister_socket(&sockets[i].socket);
-
-       leave("i82092aa_pci_remove");
 }
 
 static DEFINE_SPINLOCK(port_lock);
@@ -184,44 +190,27 @@ static unsigned char indirect_read(int socket, unsigned short reg)
        unsigned short int port;
        unsigned char val;
        unsigned long flags;
-       spin_lock_irqsave(&port_lock,flags);
+
+       spin_lock_irqsave(&port_lock, flags);
        reg += socket * 0x40;
        port = sockets[socket].io_base;
-       outb(reg,port);
+       outb(reg, port);
        val = inb(port+1);
-       spin_unlock_irqrestore(&port_lock,flags);
+       spin_unlock_irqrestore(&port_lock, flags);
        return val;
 }
 
-#if 0
-static unsigned short indirect_read16(int socket, unsigned short reg)
-{
-       unsigned short int port;
-       unsigned short tmp;
-       unsigned long flags;
-       spin_lock_irqsave(&port_lock,flags);
-       reg  = reg + socket * 0x40;
-       port = sockets[socket].io_base;
-       outb(reg,port);
-       tmp = inb(port+1);
-       reg++;
-       outb(reg,port);
-       tmp = tmp | (inb(port+1)<<8);
-       spin_unlock_irqrestore(&port_lock,flags);
-       return tmp;
-}
-#endif
-
 static void indirect_write(int socket, unsigned short reg, unsigned char value)
 {
        unsigned short int port;
        unsigned long flags;
-       spin_lock_irqsave(&port_lock,flags);
+
+       spin_lock_irqsave(&port_lock, flags);
        reg = reg + socket * 0x40;
-       port = sockets[socket].io_base; 
-       outb(reg,port);
-       outb(value,port+1);
-       spin_unlock_irqrestore(&port_lock,flags);
+       port = sockets[socket].io_base;
+       outb(reg, port);
+       outb(value, port+1);
+       spin_unlock_irqrestore(&port_lock, flags);
 }
 
 static void indirect_setbit(int socket, unsigned short reg, unsigned char mask)
@@ -229,53 +218,58 @@ static void indirect_setbit(int socket, unsigned short reg, unsigned char mask)
        unsigned short int port;
        unsigned char val;
        unsigned long flags;
-       spin_lock_irqsave(&port_lock,flags);
+
+       spin_lock_irqsave(&port_lock, flags);
        reg = reg + socket * 0x40;
-       port = sockets[socket].io_base; 
-       outb(reg,port);
+       port = sockets[socket].io_base;
+       outb(reg, port);
        val = inb(port+1);
        val |= mask;
-       outb(reg,port);
-       outb(val,port+1);
-       spin_unlock_irqrestore(&port_lock,flags);
+       outb(reg, port);
+       outb(val, port+1);
+       spin_unlock_irqrestore(&port_lock, flags);
 }
 
 
-static void indirect_resetbit(int socket, unsigned short reg, unsigned char mask)
+static void indirect_resetbit(int socket,
+                             unsigned short reg, unsigned char mask)
 {
        unsigned short int port;
        unsigned char val;
        unsigned long flags;
-       spin_lock_irqsave(&port_lock,flags);
+
+       spin_lock_irqsave(&port_lock, flags);
        reg = reg + socket * 0x40;
-       port = sockets[socket].io_base; 
-       outb(reg,port);
+       port = sockets[socket].io_base;
+       outb(reg, port);
        val = inb(port+1);
        val &= ~mask;
-       outb(reg,port);
-       outb(val,port+1);
-       spin_unlock_irqrestore(&port_lock,flags);
+       outb(reg, port);
+       outb(val, port+1);
+       spin_unlock_irqrestore(&port_lock, flags);
 }
 
-static void indirect_write16(int socket, unsigned short reg, unsigned short value)
+static void indirect_write16(int socket,
+                            unsigned short reg, unsigned short value)
 {
        unsigned short int port;
        unsigned char val;
        unsigned long flags;
-       spin_lock_irqsave(&port_lock,flags);
+
+       spin_lock_irqsave(&port_lock, flags);
        reg = reg + socket * 0x40;
-       port = sockets[socket].io_base; 
-       
-       outb(reg,port);
+       port = sockets[socket].io_base;
+
+       outb(reg, port);
        val = value & 255;
-       outb(val,port+1);
-       
+       outb(val, port+1);
+
        reg++;
-       
-       outb(reg,port);
+
+       outb(reg, port);
        val = value>>8;
-       outb(val,port+1);
-       spin_unlock_irqrestore(&port_lock,flags);
+       outb(val, port+1);
+       spin_unlock_irqrestore(&port_lock, flags);
 }
 
 /* simple helper functions */
@@ -284,12 +278,12 @@ static int cycle_time = 120;
 
 static int to_cycles(int ns)
 {
-       if (cycle_time!=0)
+       if (cycle_time != 0)
                return ns/cycle_time;
        else
                return 0;
 }
-    
+
 
 /* Interrupt handler functionality */
 
@@ -299,58 +293,61 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev)
        int loopcount = 0;
        int handled = 0;
 
-       unsigned int events, active=0;
-       
-/*     enter("i82092aa_interrupt");*/
-       
+       unsigned int events, active = 0;
+
        while (1) {
                loopcount++;
-               if (loopcount>20) {
-                       printk(KERN_ERR "i82092aa: infinite eventloop in interrupt \n");
+               if (loopcount > 20) {
+                       pr_err("i82092aa: infinite eventloop in interrupt\n");
                        break;
                }
-               
+
                active = 0;
-               
-               for (i=0;i<socket_count;i++) {
+
+               for (i = 0; i < socket_count; i++) {
                        int csc;
-                       if (sockets[i].card_state==0) /* Inactive socket, should not happen */
+
+                       /* Inactive socket, should not happen */
+                       if (sockets[i].card_state == 0)
+                               continue;
+
+                       /* card status change register */
+                       csc = indirect_read(i, I365_CSC);
+
+                       if (csc == 0)  /* no events on this socket */
                                continue;
-                       
-                       csc = indirect_read(i,I365_CSC); /* card status change register */
-                       
-                       if (csc==0)  /* no events on this socket */
-                               continue;
                        handled = 1;
                        events = 0;
-                        
+
                        if (csc & I365_CSC_DETECT) {
                                events |= SS_DETECT;
-                               printk("Card detected in socket %i!\n",i);
-                        }
-                       
-                       if (indirect_read(i,I365_INTCTL) & I365_PC_IOCARD) { 
+                               dev_info(&sockets[i].dev->dev,
+                                        "Card detected in socket %i!\n", i);
+                       }
+
+                       if (indirect_read(i, I365_INTCTL) & I365_PC_IOCARD) {
                                /* For IO/CARDS, bit 0 means "read the card" */
-                               events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0; 
+                               if (csc & I365_CSC_STSCHG)
+                                       events |= SS_STSCHG;
                        } else {
                                /* Check for battery/ready events */
-                               events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-                               events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
-                               events |= (csc & I365_CSC_READY) ? SS_READY : 0;
+                               if (csc & I365_CSC_BVD1)
+                                       events |= SS_BATDEAD;
+                               if (csc & I365_CSC_BVD2)
+                                       events |= SS_BATWARN;
+                               if (csc & I365_CSC_READY)
+                                       events |= SS_READY;
                        }
-                       
-                       if (events) {
+
+                       if (events)
                                pcmcia_parse_events(&sockets[i].socket, events);
-                       }
                        active |= events;
                }
-                               
-               if (active==0) /* no more events to handle */
-                       break;                          
-               
+
+               if (active == 0) /* no more events to handle */
+                       break;
        }
        return IRQ_RETVAL(handled);
-/*     leave("i82092aa_interrupt");*/
 }
 
 
@@ -358,80 +355,67 @@ static irqreturn_t i82092aa_interrupt(int irq, void *dev)
 /* socket functions */
 
 static int card_present(int socketno)
-{      
+{
        unsigned int val;
-       enter("card_present");
-       
-       if ((socketno<0) || (socketno >= MAX_SOCKETS))
+
+       if ((socketno < 0) || (socketno >= MAX_SOCKETS))
                return 0;
        if (sockets[socketno].io_base == 0)
                return 0;
 
-               
+
        val = indirect_read(socketno, 1); /* Interface status register */
-       if ((val&12)==12) {
-               leave("card_present 1");
+       if ((val&12) == 12)
                return 1;
-       }
-               
-       leave("card_present 0");
+
        return 0;
 }
 
 static void set_bridge_state(int sock)
 {
-       enter("set_bridge_state");
-       indirect_write(sock, I365_GBLCTL,0x00);
-       indirect_write(sock, I365_GENCTL,0x00);
-       
-       indirect_setbit(sock, I365_INTCTL,0x08);
-       leave("set_bridge_state");
-}
-
-
+       indirect_write(sock, I365_GBLCTL, 0x00);
+       indirect_write(sock, I365_GENCTL, 0x00);
 
+       indirect_setbit(sock, I365_INTCTL, 0x08);
+}
 
 
-      
 static int i82092aa_init(struct pcmcia_socket *sock)
 {
        int i;
        struct resource res = { .start = 0, .end = 0x0fff };
-        pccard_io_map io = { 0, 0, 0, 0, 1 };
+       pccard_io_map io = { 0, 0, 0, 0, 1 };
        pccard_mem_map mem = { .res = &res, };
-        
-        enter("i82092aa_init");
-                        
-        for (i = 0; i < 2; i++) {
-               io.map = i;
-                i82092aa_set_io_map(sock, &io);
+
+       for (i = 0; i < 2; i++) {
+               io.map = i;
+               i82092aa_set_io_map(sock, &io);
        }
-        for (i = 0; i < 5; i++) {
-               mem.map = i;
-                i82092aa_set_mem_map(sock, &mem);
+       for (i = 0; i < 5; i++) {
+               mem.map = i;
+               i82092aa_set_mem_map(sock, &mem);
        }
-       
-       leave("i82092aa_init");
+
        return 0;
 }
-                                                                                                                                                                                                                                              
+
 static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
 {
-       unsigned int sock = container_of(socket, struct socket_info, socket)->number;
+       unsigned int sock = container_of(socket,
+                               struct socket_info, socket)->number;
        unsigned int status;
-       
-       enter("i82092aa_get_status");
-       
-       status = indirect_read(sock,I365_STATUS); /* Interface Status Register */
+
+       /* Interface Status Register */
+       status = indirect_read(sock, I365_STATUS);
+
        *value = 0;
-       
-       if ((status & I365_CS_DETECT) == I365_CS_DETECT) {
+
+       if ((status & I365_CS_DETECT) == I365_CS_DETECT)
                *value |= SS_DETECT;
-       }
-               
+
        /* IO cards have a different meaning of bits 0,1 */
        /* Also notice the inverse-logic on the bits */
-       if (indirect_read(sock, I365_INTCTL) & I365_PC_IOCARD)  {
+       if (indirect_read(sock, I365_INTCTL) & I365_PC_IOCARD) {
                /* IO card */
                if (!(status & I365_CS_STSCHG))
                        *value |= SS_STSCHG;
@@ -441,246 +425,238 @@ static int i82092aa_get_status(struct pcmcia_socket *socket, u_int *value)
                if (!(status & I365_CS_BVD2))
                        *value |= SS_BATWARN;
        }
-        
+
        if (status & I365_CS_WRPROT)
                (*value) |= SS_WRPROT;  /* card is write protected */
-        
+
        if (status & I365_CS_READY)
                (*value) |= SS_READY;    /* card is not busy */
-               
+
        if (status & I365_CS_POWERON)
                (*value) |= SS_POWERON;  /* power is applied to the card */
 
-       leave("i82092aa_get_status");
        return 0;
 }
 
 
-static int i82092aa_set_socket(struct pcmcia_socket *socket, socket_state_t *state) 
+static int i82092aa_set_socket(struct pcmcia_socket *socket,
+                              socket_state_t *state)
 {
-       unsigned int sock = container_of(socket, struct socket_info, socket)->number;
+       struct socket_info *sock_info = container_of(socket, struct socket_info,
+                                                    socket);
+       unsigned int sock = sock_info->number;
        unsigned char reg;
-       
-       enter("i82092aa_set_socket");
-       
+
        /* First, set the global controller options */
-       
+
        set_bridge_state(sock);
-       
+
        /* Values for the IGENC register */
-       
+
        reg = 0;
-       if (!(state->flags & SS_RESET))         /* The reset bit has "inverse" logic */
-               reg = reg | I365_PC_RESET;  
-       if (state->flags & SS_IOCARD) 
+
+       /* The reset bit has "inverse" logic */
+       if (!(state->flags & SS_RESET))
+               reg = reg | I365_PC_RESET;
+       if (state->flags & SS_IOCARD)
                reg = reg | I365_PC_IOCARD;
-               
-       indirect_write(sock,I365_INTCTL,reg); /* IGENC, Interrupt and General Control Register */
-       
+
+       /* IGENC, Interrupt and General Control Register */
+       indirect_write(sock, I365_INTCTL, reg);
+
        /* Power registers */
-       
+
        reg = I365_PWR_NORESET; /* default: disable resetdrv on resume */
-       
+
        if (state->flags & SS_PWR_AUTO) {
-               printk("Auto power\n");
+               dev_info(&sock_info->dev->dev, "Auto power\n");
                reg |= I365_PWR_AUTO;   /* automatic power mngmnt */
        }
        if (state->flags & SS_OUTPUT_ENA) {
-               printk("Power Enabled \n");
+               dev_info(&sock_info->dev->dev, "Power Enabled\n");
                reg |= I365_PWR_OUT;    /* enable power */
        }
-       
+
        switch (state->Vcc) {
-               case 0: 
-                       break;
-               case 50: 
-                       printk("setting voltage to Vcc to 5V on socket %i\n",sock);
-                       reg |= I365_VCC_5V;
-                       break;
-               default:
-                       printk("i82092aa: i82092aa_set_socket called with invalid VCC power value: %i ", state->Vcc);
-                       leave("i82092aa_set_socket");
-                       return -EINVAL;
+       case 0:
+               break;
+       case 50:
+               dev_info(&sock_info->dev->dev,
+                        "setting voltage to Vcc to 5V on socket %i\n",
+                        sock);
+               reg |= I365_VCC_5V;
+               break;
+       default:
+               dev_err(&sock_info->dev->dev,
+                       "%s called with invalid VCC power value: %i",
+                       __func__, state->Vcc);
+               return -EINVAL;
        }
-       
-       
+
        switch (state->Vpp) {
-               case 0: 
-                       printk("not setting Vpp on socket %i\n",sock);
-                       break;
-               case 50: 
-                       printk("setting Vpp to 5.0 for socket %i\n",sock);
-                       reg |= I365_VPP1_5V | I365_VPP2_5V;
-                       break;
-               case 120: 
-                       printk("setting Vpp to 12.0\n");
-                       reg |= I365_VPP1_12V | I365_VPP2_12V;
-                       break;
-               default:
-                       printk("i82092aa: i82092aa_set_socket called with invalid VPP power value: %i ", state->Vcc);
-                       leave("i82092aa_set_socket");
-                       return -EINVAL;
+       case 0:
+               dev_info(&sock_info->dev->dev,
+                        "not setting Vpp on socket %i\n", sock);
+               break;
+       case 50:
+               dev_info(&sock_info->dev->dev,
+                        "setting Vpp to 5.0 for socket %i\n", sock);
+               reg |= I365_VPP1_5V | I365_VPP2_5V;
+               break;
+       case 120:
+               dev_info(&sock_info->dev->dev, "setting Vpp to 12.0\n");
+               reg |= I365_VPP1_12V | I365_VPP2_12V;
+               break;
+       default:
+               dev_err(&sock_info->dev->dev,
+                       "%s called with invalid VPP power value: %i",
+                       __func__, state->Vcc);
+               return -EINVAL;
        }
-       
-       if (reg != indirect_read(sock,I365_POWER)) /* only write if changed */
-               indirect_write(sock,I365_POWER,reg);
-               
+
+       if (reg != indirect_read(sock, I365_POWER)) /* only write if changed */
+               indirect_write(sock, I365_POWER, reg);
+
        /* Enable specific interrupt events */
-       
+
        reg = 0x00;
-       if (state->csc_mask & SS_DETECT) {
+       if (state->csc_mask & SS_DETECT)
                reg |= I365_CSC_DETECT;
-       }
        if (state->flags & SS_IOCARD) {
                if (state->csc_mask & SS_STSCHG)
                        reg |= I365_CSC_STSCHG;
        } else {
-               if (state->csc_mask & SS_BATDEAD) 
+               if (state->csc_mask & SS_BATDEAD)
                        reg |= I365_CSC_BVD1;
-               if (state->csc_mask & SS_BATWARN) 
+               if (state->csc_mask & SS_BATWARN)
                        reg |= I365_CSC_BVD2;
-               if (state->csc_mask & SS_READY) 
-                       reg |= I365_CSC_READY; 
-                                       
+               if (state->csc_mask & SS_READY)
+                       reg |= I365_CSC_READY;
+
        }
-       
-       /* now write the value and clear the (probably bogus) pending stuff by doing a dummy read*/
-       
-       indirect_write(sock,I365_CSCINT,reg);
-       (void)indirect_read(sock,I365_CSC);
 
-       leave("i82092aa_set_socket");
+       /* now write the value and clear the (probably bogus) pending stuff
+        * by doing a dummy read
+        */
+
+       indirect_write(sock, I365_CSCINT, reg);
+       (void)indirect_read(sock, I365_CSC);
+
        return 0;
 }
 
-static int i82092aa_set_io_map(struct pcmcia_socket *socket, struct pccard_io_map *io)
+static int i82092aa_set_io_map(struct pcmcia_socket *socket,
+                              struct pccard_io_map *io)
 {
-       unsigned int sock = container_of(socket, struct socket_info, socket)->number;
+       struct socket_info *sock_info = container_of(socket, struct socket_info,
+                                                    socket);
+       unsigned int sock = sock_info->number;
        unsigned char map, ioctl;
-       
-       enter("i82092aa_set_io_map");
-       
+
        map = io->map;
-       
-       /* Check error conditions */    
-       if (map > 1) {
-               leave("i82092aa_set_io_map with invalid map");
+
+       /* Check error conditions */
+       if (map > 1)
                return -EINVAL;
-       }
-       if ((io->start > 0xffff) || (io->stop > 0xffff) || (io->stop < io->start)){
-               leave("i82092aa_set_io_map with invalid io");
+
+       if ((io->start > 0xffff) || (io->stop > 0xffff)
+                                || (io->stop < io->start))
                return -EINVAL;
-       }
 
-       /* Turn off the window before changing anything */ 
+       /* Turn off the window before changing anything */
        if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_IO(map))
                indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_IO(map));
 
-/*     printk("set_io_map: Setting range to %x - %x \n",io->start,io->stop);  */
-       
        /* write the new values */
-       indirect_write16(sock,I365_IO(map)+I365_W_START,io->start);             
-       indirect_write16(sock,I365_IO(map)+I365_W_STOP,io->stop);               
-                       
-       ioctl = indirect_read(sock,I365_IOCTL) & ~I365_IOCTL_MASK(map);
-       
+       indirect_write16(sock, I365_IO(map)+I365_W_START, io->start);
+       indirect_write16(sock, I365_IO(map)+I365_W_STOP, io->stop);
+
+       ioctl = indirect_read(sock, I365_IOCTL) & ~I365_IOCTL_MASK(map);
+
        if (io->flags & (MAP_16BIT|MAP_AUTOSZ))
                ioctl |= I365_IOCTL_16BIT(map);
-               
-       indirect_write(sock,I365_IOCTL,ioctl);
-       
+
+       indirect_write(sock, I365_IOCTL, ioctl);
+
        /* Turn the window back on if needed */
        if (io->flags & MAP_ACTIVE)
-               indirect_setbit(sock,I365_ADDRWIN,I365_ENA_IO(map));
-                       
-       leave("i82092aa_set_io_map");   
+               indirect_setbit(sock, I365_ADDRWIN, I365_ENA_IO(map));
+
        return 0;
 }
 
-static int i82092aa_set_mem_map(struct pcmcia_socket *socket, struct pccard_mem_map *mem)
+static int i82092aa_set_mem_map(struct pcmcia_socket *socket,
+                               struct pccard_mem_map *mem)
 {
-       struct socket_info *sock_info = container_of(socket, struct socket_info, socket);
+       struct socket_info *sock_info = container_of(socket, struct socket_info,
+                                                    socket);
        unsigned int sock = sock_info->number;
        struct pci_bus_region region;
        unsigned short base, i;
        unsigned char map;
-       
-       enter("i82092aa_set_mem_map");
 
        pcibios_resource_to_bus(sock_info->dev->bus, &region, mem->res);
-       
+
        map = mem->map;
-       if (map > 4) {
-               leave("i82092aa_set_mem_map: invalid map");
+       if (map > 4)
                return -EINVAL;
-       }
-       
-       
-       if ( (mem->card_start > 0x3ffffff) || (region.start > region.end) ||
-            (mem->speed > 1000) ) {
-               leave("i82092aa_set_mem_map: invalid address / speed");
-               printk("invalid mem map for socket %i: %llx to %llx with a "
-                       "start of %x\n",
+
+       if ((mem->card_start > 0x3ffffff) || (region.start > region.end) ||
+            (mem->speed > 1000)) {
+               dev_err(&sock_info->dev->dev,
+                       "invalid mem map for socket %i: %llx to %llx with a start of %x\n",
                        sock,
                        (unsigned long long)region.start,
                        (unsigned long long)region.end,
                        mem->card_start);
                return -EINVAL;
        }
-       
+
        /* Turn off the window before changing anything */
        if (indirect_read(sock, I365_ADDRWIN) & I365_ENA_MEM(map))
-                     indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
-                        
-                        
-/*     printk("set_mem_map: Setting map %i range to %x - %x on socket %i, speed is %i, active = %i \n",map, region.start,region.end,sock,mem->speed,mem->flags & MAP_ACTIVE);  */
+               indirect_resetbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
 
        /* write the start address */
        base = I365_MEM(map);
        i = (region.start >> 12) & 0x0fff;
-       if (mem->flags & MAP_16BIT) 
+       if (mem->flags & MAP_16BIT)
                i |= I365_MEM_16BIT;
        if (mem->flags & MAP_0WS)
-               i |= I365_MEM_0WS;      
-       indirect_write16(sock,base+I365_W_START,i);
-                              
+               i |= I365_MEM_0WS;
+       indirect_write16(sock, base+I365_W_START, i);
+
        /* write the stop address */
-       
-       i= (region.end >> 12) & 0x0fff;
+
+       i = (region.end >> 12) & 0x0fff;
        switch (to_cycles(mem->speed)) {
-               case 0:
-                       break;
-               case 1:
-                       i |= I365_MEM_WS0;
-                       break;
-               case 2:
-                       i |= I365_MEM_WS1;
-                       break;
-               default:
-                       i |= I365_MEM_WS1 | I365_MEM_WS0;
-                       break;
+       case 0:
+               break;
+       case 1:
+               i |= I365_MEM_WS0;
+               break;
+       case 2:
+               i |= I365_MEM_WS1;
+               break;
+       default:
+               i |= I365_MEM_WS1 | I365_MEM_WS0;
+               break;
        }
-       
-       indirect_write16(sock,base+I365_W_STOP,i);
-       
+
+       indirect_write16(sock, base+I365_W_STOP, i);
+
        /* card start */
-       
+
        i = ((mem->card_start - region.start) >> 12) & 0x3fff;
        if (mem->flags & MAP_WRPROT)
                i |= I365_MEM_WRPROT;
-       if (mem->flags & MAP_ATTRIB) {
-/*             printk("requesting attribute memory for socket %i\n",sock);*/
+       if (mem->flags & MAP_ATTRIB)
                i |= I365_MEM_REG;
-       } else {
-/*             printk("requesting normal memory for socket %i\n",sock);*/
-       }
-       indirect_write16(sock,base+I365_W_OFF,i);
-       
+       indirect_write16(sock, base+I365_W_OFF, i);
+
        /* Enable the window if necessary */
        if (mem->flags & MAP_ACTIVE)
                indirect_setbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
-                   
-       leave("i82092aa_set_mem_map");
+
        return 0;
 }
 
@@ -691,11 +667,9 @@ static int i82092aa_module_init(void)
 
 static void i82092aa_module_exit(void)
 {
-       enter("i82092aa_module_exit");
        pci_unregister_driver(&i82092aa_pci_driver);
-       if (sockets[0].io_base>0)
-                        release_region(sockets[0].io_base, 2);
-       leave("i82092aa_module_exit");
+       if (sockets[0].io_base > 0)
+               release_region(sockets[0].io_base, 2);
 }
 
 module_init(i82092aa_module_init);
index 4586c43..0f851ac 100644 (file)
@@ -4,17 +4,6 @@
 
 #include <linux/interrupt.h>
 
-/* Debuging defines */
-#ifdef NOTRACE
-#define enter(x)   printk("Enter: %s, %s line %i\n",x,__FILE__,__LINE__)
-#define leave(x)   printk("Leave: %s, %s line %i\n",x,__FILE__,__LINE__)
-#else
-#define enter(x)   do {} while (0)
-#define leave(x)   do {} while (0)
-#endif
-
-
-
 /* prototypes */
 
 static int  i82092aa_pci_probe(struct pci_dev *dev, const struct pci_device_id *id);
index 2eb28cc..cd5a6c9 100644 (file)
@@ -712,7 +712,7 @@ struct phy *phy_optional_get(struct device *dev, const char *string)
 {
        struct phy *phy = phy_get(dev, string);
 
-       if (IS_ERR(phy) && (PTR_ERR(phy) == -ENODEV))
+       if (PTR_ERR(phy) == -ENODEV)
                phy = NULL;
 
        return phy;
@@ -766,7 +766,7 @@ struct phy *devm_phy_optional_get(struct device *dev, const char *string)
 {
        struct phy *phy = devm_phy_get(dev, string);
 
-       if (IS_ERR(phy) && (PTR_ERR(phy) == -ENODEV))
+       if (PTR_ERR(phy) == -ENODEV)
                phy = NULL;
 
        return phy;
index 21c370d..bddf2c5 100644 (file)
@@ -10,6 +10,7 @@
 #include <linux/of.h>
 #include <linux/of_address.h>
 #include <linux/module.h>
+#include <linux/pinctrl/machine.h>
 #include <linux/pinctrl/pinconf.h>
 #include <linux/pinctrl/pinconf-generic.h>
 #include <linux/pinctrl/pinmux.h>
index 8723bcf..4f3651f 100644 (file)
@@ -63,7 +63,7 @@ struct acpi_peripheral {
 struct chromeos_laptop {
        /*
         * Note that we can't mark this pointer as const because
-        * i2c_new_probed_device() changes passed in I2C board info, so.
+        * i2c_new_scanned_device() changes passed in I2C board info, so.
         */
        struct i2c_peripheral *i2c_peripherals;
        unsigned int num_i2c_peripherals;
@@ -87,8 +87,8 @@ chromes_laptop_instantiate_i2c_device(struct i2c_adapter *adapter,
         * address we scan secondary addresses. In any case the client
         * structure gets assigned primary address.
         */
-       client = i2c_new_probed_device(adapter, info, addr_list, NULL);
-       if (!client && alt_addr) {
+       client = i2c_new_scanned_device(adapter, info, addr_list, NULL);
+       if (IS_ERR(client) && alt_addr) {
                struct i2c_board_info dummy_info = {
                        I2C_BOARD_INFO("dummy", info->addr),
                };
@@ -97,9 +97,9 @@ chromes_laptop_instantiate_i2c_device(struct i2c_adapter *adapter,
                };
                struct i2c_client *dummy;
 
-               dummy = i2c_new_probed_device(adapter, &dummy_info,
-                                             alt_addr_list, NULL);
-               if (dummy) {
+               dummy = i2c_new_scanned_device(adapter, &dummy_info,
+                                              alt_addr_list, NULL);
+               if (!IS_ERR(dummy)) {
                        pr_debug("%d-%02x is probed at %02x\n",
                                 adapter->nr, info->addr, dummy->addr);
                        i2c_unregister_device(dummy);
@@ -107,12 +107,14 @@ chromes_laptop_instantiate_i2c_device(struct i2c_adapter *adapter,
                }
        }
 
-       if (!client)
+       if (IS_ERR(client)) {
+               client = NULL;
                pr_debug("failed to register device %d-%02x\n",
                         adapter->nr, info->addr);
-       else
+       } else {
                pr_debug("added i2c device %d-%02x\n",
                         adapter->nr, info->addr);
+       }
 
        return client;
 }
index 6d6ce86..6fc8f2c 100644 (file)
@@ -16,7 +16,8 @@
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
 #include <linux/suspend.h>
-#include <asm/unaligned.h>
+
+#include "cros_ec.h"
 
 #define CROS_EC_DEV_EC_INDEX 0
 #define CROS_EC_DEV_PD_INDEX 1
diff --git a/drivers/platform/chrome/cros_ec.h b/drivers/platform/chrome/cros_ec.h
new file mode 100644 (file)
index 0000000..e69fc1f
--- /dev/null
@@ -0,0 +1,19 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * ChromeOS Embedded Controller core interface.
+ *
+ * Copyright (C) 2020 Google LLC
+ */
+
+#ifndef __CROS_EC_H
+#define __CROS_EC_H
+
+int cros_ec_register(struct cros_ec_device *ec_dev);
+int cros_ec_unregister(struct cros_ec_device *ec_dev);
+
+int cros_ec_suspend(struct cros_ec_device *ec_dev);
+int cros_ec_resume(struct cros_ec_device *ec_dev);
+
+bool cros_ec_handle_event(struct cros_ec_device *ec_dev);
+
+#endif /* __CROS_EC_H */
index 74ded44..c65e70b 100644 (file)
@@ -13,7 +13,6 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/fs.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/miscdevice.h>
 #include <linux/module.h>
 #include <linux/notifier.h>
index 6ae4849..ecfada0 100644 (file)
@@ -7,7 +7,6 @@
 #include <linux/debugfs.h>
 #include <linux/delay.h>
 #include <linux/fs.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/mutex.h>
 #include <linux/platform_data/cros_ec_commands.h>
index 9bd97bc..6119ecc 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 
+#include "cros_ec.h"
+
 /**
  * Request format for protocol v3
  * byte 0      0xda (EC_COMMAND_PROTOCOL_3)
index e599682..93a71e9 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/platform_data/cros_ec_proto.h>
 #include <linux/intel-ish-client-if.h>
 
+#include "cros_ec.h"
+
 /*
  * ISH TX/RX ring buffer pool size
  *
@@ -76,7 +78,7 @@ struct cros_ish_in_msg {
  *
  * The writers are .reset() and .probe() function.
  */
-DECLARE_RWSEM(init_lock);
+static DECLARE_RWSEM(init_lock);
 
 /**
  * struct response_info - Encapsulate firmware response related
index c0f2eec..b4c110c 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/kobject.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
index dccf479..1f78619 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/printk.h>
 #include <linux/suspend.h>
 
+#include "cros_ec.h"
 #include "cros_ec_lpc_mec.h"
 
 #define DRV_NAME "cros_ec_lpcs"
@@ -396,7 +397,7 @@ static int cros_ec_lpc_probe(struct platform_device *pdev)
         * Some boards do not have an IRQ allotted for cros_ec_lpc,
         * which makes ENXIO an expected (and safe) scenario.
         */
-       irq = platform_get_irq(pdev, 0);
+       irq = platform_get_irq_optional(pdev, 0);
        if (irq > 0)
                ec_dev->irq = irq;
        else if (irq != -ENXIO) {
index da1b1c4..3cfa643 100644 (file)
@@ -54,8 +54,6 @@ static int send_command(struct cros_ec_device *ec_dev,
        int ret;
        int (*xfer_fxn)(struct cros_ec_device *ec, struct cros_ec_command *msg);
 
-       trace_cros_ec_cmd(msg);
-
        if (ec_dev->proto_version > 2)
                xfer_fxn = ec_dev->pkt_xfer;
        else
@@ -72,7 +70,9 @@ static int send_command(struct cros_ec_device *ec_dev,
                return -EIO;
        }
 
+       trace_cros_ec_request_start(msg);
        ret = (*xfer_fxn)(ec_dev, msg);
+       trace_cros_ec_request_done(msg, ret);
        if (msg->result == EC_RES_IN_PROGRESS) {
                int i;
                struct cros_ec_command *status_msg;
@@ -95,7 +95,9 @@ static int send_command(struct cros_ec_device *ec_dev,
                for (i = 0; i < EC_COMMAND_RETRIES; i++) {
                        usleep_range(10000, 11000);
 
+                       trace_cros_ec_request_start(status_msg);
                        ret = (*xfer_fxn)(ec_dev, status_msg);
+                       trace_cros_ec_request_done(status_msg, ret);
                        if (ret == -EAGAIN)
                                continue;
                        if (ret < 0)
index bd068af..dbc3f55 100644 (file)
@@ -13,6 +13,8 @@
 #include <linux/rpmsg.h>
 #include <linux/slab.h>
 
+#include "cros_ec.h"
+
 #define EC_MSG_TIMEOUT_MS      200
 #define HOST_COMMAND_MARK      1
 #define HOST_EVENT_MARK                2
index 04d8879..79fefd3 100644 (file)
@@ -9,7 +9,6 @@
 #include <linux/init.h>
 #include <linux/device.h>
 #include <linux/module.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
 #include <linux/platform_data/cros_ec_sensorhub.h>
index a831bd5..46786d2 100644 (file)
@@ -14,6 +14,8 @@
 #include <linux/spi/spi.h>
 #include <uapi/linux/sched/types.h>
 
+#include "cros_ec.h"
+
 /* The header byte, which follows the preamble */
 #define EC_MSG_HEADER                  0xec
 
index 74d36b8..07dac97 100644 (file)
@@ -8,7 +8,6 @@
 #include <linux/device.h>
 #include <linux/fs.h>
 #include <linux/kobject.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
index 5af1d66..523a39b 100644 (file)
@@ -8,6 +8,11 @@
 // Generate the list using the following script:
 // sed -n 's/^#define \(EC_CMD_[[:alnum:]_]*\)\s.*/\tTRACE_SYMBOL(\1), \\/p' include/linux/platform_data/cros_ec_commands.h
 #define EC_CMDS \
+       TRACE_SYMBOL(EC_CMD_ACPI_READ), \
+       TRACE_SYMBOL(EC_CMD_ACPI_WRITE), \
+       TRACE_SYMBOL(EC_CMD_ACPI_BURST_ENABLE), \
+       TRACE_SYMBOL(EC_CMD_ACPI_BURST_DISABLE), \
+       TRACE_SYMBOL(EC_CMD_ACPI_QUERY_EVENT), \
        TRACE_SYMBOL(EC_CMD_PROTO_VERSION), \
        TRACE_SYMBOL(EC_CMD_HELLO), \
        TRACE_SYMBOL(EC_CMD_GET_VERSION), \
@@ -22,6 +27,8 @@
        TRACE_SYMBOL(EC_CMD_GET_PROTOCOL_INFO), \
        TRACE_SYMBOL(EC_CMD_GSV_PAUSE_IN_S5), \
        TRACE_SYMBOL(EC_CMD_GET_FEATURES), \
+       TRACE_SYMBOL(EC_CMD_GET_SKU_ID), \
+       TRACE_SYMBOL(EC_CMD_SET_SKU_ID), \
        TRACE_SYMBOL(EC_CMD_FLASH_INFO), \
        TRACE_SYMBOL(EC_CMD_FLASH_READ), \
        TRACE_SYMBOL(EC_CMD_FLASH_WRITE), \
@@ -29,6 +36,8 @@
        TRACE_SYMBOL(EC_CMD_FLASH_PROTECT), \
        TRACE_SYMBOL(EC_CMD_FLASH_REGION_INFO), \
        TRACE_SYMBOL(EC_CMD_VBNV_CONTEXT), \
+       TRACE_SYMBOL(EC_CMD_FLASH_SPI_INFO), \
+       TRACE_SYMBOL(EC_CMD_FLASH_SELECT), \
        TRACE_SYMBOL(EC_CMD_PWM_GET_FAN_TARGET_RPM), \
        TRACE_SYMBOL(EC_CMD_PWM_SET_FAN_TARGET_RPM), \
        TRACE_SYMBOL(EC_CMD_PWM_GET_KEYBOARD_BACKLIGHT), \
@@ -40,6 +49,8 @@
        TRACE_SYMBOL(EC_CMD_LED_CONTROL), \
        TRACE_SYMBOL(EC_CMD_VBOOT_HASH), \
        TRACE_SYMBOL(EC_CMD_MOTION_SENSE_CMD), \
+       TRACE_SYMBOL(EC_CMD_FORCE_LID_OPEN), \
+       TRACE_SYMBOL(EC_CMD_CONFIG_POWER_BUTTON), \
        TRACE_SYMBOL(EC_CMD_USB_CHARGE_SET_MODE), \
        TRACE_SYMBOL(EC_CMD_PSTORE_INFO), \
        TRACE_SYMBOL(EC_CMD_PSTORE_READ), \
@@ -50,6 +61,9 @@
        TRACE_SYMBOL(EC_CMD_RTC_SET_ALARM), \
        TRACE_SYMBOL(EC_CMD_PORT80_LAST_BOOT), \
        TRACE_SYMBOL(EC_CMD_PORT80_READ), \
+       TRACE_SYMBOL(EC_CMD_VSTORE_INFO), \
+       TRACE_SYMBOL(EC_CMD_VSTORE_READ), \
+       TRACE_SYMBOL(EC_CMD_VSTORE_WRITE), \
        TRACE_SYMBOL(EC_CMD_THERMAL_SET_THRESHOLD), \
        TRACE_SYMBOL(EC_CMD_THERMAL_GET_THRESHOLD), \
        TRACE_SYMBOL(EC_CMD_THERMAL_AUTO_FAN_CTRL), \
        TRACE_SYMBOL(EC_CMD_MKBP_STATE), \
        TRACE_SYMBOL(EC_CMD_MKBP_INFO), \
        TRACE_SYMBOL(EC_CMD_MKBP_SIMULATE_KEY), \
+       TRACE_SYMBOL(EC_CMD_GET_KEYBOARD_ID), \
        TRACE_SYMBOL(EC_CMD_MKBP_SET_CONFIG), \
        TRACE_SYMBOL(EC_CMD_MKBP_GET_CONFIG), \
        TRACE_SYMBOL(EC_CMD_KEYSCAN_SEQ_CTRL), \
        TRACE_SYMBOL(EC_CMD_GET_NEXT_EVENT), \
+       TRACE_SYMBOL(EC_CMD_KEYBOARD_FACTORY_TEST), \
        TRACE_SYMBOL(EC_CMD_TEMP_SENSOR_GET_INFO), \
        TRACE_SYMBOL(EC_CMD_HOST_EVENT_GET_B), \
        TRACE_SYMBOL(EC_CMD_HOST_EVENT_GET_SMI_MASK), \
@@ -73,6 +89,7 @@
        TRACE_SYMBOL(EC_CMD_HOST_EVENT_CLEAR), \
        TRACE_SYMBOL(EC_CMD_HOST_EVENT_SET_WAKE_MASK), \
        TRACE_SYMBOL(EC_CMD_HOST_EVENT_CLEAR_B), \
+       TRACE_SYMBOL(EC_CMD_HOST_EVENT), \
        TRACE_SYMBOL(EC_CMD_SWITCH_ENABLE_BKLIGHT), \
        TRACE_SYMBOL(EC_CMD_SWITCH_ENABLE_WIRELESS), \
        TRACE_SYMBOL(EC_CMD_GPIO_SET), \
        TRACE_SYMBOL(EC_CMD_CHARGE_STATE), \
        TRACE_SYMBOL(EC_CMD_CHARGE_CURRENT_LIMIT), \
        TRACE_SYMBOL(EC_CMD_EXTERNAL_POWER_LIMIT), \
+       TRACE_SYMBOL(EC_CMD_OVERRIDE_DEDICATED_CHARGER_LIMIT), \
+       TRACE_SYMBOL(EC_CMD_HIBERNATION_DELAY), \
        TRACE_SYMBOL(EC_CMD_HOST_SLEEP_EVENT), \
+       TRACE_SYMBOL(EC_CMD_DEVICE_EVENT), \
        TRACE_SYMBOL(EC_CMD_SB_READ_WORD), \
        TRACE_SYMBOL(EC_CMD_SB_WRITE_WORD), \
        TRACE_SYMBOL(EC_CMD_SB_READ_BLOCK), \
        TRACE_SYMBOL(EC_CMD_SB_WRITE_BLOCK), \
        TRACE_SYMBOL(EC_CMD_BATTERY_VENDOR_PARAM), \
+       TRACE_SYMBOL(EC_CMD_SB_FW_UPDATE), \
+       TRACE_SYMBOL(EC_CMD_ENTERING_MODE), \
+       TRACE_SYMBOL(EC_CMD_I2C_PASSTHRU_PROTECT), \
+       TRACE_SYMBOL(EC_CMD_CEC_WRITE_MSG), \
+       TRACE_SYMBOL(EC_CMD_CEC_SET), \
+       TRACE_SYMBOL(EC_CMD_CEC_GET), \
        TRACE_SYMBOL(EC_CMD_EC_CODEC), \
        TRACE_SYMBOL(EC_CMD_EC_CODEC_DMIC), \
        TRACE_SYMBOL(EC_CMD_EC_CODEC_I2S_RX), \
        TRACE_SYMBOL(EC_CMD_EC_CODEC_WOV), \
        TRACE_SYMBOL(EC_CMD_REBOOT_EC), \
        TRACE_SYMBOL(EC_CMD_GET_PANIC_INFO), \
-       TRACE_SYMBOL(EC_CMD_ACPI_READ), \
-       TRACE_SYMBOL(EC_CMD_ACPI_WRITE), \
-       TRACE_SYMBOL(EC_CMD_ACPI_QUERY_EVENT), \
-       TRACE_SYMBOL(EC_CMD_CEC_WRITE_MSG), \
-       TRACE_SYMBOL(EC_CMD_CEC_SET), \
-       TRACE_SYMBOL(EC_CMD_CEC_GET), \
        TRACE_SYMBOL(EC_CMD_REBOOT), \
        TRACE_SYMBOL(EC_CMD_RESEND_RESPONSE), \
        TRACE_SYMBOL(EC_CMD_VERSION0), \
        TRACE_SYMBOL(EC_CMD_PD_EXCHANGE_STATUS), \
+       TRACE_SYMBOL(EC_CMD_PD_HOST_EVENT_STATUS), \
        TRACE_SYMBOL(EC_CMD_USB_PD_CONTROL), \
        TRACE_SYMBOL(EC_CMD_USB_PD_PORTS), \
        TRACE_SYMBOL(EC_CMD_USB_PD_POWER_INFO), \
        TRACE_SYMBOL(EC_CMD_CHARGE_PORT_COUNT), \
+       TRACE_SYMBOL(EC_CMD_USB_PD_FW_UPDATE), \
+       TRACE_SYMBOL(EC_CMD_USB_PD_RW_HASH_ENTRY), \
+       TRACE_SYMBOL(EC_CMD_USB_PD_DEV_INFO), \
        TRACE_SYMBOL(EC_CMD_USB_PD_DISCOVERY), \
        TRACE_SYMBOL(EC_CMD_PD_CHARGE_PORT_OVERRIDE), \
        TRACE_SYMBOL(EC_CMD_PD_GET_LOG_ENTRY), \
-       TRACE_SYMBOL(EC_CMD_USB_PD_MUX_INFO)
+       TRACE_SYMBOL(EC_CMD_USB_PD_GET_AMODE), \
+       TRACE_SYMBOL(EC_CMD_USB_PD_SET_AMODE), \
+       TRACE_SYMBOL(EC_CMD_PD_WRITE_LOG_ENTRY), \
+       TRACE_SYMBOL(EC_CMD_PD_CONTROL), \
+       TRACE_SYMBOL(EC_CMD_USB_PD_MUX_INFO), \
+       TRACE_SYMBOL(EC_CMD_PD_CHIP_INFO), \
+       TRACE_SYMBOL(EC_CMD_RWSIG_CHECK_STATUS), \
+       TRACE_SYMBOL(EC_CMD_RWSIG_ACTION), \
+       TRACE_SYMBOL(EC_CMD_EFS_VERIFY), \
+       TRACE_SYMBOL(EC_CMD_GET_CROS_BOARD_INFO), \
+       TRACE_SYMBOL(EC_CMD_SET_CROS_BOARD_INFO), \
+       TRACE_SYMBOL(EC_CMD_GET_UPTIME_INFO), \
+       TRACE_SYMBOL(EC_CMD_ADD_ENTROPY), \
+       TRACE_SYMBOL(EC_CMD_ADC_READ), \
+       TRACE_SYMBOL(EC_CMD_ROLLBACK_INFO), \
+       TRACE_SYMBOL(EC_CMD_AP_RESET), \
+       TRACE_SYMBOL(EC_CMD_CR51_BASE), \
+       TRACE_SYMBOL(EC_CMD_CR51_LAST), \
+       TRACE_SYMBOL(EC_CMD_FP_PASSTHRU), \
+       TRACE_SYMBOL(EC_CMD_FP_MODE), \
+       TRACE_SYMBOL(EC_CMD_FP_INFO), \
+       TRACE_SYMBOL(EC_CMD_FP_FRAME), \
+       TRACE_SYMBOL(EC_CMD_FP_TEMPLATE), \
+       TRACE_SYMBOL(EC_CMD_FP_CONTEXT), \
+       TRACE_SYMBOL(EC_CMD_FP_STATS), \
+       TRACE_SYMBOL(EC_CMD_FP_SEED), \
+       TRACE_SYMBOL(EC_CMD_FP_ENC_STATUS), \
+       TRACE_SYMBOL(EC_CMD_TP_SELF_TEST), \
+       TRACE_SYMBOL(EC_CMD_TP_FRAME_INFO), \
+       TRACE_SYMBOL(EC_CMD_TP_FRAME_SNAPSHOT), \
+       TRACE_SYMBOL(EC_CMD_TP_FRAME_GET), \
+       TRACE_SYMBOL(EC_CMD_BATTERY_GET_STATIC), \
+       TRACE_SYMBOL(EC_CMD_BATTERY_GET_DYNAMIC), \
+       TRACE_SYMBOL(EC_CMD_CHARGER_CONTROL), \
+       TRACE_SYMBOL(EC_CMD_BOARD_SPECIFIC_BASE), \
+       TRACE_SYMBOL(EC_CMD_BOARD_SPECIFIC_LAST)
+
+/* See the enum ec_status in include/linux/platform_data/cros_ec_commands.h */
+#define EC_RESULT \
+       TRACE_SYMBOL(EC_RES_SUCCESS), \
+       TRACE_SYMBOL(EC_RES_INVALID_COMMAND), \
+       TRACE_SYMBOL(EC_RES_ERROR), \
+       TRACE_SYMBOL(EC_RES_INVALID_PARAM), \
+       TRACE_SYMBOL(EC_RES_ACCESS_DENIED), \
+       TRACE_SYMBOL(EC_RES_INVALID_RESPONSE), \
+       TRACE_SYMBOL(EC_RES_INVALID_VERSION), \
+       TRACE_SYMBOL(EC_RES_INVALID_CHECKSUM), \
+       TRACE_SYMBOL(EC_RES_IN_PROGRESS), \
+       TRACE_SYMBOL(EC_RES_UNAVAILABLE), \
+       TRACE_SYMBOL(EC_RES_TIMEOUT), \
+       TRACE_SYMBOL(EC_RES_OVERFLOW), \
+       TRACE_SYMBOL(EC_RES_INVALID_HEADER), \
+       TRACE_SYMBOL(EC_RES_REQUEST_TRUNCATED), \
+       TRACE_SYMBOL(EC_RES_RESPONSE_TOO_BIG), \
+       TRACE_SYMBOL(EC_RES_BUS_ERROR), \
+       TRACE_SYMBOL(EC_RES_BUSY), \
+       TRACE_SYMBOL(EC_RES_INVALID_HEADER_VERSION), \
+       TRACE_SYMBOL(EC_RES_INVALID_HEADER_CRC), \
+       TRACE_SYMBOL(EC_RES_INVALID_DATA_CRC), \
+       TRACE_SYMBOL(EC_RES_DUP_UNAVAILABLE)
 
 #define CREATE_TRACE_POINTS
 #include "cros_ec_trace.h"
index 0dd4df3..e9fb05f 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <linux/tracepoint.h>
 
-DECLARE_EVENT_CLASS(cros_ec_cmd_class,
+TRACE_EVENT(cros_ec_request_start,
        TP_PROTO(struct cros_ec_command *cmd),
        TP_ARGS(cmd),
        TP_STRUCT__entry(
@@ -33,10 +33,26 @@ DECLARE_EVENT_CLASS(cros_ec_cmd_class,
                  __print_symbolic(__entry->command, EC_CMDS))
 );
 
-
-DEFINE_EVENT(cros_ec_cmd_class, cros_ec_cmd,
-       TP_PROTO(struct cros_ec_command *cmd),
-       TP_ARGS(cmd)
+TRACE_EVENT(cros_ec_request_done,
+       TP_PROTO(struct cros_ec_command *cmd, int retval),
+       TP_ARGS(cmd, retval),
+       TP_STRUCT__entry(
+               __field(uint32_t, version)
+               __field(uint32_t, command)
+               __field(uint32_t, result)
+               __field(int, retval)
+       ),
+       TP_fast_assign(
+               __entry->version = cmd->version;
+               __entry->command = cmd->command;
+               __entry->result = cmd->result;
+               __entry->retval = retval;
+       ),
+       TP_printk("version: %u, command: %s, ec result: %s, retval: %d",
+                 __entry->version,
+                 __print_symbolic(__entry->command, EC_CMDS),
+                 __print_symbolic(__entry->result, EC_RESULT),
+                 __entry->retval)
 );
 
 
index f11a128..8edae46 100644 (file)
@@ -6,7 +6,6 @@
 
 #include <linux/of.h>
 #include <linux/platform_device.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
index 374cdd1..7de3ea7 100644 (file)
@@ -6,7 +6,6 @@
  */
 
 #include <linux/ktime.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/math64.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
index 365f30e..49e8530 100644 (file)
@@ -1,7 +1,8 @@
 # SPDX-License-Identifier: GPL-2.0-only
 config WILCO_EC
        tristate "ChromeOS Wilco Embedded Controller"
-       depends on ACPI && X86 && CROS_EC_LPC && LEDS_CLASS
+       depends on X86 || COMPILE_TEST
+       depends on ACPI && CROS_EC_LPC && LEDS_CLASS
        help
          If you say Y here, you get support for talking to the ChromeOS
          Wilco EC over an eSPI bus. This uses a simple byte-level protocol
index 5210c35..5b42992 100644 (file)
@@ -94,7 +94,7 @@ static int wilco_ec_probe(struct platform_device *pdev)
 
        ret = wilco_ec_add_sysfs(ec);
        if (ret < 0) {
-               dev_err(dev, "Failed to create sysfs entries: %d", ret);
+               dev_err(dev, "Failed to create sysfs entries: %d\n", ret);
                goto unregister_rtc;
        }
 
@@ -137,9 +137,9 @@ static int wilco_ec_remove(struct platform_device *pdev)
 {
        struct wilco_ec_device *ec = platform_get_drvdata(pdev);
 
+       platform_device_unregister(ec->telem_pdev);
        platform_device_unregister(ec->charger_pdev);
        wilco_ec_remove_sysfs(ec);
-       platform_device_unregister(ec->telem_pdev);
        platform_device_unregister(ec->rtc_pdev);
        if (ec->debugfs_pdev)
                platform_device_unregister(ec->debugfs_pdev);
index 5731d1b..6ce9c67 100644 (file)
@@ -69,7 +69,7 @@ static int send_kbbl_msg(struct wilco_ec_device *ec,
        ret = wilco_ec_mailbox(ec, &msg);
        if (ret < 0) {
                dev_err(ec->dev,
-                       "Failed sending keyboard LEDs command: %d", ret);
+                       "Failed sending keyboard LEDs command: %d\n", ret);
                return ret;
        }
 
@@ -94,7 +94,7 @@ static int set_kbbl(struct wilco_ec_device *ec, enum led_brightness brightness)
 
        if (response.status) {
                dev_err(ec->dev,
-                       "EC reported failure sending keyboard LEDs command: %d",
+                       "EC reported failure sending keyboard LEDs command: %d\n",
                        response.status);
                return -EIO;
        }
@@ -147,7 +147,7 @@ static int kbbl_init(struct wilco_ec_device *ec)
 
        if (response.status) {
                dev_err(ec->dev,
-                       "EC reported failure sending keyboard LEDs command: %d",
+                       "EC reported failure sending keyboard LEDs command: %d\n",
                        response.status);
                return -EIO;
        }
@@ -179,7 +179,7 @@ int wilco_keyboard_leds_init(struct wilco_ec_device *ec)
        ret = kbbl_exist(ec, &leds_exist);
        if (ret < 0) {
                dev_err(ec->dev,
-                       "Failed checking keyboard LEDs support: %d", ret);
+                       "Failed checking keyboard LEDs support: %d\n", ret);
                return ret;
        }
        if (!leds_exist)
index ced1f9f..0f98358 100644 (file)
@@ -163,13 +163,13 @@ static int wilco_ec_transfer(struct wilco_ec_device *ec,
        }
 
        if (rs->data_size != EC_MAILBOX_DATA_SIZE) {
-               dev_dbg(ec->dev, "unexpected packet size (%u != %u)",
+               dev_dbg(ec->dev, "unexpected packet size (%u != %u)\n",
                        rs->data_size, EC_MAILBOX_DATA_SIZE);
                return -EMSGSIZE;
        }
 
        if (rs->data_size < msg->response_size) {
-               dev_dbg(ec->dev, "EC didn't return enough data (%u < %zu)",
+               dev_dbg(ec->dev, "EC didn't return enough data (%u < %zu)\n",
                        rs->data_size, msg->response_size);
                return -EMSGSIZE;
        }
index 1176d54..e06d96f 100644 (file)
@@ -367,7 +367,7 @@ static int telem_device_probe(struct platform_device *pdev)
        minor = ida_alloc_max(&telem_ida, TELEM_MAX_DEV-1, GFP_KERNEL);
        if (minor < 0) {
                error = minor;
-               dev_err(&pdev->dev, "Failed to find minor number: %d", error);
+               dev_err(&pdev->dev, "Failed to find minor number: %d\n", error);
                return error;
        }
 
@@ -427,14 +427,14 @@ static int __init telem_module_init(void)
 
        ret = class_register(&telem_class);
        if (ret) {
-               pr_err(DRV_NAME ": Failed registering class: %d", ret);
+               pr_err(DRV_NAME ": Failed registering class: %d\n", ret);
                return ret;
        }
 
        /* Request the kernel for device numbers, starting with minor=0 */
        ret = alloc_chrdev_region(&dev_num, 0, TELEM_MAX_DEV, TELEM_DEV_NAME);
        if (ret) {
-               pr_err(DRV_NAME ": Failed allocating dev numbers: %d", ret);
+               pr_err(DRV_NAME ": Failed allocating dev numbers: %d\n", ret);
                goto destroy_class;
        }
        telem_major = MAJOR(dev_num);
index da794dc..8eaadba 100644 (file)
@@ -907,13 +907,12 @@ static ssize_t dispatch_proc_write(struct file *file,
        return ret;
 }
 
-static const struct file_operations dispatch_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = dispatch_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = dispatch_proc_write,
+static const struct proc_ops dispatch_proc_ops = {
+       .proc_open      = dispatch_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = dispatch_proc_write,
 };
 
 static char *next_cmd(char **cmds)
@@ -9984,7 +9983,7 @@ static int __init ibm_init(struct ibm_init_struct *iibm)
                if (ibm->write)
                        mode |= S_IWUSR;
                entry = proc_create_data(ibm->name, mode, proc_dir,
-                                        &dispatch_proc_fops, ibm);
+                                        &dispatch_proc_ops, ibm);
                if (!entry) {
                        pr_err("unable to create proc entry %s\n", ibm->name);
                        ret = -ENODEV;
index a1e6569..8089445 100644 (file)
@@ -1432,13 +1432,12 @@ static ssize_t lcd_proc_write(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct file_operations lcd_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = lcd_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = lcd_proc_write,
+static const struct proc_ops lcd_proc_ops = {
+       .proc_open      = lcd_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = lcd_proc_write,
 };
 
 /* Video-Out */
@@ -1539,13 +1538,12 @@ static ssize_t video_proc_write(struct file *file, const char __user *buf,
        return ret ? -EIO : count;
 }
 
-static const struct file_operations video_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = video_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = video_proc_write,
+static const struct proc_ops video_proc_ops = {
+       .proc_open      = video_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = video_proc_write,
 };
 
 /* Fan status */
@@ -1617,13 +1615,12 @@ static ssize_t fan_proc_write(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct file_operations fan_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = fan_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = fan_proc_write,
+static const struct proc_ops fan_proc_ops = {
+       .proc_open      = fan_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = fan_proc_write,
 };
 
 static int keys_proc_show(struct seq_file *m, void *v)
@@ -1662,13 +1659,12 @@ static ssize_t keys_proc_write(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct file_operations keys_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = keys_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = keys_proc_write,
+static const struct proc_ops keys_proc_ops = {
+       .proc_open      = keys_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = keys_proc_write,
 };
 
 static int __maybe_unused version_proc_show(struct seq_file *m, void *v)
@@ -1688,16 +1684,16 @@ static void create_toshiba_proc_entries(struct toshiba_acpi_dev *dev)
 {
        if (dev->backlight_dev)
                proc_create_data("lcd", S_IRUGO | S_IWUSR, toshiba_proc_dir,
-                                &lcd_proc_fops, dev);
+                                &lcd_proc_ops, dev);
        if (dev->video_supported)
                proc_create_data("video", S_IRUGO | S_IWUSR, toshiba_proc_dir,
-                                &video_proc_fops, dev);
+                                &video_proc_ops, dev);
        if (dev->fan_supported)
                proc_create_data("fan", S_IRUGO | S_IWUSR, toshiba_proc_dir,
-                                &fan_proc_fops, dev);
+                                &fan_proc_ops, dev);
        if (dev->hotkey_dev)
                proc_create_data("keys", S_IRUGO | S_IWUSR, toshiba_proc_dir,
-                                &keys_proc_fops, dev);
+                                &keys_proc_ops, dev);
        proc_create_single_data("version", S_IRUGO, toshiba_proc_dir,
                        version_proc_show, dev);
 }
index 3682097..785a796 100644 (file)
@@ -49,10 +49,9 @@ static ssize_t isapnp_proc_bus_read(struct file *file, char __user * buf,
        return nbytes;
 }
 
-static const struct file_operations isapnp_proc_bus_file_operations = {
-       .owner  = THIS_MODULE,
-       .llseek = isapnp_proc_bus_lseek,
-       .read = isapnp_proc_bus_read,
+static const struct proc_ops isapnp_proc_bus_proc_ops = {
+       .proc_lseek     = isapnp_proc_bus_lseek,
+       .proc_read      = isapnp_proc_bus_read,
 };
 
 static int isapnp_proc_attach_device(struct pnp_dev *dev)
@@ -69,7 +68,7 @@ static int isapnp_proc_attach_device(struct pnp_dev *dev)
        }
        sprintf(name, "%02x", dev->number);
        e = dev->procent = proc_create_data(name, S_IFREG | S_IRUGO, de,
-                       &isapnp_proc_bus_file_operations, dev);
+                                           &isapnp_proc_bus_proc_ops, dev);
        if (!e)
                return -ENOMEM;
        proc_set_size(e, 256);
index fe1c8f5..a806830 100644 (file)
@@ -210,13 +210,12 @@ out:
        return ret;
 }
 
-static const struct file_operations pnpbios_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = pnpbios_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = pnpbios_proc_write,
+static const struct proc_ops pnpbios_proc_ops = {
+       .proc_open      = pnpbios_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = pnpbios_proc_write,
 };
 
 int pnpbios_interface_attach_device(struct pnp_bios_node *node)
@@ -228,13 +227,13 @@ int pnpbios_interface_attach_device(struct pnp_bios_node *node)
        if (!proc_pnp)
                return -EIO;
        if (!pnpbios_dont_use_current_config) {
-               proc_create_data(name, 0644, proc_pnp, &pnpbios_proc_fops,
+               proc_create_data(name, 0644, proc_pnp, &pnpbios_proc_ops,
                                 (void *)(long)(node->handle));
        }
 
        if (!proc_pnp_boot)
                return -EIO;
-       if (proc_create_data(name, 0644, proc_pnp_boot, &pnpbios_proc_fops,
+       if (proc_create_data(name, 0644, proc_pnp_boot, &pnpbios_proc_ops,
                             (void *)(long)(node->handle + 0x100)))
                return 0;
        return -EIO;
index b8fe166..cdb4237 100644 (file)
@@ -14,7 +14,7 @@ menuconfig POWER_AVS
 
 config QCOM_CPR
        tristate "QCOM Core Power Reduction (CPR) support"
-       depends on POWER_AVS
+       depends on POWER_AVS && HAS_IOMEM
        select PM_OPP
        select REGMAP
        help
index 9192fb7..bd7c3e4 100644 (file)
@@ -517,7 +517,7 @@ static int cpr_scale(struct cpr_drv *drv, enum voltage_change_dir dir)
                dev_dbg(drv->dev,
                        "UP: -> new_uV: %d last_uV: %d perf state: %u\n",
                        new_uV, last_uV, cpr_get_cur_perf_state(drv));
-       } else if (dir == DOWN) {
+       } else {
                if (desc->clamp_timer_interval &&
                    error_steps < desc->down_threshold) {
                        /*
@@ -567,7 +567,7 @@ static int cpr_scale(struct cpr_drv *drv, enum voltage_change_dir dir)
                /* Disable auto nack down */
                reg_mask = RBCPR_CTL_SW_AUTO_CONT_NACK_DN_EN;
                val = 0;
-       } else if (dir == DOWN) {
+       } else {
                /* Restore default threshold for UP */
                reg_mask = RBCPR_CTL_UP_THRESHOLD_MASK;
                reg_mask <<= RBCPR_CTL_UP_THRESHOLD_SHIFT;
@@ -1547,8 +1547,6 @@ static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
                goto unlock;
        }
 
-       dev_dbg(drv->dev, "number of OPPs: %d\n", drv->num_corners);
-
        drv->corners = devm_kcalloc(drv->dev, drv->num_corners,
                                    sizeof(*drv->corners),
                                    GFP_KERNEL);
@@ -1586,6 +1584,9 @@ static int cpr_pd_attach_dev(struct generic_pm_domain *domain,
                                   acc_desc->enable_mask,
                                   acc_desc->enable_mask);
 
+       dev_info(drv->dev, "driver initialized with %u OPPs\n",
+                drv->num_corners);
+
 unlock:
        mutex_unlock(&drv->lock);
 
index 398fc95..eece97f 100644 (file)
@@ -152,18 +152,18 @@ static void px30_iodomain_init(struct rockchip_iodomain *iod)
        int ret;
        u32 val;
 
-       /* if no VCCIO0 supply we should leave things alone */
+       /* if no VCCIO6 supply we should leave things alone */
        if (!iod->supplies[PX30_IO_VSEL_VCCIO6_SUPPLY_NUM].reg)
                return;
 
        /*
-        * set vccio0 iodomain to also use this framework
+        * set vccio6 iodomain to also use this framework
         * instead of a special gpio.
         */
        val = PX30_IO_VSEL_VCCIO6_SRC | (PX30_IO_VSEL_VCCIO6_SRC << 16);
        ret = regmap_write(iod->grf, PX30_IO_VSEL, val);
        if (ret < 0)
-               dev_warn(iod->dev, "couldn't update vccio0 ctrl\n");
+               dev_warn(iod->dev, "couldn't update vccio6 ctrl\n");
 }
 
 static void rk3288_iodomain_init(struct rockchip_iodomain *iod)
index 0498363..513efe8 100644 (file)
@@ -26,7 +26,7 @@ config POWER_RESET_AT91_POWEROFF
 config POWER_RESET_AT91_RESET
        tristate "Atmel AT91 reset driver"
        depends on ARCH_AT91
-       default SOC_AT91SAM9 || SOC_SAMA5
+       default SOC_AT91SAM9 || SOC_SAM9X60 || SOC_SAMA5
        help
          This driver supports restart for Atmel AT91SAM9 and SAMA5
          SoCs
@@ -34,7 +34,7 @@ config POWER_RESET_AT91_RESET
 config POWER_RESET_AT91_SAMA5D2_SHDWC
        tristate "Atmel AT91 SAMA5D2-Compatible shutdown controller driver"
        depends on ARCH_AT91
-       default SOC_SAMA5
+       default SOC_SAM9X60 || SOC_SAMA5
        help
          This driver supports the alternate shutdown controller for some Atmel
          SAMA5 SoCs. It is present for example on SAMA5D2 SoC.
index ffad9ee..30c3d37 100644 (file)
@@ -5,7 +5,6 @@
  * Copyright (c) 2014 - 2018 Google, Inc
  */
 
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
index bd21655..30190be 100644 (file)
@@ -100,7 +100,7 @@ config PWM_BCM_KONA
 
 config PWM_BCM2835
        tristate "BCM2835 PWM support"
-       depends on ARCH_BCM2835
+       depends on ARCH_BCM2835 || ARCH_BRCMSTB
        help
          PWM framework driver for BCM2835 controller (Raspberry Pi)
 
@@ -328,7 +328,8 @@ config PWM_MXS
 
 config PWM_OMAP_DMTIMER
        tristate "OMAP Dual-Mode Timer PWM support"
-       depends on OF && ARCH_OMAP && OMAP_DM_TIMER
+       depends on OF
+       depends on OMAP_DM_TIMER || COMPILE_TEST
        help
          Generic PWM framework driver for OMAP Dual-Mode Timer PWM output
 
@@ -490,7 +491,7 @@ config PWM_TEGRA
          To compile this driver as a module, choose M here: the module
          will be called pwm-tegra.
 
-config  PWM_TIECAP
+config PWM_TIECAP
        tristate "ECAP PWM support"
        depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_KEYSTONE || ARCH_K3
        help
@@ -499,7 +500,7 @@ config  PWM_TIECAP
          To compile this driver as a module, choose M here: the module
          will be called pwm-tiecap.
 
-config  PWM_TIEHRPWM
+config PWM_TIEHRPWM
        tristate "EHRPWM PWM support"
        depends on ARCH_OMAP2PLUS || ARCH_DAVINCI_DA8XX || ARCH_K3
        help
index f877e77..5a7f659 100644 (file)
@@ -20,6 +20,9 @@
 
 #include <dt-bindings/pwm/pwm.h>
 
+#define CREATE_TRACE_POINTS
+#include <trace/events/pwm.h>
+
 #define MAX_PWMS 1024
 
 static DEFINE_MUTEX(pwm_lookup_lock);
@@ -114,6 +117,11 @@ static int pwm_device_request(struct pwm_device *pwm, const char *label)
                }
        }
 
+       if (pwm->chip->ops->get_state) {
+               pwm->chip->ops->get_state(pwm->chip, pwm, &pwm->state);
+               trace_pwm_get(pwm, &pwm->state);
+       }
+
        set_bit(PWMF_REQUESTED, &pwm->flags);
        pwm->label = label;
 
@@ -283,9 +291,6 @@ int pwmchip_add_with_polarity(struct pwm_chip *chip,
                pwm->hwpwm = i;
                pwm->state.polarity = polarity;
 
-               if (chip->ops->get_state)
-                       chip->ops->get_state(chip, pwm, &pwm->state);
-
                radix_tree_insert(&pwm_tree, pwm->pwm, pwm);
        }
 
@@ -472,6 +477,8 @@ int pwm_apply_state(struct pwm_device *pwm, const struct pwm_state *state)
                if (err)
                        return err;
 
+               trace_pwm_apply(pwm, state);
+
                pwm->state = *state;
        } else {
                /*
index 9ba7334..6161e7e 100644 (file)
@@ -4,6 +4,19 @@
  *
  * Copyright (C) 2013 Atmel Corporation
  *              Bo Shen <voice.shen@atmel.com>
+ *
+ * Links to reference manuals for the supported PWM chips can be found in
+ * Documentation/arm/microchip.rst.
+ *
+ * Limitations:
+ * - Periods start with the inactive level.
+ * - Hardware has to be stopped in general to update settings.
+ *
+ * Software bugs/possible improvements:
+ * - When atmel_pwm_apply() is called with state->enabled=false a change in
+ *   state->polarity isn't honored.
+ * - Instead of sleeping to wait for a completed period, the interrupt
+ *   functionality could be used.
  */
 
 #include <linux/clk.h>
@@ -47,6 +60,8 @@
 #define PWMV2_CPRD             0x0C
 #define PWMV2_CPRDUPD          0x10
 
+#define PWM_MAX_PRES           10
+
 struct atmel_pwm_registers {
        u8 period;
        u8 period_upd;
@@ -55,8 +70,7 @@ struct atmel_pwm_registers {
 };
 
 struct atmel_pwm_config {
-       u32 max_period;
-       u32 max_pres;
+       u32 period_bits;
 };
 
 struct atmel_pwm_data {
@@ -97,7 +111,7 @@ static inline u32 atmel_pwm_ch_readl(struct atmel_pwm_chip *chip,
 {
        unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;
 
-       return readl_relaxed(chip->base + base + offset);
+       return atmel_pwm_readl(chip, base + offset);
 }
 
 static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
@@ -106,7 +120,7 @@ static inline void atmel_pwm_ch_writel(struct atmel_pwm_chip *chip,
 {
        unsigned long base = PWM_CH_REG_OFFSET + ch * PWM_CH_REG_SIZE;
 
-       writel_relaxed(val, chip->base + base + offset);
+       atmel_pwm_writel(chip, base + offset, val);
 }
 
 static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
@@ -115,17 +129,27 @@ static int atmel_pwm_calculate_cprd_and_pres(struct pwm_chip *chip,
 {
        struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
        unsigned long long cycles = state->period;
+       int shift;
 
        /* Calculate the period cycles and prescale value */
        cycles *= clk_get_rate(atmel_pwm->clk);
        do_div(cycles, NSEC_PER_SEC);
 
-       for (*pres = 0; cycles > atmel_pwm->data->cfg.max_period; cycles >>= 1)
-               (*pres)++;
+       /*
+        * The register for the period length is cfg.period_bits bits wide.
+        * So for each bit the number of clock cycles is wider divide the input
+        * clock frequency by two using pres and shift cprd accordingly.
+        */
+       shift = fls(cycles) - atmel_pwm->data->cfg.period_bits;
 
-       if (*pres > atmel_pwm->data->cfg.max_pres) {
+       if (shift > PWM_MAX_PRES) {
                dev_err(chip->dev, "pres exceeds the maximum value\n");
                return -EINVAL;
+       } else if (shift > 0) {
+               *pres = shift;
+               cycles >>= *pres;
+       } else {
+               *pres = 0;
        }
 
        *cprd = cycles;
@@ -271,8 +295,48 @@ static int atmel_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
        return 0;
 }
 
+static void atmel_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
+                               struct pwm_state *state)
+{
+       struct atmel_pwm_chip *atmel_pwm = to_atmel_pwm_chip(chip);
+       u32 sr, cmr;
+
+       sr = atmel_pwm_readl(atmel_pwm, PWM_SR);
+       cmr = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm, PWM_CMR);
+
+       if (sr & (1 << pwm->hwpwm)) {
+               unsigned long rate = clk_get_rate(atmel_pwm->clk);
+               u32 cdty, cprd, pres;
+               u64 tmp;
+
+               pres = cmr & PWM_CMR_CPRE_MSK;
+
+               cprd = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
+                                         atmel_pwm->data->regs.period);
+               tmp = (u64)cprd * NSEC_PER_SEC;
+               tmp <<= pres;
+               state->period = DIV64_U64_ROUND_UP(tmp, rate);
+
+               cdty = atmel_pwm_ch_readl(atmel_pwm, pwm->hwpwm,
+                                         atmel_pwm->data->regs.duty);
+               tmp = (u64)cdty * NSEC_PER_SEC;
+               tmp <<= pres;
+               state->duty_cycle = DIV64_U64_ROUND_UP(tmp, rate);
+
+               state->enabled = true;
+       } else {
+               state->enabled = false;
+       }
+
+       if (cmr & PWM_CMR_CPOL)
+               state->polarity = PWM_POLARITY_INVERSED;
+       else
+               state->polarity = PWM_POLARITY_NORMAL;
+}
+
 static const struct pwm_ops atmel_pwm_ops = {
        .apply = atmel_pwm_apply,
+       .get_state = atmel_pwm_get_state,
        .owner = THIS_MODULE,
 };
 
@@ -285,8 +349,7 @@ static const struct atmel_pwm_data atmel_sam9rl_pwm_data = {
        },
        .cfg = {
                /* 16 bits to keep period and duty. */
-               .max_period     = 0xffff,
-               .max_pres       = 10,
+               .period_bits    = 16,
        },
 };
 
@@ -299,8 +362,7 @@ static const struct atmel_pwm_data atmel_sama5_pwm_data = {
        },
        .cfg = {
                /* 16 bits to keep period and duty. */
-               .max_period     = 0xffff,
-               .max_pres       = 10,
+               .period_bits    = 16,
        },
 };
 
@@ -313,8 +375,7 @@ static const struct atmel_pwm_data mchp_sam9x60_pwm_data = {
        },
        .cfg = {
                /* 32 bits to keep period and duty. */
-               .max_period     = 0xffffffff,
-               .max_pres       = 10,
+               .period_bits    = 32,
        },
 };
 
index 8949744..09c08de 100644 (file)
@@ -25,11 +25,39 @@ struct cros_ec_pwm_device {
        struct pwm_chip chip;
 };
 
+/**
+ * struct cros_ec_pwm - per-PWM driver data
+ * @duty_cycle: cached duty cycle
+ */
+struct cros_ec_pwm {
+       u16 duty_cycle;
+};
+
 static inline struct cros_ec_pwm_device *pwm_to_cros_ec_pwm(struct pwm_chip *c)
 {
        return container_of(c, struct cros_ec_pwm_device, chip);
 }
 
+static int cros_ec_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct cros_ec_pwm *channel;
+
+       channel = kzalloc(sizeof(*channel), GFP_KERNEL);
+       if (!channel)
+               return -ENOMEM;
+
+       pwm_set_chip_data(pwm, channel);
+
+       return 0;
+}
+
+static void cros_ec_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+       struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
+
+       kfree(channel);
+}
+
 static int cros_ec_pwm_set_duty(struct cros_ec_device *ec, u8 index, u16 duty)
 {
        struct {
@@ -96,7 +124,9 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                             const struct pwm_state *state)
 {
        struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip);
-       int duty_cycle;
+       struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
+       u16 duty_cycle;
+       int ret;
 
        /* The EC won't let us change the period */
        if (state->period != EC_PWM_MAX_DUTY)
@@ -108,13 +138,20 @@ static int cros_ec_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
         */
        duty_cycle = state->enabled ? state->duty_cycle : 0;
 
-       return cros_ec_pwm_set_duty(ec_pwm->ec, pwm->hwpwm, duty_cycle);
+       ret = cros_ec_pwm_set_duty(ec_pwm->ec, pwm->hwpwm, duty_cycle);
+       if (ret < 0)
+               return ret;
+
+       channel->duty_cycle = state->duty_cycle;
+
+       return 0;
 }
 
 static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
                                  struct pwm_state *state)
 {
        struct cros_ec_pwm_device *ec_pwm = pwm_to_cros_ec_pwm(chip);
+       struct cros_ec_pwm *channel = pwm_get_chip_data(pwm);
        int ret;
 
        ret = cros_ec_pwm_get_duty(ec_pwm->ec, pwm->hwpwm);
@@ -126,8 +163,19 @@ static void cros_ec_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
        state->enabled = (ret > 0);
        state->period = EC_PWM_MAX_DUTY;
 
-       /* Note that "disabled" and "duty cycle == 0" are treated the same */
-       state->duty_cycle = ret;
+       /*
+        * Note that "disabled" and "duty cycle == 0" are treated the same. If
+        * the cached duty cycle is not zero, used the cached duty cycle. This
+        * ensures that the configured duty cycle is kept across a disable and
+        * enable operation and avoids potentially confusing consumers.
+        *
+        * For the case of the initial hardware readout, channel->duty_cycle
+        * will be 0 and the actual duty cycle read from the EC is used.
+        */
+       if (ret == 0 && channel->duty_cycle > 0)
+               state->duty_cycle = channel->duty_cycle;
+       else
+               state->duty_cycle = ret;
 }
 
 static struct pwm_device *
@@ -149,6 +197,8 @@ cros_ec_pwm_xlate(struct pwm_chip *pc, const struct of_phandle_args *args)
 }
 
 static const struct pwm_ops cros_ec_pwm_ops = {
+       .request = cros_ec_pwm_request,
+       .free = cros_ec_pwm_free,
        .get_state      = cros_ec_pwm_get_state,
        .apply          = cros_ec_pwm_apply,
        .owner          = THIS_MODULE,
index ae11d85..35a7ac4 100644 (file)
@@ -85,6 +85,13 @@ struct pwm_imx27_chip {
        struct clk      *clk_per;
        void __iomem    *mmio_base;
        struct pwm_chip chip;
+
+       /*
+        * The driver cannot read the current duty cycle from the hardware if
+        * the hardware is disabled. Cache the last programmed duty cycle
+        * value to return in that case.
+        */
+       unsigned int duty_cycle;
 };
 
 #define to_pwm_imx27_chip(chip)        container_of(chip, struct pwm_imx27_chip, chip)
@@ -155,14 +162,17 @@ static void pwm_imx27_get_state(struct pwm_chip *chip,
        tmp = NSEC_PER_SEC * (u64)(period + 2);
        state->period = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
 
-       /* PWMSAR can be read only if PWM is enabled */
-       if (state->enabled) {
+       /*
+        * PWMSAR can be read only if PWM is enabled. If the PWM is disabled,
+        * use the cached value.
+        */
+       if (state->enabled)
                val = readl(imx->mmio_base + MX3_PWMSAR);
-               tmp = NSEC_PER_SEC * (u64)(val);
-               state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
-       } else {
-               state->duty_cycle = 0;
-       }
+       else
+               val = imx->duty_cycle;
+
+       tmp = NSEC_PER_SEC * (u64)(val);
+       state->duty_cycle = DIV_ROUND_CLOSEST_ULL(tmp, pwm_clk);
 
        if (!state->enabled)
                pwm_imx27_clk_disable_unprepare(chip);
@@ -220,63 +230,68 @@ static int pwm_imx27_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 
        pwm_get_state(pwm, &cstate);
 
-       if (state->enabled) {
-               c = clk_get_rate(imx->clk_per);
-               c *= state->period;
-
-               do_div(c, 1000000000);
-               period_cycles = c;
-
-               prescale = period_cycles / 0x10000 + 1;
-
-               period_cycles /= prescale;
-               c = (unsigned long long)period_cycles * state->duty_cycle;
-               do_div(c, state->period);
-               duty_cycles = c;
-
-               /*
-                * according to imx pwm RM, the real period value should be
-                * PERIOD value in PWMPR plus 2.
-                */
-               if (period_cycles > 2)
-                       period_cycles -= 2;
-               else
-                       period_cycles = 0;
-
-               /*
-                * Wait for a free FIFO slot if the PWM is already enabled, and
-                * flush the FIFO if the PWM was disabled and is about to be
-                * enabled.
-                */
-               if (cstate.enabled) {
-                       pwm_imx27_wait_fifo_slot(chip, pwm);
-               } else {
-                       ret = pwm_imx27_clk_prepare_enable(chip);
-                       if (ret)
-                               return ret;
-
-                       pwm_imx27_sw_reset(chip);
-               }
-
-               writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
-               writel(period_cycles, imx->mmio_base + MX3_PWMPR);
-
-               cr = MX3_PWMCR_PRESCALER_SET(prescale) |
-                    MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN |
-                    FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) |
-                    MX3_PWMCR_DBGEN | MX3_PWMCR_EN;
-
-               if (state->polarity == PWM_POLARITY_INVERSED)
-                       cr |= FIELD_PREP(MX3_PWMCR_POUTC,
-                                       MX3_PWMCR_POUTC_INVERTED);
-
-               writel(cr, imx->mmio_base + MX3_PWMCR);
-       } else if (cstate.enabled) {
-               writel(0, imx->mmio_base + MX3_PWMCR);
+       c = clk_get_rate(imx->clk_per);
+       c *= state->period;
 
-               pwm_imx27_clk_disable_unprepare(chip);
+       do_div(c, 1000000000);
+       period_cycles = c;
+
+       prescale = period_cycles / 0x10000 + 1;
+
+       period_cycles /= prescale;
+       c = (unsigned long long)period_cycles * state->duty_cycle;
+       do_div(c, state->period);
+       duty_cycles = c;
+
+       /*
+        * according to imx pwm RM, the real period value should be PERIOD
+        * value in PWMPR plus 2.
+        */
+       if (period_cycles > 2)
+               period_cycles -= 2;
+       else
+               period_cycles = 0;
+
+       /*
+        * Wait for a free FIFO slot if the PWM is already enabled, and flush
+        * the FIFO if the PWM was disabled and is about to be enabled.
+        */
+       if (cstate.enabled) {
+               pwm_imx27_wait_fifo_slot(chip, pwm);
+       } else {
+               ret = pwm_imx27_clk_prepare_enable(chip);
+               if (ret)
+                       return ret;
+
+               pwm_imx27_sw_reset(chip);
        }
 
+       writel(duty_cycles, imx->mmio_base + MX3_PWMSAR);
+       writel(period_cycles, imx->mmio_base + MX3_PWMPR);
+
+       /*
+        * Store the duty cycle for future reference in cases where the
+        * MX3_PWMSAR register can't be read (i.e. when the PWM is disabled).
+        */
+       imx->duty_cycle = duty_cycles;
+
+       cr = MX3_PWMCR_PRESCALER_SET(prescale) |
+            MX3_PWMCR_STOPEN | MX3_PWMCR_DOZEN | MX3_PWMCR_WAITEN |
+            FIELD_PREP(MX3_PWMCR_CLKSRC, MX3_PWMCR_CLKSRC_IPG_HIGH) |
+            MX3_PWMCR_DBGEN;
+
+       if (state->polarity == PWM_POLARITY_INVERSED)
+               cr |= FIELD_PREP(MX3_PWMCR_POUTC,
+                               MX3_PWMCR_POUTC_INVERTED);
+
+       if (state->enabled)
+               cr |= MX3_PWMCR_EN;
+
+       writel(cr, imx->mmio_base + MX3_PWMCR);
+
+       if (!state->enabled && cstate.enabled)
+               pwm_imx27_clk_disable_unprepare(chip);
+
        return 0;
 }
 
@@ -304,9 +319,13 @@ static int pwm_imx27_probe(struct platform_device *pdev)
 
        imx->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
        if (IS_ERR(imx->clk_ipg)) {
-               dev_err(&pdev->dev, "getting ipg clock failed with %ld\n",
-                               PTR_ERR(imx->clk_ipg));
-               return PTR_ERR(imx->clk_ipg);
+               int ret = PTR_ERR(imx->clk_ipg);
+
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "getting ipg clock failed with %d\n",
+                               ret);
+               return ret;
        }
 
        imx->clk_per = devm_clk_get(&pdev->dev, "per");
index b14376b..f2e57fc 100644 (file)
 #define  PERIOD_PERIOD(p)      ((p) & 0xffff)
 #define  PERIOD_PERIOD_MAX     0x10000
 #define  PERIOD_ACTIVE_HIGH    (3 << 16)
+#define  PERIOD_ACTIVE_LOW     (2 << 16)
+#define  PERIOD_INACTIVE_HIGH  (3 << 18)
 #define  PERIOD_INACTIVE_LOW   (2 << 18)
+#define  PERIOD_POLARITY_NORMAL        (PERIOD_ACTIVE_HIGH | PERIOD_INACTIVE_LOW)
+#define  PERIOD_POLARITY_INVERSE       (PERIOD_ACTIVE_LOW | PERIOD_INACTIVE_HIGH)
 #define  PERIOD_CDIV(div)      (((div) & 0x7) << 20)
 #define  PERIOD_CDIV_MAX       8
 
-static const unsigned int cdiv[PERIOD_CDIV_MAX] = {
-       1, 2, 4, 8, 16, 64, 256, 1024
+static const u8 cdiv_shift[PERIOD_CDIV_MAX] = {
+       0, 1, 2, 3, 4, 6, 8, 10
 };
 
 struct mxs_pwm_chip {
@@ -41,19 +45,34 @@ struct mxs_pwm_chip {
 
 #define to_mxs_pwm_chip(_chip) container_of(_chip, struct mxs_pwm_chip, chip)
 
-static int mxs_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
-                         int duty_ns, int period_ns)
+static int mxs_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
+                        const struct pwm_state *state)
 {
        struct mxs_pwm_chip *mxs = to_mxs_pwm_chip(chip);
        int ret, div = 0;
        unsigned int period_cycles, duty_cycles;
        unsigned long rate;
        unsigned long long c;
+       unsigned int pol_bits;
+
+       /*
+        * If the PWM channel is disabled, make sure to turn on the
+        * clock before calling clk_get_rate() and writing to the
+        * registers. Otherwise, just keep it enabled.
+        */
+       if (!pwm_is_enabled(pwm)) {
+               ret = clk_prepare_enable(mxs->clk);
+               if (ret)
+                       return ret;
+       }
+
+       if (!state->enabled && pwm_is_enabled(pwm))
+               writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + CLR);
 
        rate = clk_get_rate(mxs->clk);
        while (1) {
-               c = rate / cdiv[div];
-               c = c * period_ns;
+               c = rate >> cdiv_shift[div];
+               c = c * state->period;
                do_div(c, 1000000000);
                if (c < PERIOD_PERIOD_MAX)
                        break;
@@ -63,62 +82,40 @@ static int mxs_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
        }
 
        period_cycles = c;
-       c *= duty_ns;
-       do_div(c, period_ns);
+       c *= state->duty_cycle;
+       do_div(c, state->period);
        duty_cycles = c;
 
        /*
-        * If the PWM channel is disabled, make sure to turn on the clock
-        * before writing the register. Otherwise, keep it enabled.
+        * The data sheet the says registers must be written to in
+        * this order (ACTIVEn, then PERIODn). Also, the new settings
+        * only take effect at the beginning of a new period, avoiding
+        * glitches.
         */
-       if (!pwm_is_enabled(pwm)) {
-               ret = clk_prepare_enable(mxs->clk);
-               if (ret)
-                       return ret;
-       }
 
+       pol_bits = state->polarity == PWM_POLARITY_NORMAL ?
+               PERIOD_POLARITY_NORMAL : PERIOD_POLARITY_INVERSE;
        writel(duty_cycles << 16,
-                       mxs->base + PWM_ACTIVE0 + pwm->hwpwm * 0x20);
-       writel(PERIOD_PERIOD(period_cycles) | PERIOD_ACTIVE_HIGH |
-              PERIOD_INACTIVE_LOW | PERIOD_CDIV(div),
-                       mxs->base + PWM_PERIOD0 + pwm->hwpwm * 0x20);
-
-       /*
-        * If the PWM is not enabled, turn the clock off again to save power.
-        */
-       if (!pwm_is_enabled(pwm))
+              mxs->base + PWM_ACTIVE0 + pwm->hwpwm * 0x20);
+       writel(PERIOD_PERIOD(period_cycles) | pol_bits | PERIOD_CDIV(div),
+              mxs->base + PWM_PERIOD0 + pwm->hwpwm * 0x20);
+
+       if (state->enabled) {
+               if (!pwm_is_enabled(pwm)) {
+                       /*
+                        * The clock was enabled above. Just enable
+                        * the channel in the control register.
+                        */
+                       writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + SET);
+               }
+       } else {
                clk_disable_unprepare(mxs->clk);
-
-       return 0;
-}
-
-static int mxs_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-       struct mxs_pwm_chip *mxs = to_mxs_pwm_chip(chip);
-       int ret;
-
-       ret = clk_prepare_enable(mxs->clk);
-       if (ret)
-               return ret;
-
-       writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + SET);
-
+       }
        return 0;
 }
 
-static void mxs_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
-{
-       struct mxs_pwm_chip *mxs = to_mxs_pwm_chip(chip);
-
-       writel(1 << pwm->hwpwm, mxs->base + PWM_CTRL + CLR);
-
-       clk_disable_unprepare(mxs->clk);
-}
-
 static const struct pwm_ops mxs_pwm_ops = {
-       .config = mxs_pwm_config,
-       .enable = mxs_pwm_enable,
-       .disable = mxs_pwm_disable,
+       .apply = mxs_pwm_apply,
        .owner = THIS_MODULE,
 };
 
@@ -142,6 +139,8 @@ static int mxs_pwm_probe(struct platform_device *pdev)
 
        mxs->chip.dev = &pdev->dev;
        mxs->chip.ops = &mxs_pwm_ops;
+       mxs->chip.of_xlate = of_pwm_xlate_with_flags;
+       mxs->chip.of_pwm_n_cells = 3;
        mxs->chip.base = -1;
 
        ret = of_property_read_u32(np, "fsl,pwm-number", &mxs->chip.npwm);
index 00772fc..88a3c56 100644 (file)
@@ -256,7 +256,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
        if (!timer_pdev) {
                dev_err(&pdev->dev, "Unable to find Timer pdev\n");
                ret = -ENODEV;
-               goto put;
+               goto err_find_timer_pdev;
        }
 
        timer_pdata = dev_get_platdata(&timer_pdev->dev);
@@ -264,7 +264,7 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
                dev_dbg(&pdev->dev,
                         "dmtimer pdata structure NULL, deferring probe\n");
                ret = -EPROBE_DEFER;
-               goto put;
+               goto err_platdata;
        }
 
        pdata = timer_pdata->timer_ops;
@@ -283,30 +283,25 @@ static int pwm_omap_dmtimer_probe(struct platform_device *pdev)
            !pdata->write_counter) {
                dev_err(&pdev->dev, "Incomplete dmtimer pdata structure\n");
                ret = -EINVAL;
-               goto put;
+               goto err_platdata;
        }
 
        if (!of_get_property(timer, "ti,timer-pwm", NULL)) {
                dev_err(&pdev->dev, "Missing ti,timer-pwm capability\n");
                ret = -ENODEV;
-               goto put;
+               goto err_timer_property;
        }
 
        dm_timer = pdata->request_by_node(timer);
        if (!dm_timer) {
                ret = -EPROBE_DEFER;
-               goto put;
+               goto err_request_timer;
        }
 
-put:
-       of_node_put(timer);
-       if (ret < 0)
-               return ret;
-
        omap = devm_kzalloc(&pdev->dev, sizeof(*omap), GFP_KERNEL);
        if (!omap) {
-               pdata->free(dm_timer);
-               return -ENOMEM;
+               ret = -ENOMEM;
+               goto err_alloc_omap;
        }
 
        omap->pdata = pdata;
@@ -339,27 +334,56 @@ put:
        ret = pwmchip_add(&omap->chip);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to register PWM\n");
-               omap->pdata->free(omap->dm_timer);
-               return ret;
+               goto err_pwmchip_add;
        }
 
+       of_node_put(timer);
+
        platform_set_drvdata(pdev, omap);
 
        return 0;
+
+err_pwmchip_add:
+
+       /*
+        * *omap is allocated using devm_kzalloc,
+        * so no free necessary here
+        */
+err_alloc_omap:
+
+       pdata->free(dm_timer);
+err_request_timer:
+
+err_timer_property:
+err_platdata:
+
+       put_device(&timer_pdev->dev);
+err_find_timer_pdev:
+
+       of_node_put(timer);
+
+       return ret;
 }
 
 static int pwm_omap_dmtimer_remove(struct platform_device *pdev)
 {
        struct pwm_omap_dmtimer_chip *omap = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = pwmchip_remove(&omap->chip);
+       if (ret)
+               return ret;
 
        if (pm_runtime_active(&omap->dm_timer_pdev->dev))
                omap->pdata->stop(omap->dm_timer);
 
        omap->pdata->free(omap->dm_timer);
 
+       put_device(&omap->dm_timer_pdev->dev);
+
        mutex_destroy(&omap->mutex);
 
-       return pwmchip_remove(&omap->chip);
+       return 0;
 }
 
 static const struct of_device_id pwm_omap_dmtimer_of_match[] = {
index 168684b..b07bdca 100644 (file)
@@ -159,13 +159,9 @@ static void pca9685_pwm_gpio_set(struct gpio_chip *gpio, unsigned int offset,
 static void pca9685_pwm_gpio_free(struct gpio_chip *gpio, unsigned int offset)
 {
        struct pca9685 *pca = gpiochip_get_data(gpio);
-       struct pwm_device *pwm;
 
        pca9685_pwm_gpio_set(gpio, offset, 0);
        pm_runtime_put(pca->chip.dev);
-       mutex_lock(&pca->lock);
-       pwm = &pca->chip.pwms[offset];
-       mutex_unlock(&pca->lock);
 }
 
 static int pca9685_pwm_gpio_get_direction(struct gpio_chip *chip,
index 852eb23..2685577 100644 (file)
@@ -3,6 +3,9 @@
  * R-Car PWM Timer driver
  *
  * Copyright (C) 2015 Renesas Electronics Corporation
+ *
+ * Limitations:
+ * - The hardware cannot generate a 0% duty cycle.
  */
 
 #include <linux/clk.h>
@@ -161,11 +164,9 @@ static int rcar_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                          const struct pwm_state *state)
 {
        struct rcar_pwm_chip *rp = to_rcar_pwm_chip(chip);
-       struct pwm_state cur_state;
        int div, ret;
 
        /* This HW/driver only supports normal polarity */
-       pwm_get_state(pwm, &cur_state);
        if (state->polarity != PWM_POLARITY_NORMAL)
                return -ENOTSUPP;
 
index 7ff48c1..d3be944 100644 (file)
@@ -377,9 +377,7 @@ static int stm32_pwm_config(struct stm32_pwm *priv, int ch,
        else
                regmap_update_bits(priv->regmap, TIM_CCMR2, mask, ccmr);
 
-       regmap_update_bits(priv->regmap, TIM_BDTR,
-                          TIM_BDTR_MOE | TIM_BDTR_AOE,
-                          TIM_BDTR_MOE | TIM_BDTR_AOE);
+       regmap_update_bits(priv->regmap, TIM_BDTR, TIM_BDTR_MOE, TIM_BDTR_MOE);
 
        return 0;
 }
index 581d232..3e3efa6 100644 (file)
@@ -3,6 +3,10 @@
  * Driver for Allwinner sun4i Pulse Width Modulation Controller
  *
  * Copyright (C) 2014 Alexandre Belloni <alexandre.belloni@free-electrons.com>
+ *
+ * Limitations:
+ * - When outputing the source clock directly, the PWM logic will be bypassed
+ *   and the currently running period is not guaranteed to be completed
  */
 
 #include <linux/bitops.h>
@@ -16,6 +20,7 @@
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
 #include <linux/pwm.h>
+#include <linux/reset.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/time.h>
@@ -72,12 +77,15 @@ static const u32 prescaler_table[] = {
 
 struct sun4i_pwm_data {
        bool has_prescaler_bypass;
+       bool has_direct_mod_clk_output;
        unsigned int npwm;
 };
 
 struct sun4i_pwm_chip {
        struct pwm_chip chip;
+       struct clk *bus_clk;
        struct clk *clk;
+       struct reset_control *rst;
        void __iomem *base;
        spinlock_t ctrl_lock;
        const struct sun4i_pwm_data *data;
@@ -115,6 +123,20 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
 
        val = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 
+       /*
+        * PWM chapter in H6 manual has a diagram which explains that if bypass
+        * bit is set, no other setting has any meaning. Even more, experiment
+        * proved that also enable bit is ignored in this case.
+        */
+       if ((val & BIT_CH(PWM_BYPASS, pwm->hwpwm)) &&
+           sun4i_pwm->data->has_direct_mod_clk_output) {
+               state->period = DIV_ROUND_UP_ULL(NSEC_PER_SEC, clk_rate);
+               state->duty_cycle = DIV_ROUND_UP_ULL(state->period, 2);
+               state->polarity = PWM_POLARITY_NORMAL;
+               state->enabled = true;
+               return;
+       }
+
        if ((PWM_REG_PRESCAL(val, pwm->hwpwm) == PWM_PRESCAL_MASK) &&
            sun4i_pwm->data->has_prescaler_bypass)
                prescaler = 1;
@@ -146,13 +168,24 @@ static void sun4i_pwm_get_state(struct pwm_chip *chip,
 
 static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
                               const struct pwm_state *state,
-                              u32 *dty, u32 *prd, unsigned int *prsclr)
+                              u32 *dty, u32 *prd, unsigned int *prsclr,
+                              bool *bypass)
 {
        u64 clk_rate, div = 0;
-       unsigned int pval, prescaler = 0;
+       unsigned int prescaler = 0;
 
        clk_rate = clk_get_rate(sun4i_pwm->clk);
 
+       *bypass = sun4i_pwm->data->has_direct_mod_clk_output &&
+                 state->enabled &&
+                 (state->period * clk_rate >= NSEC_PER_SEC) &&
+                 (state->period * clk_rate < 2 * NSEC_PER_SEC) &&
+                 (state->duty_cycle * clk_rate * 2 >= NSEC_PER_SEC);
+
+       /* Skip calculation of other parameters if we bypass them */
+       if (*bypass)
+               return 0;
+
        if (sun4i_pwm->data->has_prescaler_bypass) {
                /* First, test without any prescaler when available */
                prescaler = PWM_PRESCAL_MASK;
@@ -170,9 +203,11 @@ static int sun4i_pwm_calculate(struct sun4i_pwm_chip *sun4i_pwm,
        if (prescaler == 0) {
                /* Go up from the first divider */
                for (prescaler = 0; prescaler < PWM_PRESCAL_MASK; prescaler++) {
-                       if (!prescaler_table[prescaler])
+                       unsigned int pval = prescaler_table[prescaler];
+
+                       if (!pval)
                                continue;
-                       pval = prescaler_table[prescaler];
+
                        div = clk_rate;
                        do_div(div, pval);
                        div = div * state->period;
@@ -199,10 +234,11 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
 {
        struct sun4i_pwm_chip *sun4i_pwm = to_sun4i_pwm_chip(chip);
        struct pwm_state cstate;
-       u32 ctrl;
+       u32 ctrl, duty = 0, period = 0, val;
        int ret;
-       unsigned int delay_us;
+       unsigned int delay_us, prescaler = 0;
        unsigned long now;
+       bool bypass;
 
        pwm_get_state(pwm, &cstate);
 
@@ -214,46 +250,52 @@ static int sun4i_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
                }
        }
 
+       ret = sun4i_pwm_calculate(sun4i_pwm, state, &duty, &period, &prescaler,
+                                 &bypass);
+       if (ret) {
+               dev_err(chip->dev, "period exceeds the maximum value\n");
+               if (!cstate.enabled)
+                       clk_disable_unprepare(sun4i_pwm->clk);
+               return ret;
+       }
+
        spin_lock(&sun4i_pwm->ctrl_lock);
        ctrl = sun4i_pwm_readl(sun4i_pwm, PWM_CTRL_REG);
 
-       if ((cstate.period != state->period) ||
-           (cstate.duty_cycle != state->duty_cycle)) {
-               u32 period, duty, val;
-               unsigned int prescaler;
-
-               ret = sun4i_pwm_calculate(sun4i_pwm, state,
-                                         &duty, &period, &prescaler);
-               if (ret) {
-                       dev_err(chip->dev, "period exceeds the maximum value\n");
+       if (sun4i_pwm->data->has_direct_mod_clk_output) {
+               if (bypass) {
+                       ctrl |= BIT_CH(PWM_BYPASS, pwm->hwpwm);
+                       /* We can skip other parameter */
+                       sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
                        spin_unlock(&sun4i_pwm->ctrl_lock);
-                       if (!cstate.enabled)
-                               clk_disable_unprepare(sun4i_pwm->clk);
-                       return ret;
+                       return 0;
                }
 
-               if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) {
-                       /* Prescaler changed, the clock has to be gated */
-                       ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
-                       sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
+               ctrl &= ~BIT_CH(PWM_BYPASS, pwm->hwpwm);
+       }
 
-                       ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
-                       ctrl |= BIT_CH(prescaler, pwm->hwpwm);
-               }
+       if (PWM_REG_PRESCAL(ctrl, pwm->hwpwm) != prescaler) {
+               /* Prescaler changed, the clock has to be gated */
+               ctrl &= ~BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+               sun4i_pwm_writel(sun4i_pwm, ctrl, PWM_CTRL_REG);
 
-               val = (duty & PWM_DTY_MASK) | PWM_PRD(period);
-               sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
-               sun4i_pwm->next_period[pwm->hwpwm] = jiffies +
-                       usecs_to_jiffies(cstate.period / 1000 + 1);
-               sun4i_pwm->needs_delay[pwm->hwpwm] = true;
+               ctrl &= ~BIT_CH(PWM_PRESCAL_MASK, pwm->hwpwm);
+               ctrl |= BIT_CH(prescaler, pwm->hwpwm);
        }
 
+       val = (duty & PWM_DTY_MASK) | PWM_PRD(period);
+       sun4i_pwm_writel(sun4i_pwm, val, PWM_CH_PRD(pwm->hwpwm));
+       sun4i_pwm->next_period[pwm->hwpwm] = jiffies +
+               usecs_to_jiffies(cstate.period / 1000 + 1);
+       sun4i_pwm->needs_delay[pwm->hwpwm] = true;
+
        if (state->polarity != PWM_POLARITY_NORMAL)
                ctrl &= ~BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
        else
                ctrl |= BIT_CH(PWM_ACT_STATE, pwm->hwpwm);
 
        ctrl |= BIT_CH(PWM_CLK_GATING, pwm->hwpwm);
+
        if (state->enabled) {
                ctrl |= BIT_CH(PWM_EN, pwm->hwpwm);
        } else if (!sun4i_pwm->needs_delay[pwm->hwpwm]) {
@@ -319,6 +361,12 @@ static const struct sun4i_pwm_data sun4i_pwm_single_bypass = {
        .npwm = 1,
 };
 
+static const struct sun4i_pwm_data sun50i_h6_pwm_data = {
+       .has_prescaler_bypass = true,
+       .has_direct_mod_clk_output = true,
+       .npwm = 2,
+};
+
 static const struct of_device_id sun4i_pwm_dt_ids[] = {
        {
                .compatible = "allwinner,sun4i-a10-pwm",
@@ -336,6 +384,9 @@ static const struct of_device_id sun4i_pwm_dt_ids[] = {
                .compatible = "allwinner,sun8i-h3-pwm",
                .data = &sun4i_pwm_single_bypass,
        }, {
+               .compatible = "allwinner,sun50i-h6-pwm",
+               .data = &sun50i_h6_pwm_data,
+       }, {
                /* sentinel */
        },
 };
@@ -360,9 +411,69 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
        if (IS_ERR(pwm->base))
                return PTR_ERR(pwm->base);
 
-       pwm->clk = devm_clk_get(&pdev->dev, NULL);
-       if (IS_ERR(pwm->clk))
+       /*
+        * All hardware variants need a source clock that is divided and
+        * then feeds the counter that defines the output wave form. In the
+        * device tree this clock is either unnamed or called "mod".
+        * Some variants (e.g. H6) need another clock to access the
+        * hardware registers; this is called "bus".
+        * So we request "mod" first (and ignore the corner case that a
+        * parent provides a "mod" clock while the right one would be the
+        * unnamed one of the PWM device) and if this is not found we fall
+        * back to the first clock of the PWM.
+        */
+       pwm->clk = devm_clk_get_optional(&pdev->dev, "mod");
+       if (IS_ERR(pwm->clk)) {
+               if (PTR_ERR(pwm->clk) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "get mod clock failed %pe\n",
+                               pwm->clk);
                return PTR_ERR(pwm->clk);
+       }
+
+       if (!pwm->clk) {
+               pwm->clk = devm_clk_get(&pdev->dev, NULL);
+               if (IS_ERR(pwm->clk)) {
+                       if (PTR_ERR(pwm->clk) != -EPROBE_DEFER)
+                               dev_err(&pdev->dev, "get unnamed clock failed %pe\n",
+                                       pwm->clk);
+                       return PTR_ERR(pwm->clk);
+               }
+       }
+
+       pwm->bus_clk = devm_clk_get_optional(&pdev->dev, "bus");
+       if (IS_ERR(pwm->bus_clk)) {
+               if (PTR_ERR(pwm->bus_clk) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "get bus clock failed %pe\n",
+                               pwm->bus_clk);
+               return PTR_ERR(pwm->bus_clk);
+       }
+
+       pwm->rst = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
+       if (IS_ERR(pwm->rst)) {
+               if (PTR_ERR(pwm->rst) != -EPROBE_DEFER)
+                       dev_err(&pdev->dev, "get reset failed %pe\n",
+                               pwm->rst);
+               return PTR_ERR(pwm->rst);
+       }
+
+       /* Deassert reset */
+       ret = reset_control_deassert(pwm->rst);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot deassert reset control: %pe\n",
+                       ERR_PTR(ret));
+               return ret;
+       }
+
+       /*
+        * We're keeping the bus clock on for the sake of simplicity.
+        * Actually it only needs to be on for hardware register accesses.
+        */
+       ret = clk_prepare_enable(pwm->bus_clk);
+       if (ret) {
+               dev_err(&pdev->dev, "cannot prepare and enable bus_clk %pe\n",
+                       ERR_PTR(ret));
+               goto err_bus;
+       }
 
        pwm->chip.dev = &pdev->dev;
        pwm->chip.ops = &sun4i_pwm_ops;
@@ -376,19 +487,34 @@ static int sun4i_pwm_probe(struct platform_device *pdev)
        ret = pwmchip_add(&pwm->chip);
        if (ret < 0) {
                dev_err(&pdev->dev, "failed to add PWM chip: %d\n", ret);
-               return ret;
+               goto err_pwm_add;
        }
 
        platform_set_drvdata(pdev, pwm);
 
        return 0;
+
+err_pwm_add:
+       clk_disable_unprepare(pwm->bus_clk);
+err_bus:
+       reset_control_assert(pwm->rst);
+
+       return ret;
 }
 
 static int sun4i_pwm_remove(struct platform_device *pdev)
 {
        struct sun4i_pwm_chip *pwm = platform_get_drvdata(pdev);
+       int ret;
+
+       ret = pwmchip_remove(&pwm->chip);
+       if (ret)
+               return ret;
+
+       clk_disable_unprepare(pwm->bus_clk);
+       reset_control_assert(pwm->rst);
 
-       return pwmchip_remove(&pwm->chip);
+       return 0;
 }
 
 static struct platform_driver sun4i_pwm_driver = {
index 97bfdd4..074a2ef 100644 (file)
@@ -209,6 +209,7 @@ config REGULATOR_BD71828
 config REGULATOR_BD718XX
        tristate "ROHM BD71837 Power Regulator"
        depends on MFD_ROHM_BD718XX
+       select REGULATOR_ROHM
        help
          This driver supports voltage regulators on ROHM BD71837 PMIC.
          This will enable support for the software controllable buck
@@ -823,6 +824,9 @@ config REGULATOR_RN5T618
          Say y here to support the regulators found on Ricoh RN5T567,
          RN5T618 or RC5T619 PMIC.
 
+config REGULATOR_ROHM
+       tristate
+
 config REGULATOR_RT5033
        tristate "Richtek RT5033 Regulators"
        depends on MFD_RT5033
index 07bc977..c0d6b96 100644 (file)
@@ -102,6 +102,7 @@ obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
 obj-$(CONFIG_REGULATOR_RC5T583)  += rc5t583-regulator.o
 obj-$(CONFIG_REGULATOR_RK808)   += rk808-regulator.o
 obj-$(CONFIG_REGULATOR_RN5T618) += rn5t618-regulator.o
+obj-$(CONFIG_REGULATOR_ROHM)   += rohm-regulator.o
 obj-$(CONFIG_REGULATOR_RT5033) += rt5033-regulator.o
 obj-$(CONFIG_REGULATOR_S2MPA01) += s2mpa01.o
 obj-$(CONFIG_REGULATOR_S2MPS11) += s2mps11.o
index 8f9b2d8..cf38728 100644 (file)
@@ -318,6 +318,7 @@ struct reg_init {
 };
 struct bd718xx_regulator_data {
        struct regulator_desc desc;
+       const struct rohm_dvs_config dvs;
        const struct reg_init init;
        const struct reg_init *additional_inits;
        int additional_init_amnt;
@@ -349,133 +350,15 @@ static const struct reg_init bd71837_ldo6_inits[] = {
        },
 };
 
-#define NUM_DVS_BUCKS 4
-
-struct of_dvs_setting {
-       const char *prop;
-       unsigned int reg;
-};
-
-static int set_dvs_levels(const struct of_dvs_setting *dvs,
-                         struct device_node *np,
-                         const struct regulator_desc *desc,
-                         struct regmap *regmap)
-{
-       int ret, i;
-       unsigned int uv;
-
-       ret = of_property_read_u32(np, dvs->prop, &uv);
-       if (ret) {
-               if (ret != -EINVAL)
-                       return ret;
-               return 0;
-       }
-
-       for (i = 0; i < desc->n_voltages; i++) {
-               ret = regulator_desc_list_voltage_linear_range(desc, i);
-               if (ret < 0)
-                       continue;
-               if (ret == uv) {
-                       i <<= ffs(desc->vsel_mask) - 1;
-                       ret = regmap_update_bits(regmap, dvs->reg,
-                                                DVS_BUCK_RUN_MASK, i);
-                       break;
-               }
-       }
-       return ret;
-}
-
-static int buck4_set_hw_dvs_levels(struct device_node *np,
+static int buck_set_hw_dvs_levels(struct device_node *np,
                            const struct regulator_desc *desc,
                            struct regulator_config *cfg)
 {
-       int ret, i;
-       const struct of_dvs_setting dvs[] = {
-               {
-                       .prop = "rohm,dvs-run-voltage",
-                       .reg = BD71837_REG_BUCK4_VOLT_RUN,
-               },
-       };
+       struct bd718xx_regulator_data *data;
 
-       for (i = 0; i < ARRAY_SIZE(dvs); i++) {
-               ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
-               if (ret)
-                       break;
-       }
-       return ret;
-}
-static int buck3_set_hw_dvs_levels(struct device_node *np,
-                           const struct regulator_desc *desc,
-                           struct regulator_config *cfg)
-{
-       int ret, i;
-       const struct of_dvs_setting dvs[] = {
-               {
-                       .prop = "rohm,dvs-run-voltage",
-                       .reg = BD71837_REG_BUCK3_VOLT_RUN,
-               },
-       };
+       data = container_of(desc, struct bd718xx_regulator_data, desc);
 
-       for (i = 0; i < ARRAY_SIZE(dvs); i++) {
-               ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
-               if (ret)
-                       break;
-       }
-       return ret;
-}
-
-static int buck2_set_hw_dvs_levels(struct device_node *np,
-                           const struct regulator_desc *desc,
-                           struct regulator_config *cfg)
-{
-       int ret, i;
-       const struct of_dvs_setting dvs[] = {
-               {
-                       .prop = "rohm,dvs-run-voltage",
-                       .reg = BD718XX_REG_BUCK2_VOLT_RUN,
-               },
-               {
-                       .prop = "rohm,dvs-idle-voltage",
-                       .reg = BD718XX_REG_BUCK2_VOLT_IDLE,
-               },
-       };
-
-
-
-       for (i = 0; i < ARRAY_SIZE(dvs); i++) {
-               ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
-               if (ret)
-                       break;
-       }
-       return ret;
-}
-
-static int buck1_set_hw_dvs_levels(struct device_node *np,
-                           const struct regulator_desc *desc,
-                           struct regulator_config *cfg)
-{
-       int ret, i;
-       const struct of_dvs_setting dvs[] = {
-               {
-                       .prop = "rohm,dvs-run-voltage",
-                       .reg = BD718XX_REG_BUCK1_VOLT_RUN,
-               },
-               {
-                       .prop = "rohm,dvs-idle-voltage",
-                       .reg = BD718XX_REG_BUCK1_VOLT_IDLE,
-               },
-               {
-                       .prop = "rohm,dvs-suspend-voltage",
-                       .reg = BD718XX_REG_BUCK1_VOLT_SUSP,
-               },
-       };
-
-       for (i = 0; i < ARRAY_SIZE(dvs); i++) {
-               ret = set_dvs_levels(&dvs[i], np, desc, cfg->regmap);
-               if (ret)
-                       break;
-       }
-       return ret;
+       return rohm_regulator_set_dvs_levels(&data->dvs, np, desc, cfg->regmap);
 }
 
 static const struct bd718xx_regulator_data bd71847_regulators[] = {
@@ -496,7 +379,17 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
                        .enable_reg = BD718XX_REG_BUCK1_CTRL,
                        .enable_mask = BD718XX_BUCK_EN,
                        .owner = THIS_MODULE,
-                       .of_parse_cb = buck1_set_hw_dvs_levels,
+                       .of_parse_cb = buck_set_hw_dvs_levels,
+               },
+               .dvs = {
+                       .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+                                    ROHM_DVS_LEVEL_SUSPEND,
+                       .run_reg = BD718XX_REG_BUCK1_VOLT_RUN,
+                       .run_mask = DVS_BUCK_RUN_MASK,
+                       .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE,
+                       .idle_mask = DVS_BUCK_RUN_MASK,
+                       .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP,
+                       .suspend_mask = DVS_BUCK_RUN_MASK,
                },
                .init = {
                        .reg = BD718XX_REG_BUCK1_CTRL,
@@ -520,7 +413,14 @@ static const struct bd718xx_regulator_data bd71847_regulators[] = {
                        .enable_reg = BD718XX_REG_BUCK2_CTRL,
                        .enable_mask = BD718XX_BUCK_EN,
                        .owner = THIS_MODULE,
-                       .of_parse_cb = buck2_set_hw_dvs_levels,
+                       .of_parse_cb = buck_set_hw_dvs_levels,
+               },
+               .dvs = {
+                       .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE,
+                       .run_reg = BD718XX_REG_BUCK2_VOLT_RUN,
+                       .run_mask = DVS_BUCK_RUN_MASK,
+                       .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE,
+                       .idle_mask = DVS_BUCK_RUN_MASK,
                },
                .init = {
                        .reg = BD718XX_REG_BUCK2_CTRL,
@@ -792,7 +692,17 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
                        .enable_reg = BD718XX_REG_BUCK1_CTRL,
                        .enable_mask = BD718XX_BUCK_EN,
                        .owner = THIS_MODULE,
-                       .of_parse_cb = buck1_set_hw_dvs_levels,
+                       .of_parse_cb = buck_set_hw_dvs_levels,
+               },
+               .dvs = {
+                       .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE |
+                                    ROHM_DVS_LEVEL_SUSPEND,
+                       .run_reg = BD718XX_REG_BUCK1_VOLT_RUN,
+                       .run_mask = DVS_BUCK_RUN_MASK,
+                       .idle_reg = BD718XX_REG_BUCK1_VOLT_IDLE,
+                       .idle_mask = DVS_BUCK_RUN_MASK,
+                       .suspend_reg = BD718XX_REG_BUCK1_VOLT_SUSP,
+                       .suspend_mask = DVS_BUCK_RUN_MASK,
                },
                .init = {
                        .reg = BD718XX_REG_BUCK1_CTRL,
@@ -816,7 +726,14 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
                        .enable_reg = BD718XX_REG_BUCK2_CTRL,
                        .enable_mask = BD718XX_BUCK_EN,
                        .owner = THIS_MODULE,
-                       .of_parse_cb = buck2_set_hw_dvs_levels,
+                       .of_parse_cb = buck_set_hw_dvs_levels,
+               },
+               .dvs = {
+                       .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE,
+                       .run_reg = BD718XX_REG_BUCK2_VOLT_RUN,
+                       .run_mask = DVS_BUCK_RUN_MASK,
+                       .idle_reg = BD718XX_REG_BUCK2_VOLT_IDLE,
+                       .idle_mask = DVS_BUCK_RUN_MASK,
                },
                .init = {
                        .reg = BD718XX_REG_BUCK2_CTRL,
@@ -840,7 +757,12 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
                        .enable_reg = BD71837_REG_BUCK3_CTRL,
                        .enable_mask = BD718XX_BUCK_EN,
                        .owner = THIS_MODULE,
-                       .of_parse_cb = buck3_set_hw_dvs_levels,
+                       .of_parse_cb = buck_set_hw_dvs_levels,
+               },
+               .dvs = {
+                       .level_map = ROHM_DVS_LEVEL_RUN,
+                       .run_reg = BD71837_REG_BUCK3_VOLT_RUN,
+                       .run_mask = DVS_BUCK_RUN_MASK,
                },
                .init = {
                        .reg = BD71837_REG_BUCK3_CTRL,
@@ -864,7 +786,12 @@ static const struct bd718xx_regulator_data bd71837_regulators[] = {
                        .enable_reg = BD71837_REG_BUCK4_CTRL,
                        .enable_mask = BD718XX_BUCK_EN,
                        .owner = THIS_MODULE,
-                       .of_parse_cb = buck4_set_hw_dvs_levels,
+                       .of_parse_cb = buck_set_hw_dvs_levels,
+               },
+               .dvs = {
+                       .level_map = ROHM_DVS_LEVEL_RUN,
+                       .run_reg = BD71837_REG_BUCK4_VOLT_RUN,
+                       .run_mask = DVS_BUCK_RUN_MASK,
                },
                .init = {
                        .reg = BD71837_REG_BUCK4_CTRL,
@@ -1150,6 +1077,7 @@ static int bd718xx_probe(struct platform_device *pdev)
        bool use_snvs;
        const struct bd718xx_regulator_data *reg_data;
        unsigned int num_reg_data;
+       enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
 
        mfd = dev_get_drvdata(pdev->dev.parent);
        if (!mfd) {
@@ -1158,7 +1086,7 @@ static int bd718xx_probe(struct platform_device *pdev)
                goto err;
        }
 
-       switch (mfd->chip.chip_type) {
+       switch (chip) {
        case ROHM_CHIP_TYPE_BD71837:
                reg_data = bd71837_regulators;
                num_reg_data = ARRAY_SIZE(bd71837_regulators);
@@ -1275,11 +1203,19 @@ err:
        return err;
 }
 
+static const struct platform_device_id bd718x7_pmic_id[] = {
+       { "bd71837-pmic", ROHM_CHIP_TYPE_BD71837 },
+       { "bd71847-pmic", ROHM_CHIP_TYPE_BD71847 },
+       { },
+};
+MODULE_DEVICE_TABLE(platform, bd718x7_pmic_id);
+
 static struct platform_driver bd718xx_regulator = {
        .driver = {
                .name = "bd718xx-pmic",
        },
        .probe = bd718xx_probe,
+       .id_table = bd718x7_pmic_id,
 };
 
 module_platform_driver(bd718xx_regulator);
diff --git a/drivers/regulator/rohm-regulator.c b/drivers/regulator/rohm-regulator.c
new file mode 100644 (file)
index 0000000..3990023
--- /dev/null
@@ -0,0 +1,95 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (C) 2020 ROHM Semiconductors
+
+#include <linux/errno.h>
+#include <linux/mfd/rohm-generic.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+static int set_dvs_level(const struct regulator_desc *desc,
+                        struct device_node *np, struct regmap *regmap,
+                        char *prop, unsigned int reg, unsigned int mask,
+                        unsigned int omask, unsigned int oreg)
+{
+       int ret, i;
+       uint32_t uv;
+
+       ret = of_property_read_u32(np, prop, &uv);
+       if (ret) {
+               if (ret != -EINVAL)
+                       return ret;
+               return 0;
+       }
+
+       if (uv == 0) {
+               if (omask)
+                       return regmap_update_bits(regmap, oreg, omask, 0);
+       }
+       for (i = 0; i < desc->n_voltages; i++) {
+               ret = regulator_desc_list_voltage_linear_range(desc, i);
+               if (ret < 0)
+                       continue;
+               if (ret == uv) {
+                       i <<= ffs(desc->vsel_mask) - 1;
+                       ret = regmap_update_bits(regmap, reg, mask, i);
+                       if (omask && !ret)
+                               ret = regmap_update_bits(regmap, oreg, omask,
+                                                        omask);
+                       break;
+               }
+       }
+       return ret;
+}
+
+int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,
+                         struct device_node *np,
+                         const struct regulator_desc *desc,
+                         struct regmap *regmap)
+{
+       int i, ret = 0;
+       char *prop;
+       unsigned int reg, mask, omask, oreg = desc->enable_reg;
+
+       for (i = 0; i < ROHM_DVS_LEVEL_MAX && !ret; i++) {
+               if (dvs->level_map & (1 << i)) {
+                       switch (i + 1) {
+                       case ROHM_DVS_LEVEL_RUN:
+                               prop = "rohm,dvs-run-voltage";
+                               reg = dvs->run_reg;
+                               mask = dvs->run_mask;
+                               omask = dvs->run_on_mask;
+                               break;
+                       case ROHM_DVS_LEVEL_IDLE:
+                               prop = "rohm,dvs-idle-voltage";
+                               reg = dvs->idle_reg;
+                               mask = dvs->idle_mask;
+                               omask = dvs->idle_on_mask;
+                               break;
+                       case ROHM_DVS_LEVEL_SUSPEND:
+                               prop = "rohm,dvs-suspend-voltage";
+                               reg = dvs->suspend_reg;
+                               mask = dvs->suspend_mask;
+                               omask = dvs->suspend_on_mask;
+                               break;
+                       case ROHM_DVS_LEVEL_LPSR:
+                               prop = "rohm,dvs-lpsr-voltage";
+                               reg = dvs->lpsr_reg;
+                               mask = dvs->lpsr_mask;
+                               omask = dvs->lpsr_on_mask;
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+                       ret = set_dvs_level(desc, np, regmap, prop, reg, mask,
+                                           omask, oreg);
+               }
+       }
+       return ret;
+}
+EXPORT_SYMBOL(rohm_regulator_set_dvs_levels);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
+MODULE_DESCRIPTION("Generic helpers for ROHM PMIC regulator drivers");
index 94afdde..de3862c 100644 (file)
@@ -23,6 +23,16 @@ config IMX_REMOTEPROC
 
          It's safe to say N here.
 
+config MTK_SCP
+       tristate "Mediatek SCP support"
+       depends on ARCH_MEDIATEK
+       select RPMSG_MTK_SCP
+       help
+         Say y here to support Mediatek's System Companion Processor (SCP) via
+         the remote processor framework.
+
+         It's safe to say N here.
+
 config OMAP_REMOTEPROC
        tristate "OMAP remoteproc support"
        depends on ARCH_OMAP4 || SOC_OMAP5
index 00f09e6..e30a1b1 100644 (file)
@@ -10,6 +10,7 @@ remoteproc-y                          += remoteproc_sysfs.o
 remoteproc-y                           += remoteproc_virtio.o
 remoteproc-y                           += remoteproc_elf_loader.o
 obj-$(CONFIG_IMX_REMOTEPROC)           += imx_rproc.o
+obj-$(CONFIG_MTK_SCP)                  += mtk_scp.o mtk_scp_ipi.o
 obj-$(CONFIG_OMAP_REMOTEPROC)          += omap_remoteproc.o
 obj-$(CONFIG_WKUP_M3_RPROC)            += wkup_m3_rproc.o
 obj-$(CONFIG_DA8XX_REMOTEPROC)         += da8xx_remoteproc.o
diff --git a/drivers/remoteproc/mtk_common.h b/drivers/remoteproc/mtk_common.h
new file mode 100644 (file)
index 0000000..deb2009
--- /dev/null
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef __RPROC_MTK_COMMON_H
+#define __RPROC_MTK_COMMON_H
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/remoteproc/mtk_scp.h>
+
+#define MT8183_SW_RSTN                 0x0
+#define MT8183_SW_RSTN_BIT             BIT(0)
+#define MT8183_SCP_TO_HOST             0x1C
+#define MT8183_SCP_IPC_INT_BIT         BIT(0)
+#define MT8183_SCP_WDT_INT_BIT         BIT(8)
+#define MT8183_HOST_TO_SCP             0x28
+#define MT8183_HOST_IPC_INT_BIT                BIT(0)
+#define MT8183_WDT_CFG                 0x84
+#define MT8183_SCP_CLK_SW_SEL          0x4000
+#define MT8183_SCP_CLK_DIV_SEL         0x4024
+#define MT8183_SCP_SRAM_PDN            0x402C
+#define MT8183_SCP_L1_SRAM_PD          0x4080
+#define MT8183_SCP_TCM_TAIL_SRAM_PD    0x4094
+
+#define MT8183_SCP_CACHE_SEL(x)                (0x14000 + (x) * 0x3000)
+#define MT8183_SCP_CACHE_CON           MT8183_SCP_CACHE_SEL(0)
+#define MT8183_SCP_DCACHE_CON          MT8183_SCP_CACHE_SEL(1)
+#define MT8183_SCP_CACHESIZE_8KB       BIT(8)
+#define MT8183_SCP_CACHE_CON_WAYEN     BIT(10)
+
+#define SCP_FW_VER_LEN                 32
+#define SCP_SHARE_BUFFER_SIZE          288
+
+struct scp_run {
+       u32 signaled;
+       s8 fw_ver[SCP_FW_VER_LEN];
+       u32 dec_capability;
+       u32 enc_capability;
+       wait_queue_head_t wq;
+};
+
+struct scp_ipi_desc {
+       /* For protecting handler. */
+       struct mutex lock;
+       scp_ipi_handler_t handler;
+       void *priv;
+};
+
+struct mtk_scp {
+       struct device *dev;
+       struct rproc *rproc;
+       struct clk *clk;
+       void __iomem *reg_base;
+       void __iomem *sram_base;
+       size_t sram_size;
+
+       struct mtk_share_obj __iomem *recv_buf;
+       struct mtk_share_obj __iomem *send_buf;
+       struct scp_run run;
+       /* To prevent multiple ipi_send run concurrently. */
+       struct mutex send_lock;
+       struct scp_ipi_desc ipi_desc[SCP_IPI_MAX];
+       bool ipi_id_ack[SCP_IPI_MAX];
+       wait_queue_head_t ack_wq;
+
+       void __iomem *cpu_addr;
+       phys_addr_t phys_addr;
+       size_t dram_size;
+
+       struct rproc_subdev *rpmsg_subdev;
+};
+
+/**
+ * struct mtk_share_obj - SRAM buffer shared with AP and SCP
+ *
+ * @id:                IPI id
+ * @len:       share buffer length
+ * @share_buf: share buffer data
+ */
+struct mtk_share_obj {
+       u32 id;
+       u32 len;
+       u8 share_buf[SCP_SHARE_BUFFER_SIZE];
+};
+
+void scp_memcpy_aligned(void __iomem *dst, const void *src, unsigned int len);
+void scp_ipi_lock(struct mtk_scp *scp, u32 id);
+void scp_ipi_unlock(struct mtk_scp *scp, u32 id);
+
+#endif
diff --git a/drivers/remoteproc/mtk_scp.c b/drivers/remoteproc/mtk_scp.c
new file mode 100644 (file)
index 0000000..7ccdf64
--- /dev/null
@@ -0,0 +1,663 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2019 MediaTek Inc.
+
+#include <asm/barrier.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/of_reserved_mem.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/remoteproc/mtk_scp.h>
+#include <linux/rpmsg/mtk_rpmsg.h>
+
+#include "mtk_common.h"
+#include "remoteproc_internal.h"
+
+#define MAX_CODE_SIZE 0x500000
+#define SCP_FW_END 0x7C000
+
+/**
+ * scp_get() - get a reference to SCP.
+ *
+ * @pdev:      the platform device of the module requesting SCP platform
+ *             device for using SCP API.
+ *
+ * Return: Return NULL if failed.  otherwise reference to SCP.
+ **/
+struct mtk_scp *scp_get(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *scp_node;
+       struct platform_device *scp_pdev;
+
+       scp_node = of_parse_phandle(dev->of_node, "mediatek,scp", 0);
+       if (!scp_node) {
+               dev_err(dev, "can't get SCP node\n");
+               return NULL;
+       }
+
+       scp_pdev = of_find_device_by_node(scp_node);
+       of_node_put(scp_node);
+
+       if (WARN_ON(!scp_pdev)) {
+               dev_err(dev, "SCP pdev failed\n");
+               return NULL;
+       }
+
+       return platform_get_drvdata(scp_pdev);
+}
+EXPORT_SYMBOL_GPL(scp_get);
+
+/**
+ * scp_put() - "free" the SCP
+ *
+ * @scp:       mtk_scp structure from scp_get().
+ **/
+void scp_put(struct mtk_scp *scp)
+{
+       put_device(scp->dev);
+}
+EXPORT_SYMBOL_GPL(scp_put);
+
+static void scp_wdt_handler(struct mtk_scp *scp, u32 scp_to_host)
+{
+       dev_err(scp->dev, "SCP watchdog timeout! 0x%x", scp_to_host);
+       rproc_report_crash(scp->rproc, RPROC_WATCHDOG);
+}
+
+static void scp_init_ipi_handler(void *data, unsigned int len, void *priv)
+{
+       struct mtk_scp *scp = (struct mtk_scp *)priv;
+       struct scp_run *run = (struct scp_run *)data;
+
+       scp->run.signaled = run->signaled;
+       strscpy(scp->run.fw_ver, run->fw_ver, SCP_FW_VER_LEN);
+       scp->run.dec_capability = run->dec_capability;
+       scp->run.enc_capability = run->enc_capability;
+       wake_up_interruptible(&scp->run.wq);
+}
+
+static void scp_ipi_handler(struct mtk_scp *scp)
+{
+       struct mtk_share_obj __iomem *rcv_obj = scp->recv_buf;
+       struct scp_ipi_desc *ipi_desc = scp->ipi_desc;
+       u8 tmp_data[SCP_SHARE_BUFFER_SIZE];
+       scp_ipi_handler_t handler;
+       u32 id = readl(&rcv_obj->id);
+       u32 len = readl(&rcv_obj->len);
+
+       if (len > SCP_SHARE_BUFFER_SIZE) {
+               dev_err(scp->dev, "ipi message too long (len %d, max %d)", len,
+                       SCP_SHARE_BUFFER_SIZE);
+               return;
+       }
+       if (id >= SCP_IPI_MAX) {
+               dev_err(scp->dev, "No such ipi id = %d\n", id);
+               return;
+       }
+
+       scp_ipi_lock(scp, id);
+       handler = ipi_desc[id].handler;
+       if (!handler) {
+               dev_err(scp->dev, "No such ipi id = %d\n", id);
+               scp_ipi_unlock(scp, id);
+               return;
+       }
+
+       memcpy_fromio(tmp_data, &rcv_obj->share_buf, len);
+       handler(tmp_data, len, ipi_desc[id].priv);
+       scp_ipi_unlock(scp, id);
+
+       scp->ipi_id_ack[id] = true;
+       wake_up(&scp->ack_wq);
+}
+
+static int scp_ipi_init(struct mtk_scp *scp)
+{
+       size_t send_offset = SCP_FW_END - sizeof(struct mtk_share_obj);
+       size_t recv_offset = send_offset - sizeof(struct mtk_share_obj);
+
+       /* Disable SCP to host interrupt */
+       writel(MT8183_SCP_IPC_INT_BIT, scp->reg_base + MT8183_SCP_TO_HOST);
+
+       /* shared buffer initialization */
+       scp->recv_buf =
+               (struct mtk_share_obj __iomem *)(scp->sram_base + recv_offset);
+       scp->send_buf =
+               (struct mtk_share_obj __iomem *)(scp->sram_base + send_offset);
+       memset_io(scp->recv_buf, 0, sizeof(scp->recv_buf));
+       memset_io(scp->send_buf, 0, sizeof(scp->send_buf));
+
+       return 0;
+}
+
+static void scp_reset_assert(const struct mtk_scp *scp)
+{
+       u32 val;
+
+       val = readl(scp->reg_base + MT8183_SW_RSTN);
+       val &= ~MT8183_SW_RSTN_BIT;
+       writel(val, scp->reg_base + MT8183_SW_RSTN);
+}
+
+static void scp_reset_deassert(const struct mtk_scp *scp)
+{
+       u32 val;
+
+       val = readl(scp->reg_base + MT8183_SW_RSTN);
+       val |= MT8183_SW_RSTN_BIT;
+       writel(val, scp->reg_base + MT8183_SW_RSTN);
+}
+
+static irqreturn_t scp_irq_handler(int irq, void *priv)
+{
+       struct mtk_scp *scp = priv;
+       u32 scp_to_host;
+       int ret;
+
+       ret = clk_prepare_enable(scp->clk);
+       if (ret) {
+               dev_err(scp->dev, "failed to enable clocks\n");
+               return IRQ_NONE;
+       }
+
+       scp_to_host = readl(scp->reg_base + MT8183_SCP_TO_HOST);
+       if (scp_to_host & MT8183_SCP_IPC_INT_BIT)
+               scp_ipi_handler(scp);
+       else
+               scp_wdt_handler(scp, scp_to_host);
+
+       /* SCP won't send another interrupt until we set SCP_TO_HOST to 0. */
+       writel(MT8183_SCP_IPC_INT_BIT | MT8183_SCP_WDT_INT_BIT,
+              scp->reg_base + MT8183_SCP_TO_HOST);
+       clk_disable_unprepare(scp->clk);
+
+       return IRQ_HANDLED;
+}
+
+static int scp_elf_load_segments(struct rproc *rproc, const struct firmware *fw)
+{
+       struct device *dev = &rproc->dev;
+       struct elf32_hdr *ehdr;
+       struct elf32_phdr *phdr;
+       int i, ret = 0;
+       const u8 *elf_data = fw->data;
+
+       ehdr = (struct elf32_hdr *)elf_data;
+       phdr = (struct elf32_phdr *)(elf_data + ehdr->e_phoff);
+
+       /* go through the available ELF segments */
+       for (i = 0; i < ehdr->e_phnum; i++, phdr++) {
+               u32 da = phdr->p_paddr;
+               u32 memsz = phdr->p_memsz;
+               u32 filesz = phdr->p_filesz;
+               u32 offset = phdr->p_offset;
+               void __iomem *ptr;
+
+               if (phdr->p_type != PT_LOAD)
+                       continue;
+
+               dev_dbg(dev, "phdr: type %d da 0x%x memsz 0x%x filesz 0x%x\n",
+                       phdr->p_type, da, memsz, filesz);
+
+               if (filesz > memsz) {
+                       dev_err(dev, "bad phdr filesz 0x%x memsz 0x%x\n",
+                               filesz, memsz);
+                       ret = -EINVAL;
+                       break;
+               }
+
+               if (offset + filesz > fw->size) {
+                       dev_err(dev, "truncated fw: need 0x%x avail 0x%zx\n",
+                               offset + filesz, fw->size);
+                       ret = -EINVAL;
+                       break;
+               }
+
+               /* grab the kernel address for this device address */
+               ptr = (void __iomem *)rproc_da_to_va(rproc, da, memsz);
+               if (!ptr) {
+                       dev_err(dev, "bad phdr da 0x%x mem 0x%x\n", da, memsz);
+                       ret = -EINVAL;
+                       break;
+               }
+
+               /* put the segment where the remote processor expects it */
+               if (phdr->p_filesz)
+                       scp_memcpy_aligned(ptr, elf_data + phdr->p_offset,
+                                          filesz);
+       }
+
+       return ret;
+}
+
+static int scp_load(struct rproc *rproc, const struct firmware *fw)
+{
+       const struct mtk_scp *scp = rproc->priv;
+       struct device *dev = scp->dev;
+       int ret;
+
+       ret = clk_prepare_enable(scp->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable clocks\n");
+               return ret;
+       }
+
+       /* Hold SCP in reset while loading FW. */
+       scp_reset_assert(scp);
+
+       /* Reset clocks before loading FW */
+       writel(0x0, scp->reg_base + MT8183_SCP_CLK_SW_SEL);
+       writel(0x0, scp->reg_base + MT8183_SCP_CLK_DIV_SEL);
+
+       /* Initialize TCM before loading FW. */
+       writel(0x0, scp->reg_base + MT8183_SCP_L1_SRAM_PD);
+       writel(0x0, scp->reg_base + MT8183_SCP_TCM_TAIL_SRAM_PD);
+
+       /* Turn on the power of SCP's SRAM before using it. */
+       writel(0x0, scp->reg_base + MT8183_SCP_SRAM_PDN);
+
+       /*
+        * Set I-cache and D-cache size before loading SCP FW.
+        * SCP SRAM logical address may change when cache size setting differs.
+        */
+       writel(MT8183_SCP_CACHE_CON_WAYEN | MT8183_SCP_CACHESIZE_8KB,
+              scp->reg_base + MT8183_SCP_CACHE_CON);
+       writel(MT8183_SCP_CACHESIZE_8KB, scp->reg_base + MT8183_SCP_DCACHE_CON);
+
+       ret = scp_elf_load_segments(rproc, fw);
+       clk_disable_unprepare(scp->clk);
+
+       return ret;
+}
+
+static int scp_start(struct rproc *rproc)
+{
+       struct mtk_scp *scp = (struct mtk_scp *)rproc->priv;
+       struct device *dev = scp->dev;
+       struct scp_run *run = &scp->run;
+       int ret;
+
+       ret = clk_prepare_enable(scp->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable clocks\n");
+               return ret;
+       }
+
+       run->signaled = false;
+
+       scp_reset_deassert(scp);
+
+       ret = wait_event_interruptible_timeout(
+                                       run->wq,
+                                       run->signaled,
+                                       msecs_to_jiffies(2000));
+
+       if (ret == 0) {
+               dev_err(dev, "wait SCP initialization timeout!\n");
+               ret = -ETIME;
+               goto stop;
+       }
+       if (ret == -ERESTARTSYS) {
+               dev_err(dev, "wait SCP interrupted by a signal!\n");
+               goto stop;
+       }
+       clk_disable_unprepare(scp->clk);
+       dev_info(dev, "SCP is ready. FW version %s\n", run->fw_ver);
+
+       return 0;
+
+stop:
+       scp_reset_assert(scp);
+       clk_disable_unprepare(scp->clk);
+       return ret;
+}
+
+static void *scp_da_to_va(struct rproc *rproc, u64 da, int len)
+{
+       struct mtk_scp *scp = (struct mtk_scp *)rproc->priv;
+       int offset;
+
+       if (da < scp->sram_size) {
+               offset = da;
+               if (offset >= 0 && (offset + len) < scp->sram_size)
+                       return (void __force *)scp->sram_base + offset;
+       } else {
+               offset = da - scp->phys_addr;
+               if (offset >= 0 && (offset + len) < scp->dram_size)
+                       return (void __force *)scp->cpu_addr + offset;
+       }
+
+       return NULL;
+}
+
+static int scp_stop(struct rproc *rproc)
+{
+       struct mtk_scp *scp = (struct mtk_scp *)rproc->priv;
+       int ret;
+
+       ret = clk_prepare_enable(scp->clk);
+       if (ret) {
+               dev_err(scp->dev, "failed to enable clocks\n");
+               return ret;
+       }
+
+       scp_reset_assert(scp);
+       /* Disable SCP watchdog */
+       writel(0, scp->reg_base + MT8183_WDT_CFG);
+       clk_disable_unprepare(scp->clk);
+
+       return 0;
+}
+
+static const struct rproc_ops scp_ops = {
+       .start          = scp_start,
+       .stop           = scp_stop,
+       .load           = scp_load,
+       .da_to_va       = scp_da_to_va,
+};
+
+/**
+ * scp_get_device() - get device struct of SCP
+ *
+ * @scp:       mtk_scp structure
+ **/
+struct device *scp_get_device(struct mtk_scp *scp)
+{
+       return scp->dev;
+}
+EXPORT_SYMBOL_GPL(scp_get_device);
+
+/**
+ * scp_get_rproc() - get rproc struct of SCP
+ *
+ * @scp:       mtk_scp structure
+ **/
+struct rproc *scp_get_rproc(struct mtk_scp *scp)
+{
+       return scp->rproc;
+}
+EXPORT_SYMBOL_GPL(scp_get_rproc);
+
+/**
+ * scp_get_vdec_hw_capa() - get video decoder hardware capability
+ *
+ * @scp:       mtk_scp structure
+ *
+ * Return: video decoder hardware capability
+ **/
+unsigned int scp_get_vdec_hw_capa(struct mtk_scp *scp)
+{
+       return scp->run.dec_capability;
+}
+EXPORT_SYMBOL_GPL(scp_get_vdec_hw_capa);
+
+/**
+ * scp_get_venc_hw_capa() - get video encoder hardware capability
+ *
+ * @scp:       mtk_scp structure
+ *
+ * Return: video encoder hardware capability
+ **/
+unsigned int scp_get_venc_hw_capa(struct mtk_scp *scp)
+{
+       return scp->run.enc_capability;
+}
+EXPORT_SYMBOL_GPL(scp_get_venc_hw_capa);
+
+/**
+ * scp_mapping_dm_addr() - Mapping SRAM/DRAM to kernel virtual address
+ *
+ * @scp:       mtk_scp structure
+ * @mem_addr:  SCP views memory address
+ *
+ * Mapping the SCP's SRAM address /
+ * DMEM (Data Extended Memory) memory address /
+ * Working buffer memory address to
+ * kernel virtual address.
+ *
+ * Return: Return ERR_PTR(-EINVAL) if mapping failed,
+ * otherwise the mapped kernel virtual address
+ **/
+void *scp_mapping_dm_addr(struct mtk_scp *scp, u32 mem_addr)
+{
+       void *ptr;
+
+       ptr = scp_da_to_va(scp->rproc, mem_addr, 0);
+       if (!ptr)
+               return ERR_PTR(-EINVAL);
+
+       return ptr;
+}
+EXPORT_SYMBOL_GPL(scp_mapping_dm_addr);
+
+static int scp_map_memory_region(struct mtk_scp *scp)
+{
+       int ret;
+
+       ret = of_reserved_mem_device_init(scp->dev);
+       if (ret) {
+               dev_err(scp->dev, "failed to assign memory-region: %d\n", ret);
+               return -ENOMEM;
+       }
+
+       /* Reserved SCP code size */
+       scp->dram_size = MAX_CODE_SIZE;
+       scp->cpu_addr = dma_alloc_coherent(scp->dev, scp->dram_size,
+                                          &scp->phys_addr, GFP_KERNEL);
+       if (!scp->cpu_addr)
+               return -ENOMEM;
+
+       return 0;
+}
+
+static void scp_unmap_memory_region(struct mtk_scp *scp)
+{
+       dma_free_coherent(scp->dev, scp->dram_size, scp->cpu_addr,
+                         scp->phys_addr);
+       of_reserved_mem_device_release(scp->dev);
+}
+
+static int scp_register_ipi(struct platform_device *pdev, u32 id,
+                           ipi_handler_t handler, void *priv)
+{
+       struct mtk_scp *scp = platform_get_drvdata(pdev);
+
+       return scp_ipi_register(scp, id, handler, priv);
+}
+
+static void scp_unregister_ipi(struct platform_device *pdev, u32 id)
+{
+       struct mtk_scp *scp = platform_get_drvdata(pdev);
+
+       scp_ipi_unregister(scp, id);
+}
+
+static int scp_send_ipi(struct platform_device *pdev, u32 id, void *buf,
+                       unsigned int len, unsigned int wait)
+{
+       struct mtk_scp *scp = platform_get_drvdata(pdev);
+
+       return scp_ipi_send(scp, id, buf, len, wait);
+}
+
+static struct mtk_rpmsg_info mtk_scp_rpmsg_info = {
+       .send_ipi = scp_send_ipi,
+       .register_ipi = scp_register_ipi,
+       .unregister_ipi = scp_unregister_ipi,
+       .ns_ipi_id = SCP_IPI_NS_SERVICE,
+};
+
+static void scp_add_rpmsg_subdev(struct mtk_scp *scp)
+{
+       scp->rpmsg_subdev =
+               mtk_rpmsg_create_rproc_subdev(to_platform_device(scp->dev),
+                                             &mtk_scp_rpmsg_info);
+       if (scp->rpmsg_subdev)
+               rproc_add_subdev(scp->rproc, scp->rpmsg_subdev);
+}
+
+static void scp_remove_rpmsg_subdev(struct mtk_scp *scp)
+{
+       if (scp->rpmsg_subdev) {
+               rproc_remove_subdev(scp->rproc, scp->rpmsg_subdev);
+               mtk_rpmsg_destroy_rproc_subdev(scp->rpmsg_subdev);
+               scp->rpmsg_subdev = NULL;
+       }
+}
+
+static int scp_probe(struct platform_device *pdev)
+{
+       struct device *dev = &pdev->dev;
+       struct device_node *np = dev->of_node;
+       struct mtk_scp *scp;
+       struct rproc *rproc;
+       struct resource *res;
+       char *fw_name = "scp.img";
+       int ret, i;
+
+       rproc = rproc_alloc(dev,
+                           np->name,
+                           &scp_ops,
+                           fw_name,
+                           sizeof(*scp));
+       if (!rproc) {
+               dev_err(dev, "unable to allocate remoteproc\n");
+               return -ENOMEM;
+       }
+
+       scp = (struct mtk_scp *)rproc->priv;
+       scp->rproc = rproc;
+       scp->dev = dev;
+       platform_set_drvdata(pdev, scp);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
+       scp->sram_base = devm_ioremap_resource(dev, res);
+       if (IS_ERR((__force void *)scp->sram_base)) {
+               dev_err(dev, "Failed to parse and map sram memory\n");
+               ret = PTR_ERR((__force void *)scp->sram_base);
+               goto free_rproc;
+       }
+       scp->sram_size = resource_size(res);
+
+       mutex_init(&scp->send_lock);
+       for (i = 0; i < SCP_IPI_MAX; i++)
+               mutex_init(&scp->ipi_desc[i].lock);
+
+       res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
+       scp->reg_base = devm_ioremap_resource(dev, res);
+       if (IS_ERR((__force void *)scp->reg_base)) {
+               dev_err(dev, "Failed to parse and map cfg memory\n");
+               ret = PTR_ERR((__force void *)scp->reg_base);
+               goto destroy_mutex;
+       }
+
+       ret = scp_map_memory_region(scp);
+       if (ret)
+               goto destroy_mutex;
+
+       scp->clk = devm_clk_get(dev, "main");
+       if (IS_ERR(scp->clk)) {
+               dev_err(dev, "Failed to get clock\n");
+               ret = PTR_ERR(scp->clk);
+               goto release_dev_mem;
+       }
+
+       ret = clk_prepare_enable(scp->clk);
+       if (ret) {
+               dev_err(dev, "failed to enable clocks\n");
+               goto release_dev_mem;
+       }
+
+       ret = scp_ipi_init(scp);
+       clk_disable_unprepare(scp->clk);
+       if (ret) {
+               dev_err(dev, "Failed to init ipi\n");
+               goto release_dev_mem;
+       }
+
+       /* register SCP initialization IPI */
+       ret = scp_ipi_register(scp, SCP_IPI_INIT, scp_init_ipi_handler, scp);
+       if (ret) {
+               dev_err(dev, "Failed to register IPI_SCP_INIT\n");
+               goto release_dev_mem;
+       }
+
+       init_waitqueue_head(&scp->run.wq);
+       init_waitqueue_head(&scp->ack_wq);
+
+       scp_add_rpmsg_subdev(scp);
+
+       ret = devm_request_threaded_irq(dev, platform_get_irq(pdev, 0), NULL,
+                                       scp_irq_handler, IRQF_ONESHOT,
+                                       pdev->name, scp);
+
+       if (ret) {
+               dev_err(dev, "failed to request irq\n");
+               goto remove_subdev;
+       }
+
+       ret = rproc_add(rproc);
+       if (ret)
+               goto remove_subdev;
+
+       return 0;
+
+remove_subdev:
+       scp_remove_rpmsg_subdev(scp);
+       scp_ipi_unregister(scp, SCP_IPI_INIT);
+release_dev_mem:
+       scp_unmap_memory_region(scp);
+destroy_mutex:
+       for (i = 0; i < SCP_IPI_MAX; i++)
+               mutex_destroy(&scp->ipi_desc[i].lock);
+       mutex_destroy(&scp->send_lock);
+free_rproc:
+       rproc_free(rproc);
+
+       return ret;
+}
+
+static int scp_remove(struct platform_device *pdev)
+{
+       struct mtk_scp *scp = platform_get_drvdata(pdev);
+       int i;
+
+       rproc_del(scp->rproc);
+       scp_remove_rpmsg_subdev(scp);
+       scp_ipi_unregister(scp, SCP_IPI_INIT);
+       scp_unmap_memory_region(scp);
+       for (i = 0; i < SCP_IPI_MAX; i++)
+               mutex_destroy(&scp->ipi_desc[i].lock);
+       mutex_destroy(&scp->send_lock);
+       rproc_free(scp->rproc);
+
+       return 0;
+}
+
+static const struct of_device_id mtk_scp_of_match[] = {
+       { .compatible = "mediatek,mt8183-scp"},
+       {},
+};
+MODULE_DEVICE_TABLE(of, mtk_scp_of_match);
+
+static struct platform_driver mtk_scp_driver = {
+       .probe = scp_probe,
+       .remove = scp_remove,
+       .driver = {
+               .name = "mtk-scp",
+               .of_match_table = of_match_ptr(mtk_scp_of_match),
+       },
+};
+
+module_platform_driver(mtk_scp_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MediaTek SCP control driver");
diff --git a/drivers/remoteproc/mtk_scp_ipi.c b/drivers/remoteproc/mtk_scp_ipi.c
new file mode 100644 (file)
index 0000000..3d3d872
--- /dev/null
@@ -0,0 +1,219 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright (c) 2019 MediaTek Inc.
+
+#include <asm/barrier.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc/mtk_scp.h>
+
+#include "mtk_common.h"
+
+/**
+ * scp_ipi_register() - register an ipi function
+ *
+ * @scp:       mtk_scp structure
+ * @id:                IPI ID
+ * @handler:   IPI handler
+ * @priv:      private data for IPI handler
+ *
+ * Register an ipi function to receive ipi interrupt from SCP.
+ *
+ * Returns 0 if ipi registers successfully, -error on error.
+ */
+int scp_ipi_register(struct mtk_scp *scp,
+                    u32 id,
+                    scp_ipi_handler_t handler,
+                    void *priv)
+{
+       if (!scp) {
+               dev_err(scp->dev, "scp device is not ready\n");
+               return -EPROBE_DEFER;
+       }
+
+       if (WARN_ON(id >= SCP_IPI_MAX) || WARN_ON(handler == NULL))
+               return -EINVAL;
+
+       scp_ipi_lock(scp, id);
+       scp->ipi_desc[id].handler = handler;
+       scp->ipi_desc[id].priv = priv;
+       scp_ipi_unlock(scp, id);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(scp_ipi_register);
+
+/**
+ * scp_ipi_unregister() - unregister an ipi function
+ *
+ * @scp:       mtk_scp structure
+ * @id:                IPI ID
+ *
+ * Unregister an ipi function to receive ipi interrupt from SCP.
+ */
+void scp_ipi_unregister(struct mtk_scp *scp, u32 id)
+{
+       if (!scp)
+               return;
+
+       if (WARN_ON(id >= SCP_IPI_MAX))
+               return;
+
+       scp_ipi_lock(scp, id);
+       scp->ipi_desc[id].handler = NULL;
+       scp->ipi_desc[id].priv = NULL;
+       scp_ipi_unlock(scp, id);
+}
+EXPORT_SYMBOL_GPL(scp_ipi_unregister);
+
+/*
+ * scp_memcpy_aligned() - Copy src to dst, where dst is in SCP SRAM region.
+ *
+ * @dst:       Pointer to the destination buffer, should be in SCP SRAM region.
+ * @src:       Pointer to the source buffer.
+ * @len:       Length of the source buffer to be copied.
+ *
+ * Since AP access of SCP SRAM don't support byte write, this always write a
+ * full word at a time, and may cause some extra bytes to be written at the
+ * beginning & ending of dst.
+ */
+void scp_memcpy_aligned(void __iomem *dst, const void *src, unsigned int len)
+{
+       void __iomem *ptr;
+       u32 val;
+       unsigned int i = 0, remain;
+
+       if (!IS_ALIGNED((unsigned long)dst, 4)) {
+               ptr = (void __iomem *)ALIGN_DOWN((unsigned long)dst, 4);
+               i = 4 - (dst - ptr);
+               val = readl_relaxed(ptr);
+               memcpy((u8 *)&val + (4 - i), src, i);
+               writel_relaxed(val, ptr);
+       }
+
+       __iowrite32_copy(dst + i, src + i, (len - i) / 4);
+       remain = (len - i) % 4;
+
+       if (remain > 0) {
+               val = readl_relaxed(dst + len - remain);
+               memcpy(&val, src + len - remain, remain);
+               writel_relaxed(val, dst + len - remain);
+       }
+}
+EXPORT_SYMBOL_GPL(scp_memcpy_aligned);
+
+/**
+ * scp_ipi_lock() - Lock before operations of an IPI ID
+ *
+ * @scp:       mtk_scp structure
+ * @id:                IPI ID
+ *
+ * Note: This should not be used by drivers other than mtk_scp.
+ */
+void scp_ipi_lock(struct mtk_scp *scp, u32 id)
+{
+       if (WARN_ON(id >= SCP_IPI_MAX))
+               return;
+       mutex_lock(&scp->ipi_desc[id].lock);
+}
+EXPORT_SYMBOL_GPL(scp_ipi_lock);
+
+/**
+ * scp_ipi_lock() - Unlock after operations of an IPI ID
+ *
+ * @scp:       mtk_scp structure
+ * @id:                IPI ID
+ *
+ * Note: This should not be used by drivers other than mtk_scp.
+ */
+void scp_ipi_unlock(struct mtk_scp *scp, u32 id)
+{
+       if (WARN_ON(id >= SCP_IPI_MAX))
+               return;
+       mutex_unlock(&scp->ipi_desc[id].lock);
+}
+EXPORT_SYMBOL_GPL(scp_ipi_unlock);
+
+/**
+ * scp_ipi_send() - send data from AP to scp.
+ *
+ * @scp:       mtk_scp structure
+ * @id:                IPI ID
+ * @buf:       the data buffer
+ * @len:       the data buffer length
+ * @wait:      number of msecs to wait for ack. 0 to skip waiting.
+ *
+ * This function is thread-safe. When this function returns,
+ * SCP has received the data and starts the processing.
+ * When the processing completes, IPI handler registered
+ * by scp_ipi_register will be called in interrupt context.
+ *
+ * Returns 0 if sending data successfully, -error on error.
+ **/
+int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len,
+                unsigned int wait)
+{
+       struct mtk_share_obj __iomem *send_obj = scp->send_buf;
+       unsigned long timeout;
+       int ret;
+
+       if (WARN_ON(id <= SCP_IPI_INIT) || WARN_ON(id >= SCP_IPI_MAX) ||
+           WARN_ON(id == SCP_IPI_NS_SERVICE) ||
+           WARN_ON(len > sizeof(send_obj->share_buf)) || WARN_ON(!buf))
+               return -EINVAL;
+
+       mutex_lock(&scp->send_lock);
+
+       ret = clk_prepare_enable(scp->clk);
+       if (ret) {
+               dev_err(scp->dev, "failed to enable clock\n");
+               goto unlock_mutex;
+       }
+
+        /* Wait until SCP receives the last command */
+       timeout = jiffies + msecs_to_jiffies(2000);
+       do {
+               if (time_after(jiffies, timeout)) {
+                       dev_err(scp->dev, "%s: IPI timeout!\n", __func__);
+                       ret = -ETIMEDOUT;
+                       goto clock_disable;
+               }
+       } while (readl(scp->reg_base + MT8183_HOST_TO_SCP));
+
+       scp_memcpy_aligned(send_obj->share_buf, buf, len);
+
+       writel(len, &send_obj->len);
+       writel(id, &send_obj->id);
+
+       scp->ipi_id_ack[id] = false;
+       /* send the command to SCP */
+       writel(MT8183_HOST_IPC_INT_BIT, scp->reg_base + MT8183_HOST_TO_SCP);
+
+       if (wait) {
+               /* wait for SCP's ACK */
+               timeout = msecs_to_jiffies(wait);
+               ret = wait_event_timeout(scp->ack_wq,
+                                        scp->ipi_id_ack[id],
+                                        timeout);
+               scp->ipi_id_ack[id] = false;
+               if (WARN(!ret, "scp ipi %d ack time out !", id))
+                       ret = -EIO;
+               else
+                       ret = 0;
+       }
+
+clock_disable:
+       clk_disable_unprepare(scp->clk);
+unlock_mutex:
+       mutex_unlock(&scp->send_lock);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(scp_ipi_send);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MediaTek scp IPI interface");
index 471128a..a1cc9cb 100644 (file)
 #define AXI_HALTREQ_REG                        0x0
 #define AXI_HALTACK_REG                        0x4
 #define AXI_IDLE_REG                   0x8
+#define NAV_AXI_HALTREQ_BIT            BIT(0)
+#define NAV_AXI_HALTACK_BIT            BIT(1)
+#define NAV_AXI_IDLE_BIT               BIT(2)
+#define AXI_GATING_VALID_OVERRIDE      BIT(0)
 
-#define HALT_ACK_TIMEOUT_MS            100
+#define HALT_ACK_TIMEOUT_US            100000
+#define NAV_HALT_ACK_TIMEOUT_US                200
 
 /* QDSP6SS_RESET */
 #define Q6SS_STOP_CORE                 BIT(0)
 #define Q6SS_CORE_ARES                 BIT(1)
 #define Q6SS_BUS_ARES_ENABLE           BIT(2)
 
+/* QDSP6SS CBCR */
+#define Q6SS_CBCR_CLKEN                        BIT(0)
+#define Q6SS_CBCR_CLKOFF               BIT(31)
+#define Q6SS_CBCR_TIMEOUT_US           200
+
 /* QDSP6SS_GFMUX_CTL */
 #define Q6SS_CLK_ENABLE                        BIT(1)
 
 #define QDSP6v56_BHS_ON                BIT(24)
 #define QDSP6v56_CLAMP_WL              BIT(21)
 #define QDSP6v56_CLAMP_QMC_MEM         BIT(22)
-#define HALT_CHECK_MAX_LOOPS           200
 #define QDSP6SS_XO_CBCR                0x0038
 #define QDSP6SS_ACC_OVERRIDE_VAL               0x20
 
 /* QDSP6v65 parameters */
+#define QDSP6SS_CORE_CBCR              0x20
 #define QDSP6SS_SLEEP                   0x3C
 #define QDSP6SS_BOOT_CORE_START         0x400
 #define QDSP6SS_BOOT_CMD                0x404
-#define SLEEP_CHECK_MAX_LOOPS           200
+#define QDSP6SS_BOOT_STATUS            0x408
+#define BOOT_STATUS_TIMEOUT_US         200
 #define BOOT_FSM_TIMEOUT                10000
 
 struct reg_info {
@@ -131,6 +142,7 @@ struct rproc_hexagon_res {
        int version;
        bool need_mem_protection;
        bool has_alt_reset;
+       bool has_halt_nav;
 };
 
 struct q6v5 {
@@ -141,9 +153,14 @@ struct q6v5 {
        void __iomem *rmb_base;
 
        struct regmap *halt_map;
+       struct regmap *halt_nav_map;
+       struct regmap *conn_map;
+
        u32 halt_q6;
        u32 halt_modem;
        u32 halt_nc;
+       u32 halt_nav;
+       u32 conn_box;
 
        struct reset_control *mss_restart;
        struct reset_control *pdc_reset;
@@ -187,6 +204,7 @@ struct q6v5 {
        struct qcom_sysmon *sysmon;
        bool need_mem_protection;
        bool has_alt_reset;
+       bool has_halt_nav;
        int mpss_perm;
        int mba_perm;
        const char *hexagon_mdt_image;
@@ -198,6 +216,7 @@ enum {
        MSS_MSM8974,
        MSS_MSM8996,
        MSS_MSM8998,
+       MSS_SC7180,
        MSS_SDM845,
 };
 
@@ -396,6 +415,26 @@ static int q6v5_reset_assert(struct q6v5 *qproc)
                reset_control_assert(qproc->pdc_reset);
                ret = reset_control_reset(qproc->mss_restart);
                reset_control_deassert(qproc->pdc_reset);
+       } else if (qproc->has_halt_nav) {
+               /*
+                * When the AXI pipeline is being reset with the Q6 modem partly
+                * operational there is possibility of AXI valid signal to
+                * glitch, leading to spurious transactions and Q6 hangs. A work
+                * around is employed by asserting the AXI_GATING_VALID_OVERRIDE
+                * BIT before triggering Q6 MSS reset. Both the HALTREQ and
+                * AXI_GATING_VALID_OVERRIDE are withdrawn post MSS assert
+                * followed by a MSS deassert, while holding the PDC reset.
+                */
+               reset_control_assert(qproc->pdc_reset);
+               regmap_update_bits(qproc->conn_map, qproc->conn_box,
+                                  AXI_GATING_VALID_OVERRIDE, 1);
+               regmap_update_bits(qproc->halt_nav_map, qproc->halt_nav,
+                                  NAV_AXI_HALTREQ_BIT, 0);
+               reset_control_assert(qproc->mss_restart);
+               reset_control_deassert(qproc->pdc_reset);
+               regmap_update_bits(qproc->conn_map, qproc->conn_box,
+                                  AXI_GATING_VALID_OVERRIDE, 0);
+               ret = reset_control_deassert(qproc->mss_restart);
        } else {
                ret = reset_control_assert(qproc->mss_restart);
        }
@@ -413,6 +452,8 @@ static int q6v5_reset_deassert(struct q6v5 *qproc)
                ret = reset_control_reset(qproc->mss_restart);
                writel(0, qproc->rmb_base + RMB_MBA_ALT_RESET);
                reset_control_deassert(qproc->pdc_reset);
+       } else if (qproc->has_halt_nav) {
+               ret = reset_control_reset(qproc->mss_restart);
        } else {
                ret = reset_control_deassert(qproc->mss_restart);
        }
@@ -474,12 +515,12 @@ static int q6v5proc_reset(struct q6v5 *qproc)
 
        if (qproc->version == MSS_SDM845) {
                val = readl(qproc->reg_base + QDSP6SS_SLEEP);
-               val |= 0x1;
+               val |= Q6SS_CBCR_CLKEN;
                writel(val, qproc->reg_base + QDSP6SS_SLEEP);
 
                ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
-                                        val, !(val & BIT(31)), 1,
-                                        SLEEP_CHECK_MAX_LOOPS);
+                                        val, !(val & Q6SS_CBCR_CLKOFF), 1,
+                                        Q6SS_CBCR_TIMEOUT_US);
                if (ret) {
                        dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
                        return -ETIMEDOUT;
@@ -500,6 +541,54 @@ static int q6v5proc_reset(struct q6v5 *qproc)
                }
 
                goto pbl_wait;
+       } else if (qproc->version == MSS_SC7180) {
+               val = readl(qproc->reg_base + QDSP6SS_SLEEP);
+               val |= Q6SS_CBCR_CLKEN;
+               writel(val, qproc->reg_base + QDSP6SS_SLEEP);
+
+               ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_SLEEP,
+                                        val, !(val & Q6SS_CBCR_CLKOFF), 1,
+                                        Q6SS_CBCR_TIMEOUT_US);
+               if (ret) {
+                       dev_err(qproc->dev, "QDSP6SS Sleep clock timed out\n");
+                       return -ETIMEDOUT;
+               }
+
+               /* Turn on the XO clock needed for PLL setup */
+               val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
+               val |= Q6SS_CBCR_CLKEN;
+               writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
+
+               ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
+                                        val, !(val & Q6SS_CBCR_CLKOFF), 1,
+                                        Q6SS_CBCR_TIMEOUT_US);
+               if (ret) {
+                       dev_err(qproc->dev, "QDSP6SS XO clock timed out\n");
+                       return -ETIMEDOUT;
+               }
+
+               /* Configure Q6 core CBCR to auto-enable after reset sequence */
+               val = readl(qproc->reg_base + QDSP6SS_CORE_CBCR);
+               val |= Q6SS_CBCR_CLKEN;
+               writel(val, qproc->reg_base + QDSP6SS_CORE_CBCR);
+
+               /* De-assert the Q6 stop core signal */
+               writel(1, qproc->reg_base + QDSP6SS_BOOT_CORE_START);
+
+               /* Trigger the boot FSM to start the Q6 out-of-reset sequence */
+               writel(1, qproc->reg_base + QDSP6SS_BOOT_CMD);
+
+               /* Poll the QDSP6SS_BOOT_STATUS for FSM completion */
+               ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_BOOT_STATUS,
+                                        val, (val & BIT(0)) != 0, 1,
+                                        BOOT_STATUS_TIMEOUT_US);
+               if (ret) {
+                       dev_err(qproc->dev, "Boot FSM failed to complete.\n");
+                       /* Reset the modem so that boot FSM is in reset state */
+                       q6v5_reset_deassert(qproc);
+                       return ret;
+               }
+               goto pbl_wait;
        } else if (qproc->version == MSS_MSM8996 ||
                   qproc->version == MSS_MSM8998) {
                int mem_pwr_ctl;
@@ -515,13 +604,13 @@ static int q6v5proc_reset(struct q6v5 *qproc)
 
                /* BHS require xo cbcr to be enabled */
                val = readl(qproc->reg_base + QDSP6SS_XO_CBCR);
-               val |= 0x1;
+               val |= Q6SS_CBCR_CLKEN;
                writel(val, qproc->reg_base + QDSP6SS_XO_CBCR);
 
                /* Read CLKOFF bit to go low indicating CLK is enabled */
                ret = readl_poll_timeout(qproc->reg_base + QDSP6SS_XO_CBCR,
-                                        val, !(val & BIT(31)), 1,
-                                        HALT_CHECK_MAX_LOOPS);
+                                        val, !(val & Q6SS_CBCR_CLKOFF), 1,
+                                        Q6SS_CBCR_TIMEOUT_US);
                if (ret) {
                        dev_err(qproc->dev,
                                "xo cbcr enabling timed out (rc:%d)\n", ret);
@@ -637,7 +726,6 @@ static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
                                   struct regmap *halt_map,
                                   u32 offset)
 {
-       unsigned long timeout;
        unsigned int val;
        int ret;
 
@@ -650,14 +738,8 @@ static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
        regmap_write(halt_map, offset + AXI_HALTREQ_REG, 1);
 
        /* Wait for halt */
-       timeout = jiffies + msecs_to_jiffies(HALT_ACK_TIMEOUT_MS);
-       for (;;) {
-               ret = regmap_read(halt_map, offset + AXI_HALTACK_REG, &val);
-               if (ret || val || time_after(jiffies, timeout))
-                       break;
-
-               msleep(1);
-       }
+       regmap_read_poll_timeout(halt_map, offset + AXI_HALTACK_REG, val,
+                                val, 1000, HALT_ACK_TIMEOUT_US);
 
        ret = regmap_read(halt_map, offset + AXI_IDLE_REG, &val);
        if (ret || !val)
@@ -667,6 +749,32 @@ static void q6v5proc_halt_axi_port(struct q6v5 *qproc,
        regmap_write(halt_map, offset + AXI_HALTREQ_REG, 0);
 }
 
+static void q6v5proc_halt_nav_axi_port(struct q6v5 *qproc,
+                                      struct regmap *halt_map,
+                                      u32 offset)
+{
+       unsigned int val;
+       int ret;
+
+       /* Check if we're already idle */
+       ret = regmap_read(halt_map, offset, &val);
+       if (!ret && (val & NAV_AXI_IDLE_BIT))
+               return;
+
+       /* Assert halt request */
+       regmap_update_bits(halt_map, offset, NAV_AXI_HALTREQ_BIT,
+                          NAV_AXI_HALTREQ_BIT);
+
+       /* Wait for halt ack*/
+       regmap_read_poll_timeout(halt_map, offset, val,
+                                (val & NAV_AXI_HALTACK_BIT),
+                                5, NAV_HALT_ACK_TIMEOUT_US);
+
+       ret = regmap_read(halt_map, offset, &val);
+       if (ret || !(val & NAV_AXI_IDLE_BIT))
+               dev_err(qproc->dev, "port failed halt\n");
+}
+
 static int q6v5_mpss_init_image(struct q6v5 *qproc, const struct firmware *fw)
 {
        unsigned long dma_attrs = DMA_ATTR_FORCE_CONTIGUOUS;
@@ -829,6 +937,9 @@ static int q6v5_mba_load(struct q6v5 *qproc)
 halt_axi_ports:
        q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
        q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
+       if (qproc->has_halt_nav)
+               q6v5proc_halt_nav_axi_port(qproc, qproc->halt_nav_map,
+                                          qproc->halt_nav);
        q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
 
 reclaim_mba:
@@ -876,6 +987,9 @@ static void q6v5_mba_reclaim(struct q6v5 *qproc)
 
        q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_q6);
        q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_modem);
+       if (qproc->has_halt_nav)
+               q6v5proc_halt_nav_axi_port(qproc, qproc->halt_nav_map,
+                                          qproc->halt_nav);
        q6v5proc_halt_axi_port(qproc, qproc->halt_map, qproc->halt_nc);
        if (qproc->version == MSS_MSM8996) {
                /*
@@ -1253,6 +1367,47 @@ static int q6v5_init_mem(struct q6v5 *qproc, struct platform_device *pdev)
        qproc->halt_modem = args.args[1];
        qproc->halt_nc = args.args[2];
 
+       if (qproc->has_halt_nav) {
+               struct platform_device *nav_pdev;
+
+               ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
+                                                      "qcom,halt-nav-regs",
+                                                      1, 0, &args);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "failed to parse halt-nav-regs\n");
+                       return -EINVAL;
+               }
+
+               nav_pdev = of_find_device_by_node(args.np);
+               of_node_put(args.np);
+               if (!nav_pdev) {
+                       dev_err(&pdev->dev, "failed to get mss clock device\n");
+                       return -EPROBE_DEFER;
+               }
+
+               qproc->halt_nav_map = dev_get_regmap(&nav_pdev->dev, NULL);
+               if (!qproc->halt_nav_map) {
+                       dev_err(&pdev->dev, "failed to get map from device\n");
+                       return -EINVAL;
+               }
+               qproc->halt_nav = args.args[0];
+
+               ret = of_parse_phandle_with_fixed_args(pdev->dev.of_node,
+                                                      "qcom,halt-nav-regs",
+                                                      1, 1, &args);
+               if (ret < 0) {
+                       dev_err(&pdev->dev, "failed to parse halt-nav-regs\n");
+                       return -EINVAL;
+               }
+
+               qproc->conn_map = syscon_node_to_regmap(args.np);
+               of_node_put(args.np);
+               if (IS_ERR(qproc->conn_map))
+                       return PTR_ERR(qproc->conn_map);
+
+               qproc->conn_box = args.args[0];
+       }
+
        return 0;
 }
 
@@ -1327,7 +1482,7 @@ static int q6v5_init_reset(struct q6v5 *qproc)
                return PTR_ERR(qproc->mss_restart);
        }
 
-       if (qproc->has_alt_reset) {
+       if (qproc->has_alt_reset || qproc->has_halt_nav) {
                qproc->pdc_reset = devm_reset_control_get_exclusive(qproc->dev,
                                                                    "pdc_reset");
                if (IS_ERR(qproc->pdc_reset)) {
@@ -1426,6 +1581,7 @@ static int q6v5_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, qproc);
 
+       qproc->has_halt_nav = desc->has_halt_nav;
        ret = q6v5_init_mem(qproc, pdev);
        if (ret)
                goto free_rproc;
@@ -1549,6 +1705,41 @@ static int q6v5_remove(struct platform_device *pdev)
        return 0;
 }
 
+static const struct rproc_hexagon_res sc7180_mss = {
+       .hexagon_mba_image = "mba.mbn",
+       .proxy_clk_names = (char*[]){
+               "xo",
+               NULL
+       },
+       .reset_clk_names = (char*[]){
+               "iface",
+               "bus",
+               "snoc_axi",
+               NULL
+       },
+       .active_clk_names = (char*[]){
+               "mnoc_axi",
+               "nav",
+               "mss_nav",
+               "mss_crypto",
+               NULL
+       },
+       .active_pd_names = (char*[]){
+               "load_state",
+               NULL
+       },
+       .proxy_pd_names = (char*[]){
+               "cx",
+               "mx",
+               "mss",
+               NULL
+       },
+       .need_mem_protection = true,
+       .has_alt_reset = false,
+       .has_halt_nav = true,
+       .version = MSS_SC7180,
+};
+
 static const struct rproc_hexagon_res sdm845_mss = {
        .hexagon_mba_image = "mba.mbn",
        .proxy_clk_names = (char*[]){
@@ -1580,6 +1771,7 @@ static const struct rproc_hexagon_res sdm845_mss = {
        },
        .need_mem_protection = true,
        .has_alt_reset = true,
+       .has_halt_nav = false,
        .version = MSS_SDM845,
 };
 
@@ -1594,7 +1786,6 @@ static const struct rproc_hexagon_res msm8998_mss = {
        .active_clk_names = (char*[]){
                        "iface",
                        "bus",
-                       "mem",
                        "gpll0_mss",
                        "mnoc_axi",
                        "snoc_axi",
@@ -1607,6 +1798,7 @@ static const struct rproc_hexagon_res msm8998_mss = {
        },
        .need_mem_protection = true,
        .has_alt_reset = false,
+       .has_halt_nav = false,
        .version = MSS_MSM8998,
 };
 
@@ -1636,6 +1828,7 @@ static const struct rproc_hexagon_res msm8996_mss = {
        },
        .need_mem_protection = true,
        .has_alt_reset = false,
+       .has_halt_nav = false,
        .version = MSS_MSM8996,
 };
 
@@ -1668,6 +1861,7 @@ static const struct rproc_hexagon_res msm8916_mss = {
        },
        .need_mem_protection = false,
        .has_alt_reset = false,
+       .has_halt_nav = false,
        .version = MSS_MSM8916,
 };
 
@@ -1708,6 +1902,7 @@ static const struct rproc_hexagon_res msm8974_mss = {
        },
        .need_mem_protection = false,
        .has_alt_reset = false,
+       .has_halt_nav = false,
        .version = MSS_MSM8974,
 };
 
@@ -1717,6 +1912,7 @@ static const struct of_device_id q6v5_of_match[] = {
        { .compatible = "qcom,msm8974-mss-pil", .data = &msm8974_mss},
        { .compatible = "qcom,msm8996-mss-pil", .data = &msm8996_mss},
        { .compatible = "qcom,msm8998-mss-pil", .data = &msm8998_mss},
+       { .compatible = "qcom,sc7180-mss-pil", .data = &sc7180_mss},
        { .compatible = "qcom,sdm845-mss-pil", .data = &sdm845_mss},
        { },
 };
index db4b3c4..edf9d0e 100644 (file)
@@ -15,6 +15,8 @@
 #include <linux/of_address.h>
 #include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/pm_domain.h>
+#include <linux/pm_runtime.h>
 #include <linux/qcom_scm.h>
 #include <linux/regulator/consumer.h>
 #include <linux/remoteproc.h>
@@ -31,6 +33,10 @@ struct adsp_data {
        const char *firmware_name;
        int pas_id;
        bool has_aggre2_clk;
+       bool auto_boot;
+
+       char **active_pd_names;
+       char **proxy_pd_names;
 
        const char *ssr_name;
        const char *sysmon_name;
@@ -49,6 +55,12 @@ struct qcom_adsp {
        struct regulator *cx_supply;
        struct regulator *px_supply;
 
+       struct device *active_pds[1];
+       struct device *proxy_pds[3];
+
+       int active_pd_count;
+       int proxy_pd_count;
+
        int pas_id;
        int crash_reason_smem;
        bool has_aggre2_clk;
@@ -67,6 +79,41 @@ struct qcom_adsp {
        struct qcom_sysmon *sysmon;
 };
 
+static int adsp_pds_enable(struct qcom_adsp *adsp, struct device **pds,
+                          size_t pd_count)
+{
+       int ret;
+       int i;
+
+       for (i = 0; i < pd_count; i++) {
+               dev_pm_genpd_set_performance_state(pds[i], INT_MAX);
+               ret = pm_runtime_get_sync(pds[i]);
+               if (ret < 0)
+                       goto unroll_pd_votes;
+       }
+
+       return 0;
+
+unroll_pd_votes:
+       for (i--; i >= 0; i--) {
+               dev_pm_genpd_set_performance_state(pds[i], 0);
+               pm_runtime_put(pds[i]);
+       }
+
+       return ret;
+};
+
+static void adsp_pds_disable(struct qcom_adsp *adsp, struct device **pds,
+                            size_t pd_count)
+{
+       int i;
+
+       for (i = 0; i < pd_count; i++) {
+               dev_pm_genpd_set_performance_state(pds[i], 0);
+               pm_runtime_put(pds[i]);
+       }
+}
+
 static int adsp_load(struct rproc *rproc, const struct firmware *fw)
 {
        struct qcom_adsp *adsp = (struct qcom_adsp *)rproc->priv;
@@ -84,9 +131,17 @@ static int adsp_start(struct rproc *rproc)
 
        qcom_q6v5_prepare(&adsp->q6v5);
 
+       ret = adsp_pds_enable(adsp, adsp->active_pds, adsp->active_pd_count);
+       if (ret < 0)
+               goto disable_irqs;
+
+       ret = adsp_pds_enable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
+       if (ret < 0)
+               goto disable_active_pds;
+
        ret = clk_prepare_enable(adsp->xo);
        if (ret)
-               return ret;
+               goto disable_proxy_pds;
 
        ret = clk_prepare_enable(adsp->aggre2_clk);
        if (ret)
@@ -124,6 +179,12 @@ disable_aggre2_clk:
        clk_disable_unprepare(adsp->aggre2_clk);
 disable_xo_clk:
        clk_disable_unprepare(adsp->xo);
+disable_proxy_pds:
+       adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
+disable_active_pds:
+       adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
+disable_irqs:
+       qcom_q6v5_unprepare(&adsp->q6v5);
 
        return ret;
 }
@@ -136,6 +197,7 @@ static void qcom_pas_handover(struct qcom_q6v5 *q6v5)
        regulator_disable(adsp->cx_supply);
        clk_disable_unprepare(adsp->aggre2_clk);
        clk_disable_unprepare(adsp->xo);
+       adsp_pds_disable(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
 }
 
 static int adsp_stop(struct rproc *rproc)
@@ -152,6 +214,7 @@ static int adsp_stop(struct rproc *rproc)
        if (ret)
                dev_err(adsp->dev, "failed to shutdown: %d\n", ret);
 
+       adsp_pds_disable(adsp, adsp->active_pds, adsp->active_pd_count);
        handover = qcom_q6v5_unprepare(&adsp->q6v5);
        if (handover)
                qcom_pas_handover(&adsp->q6v5);
@@ -217,6 +280,59 @@ static int adsp_init_regulator(struct qcom_adsp *adsp)
        return PTR_ERR_OR_ZERO(adsp->px_supply);
 }
 
+static int adsp_pds_attach(struct device *dev, struct device **devs,
+                          char **pd_names)
+{
+       size_t num_pds = 0;
+       int ret;
+       int i;
+
+       if (!pd_names)
+               return 0;
+
+       /* Handle single power domain */
+       if (dev->pm_domain) {
+               devs[0] = dev;
+               pm_runtime_enable(dev);
+               return 1;
+       }
+
+       while (pd_names[num_pds])
+               num_pds++;
+
+       for (i = 0; i < num_pds; i++) {
+               devs[i] = dev_pm_domain_attach_by_name(dev, pd_names[i]);
+               if (IS_ERR_OR_NULL(devs[i])) {
+                       ret = PTR_ERR(devs[i]) ? : -ENODATA;
+                       goto unroll_attach;
+               }
+       }
+
+       return num_pds;
+
+unroll_attach:
+       for (i--; i >= 0; i--)
+               dev_pm_domain_detach(devs[i], false);
+
+       return ret;
+};
+
+static void adsp_pds_detach(struct qcom_adsp *adsp, struct device **pds,
+                           size_t pd_count)
+{
+       struct device *dev = adsp->dev;
+       int i;
+
+       /* Handle single power domain */
+       if (dev->pm_domain && pd_count) {
+               pm_runtime_disable(dev);
+               return;
+       }
+
+       for (i = 0; i < pd_count; i++)
+               dev_pm_domain_detach(pds[i], false);
+}
+
 static int adsp_alloc_memory_region(struct qcom_adsp *adsp)
 {
        struct device_node *node;
@@ -273,6 +389,8 @@ static int adsp_probe(struct platform_device *pdev)
                return -ENOMEM;
        }
 
+       rproc->auto_boot = desc->auto_boot;
+
        adsp = (struct qcom_adsp *)rproc->priv;
        adsp->dev = &pdev->dev;
        adsp->rproc = rproc;
@@ -292,10 +410,22 @@ static int adsp_probe(struct platform_device *pdev)
        if (ret)
                goto free_rproc;
 
+       ret = adsp_pds_attach(&pdev->dev, adsp->active_pds,
+                             desc->active_pd_names);
+       if (ret < 0)
+               goto free_rproc;
+       adsp->active_pd_count = ret;
+
+       ret = adsp_pds_attach(&pdev->dev, adsp->proxy_pds,
+                             desc->proxy_pd_names);
+       if (ret < 0)
+               goto detach_active_pds;
+       adsp->proxy_pd_count = ret;
+
        ret = qcom_q6v5_init(&adsp->q6v5, pdev, rproc, desc->crash_reason_smem,
                             qcom_pas_handover);
        if (ret)
-               goto free_rproc;
+               goto detach_proxy_pds;
 
        qcom_add_glink_subdev(rproc, &adsp->glink_subdev);
        qcom_add_smd_subdev(rproc, &adsp->smd_subdev);
@@ -305,15 +435,19 @@ static int adsp_probe(struct platform_device *pdev)
                                              desc->ssctl_id);
        if (IS_ERR(adsp->sysmon)) {
                ret = PTR_ERR(adsp->sysmon);
-               goto free_rproc;
+               goto detach_proxy_pds;
        }
 
        ret = rproc_add(rproc);
        if (ret)
-               goto free_rproc;
+               goto detach_proxy_pds;
 
        return 0;
 
+detach_proxy_pds:
+       adsp_pds_detach(adsp, adsp->proxy_pds, adsp->proxy_pd_count);
+detach_active_pds:
+       adsp_pds_detach(adsp, adsp->active_pds, adsp->active_pd_count);
 free_rproc:
        rproc_free(rproc);
 
@@ -340,6 +474,41 @@ static const struct adsp_data adsp_resource_init = {
                .firmware_name = "adsp.mdt",
                .pas_id = 1,
                .has_aggre2_clk = false,
+               .auto_boot = true,
+               .ssr_name = "lpass",
+               .sysmon_name = "adsp",
+               .ssctl_id = 0x14,
+};
+
+static const struct adsp_data sm8150_adsp_resource = {
+               .crash_reason_smem = 423,
+               .firmware_name = "adsp.mdt",
+               .pas_id = 1,
+               .has_aggre2_clk = false,
+               .auto_boot = true,
+               .active_pd_names = (char*[]){
+                       "load_state",
+                       NULL
+               },
+               .proxy_pd_names = (char*[]){
+                       "cx",
+                       NULL
+               },
+               .ssr_name = "lpass",
+               .sysmon_name = "adsp",
+               .ssctl_id = 0x14,
+};
+
+static const struct adsp_data msm8998_adsp_resource = {
+               .crash_reason_smem = 423,
+               .firmware_name = "adsp.mdt",
+               .pas_id = 1,
+               .has_aggre2_clk = false,
+               .auto_boot = true,
+               .proxy_pd_names = (char*[]){
+                       "cx",
+                       NULL
+               },
                .ssr_name = "lpass",
                .sysmon_name = "adsp",
                .ssctl_id = 0x14,
@@ -350,16 +519,92 @@ static const struct adsp_data cdsp_resource_init = {
        .firmware_name = "cdsp.mdt",
        .pas_id = 18,
        .has_aggre2_clk = false,
+       .auto_boot = true,
+       .ssr_name = "cdsp",
+       .sysmon_name = "cdsp",
+       .ssctl_id = 0x17,
+};
+
+static const struct adsp_data sm8150_cdsp_resource = {
+       .crash_reason_smem = 601,
+       .firmware_name = "cdsp.mdt",
+       .pas_id = 18,
+       .has_aggre2_clk = false,
+       .auto_boot = true,
+       .active_pd_names = (char*[]){
+               "load_state",
+               NULL
+       },
+       .proxy_pd_names = (char*[]){
+               "cx",
+               NULL
+       },
        .ssr_name = "cdsp",
        .sysmon_name = "cdsp",
        .ssctl_id = 0x17,
 };
 
+static const struct adsp_data mpss_resource_init = {
+       .crash_reason_smem = 421,
+       .firmware_name = "modem.mdt",
+       .pas_id = 4,
+       .has_aggre2_clk = false,
+       .auto_boot = false,
+       .active_pd_names = (char*[]){
+               "load_state",
+               NULL
+       },
+       .proxy_pd_names = (char*[]){
+               "cx",
+               "mss",
+               NULL
+       },
+       .ssr_name = "mpss",
+       .sysmon_name = "modem",
+       .ssctl_id = 0x12,
+};
+
 static const struct adsp_data slpi_resource_init = {
                .crash_reason_smem = 424,
                .firmware_name = "slpi.mdt",
                .pas_id = 12,
                .has_aggre2_clk = true,
+               .auto_boot = true,
+               .ssr_name = "dsps",
+               .sysmon_name = "slpi",
+               .ssctl_id = 0x16,
+};
+
+static const struct adsp_data sm8150_slpi_resource = {
+               .crash_reason_smem = 424,
+               .firmware_name = "slpi.mdt",
+               .pas_id = 12,
+               .has_aggre2_clk = false,
+               .auto_boot = true,
+               .active_pd_names = (char*[]){
+                       "load_state",
+                       NULL
+               },
+               .proxy_pd_names = (char*[]){
+                       "lcx",
+                       "lmx",
+                       NULL
+               },
+               .ssr_name = "dsps",
+               .sysmon_name = "slpi",
+               .ssctl_id = 0x16,
+};
+
+static const struct adsp_data msm8998_slpi_resource = {
+               .crash_reason_smem = 424,
+               .firmware_name = "slpi.mdt",
+               .pas_id = 12,
+               .has_aggre2_clk = true,
+               .auto_boot = true,
+               .proxy_pd_names = (char*[]){
+                       "ssc_cx",
+                       NULL
+               },
                .ssr_name = "dsps",
                .sysmon_name = "slpi",
                .ssctl_id = 0x16,
@@ -369,6 +614,7 @@ static const struct adsp_data wcss_resource_init = {
        .crash_reason_smem = 421,
        .firmware_name = "wcnss.mdt",
        .pas_id = 6,
+       .auto_boot = true,
        .ssr_name = "mpss",
        .sysmon_name = "wcnss",
        .ssctl_id = 0x12,
@@ -378,11 +624,17 @@ static const struct of_device_id adsp_of_match[] = {
        { .compatible = "qcom,msm8974-adsp-pil", .data = &adsp_resource_init},
        { .compatible = "qcom,msm8996-adsp-pil", .data = &adsp_resource_init},
        { .compatible = "qcom,msm8996-slpi-pil", .data = &slpi_resource_init},
+       { .compatible = "qcom,msm8998-adsp-pas", .data = &msm8998_adsp_resource},
+       { .compatible = "qcom,msm8998-slpi-pas", .data = &msm8998_slpi_resource},
        { .compatible = "qcom,qcs404-adsp-pas", .data = &adsp_resource_init },
        { .compatible = "qcom,qcs404-cdsp-pas", .data = &cdsp_resource_init },
        { .compatible = "qcom,qcs404-wcss-pas", .data = &wcss_resource_init },
        { .compatible = "qcom,sdm845-adsp-pas", .data = &adsp_resource_init},
        { .compatible = "qcom,sdm845-cdsp-pas", .data = &cdsp_resource_init},
+       { .compatible = "qcom,sm8150-adsp-pas", .data = &sm8150_adsp_resource},
+       { .compatible = "qcom,sm8150-cdsp-pas", .data = &sm8150_cdsp_resource},
+       { .compatible = "qcom,sm8150-mpss-pas", .data = &mpss_resource_init},
+       { .compatible = "qcom,sm8150-slpi-pas", .data = &sm8150_slpi_resource},
        { },
 };
 MODULE_DEVICE_TABLE(of, adsp_of_match);
index c231314..faf3822 100644 (file)
@@ -394,7 +394,7 @@ static int ssctl_new_server(struct qmi_handle *qmi, struct qmi_service *svc)
                break;
        default:
                return -EINVAL;
-       };
+       }
 
        sysmon->ssctl_version = svc->version;
 
index 307df98..097f33e 100644 (file)
@@ -477,8 +477,8 @@ static int rproc_handle_vdev(struct rproc *rproc, struct fw_rsc_vdev *rsc,
        char name[16];
 
        /* make sure resource isn't truncated */
-       if (sizeof(*rsc) + rsc->num_of_vrings * sizeof(struct fw_rsc_vdev_vring)
-                       + rsc->config_len > avail) {
+       if (struct_size(rsc, vring, rsc->num_of_vrings) + rsc->config_len >
+                       avail) {
                dev_err(dev, "vdev rsc is truncated\n");
                return -EINVAL;
        }
@@ -2223,7 +2223,7 @@ static int __init remoteproc_init(void)
 
        return 0;
 }
-module_init(remoteproc_init);
+subsys_initcall(remoteproc_init);
 
 static void __exit remoteproc_exit(void)
 {
index 3ad7817..461b0e5 100644 (file)
@@ -49,6 +49,13 @@ config RESET_BRCMSTB
          This enables the reset controller driver for Broadcom STB SoCs using
          a SUN_TOP_CTRL_SW_INIT style controller.
 
+config RESET_BRCMSTB_RESCAL
+       bool "Broadcom STB RESCAL reset controller"
+       default ARCH_BRCMSTB || COMPILE_TEST
+       help
+         This enables the RESCAL reset controller for SATA, PCIe0, or PCIe1 on
+         BCM7216.
+
 config RESET_HSDK
        bool "Synopsys HSDK Reset Driver"
        depends on HAS_IOMEM
@@ -64,6 +71,15 @@ config RESET_IMX7
        help
          This enables the reset controller driver for i.MX7 SoCs.
 
+config RESET_INTEL_GW
+       bool "Intel Reset Controller Driver"
+       depends on OF
+       select REGMAP_MMIO
+       help
+         This enables the reset controller driver for Intel Gateway SoCs.
+         Say Y to control the reset signals provided by reset controller.
+         Otherwise, say N.
+
 config RESET_LANTIQ
        bool "Lantiq XWAY Reset Driver" if COMPILE_TEST
        default SOC_TYPE_XWAY
@@ -89,6 +105,13 @@ config RESET_MESON_AUDIO_ARB
          This enables the reset driver for Audio Memory Arbiter of
          Amlogic's A113 based SoCs
 
+config RESET_NPCM
+       bool "NPCM BMC Reset Driver" if COMPILE_TEST
+       default ARCH_NPCM
+       help
+         This enables the reset controller driver for Nuvoton NPCM
+         BMC SoCs.
+
 config RESET_OXNAS
        bool
 
@@ -99,7 +122,7 @@ config RESET_PISTACHIO
          This enables the reset driver for ImgTec Pistachio SoCs.
 
 config RESET_QCOM_AOSS
-       bool "Qcom AOSS Reset Driver"
+       tristate "Qcom AOSS Reset Driver"
        depends on ARCH_QCOM || COMPILE_TEST
        help
          This enables the AOSS (always on subsystem) reset driver
index cf60ce5..249ed35 100644 (file)
@@ -8,12 +8,15 @@ obj-$(CONFIG_RESET_ATH79) += reset-ath79.o
 obj-$(CONFIG_RESET_AXS10X) += reset-axs10x.o
 obj-$(CONFIG_RESET_BERLIN) += reset-berlin.o
 obj-$(CONFIG_RESET_BRCMSTB) += reset-brcmstb.o
+obj-$(CONFIG_RESET_BRCMSTB_RESCAL) += reset-brcmstb-rescal.o
 obj-$(CONFIG_RESET_HSDK) += reset-hsdk.o
 obj-$(CONFIG_RESET_IMX7) += reset-imx7.o
+obj-$(CONFIG_RESET_INTEL_GW) += reset-intel-gw.o
 obj-$(CONFIG_RESET_LANTIQ) += reset-lantiq.o
 obj-$(CONFIG_RESET_LPC18XX) += reset-lpc18xx.o
 obj-$(CONFIG_RESET_MESON) += reset-meson.o
 obj-$(CONFIG_RESET_MESON_AUDIO_ARB) += reset-meson-audio-arb.o
+obj-$(CONFIG_RESET_NPCM) += reset-npcm.o
 obj-$(CONFIG_RESET_OXNAS) += reset-oxnas.o
 obj-$(CONFIG_RESET_PISTACHIO) += reset-pistachio.o
 obj-$(CONFIG_RESET_QCOM_AOSS) += reset-qcom-aoss.o
index 7597c70..01c0c7a 100644 (file)
@@ -150,13 +150,14 @@ int devm_reset_controller_register(struct device *dev,
                return -ENOMEM;
 
        ret = reset_controller_register(rcdev);
-       if (!ret) {
-               *rcdevp = rcdev;
-               devres_add(dev, rcdevp);
-       } else {
+       if (ret) {
                devres_free(rcdevp);
+               return ret;
        }
 
+       *rcdevp = rcdev;
+       devres_add(dev, rcdevp);
+
        return ret;
 }
 EXPORT_SYMBOL_GPL(devm_reset_controller_register);
@@ -787,13 +788,14 @@ 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_OR_NULL(rstc)) {
-               *ptr = rstc;
-               devres_add(dev, ptr);
-       } else {
+       if (IS_ERR_OR_NULL(rstc)) {
                devres_free(ptr);
+               return rstc;
        }
 
+       *ptr = rstc;
+       devres_add(dev, ptr);
+
        return rstc;
 }
 EXPORT_SYMBOL_GPL(__devm_reset_control_get);
@@ -919,22 +921,21 @@ EXPORT_SYMBOL_GPL(of_reset_control_array_get);
 struct reset_control *
 devm_reset_control_array_get(struct device *dev, bool shared, bool optional)
 {
-       struct reset_control **devres;
-       struct reset_control *rstc;
+       struct reset_control **ptr, *rstc;
 
-       devres = devres_alloc(devm_reset_control_release, sizeof(*devres),
-                             GFP_KERNEL);
-       if (!devres)
+       ptr = devres_alloc(devm_reset_control_release, sizeof(*ptr),
+                          GFP_KERNEL);
+       if (!ptr)
                return ERR_PTR(-ENOMEM);
 
        rstc = of_reset_control_array_get(dev->of_node, shared, optional, true);
        if (IS_ERR_OR_NULL(rstc)) {
-               devres_free(devres);
+               devres_free(ptr);
                return rstc;
        }
 
-       *devres = rstc;
-       devres_add(dev, devres);
+       *ptr = rstc;
+       devres_add(dev, ptr);
 
        return rstc;
 }
diff --git a/drivers/reset/reset-brcmstb-rescal.c b/drivers/reset/reset-brcmstb-rescal.c
new file mode 100644 (file)
index 0000000..b6f074d
--- /dev/null
@@ -0,0 +1,107 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (C) 2018-2020 Broadcom */
+
+#include <linux/device.h>
+#include <linux/iopoll.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/reset-controller.h>
+
+#define BRCM_RESCAL_START      0x0
+#define  BRCM_RESCAL_START_BIT BIT(0)
+#define BRCM_RESCAL_CTRL       0x4
+#define BRCM_RESCAL_STATUS     0x8
+#define  BRCM_RESCAL_STATUS_BIT        BIT(0)
+
+struct brcm_rescal_reset {
+       void __iomem *base;
+       struct device *dev;
+       struct reset_controller_dev rcdev;
+};
+
+static int brcm_rescal_reset_set(struct reset_controller_dev *rcdev,
+                                unsigned long id)
+{
+       struct brcm_rescal_reset *data =
+               container_of(rcdev, struct brcm_rescal_reset, rcdev);
+       void __iomem *base = data->base;
+       u32 reg;
+       int ret;
+
+       reg = readl(base + BRCM_RESCAL_START);
+       writel(reg | BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START);
+       reg = readl(base + BRCM_RESCAL_START);
+       if (!(reg & BRCM_RESCAL_START_BIT)) {
+               dev_err(data->dev, "failed to start SATA/PCIe rescal\n");
+               return -EIO;
+       }
+
+       ret = readl_poll_timeout(base + BRCM_RESCAL_STATUS, reg,
+                                !(reg & BRCM_RESCAL_STATUS_BIT), 100, 1000);
+       if (ret) {
+               dev_err(data->dev, "time out on SATA/PCIe rescal\n");
+               return ret;
+       }
+
+       reg = readl(base + BRCM_RESCAL_START);
+       writel(reg & ~BRCM_RESCAL_START_BIT, base + BRCM_RESCAL_START);
+
+       dev_dbg(data->dev, "SATA/PCIe rescal success\n");
+
+       return 0;
+}
+
+static int brcm_rescal_reset_xlate(struct reset_controller_dev *rcdev,
+                                  const struct of_phandle_args *reset_spec)
+{
+       /* This is needed if #reset-cells == 0. */
+       return 0;
+}
+
+static const struct reset_control_ops brcm_rescal_reset_ops = {
+       .reset = brcm_rescal_reset_set,
+};
+
+static int brcm_rescal_reset_probe(struct platform_device *pdev)
+{
+       struct brcm_rescal_reset *data;
+       struct resource *res;
+
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       data->base = devm_ioremap_resource(&pdev->dev, res);
+       if (IS_ERR(data->base))
+               return PTR_ERR(data->base);
+
+       data->rcdev.owner = THIS_MODULE;
+       data->rcdev.nr_resets = 1;
+       data->rcdev.ops = &brcm_rescal_reset_ops;
+       data->rcdev.of_node = pdev->dev.of_node;
+       data->rcdev.of_xlate = brcm_rescal_reset_xlate;
+       data->dev = &pdev->dev;
+
+       return devm_reset_controller_register(&pdev->dev, &data->rcdev);
+}
+
+static const struct of_device_id brcm_rescal_reset_of_match[] = {
+       { .compatible = "brcm,bcm7216-pcie-sata-rescal" },
+       { },
+};
+MODULE_DEVICE_TABLE(of, brcm_rescal_reset_of_match);
+
+static struct platform_driver brcm_rescal_reset_driver = {
+       .probe = brcm_rescal_reset_probe,
+       .driver = {
+               .name   = "brcm-rescal-reset",
+               .of_match_table = brcm_rescal_reset_of_match,
+       }
+};
+module_platform_driver(brcm_rescal_reset_driver);
+
+MODULE_AUTHOR("Broadcom");
+MODULE_DESCRIPTION("Broadcom SATA/PCIe rescal reset controller");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/reset/reset-intel-gw.c b/drivers/reset/reset-intel-gw.c
new file mode 100644 (file)
index 0000000..8542384
--- /dev/null
@@ -0,0 +1,262 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (c) 2019 Intel Corporation.
+ * Lei Chuanhua <Chuanhua.lei@intel.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/init.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/regmap.h>
+#include <linux/reset-controller.h>
+
+#define RCU_RST_STAT   0x0024
+#define RCU_RST_REQ    0x0048
+
+#define REG_OFFSET     GENMASK(31, 16)
+#define BIT_OFFSET     GENMASK(15, 8)
+#define STAT_BIT_OFFSET        GENMASK(7, 0)
+
+#define to_reset_data(x)       container_of(x, struct intel_reset_data, rcdev)
+
+struct intel_reset_soc {
+       bool legacy;
+       u32 reset_cell_count;
+};
+
+struct intel_reset_data {
+       struct reset_controller_dev rcdev;
+       struct notifier_block restart_nb;
+       const struct intel_reset_soc *soc_data;
+       struct regmap *regmap;
+       struct device *dev;
+       u32 reboot_id;
+};
+
+static const struct regmap_config intel_rcu_regmap_config = {
+       .name =         "intel-reset",
+       .reg_bits =     32,
+       .reg_stride =   4,
+       .val_bits =     32,
+       .fast_io =      true,
+};
+
+/*
+ * Reset status register offset relative to
+ * the reset control register(X) is X + 4
+ */
+static u32 id_to_reg_and_bit_offsets(struct intel_reset_data *data,
+                                    unsigned long id, u32 *rst_req,
+                                    u32 *req_bit, u32 *stat_bit)
+{
+       *rst_req = FIELD_GET(REG_OFFSET, id);
+       *req_bit = FIELD_GET(BIT_OFFSET, id);
+
+       if (data->soc_data->legacy)
+               *stat_bit = FIELD_GET(STAT_BIT_OFFSET, id);
+       else
+               *stat_bit = *req_bit;
+
+       if (data->soc_data->legacy && *rst_req == RCU_RST_REQ)
+               return RCU_RST_STAT;
+       else
+               return *rst_req + 0x4;
+}
+
+static int intel_set_clr_bits(struct intel_reset_data *data, unsigned long id,
+                             bool set)
+{
+       u32 rst_req, req_bit, rst_stat, stat_bit, val;
+       int ret;
+
+       rst_stat = id_to_reg_and_bit_offsets(data, id, &rst_req,
+                                            &req_bit, &stat_bit);
+
+       val = set ? BIT(req_bit) : 0;
+       ret = regmap_update_bits(data->regmap, rst_req,  BIT(req_bit), val);
+       if (ret)
+               return ret;
+
+       return regmap_read_poll_timeout(data->regmap, rst_stat, val,
+                                       set == !!(val & BIT(stat_bit)), 20,
+                                       200);
+}
+
+static int intel_assert_device(struct reset_controller_dev *rcdev,
+                              unsigned long id)
+{
+       struct intel_reset_data *data = to_reset_data(rcdev);
+       int ret;
+
+       ret = intel_set_clr_bits(data, id, true);
+       if (ret)
+               dev_err(data->dev, "Reset assert failed %d\n", ret);
+
+       return ret;
+}
+
+static int intel_deassert_device(struct reset_controller_dev *rcdev,
+                                unsigned long id)
+{
+       struct intel_reset_data *data = to_reset_data(rcdev);
+       int ret;
+
+       ret = intel_set_clr_bits(data, id, false);
+       if (ret)
+               dev_err(data->dev, "Reset deassert failed %d\n", ret);
+
+       return ret;
+}
+
+static int intel_reset_status(struct reset_controller_dev *rcdev,
+                             unsigned long id)
+{
+       struct intel_reset_data *data = to_reset_data(rcdev);
+       u32 rst_req, req_bit, rst_stat, stat_bit, val;
+       int ret;
+
+       rst_stat = id_to_reg_and_bit_offsets(data, id, &rst_req,
+                                            &req_bit, &stat_bit);
+       ret = regmap_read(data->regmap, rst_stat, &val);
+       if (ret)
+               return ret;
+
+       return !!(val & BIT(stat_bit));
+}
+
+static const struct reset_control_ops intel_reset_ops = {
+       .assert =       intel_assert_device,
+       .deassert =     intel_deassert_device,
+       .status =       intel_reset_status,
+};
+
+static int intel_reset_xlate(struct reset_controller_dev *rcdev,
+                            const struct of_phandle_args *spec)
+{
+       struct intel_reset_data *data = to_reset_data(rcdev);
+       u32 id;
+
+       if (spec->args[1] > 31)
+               return -EINVAL;
+
+       id = FIELD_PREP(REG_OFFSET, spec->args[0]);
+       id |= FIELD_PREP(BIT_OFFSET, spec->args[1]);
+
+       if (data->soc_data->legacy) {
+               if (spec->args[2] > 31)
+                       return -EINVAL;
+
+               id |= FIELD_PREP(STAT_BIT_OFFSET, spec->args[2]);
+       }
+
+       return id;
+}
+
+static int intel_reset_restart_handler(struct notifier_block *nb,
+                                      unsigned long action, void *data)
+{
+       struct intel_reset_data *reset_data;
+
+       reset_data = container_of(nb, struct intel_reset_data, restart_nb);
+       intel_assert_device(&reset_data->rcdev, reset_data->reboot_id);
+
+       return NOTIFY_DONE;
+}
+
+static int intel_reset_probe(struct platform_device *pdev)
+{
+       struct device_node *np = pdev->dev.of_node;
+       struct device *dev = &pdev->dev;
+       struct intel_reset_data *data;
+       void __iomem *base;
+       u32 rb_id[3];
+       int ret;
+
+       data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       data->soc_data = of_device_get_match_data(dev);
+       if (!data->soc_data)
+               return -ENODEV;
+
+       base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(base))
+               return PTR_ERR(base);
+
+       data->regmap = devm_regmap_init_mmio(dev, base,
+                                            &intel_rcu_regmap_config);
+       if (IS_ERR(data->regmap)) {
+               dev_err(dev, "regmap initialization failed\n");
+               return PTR_ERR(data->regmap);
+       }
+
+       ret = device_property_read_u32_array(dev, "intel,global-reset", rb_id,
+                                            data->soc_data->reset_cell_count);
+       if (ret) {
+               dev_err(dev, "Failed to get global reset offset!\n");
+               return ret;
+       }
+
+       data->dev =                     dev;
+       data->rcdev.of_node =           np;
+       data->rcdev.owner =             dev->driver->owner;
+       data->rcdev.ops =               &intel_reset_ops;
+       data->rcdev.of_xlate =          intel_reset_xlate;
+       data->rcdev.of_reset_n_cells =  data->soc_data->reset_cell_count;
+       ret = devm_reset_controller_register(&pdev->dev, &data->rcdev);
+       if (ret)
+               return ret;
+
+       data->reboot_id = FIELD_PREP(REG_OFFSET, rb_id[0]);
+       data->reboot_id |= FIELD_PREP(BIT_OFFSET, rb_id[1]);
+
+       if (data->soc_data->legacy)
+               data->reboot_id |= FIELD_PREP(STAT_BIT_OFFSET, rb_id[2]);
+
+       data->restart_nb.notifier_call =        intel_reset_restart_handler;
+       data->restart_nb.priority =             128;
+       register_restart_handler(&data->restart_nb);
+
+       return 0;
+}
+
+static const struct intel_reset_soc xrx200_data = {
+       .legacy =               true,
+       .reset_cell_count =     3,
+};
+
+static const struct intel_reset_soc lgm_data = {
+       .legacy =               false,
+       .reset_cell_count =     2,
+};
+
+static const struct of_device_id intel_reset_match[] = {
+       { .compatible = "intel,rcu-lgm", .data = &lgm_data },
+       { .compatible = "intel,rcu-xrx200", .data = &xrx200_data },
+       {}
+};
+
+static struct platform_driver intel_reset_driver = {
+       .probe = intel_reset_probe,
+       .driver = {
+               .name = "intel-reset",
+               .of_match_table = intel_reset_match,
+       },
+};
+
+static int __init intel_reset_init(void)
+{
+       return platform_driver_register(&intel_reset_driver);
+}
+
+/*
+ * RCU is system core entity which is in Always On Domain whose clocks
+ * or resource initialization happens in system core initialization.
+ * Also, it is required for most of the platform or architecture
+ * specific devices to perform reset operation as part of initialization.
+ * So perform RCU as post core initialization.
+ */
+postcore_initcall(intel_reset_init);
diff --git a/drivers/reset/reset-npcm.c b/drivers/reset/reset-npcm.c
new file mode 100644 (file)
index 0000000..2ea4d31
--- /dev/null
@@ -0,0 +1,291 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2019 Nuvoton Technology corporation.
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/reset-controller.h>
+#include <linux/spinlock.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+#include <linux/of_address.h>
+
+/* NPCM7xx GCR registers */
+#define NPCM_MDLR_OFFSET       0x7C
+#define NPCM_MDLR_USBD0                BIT(9)
+#define NPCM_MDLR_USBD1                BIT(8)
+#define NPCM_MDLR_USBD2_4      BIT(21)
+#define NPCM_MDLR_USBD5_9      BIT(22)
+
+#define NPCM_USB1PHYCTL_OFFSET 0x140
+#define NPCM_USB2PHYCTL_OFFSET 0x144
+#define NPCM_USBXPHYCTL_RS     BIT(28)
+
+/* NPCM7xx Reset registers */
+#define NPCM_SWRSTR            0x14
+#define NPCM_SWRST             BIT(2)
+
+#define NPCM_IPSRST1           0x20
+#define NPCM_IPSRST1_USBD1     BIT(5)
+#define NPCM_IPSRST1_USBD2     BIT(8)
+#define NPCM_IPSRST1_USBD3     BIT(25)
+#define NPCM_IPSRST1_USBD4     BIT(22)
+#define NPCM_IPSRST1_USBD5     BIT(23)
+#define NPCM_IPSRST1_USBD6     BIT(24)
+
+#define NPCM_IPSRST2           0x24
+#define NPCM_IPSRST2_USB_HOST  BIT(26)
+
+#define NPCM_IPSRST3           0x34
+#define NPCM_IPSRST3_USBD0     BIT(4)
+#define NPCM_IPSRST3_USBD7     BIT(5)
+#define NPCM_IPSRST3_USBD8     BIT(6)
+#define NPCM_IPSRST3_USBD9     BIT(7)
+#define NPCM_IPSRST3_USBPHY1   BIT(24)
+#define NPCM_IPSRST3_USBPHY2   BIT(25)
+
+#define NPCM_RC_RESETS_PER_REG 32
+#define NPCM_MASK_RESETS       GENMASK(4, 0)
+
+struct npcm_rc_data {
+       struct reset_controller_dev rcdev;
+       struct notifier_block restart_nb;
+       u32 sw_reset_number;
+       void __iomem *base;
+       spinlock_t lock;
+};
+
+#define to_rc_data(p) container_of(p, struct npcm_rc_data, rcdev)
+
+static int npcm_rc_restart(struct notifier_block *nb, unsigned long mode,
+                          void *cmd)
+{
+       struct npcm_rc_data *rc = container_of(nb, struct npcm_rc_data,
+                                              restart_nb);
+
+       writel(NPCM_SWRST << rc->sw_reset_number, rc->base + NPCM_SWRSTR);
+       mdelay(1000);
+
+       pr_emerg("%s: unable to restart system\n", __func__);
+
+       return NOTIFY_DONE;
+}
+
+static int npcm_rc_setclear_reset(struct reset_controller_dev *rcdev,
+                                 unsigned long id, bool set)
+{
+       struct npcm_rc_data *rc = to_rc_data(rcdev);
+       unsigned int rst_bit = BIT(id & NPCM_MASK_RESETS);
+       unsigned int ctrl_offset = id >> 8;
+       unsigned long flags;
+       u32 stat;
+
+       spin_lock_irqsave(&rc->lock, flags);
+       stat = readl(rc->base + ctrl_offset);
+       if (set)
+               writel(stat | rst_bit, rc->base + ctrl_offset);
+       else
+               writel(stat & ~rst_bit, rc->base + ctrl_offset);
+       spin_unlock_irqrestore(&rc->lock, flags);
+
+       return 0;
+}
+
+static int npcm_rc_assert(struct reset_controller_dev *rcdev, unsigned long id)
+{
+       return npcm_rc_setclear_reset(rcdev, id, true);
+}
+
+static int npcm_rc_deassert(struct reset_controller_dev *rcdev,
+                           unsigned long id)
+{
+       return npcm_rc_setclear_reset(rcdev, id, false);
+}
+
+static int npcm_rc_status(struct reset_controller_dev *rcdev,
+                         unsigned long id)
+{
+       struct npcm_rc_data *rc = to_rc_data(rcdev);
+       unsigned int rst_bit = BIT(id & NPCM_MASK_RESETS);
+       unsigned int ctrl_offset = id >> 8;
+
+       return (readl(rc->base + ctrl_offset) & rst_bit);
+}
+
+static int npcm_reset_xlate(struct reset_controller_dev *rcdev,
+                           const struct of_phandle_args *reset_spec)
+{
+       unsigned int offset, bit;
+
+       offset = reset_spec->args[0];
+       if (offset != NPCM_IPSRST1 && offset != NPCM_IPSRST2 &&
+           offset != NPCM_IPSRST3) {
+               dev_err(rcdev->dev, "Error reset register (0x%x)\n", offset);
+               return -EINVAL;
+       }
+       bit = reset_spec->args[1];
+       if (bit >= NPCM_RC_RESETS_PER_REG) {
+               dev_err(rcdev->dev, "Error reset number (%d)\n", bit);
+               return -EINVAL;
+       }
+
+       return (offset << 8) | bit;
+}
+
+static const struct of_device_id npcm_rc_match[] = {
+       { .compatible = "nuvoton,npcm750-reset",
+               .data = (void *)"nuvoton,npcm750-gcr" },
+       { }
+};
+
+/*
+ *  The following procedure should be observed in USB PHY, USB device and
+ *  USB host initialization at BMC boot
+ */
+static int npcm_usb_reset(struct platform_device *pdev, struct npcm_rc_data *rc)
+{
+       u32 mdlr, iprst1, iprst2, iprst3;
+       struct device *dev = &pdev->dev;
+       struct regmap *gcr_regmap;
+       u32 ipsrst1_bits = 0;
+       u32 ipsrst2_bits = NPCM_IPSRST2_USB_HOST;
+       u32 ipsrst3_bits = 0;
+       const char *gcr_dt;
+
+       gcr_dt = (const char *)
+       of_match_device(dev->driver->of_match_table, dev)->data;
+
+       gcr_regmap = syscon_regmap_lookup_by_compatible(gcr_dt);
+       if (IS_ERR(gcr_regmap)) {
+               dev_err(&pdev->dev, "Failed to find %s\n", gcr_dt);
+               return PTR_ERR(gcr_regmap);
+       }
+
+       /* checking which USB device is enabled */
+       regmap_read(gcr_regmap, NPCM_MDLR_OFFSET, &mdlr);
+       if (!(mdlr & NPCM_MDLR_USBD0))
+               ipsrst3_bits |= NPCM_IPSRST3_USBD0;
+       if (!(mdlr & NPCM_MDLR_USBD1))
+               ipsrst1_bits |= NPCM_IPSRST1_USBD1;
+       if (!(mdlr & NPCM_MDLR_USBD2_4))
+               ipsrst1_bits |= (NPCM_IPSRST1_USBD2 |
+                                NPCM_IPSRST1_USBD3 |
+                                NPCM_IPSRST1_USBD4);
+       if (!(mdlr & NPCM_MDLR_USBD0)) {
+               ipsrst1_bits |= (NPCM_IPSRST1_USBD5 |
+                                NPCM_IPSRST1_USBD6);
+               ipsrst3_bits |= (NPCM_IPSRST3_USBD7 |
+                                NPCM_IPSRST3_USBD8 |
+                                NPCM_IPSRST3_USBD9);
+       }
+
+       /* assert reset USB PHY and USB devices */
+       iprst1 = readl(rc->base + NPCM_IPSRST1);
+       iprst2 = readl(rc->base + NPCM_IPSRST2);
+       iprst3 = readl(rc->base + NPCM_IPSRST3);
+
+       iprst1 |= ipsrst1_bits;
+       iprst2 |= ipsrst2_bits;
+       iprst3 |= (ipsrst3_bits | NPCM_IPSRST3_USBPHY1 |
+                  NPCM_IPSRST3_USBPHY2);
+
+       writel(iprst1, rc->base + NPCM_IPSRST1);
+       writel(iprst2, rc->base + NPCM_IPSRST2);
+       writel(iprst3, rc->base + NPCM_IPSRST3);
+
+       /* clear USB PHY RS bit */
+       regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
+                          NPCM_USBXPHYCTL_RS, 0);
+       regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
+                          NPCM_USBXPHYCTL_RS, 0);
+
+       /* deassert reset USB PHY */
+       iprst3 &= ~(NPCM_IPSRST3_USBPHY1 | NPCM_IPSRST3_USBPHY2);
+       writel(iprst3, rc->base + NPCM_IPSRST3);
+
+       udelay(50);
+
+       /* set USB PHY RS bit */
+       regmap_update_bits(gcr_regmap, NPCM_USB1PHYCTL_OFFSET,
+                          NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
+       regmap_update_bits(gcr_regmap, NPCM_USB2PHYCTL_OFFSET,
+                          NPCM_USBXPHYCTL_RS, NPCM_USBXPHYCTL_RS);
+
+       /* deassert reset USB devices*/
+       iprst1 &= ~ipsrst1_bits;
+       iprst2 &= ~ipsrst2_bits;
+       iprst3 &= ~ipsrst3_bits;
+
+       writel(iprst1, rc->base + NPCM_IPSRST1);
+       writel(iprst2, rc->base + NPCM_IPSRST2);
+       writel(iprst3, rc->base + NPCM_IPSRST3);
+
+       return 0;
+}
+
+static const struct reset_control_ops npcm_rc_ops = {
+       .assert         = npcm_rc_assert,
+       .deassert       = npcm_rc_deassert,
+       .status         = npcm_rc_status,
+};
+
+static int npcm_rc_probe(struct platform_device *pdev)
+{
+       struct npcm_rc_data *rc;
+       int ret;
+
+       rc = devm_kzalloc(&pdev->dev, sizeof(*rc), GFP_KERNEL);
+       if (!rc)
+               return -ENOMEM;
+
+       rc->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(rc->base))
+               return PTR_ERR(rc->base);
+
+       spin_lock_init(&rc->lock);
+
+       rc->rcdev.owner = THIS_MODULE;
+       rc->rcdev.ops = &npcm_rc_ops;
+       rc->rcdev.of_node = pdev->dev.of_node;
+       rc->rcdev.of_reset_n_cells = 2;
+       rc->rcdev.of_xlate = npcm_reset_xlate;
+
+       platform_set_drvdata(pdev, rc);
+
+       ret = devm_reset_controller_register(&pdev->dev, &rc->rcdev);
+       if (ret) {
+               dev_err(&pdev->dev, "unable to register device\n");
+               return ret;
+       }
+
+       if (npcm_usb_reset(pdev, rc))
+               dev_warn(&pdev->dev, "NPCM USB reset failed, can cause issues with UDC and USB host\n");
+
+       if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number",
+                                 &rc->sw_reset_number)) {
+               if (rc->sw_reset_number && rc->sw_reset_number < 5) {
+                       rc->restart_nb.priority = 192,
+                       rc->restart_nb.notifier_call = npcm_rc_restart,
+                       ret = register_restart_handler(&rc->restart_nb);
+                       if (ret)
+                               dev_warn(&pdev->dev, "failed to register restart handler\n");
+               }
+       }
+
+       return ret;
+}
+
+static struct platform_driver npcm_rc_driver = {
+       .probe  = npcm_rc_probe,
+       .driver = {
+               .name                   = "npcm-reset",
+               .of_match_table         = npcm_rc_match,
+               .suppress_bind_attrs    = true,
+       },
+};
+builtin_platform_driver(npcm_rc_driver);
index 36db967..9333b92 100644 (file)
@@ -118,6 +118,7 @@ static const struct of_device_id qcom_aoss_reset_of_match[] = {
        { .compatible = "qcom,sdm845-aoss-cc", .data = &sdm845_aoss_desc },
        {}
 };
+MODULE_DEVICE_TABLE(of, qcom_aoss_reset_of_match);
 
 static struct platform_driver qcom_aoss_reset_driver = {
        .probe = qcom_aoss_reset_probe,
@@ -127,7 +128,7 @@ static struct platform_driver qcom_aoss_reset_driver = {
        },
 };
 
-builtin_platform_driver(qcom_aoss_reset_driver);
+module_platform_driver(qcom_aoss_reset_driver);
 
 MODULE_DESCRIPTION("Qualcomm AOSS Reset Driver");
 MODULE_LICENSE("GPL v2");
index b46df80..8d3a858 100644 (file)
@@ -108,7 +108,7 @@ static int scmi_reset_probe(struct scmi_device *sdev)
 }
 
 static const struct scmi_device_id scmi_id_table[] = {
-       { SCMI_PROTOCOL_RESET },
+       { SCMI_PROTOCOL_RESET, "reset" },
        { },
 };
 MODULE_DEVICE_TABLE(scmi, scmi_id_table);
index 74e589f..279e535 100644 (file)
@@ -193,8 +193,8 @@ static const struct uniphier_reset_data uniphier_pro5_sd_reset_data[] = {
 #define UNIPHIER_PERI_RESET_FI2C(id, ch)               \
        UNIPHIER_RESETX((id), 0x114, 24 + (ch))
 
-#define UNIPHIER_PERI_RESET_SCSSI(id)                  \
-       UNIPHIER_RESETX((id), 0x110, 17)
+#define UNIPHIER_PERI_RESET_SCSSI(id, ch)              \
+       UNIPHIER_RESETX((id), 0x110, 17 + (ch))
 
 #define UNIPHIER_PERI_RESET_MCSSI(id)                  \
        UNIPHIER_RESETX((id), 0x114, 14)
@@ -209,7 +209,7 @@ static const struct uniphier_reset_data uniphier_ld4_peri_reset_data[] = {
        UNIPHIER_PERI_RESET_I2C(6, 2),
        UNIPHIER_PERI_RESET_I2C(7, 3),
        UNIPHIER_PERI_RESET_I2C(8, 4),
-       UNIPHIER_PERI_RESET_SCSSI(11),
+       UNIPHIER_PERI_RESET_SCSSI(11, 0),
        UNIPHIER_RESET_END,
 };
 
@@ -225,8 +225,11 @@ static const struct uniphier_reset_data uniphier_pro4_peri_reset_data[] = {
        UNIPHIER_PERI_RESET_FI2C(8, 4),
        UNIPHIER_PERI_RESET_FI2C(9, 5),
        UNIPHIER_PERI_RESET_FI2C(10, 6),
-       UNIPHIER_PERI_RESET_SCSSI(11),
-       UNIPHIER_PERI_RESET_MCSSI(12),
+       UNIPHIER_PERI_RESET_SCSSI(11, 0),
+       UNIPHIER_PERI_RESET_SCSSI(12, 1),
+       UNIPHIER_PERI_RESET_SCSSI(13, 2),
+       UNIPHIER_PERI_RESET_SCSSI(14, 3),
+       UNIPHIER_PERI_RESET_MCSSI(15),
        UNIPHIER_RESET_END,
 };
 
index 7092765..a9108ff 100644 (file)
@@ -15,6 +15,15 @@ config RPMSG_CHAR
          in /dev. They make it possible for user-space programs to send and
          receive rpmsg packets.
 
+config RPMSG_MTK_SCP
+       tristate "MediaTek SCP"
+       depends on MTK_SCP
+       select RPMSG
+       help
+         Say y here to enable support providing communication channels to
+         remote processors in MediaTek platforms.
+         This use IPI and IPC to communicate with remote processors.
+
 config RPMSG_QCOM_GLINK_NATIVE
        tristate
        select RPMSG
index 9aa8595..ae92a7f 100644 (file)
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0
 obj-$(CONFIG_RPMSG)            += rpmsg_core.o
 obj-$(CONFIG_RPMSG_CHAR)       += rpmsg_char.o
+obj-$(CONFIG_RPMSG_MTK_SCP)    += mtk_rpmsg.o
 obj-$(CONFIG_RPMSG_QCOM_GLINK_RPM) += qcom_glink_rpm.o
 obj-$(CONFIG_RPMSG_QCOM_GLINK_NATIVE) += qcom_glink_native.o
 obj-$(CONFIG_RPMSG_QCOM_GLINK_SMEM) += qcom_glink_smem.o
diff --git a/drivers/rpmsg/mtk_rpmsg.c b/drivers/rpmsg/mtk_rpmsg.c
new file mode 100644 (file)
index 0000000..232aa4e
--- /dev/null
@@ -0,0 +1,414 @@
+// SPDX-License-Identifier: GPL-2.0
+//
+// Copyright 2019 Google LLC.
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+#include <linux/rpmsg/mtk_rpmsg.h>
+#include <linux/workqueue.h>
+
+#include "rpmsg_internal.h"
+
+struct mtk_rpmsg_rproc_subdev {
+       struct platform_device *pdev;
+       struct mtk_rpmsg_info *info;
+       struct rpmsg_endpoint *ns_ept;
+       struct rproc_subdev subdev;
+
+       struct work_struct register_work;
+       struct list_head channels;
+       struct mutex channels_lock;
+};
+
+#define to_mtk_subdev(d) container_of(d, struct mtk_rpmsg_rproc_subdev, subdev)
+
+struct mtk_rpmsg_channel_info {
+       struct rpmsg_channel_info info;
+       bool registered;
+       struct list_head list;
+};
+
+/**
+ * struct rpmsg_ns_msg - dynamic name service announcement message
+ * @name: name of remote service that is published
+ * @addr: address of remote service that is published
+ *
+ * This message is sent across to publish a new service. When we receive these
+ * messages, an appropriate rpmsg channel (i.e device) is created. In turn, the
+ * ->probe() handler of the appropriate rpmsg driver will be invoked
+ *  (if/as-soon-as one is registered).
+ */
+struct rpmsg_ns_msg {
+       char name[RPMSG_NAME_SIZE];
+       u32 addr;
+} __packed;
+
+struct mtk_rpmsg_device {
+       struct rpmsg_device rpdev;
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev;
+};
+
+struct mtk_rpmsg_endpoint {
+       struct rpmsg_endpoint ept;
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev;
+};
+
+#define to_mtk_rpmsg_device(r) container_of(r, struct mtk_rpmsg_device, rpdev)
+#define to_mtk_rpmsg_endpoint(r) container_of(r, struct mtk_rpmsg_endpoint, ept)
+
+static const struct rpmsg_endpoint_ops mtk_rpmsg_endpoint_ops;
+
+static void __mtk_ept_release(struct kref *kref)
+{
+       struct rpmsg_endpoint *ept = container_of(kref, struct rpmsg_endpoint,
+                                                 refcount);
+       kfree(to_mtk_rpmsg_endpoint(ept));
+}
+
+static void mtk_rpmsg_ipi_handler(void *data, unsigned int len, void *priv)
+{
+       struct mtk_rpmsg_endpoint *mept = priv;
+       struct rpmsg_endpoint *ept = &mept->ept;
+       int ret;
+
+       ret = (*ept->cb)(ept->rpdev, data, len, ept->priv, ept->addr);
+       if (ret)
+               dev_warn(&ept->rpdev->dev, "rpmsg handler return error = %d",
+                        ret);
+}
+
+static struct rpmsg_endpoint *
+__mtk_create_ept(struct mtk_rpmsg_rproc_subdev *mtk_subdev,
+                struct rpmsg_device *rpdev, rpmsg_rx_cb_t cb, void *priv,
+                u32 id)
+{
+       struct mtk_rpmsg_endpoint *mept;
+       struct rpmsg_endpoint *ept;
+       struct platform_device *pdev = mtk_subdev->pdev;
+       int ret;
+
+       mept = kzalloc(sizeof(*mept), GFP_KERNEL);
+       if (!mept)
+               return NULL;
+       mept->mtk_subdev = mtk_subdev;
+
+       ept = &mept->ept;
+       kref_init(&ept->refcount);
+
+       ept->rpdev = rpdev;
+       ept->cb = cb;
+       ept->priv = priv;
+       ept->ops = &mtk_rpmsg_endpoint_ops;
+       ept->addr = id;
+
+       ret = mtk_subdev->info->register_ipi(pdev, id, mtk_rpmsg_ipi_handler,
+                                            mept);
+       if (ret) {
+               dev_err(&pdev->dev, "IPI register failed, id = %d", id);
+               kref_put(&ept->refcount, __mtk_ept_release);
+               return NULL;
+       }
+
+       return ept;
+}
+
+static struct rpmsg_endpoint *
+mtk_rpmsg_create_ept(struct rpmsg_device *rpdev, rpmsg_rx_cb_t cb, void *priv,
+                    struct rpmsg_channel_info chinfo)
+{
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev =
+               to_mtk_rpmsg_device(rpdev)->mtk_subdev;
+
+       return __mtk_create_ept(mtk_subdev, rpdev, cb, priv, chinfo.src);
+}
+
+static void mtk_rpmsg_destroy_ept(struct rpmsg_endpoint *ept)
+{
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev =
+               to_mtk_rpmsg_endpoint(ept)->mtk_subdev;
+
+       mtk_subdev->info->unregister_ipi(mtk_subdev->pdev, ept->addr);
+       kref_put(&ept->refcount, __mtk_ept_release);
+}
+
+static int mtk_rpmsg_send(struct rpmsg_endpoint *ept, void *data, int len)
+{
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev =
+               to_mtk_rpmsg_endpoint(ept)->mtk_subdev;
+
+       return mtk_subdev->info->send_ipi(mtk_subdev->pdev, ept->addr, data,
+                                         len, 0);
+}
+
+static int mtk_rpmsg_trysend(struct rpmsg_endpoint *ept, void *data, int len)
+{
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev =
+               to_mtk_rpmsg_endpoint(ept)->mtk_subdev;
+
+       /*
+        * TODO: This currently is same as mtk_rpmsg_send, and wait until SCP
+        * received the last command.
+        */
+       return mtk_subdev->info->send_ipi(mtk_subdev->pdev, ept->addr, data,
+                                         len, 0);
+}
+
+static const struct rpmsg_endpoint_ops mtk_rpmsg_endpoint_ops = {
+       .destroy_ept = mtk_rpmsg_destroy_ept,
+       .send = mtk_rpmsg_send,
+       .trysend = mtk_rpmsg_trysend,
+};
+
+static void mtk_rpmsg_release_device(struct device *dev)
+{
+       struct rpmsg_device *rpdev = to_rpmsg_device(dev);
+       struct mtk_rpmsg_device *mdev = to_mtk_rpmsg_device(rpdev);
+
+       kfree(mdev);
+}
+
+static const struct rpmsg_device_ops mtk_rpmsg_device_ops = {
+       .create_ept = mtk_rpmsg_create_ept,
+};
+
+static struct device_node *
+mtk_rpmsg_match_device_subnode(struct device_node *node, const char *channel)
+{
+       struct device_node *child;
+       const char *name;
+       int ret;
+
+       for_each_available_child_of_node(node, child) {
+               ret = of_property_read_string(child, "mtk,rpmsg-name", &name);
+               if (ret)
+                       continue;
+
+               if (strcmp(name, channel) == 0)
+                       return child;
+       }
+
+       return NULL;
+}
+
+static int mtk_rpmsg_register_device(struct mtk_rpmsg_rproc_subdev *mtk_subdev,
+                                    struct rpmsg_channel_info *info)
+{
+       struct rpmsg_device *rpdev;
+       struct mtk_rpmsg_device *mdev;
+       struct platform_device *pdev = mtk_subdev->pdev;
+       int ret;
+
+       mdev = kzalloc(sizeof(*mdev), GFP_KERNEL);
+       if (!mdev)
+               return -ENOMEM;
+
+       mdev->mtk_subdev = mtk_subdev;
+
+       rpdev = &mdev->rpdev;
+       rpdev->ops = &mtk_rpmsg_device_ops;
+       rpdev->src = info->src;
+       rpdev->dst = info->dst;
+       strscpy(rpdev->id.name, info->name, RPMSG_NAME_SIZE);
+
+       rpdev->dev.of_node =
+               mtk_rpmsg_match_device_subnode(pdev->dev.of_node, info->name);
+       rpdev->dev.parent = &pdev->dev;
+       rpdev->dev.release = mtk_rpmsg_release_device;
+
+       ret = rpmsg_register_device(rpdev);
+       if (ret) {
+               kfree(mdev);
+               return ret;
+       }
+
+       return 0;
+}
+
+static void mtk_register_device_work_function(struct work_struct *register_work)
+{
+       struct mtk_rpmsg_rproc_subdev *subdev = container_of(
+               register_work, struct mtk_rpmsg_rproc_subdev, register_work);
+       struct platform_device *pdev = subdev->pdev;
+       struct mtk_rpmsg_channel_info *info;
+       int ret;
+
+       mutex_lock(&subdev->channels_lock);
+       list_for_each_entry(info, &subdev->channels, list) {
+               if (info->registered)
+                       continue;
+
+               ret = mtk_rpmsg_register_device(subdev, &info->info);
+               if (ret) {
+                       dev_err(&pdev->dev, "Can't create rpmsg_device\n");
+                       continue;
+               }
+
+               info->registered = true;
+       }
+       mutex_unlock(&subdev->channels_lock);
+}
+
+static int mtk_rpmsg_create_device(struct mtk_rpmsg_rproc_subdev *mtk_subdev,
+                                  char *name, u32 addr)
+{
+       struct mtk_rpmsg_channel_info *info;
+
+       info = kzalloc(sizeof(*info), GFP_KERNEL);
+       if (!info)
+               return -ENOMEM;
+
+       strscpy(info->info.name, name, RPMSG_NAME_SIZE);
+       info->info.src = addr;
+       info->info.dst = RPMSG_ADDR_ANY;
+       mutex_lock(&mtk_subdev->channels_lock);
+       list_add(&info->list, &mtk_subdev->channels);
+       mutex_unlock(&mtk_subdev->channels_lock);
+
+       schedule_work(&mtk_subdev->register_work);
+       return 0;
+}
+
+static int mtk_rpmsg_ns_cb(struct rpmsg_device *rpdev, void *data, int len,
+                          void *priv, u32 src)
+{
+       struct rpmsg_ns_msg *msg = data;
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev = priv;
+       struct device *dev = &mtk_subdev->pdev->dev;
+
+       int ret;
+
+       if (len != sizeof(*msg)) {
+               dev_err(dev, "malformed ns msg (%d)\n", len);
+               return -EINVAL;
+       }
+
+       /*
+        * the name service ept does _not_ belong to a real rpmsg channel,
+        * and is handled by the rpmsg bus itself.
+        * for sanity reasons, make sure a valid rpdev has _not_ sneaked
+        * in somehow.
+        */
+       if (rpdev) {
+               dev_err(dev, "anomaly: ns ept has an rpdev handle\n");
+               return -EINVAL;
+       }
+
+       /* don't trust the remote processor for null terminating the name */
+       msg->name[RPMSG_NAME_SIZE - 1] = '\0';
+
+       dev_info(dev, "creating channel %s addr 0x%x\n", msg->name, msg->addr);
+
+       ret = mtk_rpmsg_create_device(mtk_subdev, msg->name, msg->addr);
+       if (ret) {
+               dev_err(dev, "create rpmsg device failed\n");
+               return ret;
+       }
+
+       return 0;
+}
+
+static int mtk_rpmsg_prepare(struct rproc_subdev *subdev)
+{
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev = to_mtk_subdev(subdev);
+
+       /* a dedicated endpoint handles the name service msgs */
+       if (mtk_subdev->info->ns_ipi_id >= 0) {
+               mtk_subdev->ns_ept =
+                       __mtk_create_ept(mtk_subdev, NULL, mtk_rpmsg_ns_cb,
+                                        mtk_subdev,
+                                        mtk_subdev->info->ns_ipi_id);
+               if (!mtk_subdev->ns_ept) {
+                       dev_err(&mtk_subdev->pdev->dev,
+                               "failed to create name service endpoint\n");
+                       return -ENOMEM;
+               }
+       }
+
+       return 0;
+}
+
+static void mtk_rpmsg_unprepare(struct rproc_subdev *subdev)
+{
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev = to_mtk_subdev(subdev);
+
+       if (mtk_subdev->ns_ept) {
+               mtk_rpmsg_destroy_ept(mtk_subdev->ns_ept);
+               mtk_subdev->ns_ept = NULL;
+       }
+}
+
+static void mtk_rpmsg_stop(struct rproc_subdev *subdev, bool crashed)
+{
+       struct mtk_rpmsg_channel_info *info, *next;
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev = to_mtk_subdev(subdev);
+       struct device *dev = &mtk_subdev->pdev->dev;
+
+       /*
+        * Destroy the name service endpoint here, to avoid new channel being
+        * created after the rpmsg_unregister_device loop below.
+        */
+       if (mtk_subdev->ns_ept) {
+               mtk_rpmsg_destroy_ept(mtk_subdev->ns_ept);
+               mtk_subdev->ns_ept = NULL;
+       }
+
+       cancel_work_sync(&mtk_subdev->register_work);
+
+       mutex_lock(&mtk_subdev->channels_lock);
+       list_for_each_entry(info, &mtk_subdev->channels, list) {
+               if (!info->registered)
+                       continue;
+               if (rpmsg_unregister_device(dev, &info->info)) {
+                       dev_warn(
+                               dev,
+                               "rpmsg_unregister_device failed for %s.%d.%d\n",
+                               info->info.name, info->info.src,
+                               info->info.dst);
+               }
+       }
+
+       list_for_each_entry_safe(info, next,
+                                &mtk_subdev->channels, list) {
+               list_del(&info->list);
+               kfree(info);
+       }
+       mutex_unlock(&mtk_subdev->channels_lock);
+}
+
+struct rproc_subdev *
+mtk_rpmsg_create_rproc_subdev(struct platform_device *pdev,
+                             struct mtk_rpmsg_info *info)
+{
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev;
+
+       mtk_subdev = kzalloc(sizeof(*mtk_subdev), GFP_KERNEL);
+       if (!mtk_subdev)
+               return NULL;
+
+       mtk_subdev->pdev = pdev;
+       mtk_subdev->subdev.prepare = mtk_rpmsg_prepare;
+       mtk_subdev->subdev.stop = mtk_rpmsg_stop;
+       mtk_subdev->subdev.unprepare = mtk_rpmsg_unprepare;
+       mtk_subdev->info = info;
+       INIT_LIST_HEAD(&mtk_subdev->channels);
+       INIT_WORK(&mtk_subdev->register_work,
+                 mtk_register_device_work_function);
+       mutex_init(&mtk_subdev->channels_lock);
+
+       return &mtk_subdev->subdev;
+}
+EXPORT_SYMBOL_GPL(mtk_rpmsg_create_rproc_subdev);
+
+void mtk_rpmsg_destroy_rproc_subdev(struct rproc_subdev *subdev)
+{
+       struct mtk_rpmsg_rproc_subdev *mtk_subdev = to_mtk_subdev(subdev);
+
+       kfree(mtk_subdev);
+}
+EXPORT_SYMBOL_GPL(mtk_rpmsg_destroy_rproc_subdev);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("MediaTek scp rpmsg driver");
index d77515d..34c8b6c 100644 (file)
@@ -240,6 +240,7 @@ config RTC_DRV_AS3722
 
 config RTC_DRV_DS1307
        tristate "Dallas/Maxim DS1307/37/38/39/40/41, ST M41T00, EPSON RX-8025, ISL12057"
+       select REGMAP_I2C
        help
          If you say yes here you get support for various compatible RTC
          chips (often with battery backup) connected with I2C. This driver
@@ -498,12 +499,13 @@ config RTC_DRV_M41T80_WDT
        help
          If you say Y here you will get support for the
          watchdog timer in the ST M41T60 and M41T80 RTC chips series.
+
 config RTC_DRV_BD70528
        tristate "ROHM BD70528 PMIC RTC"
        depends on MFD_ROHM_BD70528 && (BD70528_WATCHDOG || !BD70528_WATCHDOG)
        help
          If you say Y here you will get support for the RTC
-         on ROHM BD70528 Power Management IC.
+         block on ROHM BD70528 and BD71828 Power Management IC.
 
          This driver can also be built as a module. If so, the module
          will be called rtc-bd70528.
@@ -621,6 +623,7 @@ config RTC_DRV_RX8010
 
 config RTC_DRV_RX8581
        tristate "Epson RX-8571/RX-8581"
+       select REGMAP_I2C
        help
          If you say yes here you will get support for the Epson RX-8571/
          RX-8581.
@@ -648,6 +651,7 @@ config RTC_DRV_EM3027
 
 config RTC_DRV_RV3028
        tristate "Micro Crystal RV3028"
+       select REGMAP_I2C
        help
          If you say yes here you get support for the Micro Crystal
          RV3028.
@@ -676,13 +680,14 @@ config RTC_DRV_S5M
          will be called rtc-s5m.
 
 config RTC_DRV_SD3078
-    tristate "ZXW Shenzhen whwave SD3078"
-    help
-      If you say yes here you get support for the ZXW Shenzhen whwave
-      SD3078 RTC chips.
+       tristate "ZXW Shenzhen whwave SD3078"
+       select REGMAP_I2C
+       help
+         If you say yes here you get support for the ZXW Shenzhen whwave
+         SD3078 RTC chips.
 
-      This driver can also be built as a module. If so, the module
-      will be called rtc-sd3078
+         This driver can also be built as a module. If so, the module
+         will be called rtc-sd3078
 
 endif # I2C
 
@@ -848,14 +853,14 @@ config RTC_I2C_AND_SPI
        default m if I2C=m
        default y if I2C=y
        default y if SPI_MASTER=y
-       select REGMAP_I2C if I2C
-       select REGMAP_SPI if SPI_MASTER
 
 comment "SPI and I2C RTC drivers"
 
 config RTC_DRV_DS3232
        tristate "Dallas/Maxim DS3232/DS3234"
        depends on RTC_I2C_AND_SPI
+       select REGMAP_I2C if I2C
+       select REGMAP_SPI if SPI_MASTER
        help
          If you say yes here you get support for Dallas Semiconductor
          DS3232 and DS3234 real-time clock chips. If an interrupt is associated
@@ -875,6 +880,8 @@ config RTC_DRV_DS3232_HWMON
 config RTC_DRV_PCF2127
        tristate "NXP PCF2127"
        depends on RTC_I2C_AND_SPI
+       select REGMAP_I2C if I2C
+       select REGMAP_SPI if SPI_MASTER
        select WATCHDOG_CORE if WATCHDOG
        help
          If you say yes here you get support for the NXP PCF2127/29 RTC
@@ -891,6 +898,8 @@ config RTC_DRV_PCF2127
 config RTC_DRV_RV3029C2
        tristate "Micro Crystal RV3029/3049"
        depends on RTC_I2C_AND_SPI
+       select REGMAP_I2C if I2C
+       select REGMAP_SPI if SPI_MASTER
        help
          If you say yes here you get support for the Micro Crystal
          RV3029 and RV3049 RTC chips.
index 7383067..3521d8e 100644 (file)
@@ -523,12 +523,9 @@ static int abx80x_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
                if (status < 0)
                        return status;
 
-               tmp = !!(status & ABX8XX_STATUS_BLF);
+               tmp = status & ABX8XX_STATUS_BLF ? RTC_VL_BACKUP_LOW : 0;
 
-               if (copy_to_user((void __user *)arg, &tmp, sizeof(int)))
-                       return -EFAULT;
-
-               return 0;
+               return put_user(tmp, (unsigned int __user *)arg);
 
        case RTC_VL_CLR:
                status = i2c_smbus_read_byte_data(client, ABX8XX_REG_STATUS);
index 10064bd..3ab81cd 100644 (file)
@@ -264,6 +264,9 @@ static int asm9260_rtc_probe(struct platform_device *pdev)
                return PTR_ERR(priv->iobase);
 
        priv->clk = devm_clk_get(dev, "ahb");
+       if (IS_ERR(priv->clk))
+               return PTR_ERR(priv->clk);
+
        ret = clk_prepare_enable(priv->clk);
        if (ret) {
                dev_err(dev, "Failed to enable clk!\n");
index 3b833e0..5e811e0 100644 (file)
@@ -14,6 +14,7 @@
  */
 
 #include <linux/bcd.h>
+#include <linux/bitfield.h>
 #include <linux/clk.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
 #include <linux/time.h>
 #include <linux/uaccess.h>
 
-#include "rtc-at91rm9200.h"
+#define        AT91_RTC_CR             0x00                    /* Control Register */
+#define                AT91_RTC_UPDTIM         BIT(0)          /* Update Request Time Register */
+#define                AT91_RTC_UPDCAL         BIT(1)          /* Update Request Calendar Register */
+
+#define        AT91_RTC_MR             0x04                    /* Mode Register */
+
+#define        AT91_RTC_TIMR           0x08                    /* Time Register */
+#define                AT91_RTC_SEC            GENMASK(6, 0)   /* Current Second */
+#define                AT91_RTC_MIN            GENMASK(14, 8)  /* Current Minute */
+#define                AT91_RTC_HOUR           GENMASK(21, 16) /* Current Hour */
+#define                AT91_RTC_AMPM           BIT(22)         /* Ante Meridiem Post Meridiem Indicator */
+
+#define        AT91_RTC_CALR           0x0c                    /* Calendar Register */
+#define                AT91_RTC_CENT           GENMASK(6, 0)   /* Current Century */
+#define                AT91_RTC_YEAR           GENMASK(15, 8)  /* Current Year */
+#define                AT91_RTC_MONTH          GENMASK(20, 16) /* Current Month */
+#define                AT91_RTC_DAY            GENMASK(23, 21) /* Current Day */
+#define                AT91_RTC_DATE           GENMASK(29, 24) /* Current Date */
+
+#define        AT91_RTC_TIMALR         0x10                    /* Time Alarm Register */
+#define                AT91_RTC_SECEN          BIT(7)          /* Second Alarm Enable */
+#define                AT91_RTC_MINEN          BIT(15)         /* Minute Alarm Enable */
+#define                AT91_RTC_HOUREN         BIT(23)         /* Hour Alarm Enable */
+
+#define        AT91_RTC_CALALR         0x14                    /* Calendar Alarm Register */
+#define                AT91_RTC_MTHEN          BIT(23)         /* Month Alarm Enable */
+#define                AT91_RTC_DATEEN         BIT(31)         /* Date Alarm Enable */
+
+#define        AT91_RTC_SR             0x18                    /* Status Register */
+#define                AT91_RTC_ACKUPD         BIT(0)          /* Acknowledge for Update */
+#define                AT91_RTC_ALARM          BIT(1)          /* Alarm Flag */
+#define                AT91_RTC_SECEV          BIT(2)          /* Second Event */
+#define                AT91_RTC_TIMEV          BIT(3)          /* Time Event */
+#define                AT91_RTC_CALEV          BIT(4)          /* Calendar Event */
+
+#define        AT91_RTC_SCCR           0x1c                    /* Status Clear Command Register */
+#define        AT91_RTC_IER            0x20                    /* Interrupt Enable Register */
+#define        AT91_RTC_IDR            0x24                    /* Interrupt Disable Register */
+#define        AT91_RTC_IMR            0x28                    /* Interrupt Mask Register */
+
+#define        AT91_RTC_VER            0x2c                    /* Valid Entry Register */
+#define                AT91_RTC_NVTIM          BIT(0)          /* Non valid Time */
+#define                AT91_RTC_NVCAL          BIT(1)          /* Non valid Calendar */
+#define                AT91_RTC_NVTIMALR       BIT(2)          /* Non valid Time Alarm */
+#define                AT91_RTC_NVCALALR       BIT(3)          /* Non valid Calendar Alarm */
 
 #define at91_rtc_read(field) \
        readl_relaxed(at91_rtc_regs + field)
@@ -117,20 +162,20 @@ static void at91_rtc_decodetime(unsigned int timereg, unsigned int calreg,
        } while ((time != at91_rtc_read(timereg)) ||
                        (date != at91_rtc_read(calreg)));
 
-       tm->tm_sec  = bcd2bin((time & AT91_RTC_SEC) >> 0);
-       tm->tm_min  = bcd2bin((time & AT91_RTC_MIN) >> 8);
-       tm->tm_hour = bcd2bin((time & AT91_RTC_HOUR) >> 16);
+       tm->tm_sec  = bcd2bin(FIELD_GET(AT91_RTC_SEC, time));
+       tm->tm_min  = bcd2bin(FIELD_GET(AT91_RTC_MIN, time));
+       tm->tm_hour = bcd2bin(FIELD_GET(AT91_RTC_HOUR, time));
 
        /*
         * The Calendar Alarm register does not have a field for
         * the year - so these will return an invalid value.
         */
        tm->tm_year  = bcd2bin(date & AT91_RTC_CENT) * 100;     /* century */
-       tm->tm_year += bcd2bin((date & AT91_RTC_YEAR) >> 8);    /* year */
+       tm->tm_year += bcd2bin(FIELD_GET(AT91_RTC_YEAR, date)); /* year */
 
-       tm->tm_wday = bcd2bin((date & AT91_RTC_DAY) >> 21) - 1; /* day of the week [0-6], Sunday=0 */
-       tm->tm_mon  = bcd2bin((date & AT91_RTC_MONTH) >> 16) - 1;
-       tm->tm_mday = bcd2bin((date & AT91_RTC_DATE) >> 24);
+       tm->tm_wday = bcd2bin(FIELD_GET(AT91_RTC_DAY, date)) - 1;       /* day of the week [0-6], Sunday=0 */
+       tm->tm_mon  = bcd2bin(FIELD_GET(AT91_RTC_MONTH, date)) - 1;
+       tm->tm_mday = bcd2bin(FIELD_GET(AT91_RTC_DATE, date));
 }
 
 /*
@@ -167,16 +212,17 @@ static int at91_rtc_settime(struct device *dev, struct rtc_time *tm)
        at91_rtc_write_idr(AT91_RTC_ACKUPD);
 
        at91_rtc_write(AT91_RTC_TIMR,
-                         bin2bcd(tm->tm_sec) << 0
-                       | bin2bcd(tm->tm_min) << 8
-                       | bin2bcd(tm->tm_hour) << 16);
+                         FIELD_PREP(AT91_RTC_SEC, bin2bcd(tm->tm_sec))
+                       | FIELD_PREP(AT91_RTC_MIN, bin2bcd(tm->tm_min))
+                       | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(tm->tm_hour)));
 
        at91_rtc_write(AT91_RTC_CALR,
-                         bin2bcd((tm->tm_year + 1900) / 100)   /* century */
-                       | bin2bcd(tm->tm_year % 100) << 8       /* year */
-                       | bin2bcd(tm->tm_mon + 1) << 16         /* tm_mon starts at zero */
-                       | bin2bcd(tm->tm_wday + 1) << 21        /* day of the week [0-6], Sunday=0 */
-                       | bin2bcd(tm->tm_mday) << 24);
+                         FIELD_PREP(AT91_RTC_CENT,
+                                    bin2bcd((tm->tm_year + 1900) / 100))
+                       | FIELD_PREP(AT91_RTC_YEAR, bin2bcd(tm->tm_year % 100))
+                       | FIELD_PREP(AT91_RTC_MONTH, bin2bcd(tm->tm_mon + 1))
+                       | FIELD_PREP(AT91_RTC_DAY, bin2bcd(tm->tm_wday + 1))
+                       | FIELD_PREP(AT91_RTC_DATE, bin2bcd(tm->tm_mday)));
 
        /* Restart Time/Calendar */
        cr = at91_rtc_read(AT91_RTC_CR);
@@ -211,25 +257,17 @@ static int at91_rtc_readalarm(struct device *dev, struct rtc_wkalrm *alrm)
  */
 static int at91_rtc_setalarm(struct device *dev, struct rtc_wkalrm *alrm)
 {
-       struct rtc_time tm;
-
-       at91_rtc_decodetime(AT91_RTC_TIMR, AT91_RTC_CALR, &tm);
-
-       tm.tm_mon = alrm->time.tm_mon;
-       tm.tm_mday = alrm->time.tm_mday;
-       tm.tm_hour = alrm->time.tm_hour;
-       tm.tm_min = alrm->time.tm_min;
-       tm.tm_sec = alrm->time.tm_sec;
+       struct rtc_time tm = alrm->time;
 
        at91_rtc_write_idr(AT91_RTC_ALARM);
        at91_rtc_write(AT91_RTC_TIMALR,
-                 bin2bcd(tm.tm_sec) << 0
-               | bin2bcd(tm.tm_min) << 8
-               | bin2bcd(tm.tm_hour) << 16
+                 FIELD_PREP(AT91_RTC_SEC, bin2bcd(alrm->time.tm_sec))
+               | FIELD_PREP(AT91_RTC_MIN, bin2bcd(alrm->time.tm_min))
+               | FIELD_PREP(AT91_RTC_HOUR, bin2bcd(alrm->time.tm_hour))
                | AT91_RTC_HOUREN | AT91_RTC_MINEN | AT91_RTC_SECEN);
        at91_rtc_write(AT91_RTC_CALALR,
-                 bin2bcd(tm.tm_mon + 1) << 16          /* tm_mon starts at zero */
-               | bin2bcd(tm.tm_mday) << 24
+                 FIELD_PREP(AT91_RTC_MONTH, bin2bcd(alrm->time.tm_mon + 1))
+               | FIELD_PREP(AT91_RTC_DATE, bin2bcd(alrm->time.tm_mday))
                | AT91_RTC_DATEEN | AT91_RTC_MTHEN);
 
        if (alrm->enabled) {
@@ -254,20 +292,6 @@ static int at91_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
        return 0;
 }
-/*
- * Provide additional RTC information in /proc/driver/rtc
- */
-static int at91_rtc_proc(struct device *dev, struct seq_file *seq)
-{
-       unsigned long imr = at91_rtc_read_imr();
-
-       seq_printf(seq, "update_IRQ\t: %s\n",
-                       (imr & AT91_RTC_ACKUPD) ? "yes" : "no");
-       seq_printf(seq, "periodic_IRQ\t: %s\n",
-                       (imr & AT91_RTC_SECEV) ? "yes" : "no");
-
-       return 0;
-}
 
 /*
  * IRQ handler for the RTC
@@ -327,6 +351,12 @@ static const struct of_device_id at91_rtc_dt_ids[] = {
                .compatible = "atmel,at91sam9x5-rtc",
                .data = &at91sam9x5_config,
        }, {
+               .compatible = "atmel,sama5d4-rtc",
+               .data = &at91rm9200_config,
+       }, {
+               .compatible = "atmel,sama5d2-rtc",
+               .data = &at91rm9200_config,
+       }, {
                /* sentinel */
        }
 };
@@ -337,7 +367,6 @@ static const struct rtc_class_ops at91_rtc_ops = {
        .set_time       = at91_rtc_settime,
        .read_alarm     = at91_rtc_readalarm,
        .set_alarm      = at91_rtc_setalarm,
-       .proc           = at91_rtc_proc,
        .alarm_irq_enable = at91_rtc_alarm_irq_enable,
 };
 
diff --git a/drivers/rtc/rtc-at91rm9200.h b/drivers/rtc/rtc-at91rm9200.h
deleted file mode 100644 (file)
index 8be5289..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * arch/arm/mach-at91/include/mach/at91_rtc.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Real Time Clock (RTC) - System peripheral registers.
- * Based on AT91RM9200 datasheet revision E.
- */
-
-#ifndef AT91_RTC_H
-#define AT91_RTC_H
-
-#define        AT91_RTC_CR             0x00                    /* Control Register */
-#define                AT91_RTC_UPDTIM         (1 <<  0)               /* Update Request Time Register */
-#define                AT91_RTC_UPDCAL         (1 <<  1)               /* Update Request Calendar Register */
-#define                AT91_RTC_TIMEVSEL       (3 <<  8)               /* Time Event Selection */
-#define                        AT91_RTC_TIMEVSEL_MINUTE        (0 << 8)
-#define                        AT91_RTC_TIMEVSEL_HOUR          (1 << 8)
-#define                        AT91_RTC_TIMEVSEL_DAY24         (2 << 8)
-#define                        AT91_RTC_TIMEVSEL_DAY12         (3 << 8)
-#define                AT91_RTC_CALEVSEL       (3 << 16)               /* Calendar Event Selection */
-#define                        AT91_RTC_CALEVSEL_WEEK          (0 << 16)
-#define                        AT91_RTC_CALEVSEL_MONTH         (1 << 16)
-#define                        AT91_RTC_CALEVSEL_YEAR          (2 << 16)
-
-#define        AT91_RTC_MR             0x04                    /* Mode Register */
-#define                        AT91_RTC_HRMOD          (1 <<  0)               /* 12/24 Hour Mode */
-
-#define        AT91_RTC_TIMR           0x08                    /* Time Register */
-#define                AT91_RTC_SEC            (0x7f <<  0)            /* Current Second */
-#define                AT91_RTC_MIN            (0x7f <<  8)            /* Current Minute */
-#define                AT91_RTC_HOUR           (0x3f << 16)            /* Current Hour */
-#define                AT91_RTC_AMPM           (1    << 22)            /* Ante Meridiem Post Meridiem Indicator */
-
-#define        AT91_RTC_CALR           0x0c                    /* Calendar Register */
-#define                AT91_RTC_CENT           (0x7f <<  0)            /* Current Century */
-#define                AT91_RTC_YEAR           (0xff <<  8)            /* Current Year */
-#define                AT91_RTC_MONTH          (0x1f << 16)            /* Current Month */
-#define                AT91_RTC_DAY            (7    << 21)            /* Current Day */
-#define                AT91_RTC_DATE           (0x3f << 24)            /* Current Date */
-
-#define        AT91_RTC_TIMALR         0x10                    /* Time Alarm Register */
-#define                AT91_RTC_SECEN          (1 <<  7)               /* Second Alarm Enable */
-#define                AT91_RTC_MINEN          (1 << 15)               /* Minute Alarm Enable */
-#define                AT91_RTC_HOUREN         (1 << 23)               /* Hour Alarm Enable */
-
-#define        AT91_RTC_CALALR         0x14                    /* Calendar Alarm Register */
-#define                AT91_RTC_MTHEN          (1 << 23)               /* Month Alarm Enable */
-#define                AT91_RTC_DATEEN         (1 << 31)               /* Date Alarm Enable */
-
-#define        AT91_RTC_SR             0x18                    /* Status Register */
-#define                AT91_RTC_ACKUPD         (1 <<  0)               /* Acknowledge for Update */
-#define                AT91_RTC_ALARM          (1 <<  1)               /* Alarm Flag */
-#define                AT91_RTC_SECEV          (1 <<  2)               /* Second Event */
-#define                AT91_RTC_TIMEV          (1 <<  3)               /* Time Event */
-#define                AT91_RTC_CALEV          (1 <<  4)               /* Calendar Event */
-
-#define        AT91_RTC_SCCR           0x1c                    /* Status Clear Command Register */
-#define        AT91_RTC_IER            0x20                    /* Interrupt Enable Register */
-#define        AT91_RTC_IDR            0x24                    /* Interrupt Disable Register */
-#define        AT91_RTC_IMR            0x28                    /* Interrupt Mask Register */
-
-#define        AT91_RTC_VER            0x2c                    /* Valid Entry Register */
-#define                AT91_RTC_NVTIM          (1 <<  0)               /* Non valid Time */
-#define                AT91_RTC_NVCAL          (1 <<  1)               /* Non valid Calendar */
-#define                AT91_RTC_NVTIMALR       (1 <<  2)               /* Non valid Time Alarm */
-#define                AT91_RTC_NVCALALR       (1 <<  3)               /* Non valid Calendar Alarm */
-
-#endif
index 627037a..bbbb1f0 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/bcd.h>
 #include <linux/mfd/rohm-bd70528.h>
+#include <linux/mfd/rohm-bd71828.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/platform_device.h>
@@ -15,7 +16,7 @@
 /*
  * We read regs RTC_SEC => RTC_YEAR
  * this struct is ordered according to chip registers.
- * Keep it u8 only to avoid padding issues.
+ * Keep it u8 only (or packed) to avoid padding issues.
  */
 struct bd70528_rtc_day {
        u8 sec;
@@ -36,6 +37,13 @@ struct bd70528_rtc_wake {
        u8 ctrl;
 } __packed;
 
+struct bd71828_rtc_alm {
+       struct bd70528_rtc_data alm0;
+       struct bd70528_rtc_data alm1;
+       u8 alm_mask;
+       u8 alm1_mask;
+} __packed;
+
 struct bd70528_rtc_alm {
        struct bd70528_rtc_data data;
        u8 alm_mask;
@@ -43,8 +51,10 @@ struct bd70528_rtc_alm {
 } __packed;
 
 struct bd70528_rtc {
-       struct rohm_regmap_dev *mfd;
+       struct rohm_regmap_dev *parent;
        struct device *dev;
+       u8 reg_time_start;
+       bool has_rtc_timers;
 };
 
 static int bd70528_set_wake(struct rohm_regmap_dev *bd70528,
@@ -123,14 +133,14 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
 {
        int ret;
 
-       ret = bd70528_wdt_set(r->mfd, new_state & BD70528_WDT_STATE_BIT,
+       ret = bd70528_wdt_set(r->parent, new_state & BD70528_WDT_STATE_BIT,
                              old_state);
        if (ret) {
                dev_err(r->dev,
                        "Failed to disable WDG for RTC setting (%d)\n", ret);
                return ret;
        }
-       ret = bd70528_set_elapsed_tmr(r->mfd,
+       ret = bd70528_set_elapsed_tmr(r->parent,
                                      new_state & BD70528_ELAPSED_STATE_BIT,
                                      old_state);
        if (ret) {
@@ -138,7 +148,7 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
                        "Failed to disable 'elapsed timer' for RTC setting\n");
                return ret;
        }
-       ret = bd70528_set_wake(r->mfd, new_state & BD70528_WAKE_STATE_BIT,
+       ret = bd70528_set_wake(r->parent, new_state & BD70528_WAKE_STATE_BIT,
                               old_state);
        if (ret) {
                dev_err(r->dev,
@@ -152,12 +162,18 @@ static int bd70528_set_rtc_based_timers(struct bd70528_rtc *r, int new_state,
 static int bd70528_re_enable_rtc_based_timers(struct bd70528_rtc *r,
                                              int old_state)
 {
+       if (!r->has_rtc_timers)
+               return 0;
+
        return bd70528_set_rtc_based_timers(r, old_state, NULL);
 }
 
 static int bd70528_disable_rtc_based_timers(struct bd70528_rtc *r,
                                            int *old_state)
 {
+       if (!r->has_rtc_timers)
+               return 0;
+
        return bd70528_set_rtc_based_timers(r, 0, old_state);
 }
 
@@ -213,22 +229,52 @@ static inline void rtc2tm(struct bd70528_rtc_data *r, struct rtc_time *t)
        t->tm_wday = bcd2bin(r->week & BD70528_MASK_RTC_WEEK);
 }
 
+static int bd71828_set_alarm(struct device *dev, struct rtc_wkalrm *a)
+{
+       int ret;
+       struct bd71828_rtc_alm alm;
+       struct bd70528_rtc *r = dev_get_drvdata(dev);
+       struct rohm_regmap_dev *parent = r->parent;
+
+       ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START,
+                              &alm, sizeof(alm));
+       if (ret) {
+               dev_err(dev, "Failed to read alarm regs\n");
+               return ret;
+       }
+
+       tm2rtc(&a->time, &alm.alm0);
+
+       if (!a->enabled)
+               alm.alm_mask &= ~BD70528_MASK_ALM_EN;
+       else
+               alm.alm_mask |= BD70528_MASK_ALM_EN;
+
+       ret = regmap_bulk_write(parent->regmap, BD71828_REG_RTC_ALM_START,
+                               &alm, sizeof(alm));
+       if (ret)
+               dev_err(dev, "Failed to set alarm time\n");
+
+       return ret;
+
+}
+
 static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
 {
        struct bd70528_rtc_wake wake;
        struct bd70528_rtc_alm alm;
        int ret;
        struct bd70528_rtc *r = dev_get_drvdata(dev);
-       struct rohm_regmap_dev *bd70528 = r->mfd;
+       struct rohm_regmap_dev *parent = r->parent;
 
-       ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_WAKE_START,
+       ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_WAKE_START,
                               &wake, sizeof(wake));
        if (ret) {
                dev_err(dev, "Failed to read wake regs\n");
                return ret;
        }
 
-       ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START,
+       ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START,
                               &alm, sizeof(alm));
        if (ret) {
                dev_err(dev, "Failed to read alarm regs\n");
@@ -246,14 +292,14 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
                wake.ctrl &= ~BD70528_MASK_WAKE_EN;
        }
 
-       ret = regmap_bulk_write(bd70528->regmap,
+       ret = regmap_bulk_write(parent->regmap,
                                BD70528_REG_RTC_WAKE_START, &wake,
                                sizeof(wake));
        if (ret) {
                dev_err(dev, "Failed to set wake time\n");
                return ret;
        }
-       ret = regmap_bulk_write(bd70528->regmap, BD70528_REG_RTC_ALM_START,
+       ret = regmap_bulk_write(parent->regmap, BD70528_REG_RTC_ALM_START,
                                &alm, sizeof(alm));
        if (ret)
                dev_err(dev, "Failed to set alarm time\n");
@@ -261,14 +307,38 @@ static int bd70528_set_alarm(struct device *dev, struct rtc_wkalrm *a)
        return ret;
 }
 
+static int bd71828_read_alarm(struct device *dev, struct rtc_wkalrm *a)
+{
+       int ret;
+       struct bd71828_rtc_alm alm;
+       struct bd70528_rtc *r = dev_get_drvdata(dev);
+       struct rohm_regmap_dev *parent = r->parent;
+
+       ret = regmap_bulk_read(parent->regmap, BD71828_REG_RTC_ALM_START,
+                              &alm, sizeof(alm));
+       if (ret) {
+               dev_err(dev, "Failed to read alarm regs\n");
+               return ret;
+       }
+
+       rtc2tm(&alm.alm0, &a->time);
+       a->time.tm_mday = -1;
+       a->time.tm_mon = -1;
+       a->time.tm_year = -1;
+       a->enabled = !!(alm.alm_mask & BD70528_MASK_ALM_EN);
+       a->pending = 0;
+
+       return 0;
+}
+
 static int bd70528_read_alarm(struct device *dev, struct rtc_wkalrm *a)
 {
        struct bd70528_rtc_alm alm;
        int ret;
        struct bd70528_rtc *r = dev_get_drvdata(dev);
-       struct rohm_regmap_dev *bd70528 = r->mfd;
+       struct rohm_regmap_dev *parent = r->parent;
 
-       ret = regmap_bulk_read(bd70528->regmap, BD70528_REG_RTC_ALM_START,
+       ret = regmap_bulk_read(parent->regmap, BD70528_REG_RTC_ALM_START,
                               &alm, sizeof(alm));
        if (ret) {
                dev_err(dev, "Failed to read alarm regs\n");
@@ -290,14 +360,14 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
        int ret, tmpret, old_states;
        struct bd70528_rtc_data rtc_data;
        struct bd70528_rtc *r = dev_get_drvdata(dev);
-       struct rohm_regmap_dev *bd70528 = r->mfd;
+       struct rohm_regmap_dev *parent = r->parent;
 
        ret = bd70528_disable_rtc_based_timers(r, &old_states);
        if (ret)
                return ret;
 
-       tmpret = regmap_bulk_read(bd70528->regmap,
-                                 BD70528_REG_RTC_START, &rtc_data,
+       tmpret = regmap_bulk_read(parent->regmap,
+                                 r->reg_time_start, &rtc_data,
                                  sizeof(rtc_data));
        if (tmpret) {
                dev_err(dev, "Failed to read RTC time registers\n");
@@ -305,8 +375,8 @@ static int bd70528_set_time_locked(struct device *dev, struct rtc_time *t)
        }
        tm2rtc(t, &rtc_data);
 
-       tmpret = regmap_bulk_write(bd70528->regmap,
-                                  BD70528_REG_RTC_START, &rtc_data,
+       tmpret = regmap_bulk_write(parent->regmap,
+                                  r->reg_time_start, &rtc_data,
                                   sizeof(rtc_data));
        if (tmpret) {
                dev_err(dev, "Failed to set RTC time\n");
@@ -321,27 +391,32 @@ renable_out:
        return ret;
 }
 
+static int bd71828_set_time(struct device *dev, struct rtc_time *t)
+{
+       return bd70528_set_time_locked(dev, t);
+}
+
 static int bd70528_set_time(struct device *dev, struct rtc_time *t)
 {
        int ret;
        struct bd70528_rtc *r = dev_get_drvdata(dev);
 
-       bd70528_wdt_lock(r->mfd);
+       bd70528_wdt_lock(r->parent);
        ret = bd70528_set_time_locked(dev, t);
-       bd70528_wdt_unlock(r->mfd);
+       bd70528_wdt_unlock(r->parent);
        return ret;
 }
 
 static int bd70528_get_time(struct device *dev, struct rtc_time *t)
 {
        struct bd70528_rtc *r = dev_get_drvdata(dev);
-       struct rohm_regmap_dev *bd70528 = r->mfd;
+       struct rohm_regmap_dev *parent = r->parent;
        struct bd70528_rtc_data rtc_data;
        int ret;
 
        /* read the RTC date and time registers all at once */
-       ret = regmap_bulk_read(bd70528->regmap,
-                              BD70528_REG_RTC_START, &rtc_data,
+       ret = regmap_bulk_read(parent->regmap,
+                              r->reg_time_start, &rtc_data,
                               sizeof(rtc_data));
        if (ret) {
                dev_err(dev, "Failed to read RTC time (err %d)\n", ret);
@@ -362,19 +437,36 @@ static int bd70528_alm_enable(struct device *dev, unsigned int enabled)
        if (enabled)
                enableval = 0;
 
-       bd70528_wdt_lock(r->mfd);
-       ret = bd70528_set_wake(r->mfd, enabled, NULL);
+       bd70528_wdt_lock(r->parent);
+       ret = bd70528_set_wake(r->parent, enabled, NULL);
        if (ret) {
                dev_err(dev, "Failed to change wake state\n");
                goto out_unlock;
        }
-       ret = regmap_update_bits(r->mfd->regmap, BD70528_REG_RTC_ALM_MASK,
+       ret = regmap_update_bits(r->parent->regmap, BD70528_REG_RTC_ALM_MASK,
                                 BD70528_MASK_ALM_EN, enableval);
        if (ret)
                dev_err(dev, "Failed to change alarm state\n");
 
 out_unlock:
-       bd70528_wdt_unlock(r->mfd);
+       bd70528_wdt_unlock(r->parent);
+       return ret;
+}
+
+static int bd71828_alm_enable(struct device *dev, unsigned int enabled)
+{
+       int ret;
+       struct bd70528_rtc *r = dev_get_drvdata(dev);
+       unsigned int enableval = BD70528_MASK_ALM_EN;
+
+       if (!enabled)
+               enableval = 0;
+
+       ret = regmap_update_bits(r->parent->regmap, BD71828_REG_RTC_ALM0_MASK,
+                                BD70528_MASK_ALM_EN, enableval);
+       if (ret)
+               dev_err(dev, "Failed to change alarm state\n");
+
        return ret;
 }
 
@@ -386,6 +478,14 @@ static const struct rtc_class_ops bd70528_rtc_ops = {
        .alarm_irq_enable       = bd70528_alm_enable,
 };
 
+static const struct rtc_class_ops bd71828_rtc_ops = {
+       .read_time              = bd70528_get_time,
+       .set_time               = bd71828_set_time,
+       .read_alarm             = bd71828_read_alarm,
+       .set_alarm              = bd71828_set_alarm,
+       .alarm_irq_enable       = bd71828_alm_enable,
+};
+
 static irqreturn_t alm_hndlr(int irq, void *data)
 {
        struct rtc_device *rtc = data;
@@ -397,14 +497,19 @@ static irqreturn_t alm_hndlr(int irq, void *data)
 static int bd70528_probe(struct platform_device *pdev)
 {
        struct bd70528_rtc *bd_rtc;
-       struct rohm_regmap_dev *mfd;
+       const struct rtc_class_ops *rtc_ops;
+       struct rohm_regmap_dev *parent;
+       const char *irq_name;
        int ret;
        struct rtc_device *rtc;
        int irq;
        unsigned int hr;
+       bool enable_main_irq = false;
+       u8 hour_reg;
+       enum rohm_chip_type chip = platform_get_device_id(pdev)->driver_data;
 
-       mfd = dev_get_drvdata(pdev->dev.parent);
-       if (!mfd) {
+       parent = dev_get_drvdata(pdev->dev.parent);
+       if (!parent) {
                dev_err(&pdev->dev, "No MFD driver data\n");
                return -EINVAL;
        }
@@ -412,16 +517,39 @@ static int bd70528_probe(struct platform_device *pdev)
        if (!bd_rtc)
                return -ENOMEM;
 
-       bd_rtc->mfd = mfd;
+       bd_rtc->parent = parent;
        bd_rtc->dev = &pdev->dev;
 
-       irq = platform_get_irq_byname(pdev, "bd70528-rtc-alm");
-       if (irq < 0)
+       switch (chip) {
+       case ROHM_CHIP_TYPE_BD70528:
+               irq_name = "bd70528-rtc-alm";
+               bd_rtc->has_rtc_timers = true;
+               bd_rtc->reg_time_start = BD70528_REG_RTC_START;
+               hour_reg = BD70528_REG_RTC_HOUR;
+               enable_main_irq = true;
+               rtc_ops = &bd70528_rtc_ops;
+               break;
+       case ROHM_CHIP_TYPE_BD71828:
+               irq_name = "bd71828-rtc-alm-0";
+               bd_rtc->reg_time_start = BD71828_REG_RTC_START;
+               hour_reg = BD71828_REG_RTC_HOUR;
+               rtc_ops = &bd71828_rtc_ops;
+               break;
+       default:
+               dev_err(&pdev->dev, "Unknown chip\n");
+               return -ENOENT;
+       }
+
+       irq = platform_get_irq_byname(pdev, irq_name);
+
+       if (irq < 0) {
+               dev_err(&pdev->dev, "Failed to get irq\n");
                return irq;
+       }
 
        platform_set_drvdata(pdev, bd_rtc);
 
-       ret = regmap_read(mfd->regmap, BD70528_REG_RTC_HOUR, &hr);
+       ret = regmap_read(parent->regmap, hour_reg, &hr);
 
        if (ret) {
                dev_err(&pdev->dev, "Failed to reag RTC clock\n");
@@ -431,10 +559,10 @@ static int bd70528_probe(struct platform_device *pdev)
        if (!(hr & BD70528_MASK_RTC_HOUR_24H)) {
                struct rtc_time t;
 
-               ret = bd70528_get_time(&pdev->dev, &t);
+               ret = rtc_ops->read_time(&pdev->dev, &t);
 
                if (!ret)
-                       ret = bd70528_set_time(&pdev->dev, &t);
+                       ret = rtc_ops->set_time(&pdev->dev, &t);
 
                if (ret) {
                        dev_err(&pdev->dev,
@@ -454,7 +582,7 @@ static int bd70528_probe(struct platform_device *pdev)
 
        rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
        rtc->range_max = RTC_TIMESTAMP_END_2099;
-       rtc->ops = &bd70528_rtc_ops;
+       rtc->ops = rtc_ops;
 
        /* Request alarm IRQ prior to registerig the RTC */
        ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, &alm_hndlr,
@@ -468,27 +596,37 @@ static int bd70528_probe(struct platform_device *pdev)
         *  leave them enabled as irq-controller should disable irqs
         *  from sub-registers when IRQ is disabled or freed.
         */
-       ret = regmap_update_bits(mfd->regmap,
+       if (enable_main_irq) {
+               ret = regmap_update_bits(parent->regmap,
                                 BD70528_REG_INT_MAIN_MASK,
                                 BD70528_INT_RTC_MASK, 0);
-       if (ret) {
-               dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");
-               return ret;
+               if (ret) {
+                       dev_err(&pdev->dev, "Failed to enable RTC interrupts\n");
+                       return ret;
+               }
        }
 
        return rtc_register_device(rtc);
 }
 
+static const struct platform_device_id bd718x7_rtc_id[] = {
+       { "bd70528-rtc", ROHM_CHIP_TYPE_BD70528 },
+       { "bd71828-rtc", ROHM_CHIP_TYPE_BD71828 },
+       { },
+};
+MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id);
+
 static struct platform_driver bd70528_rtc = {
        .driver = {
                .name = "bd70528-rtc"
        },
        .probe = bd70528_probe,
+       .id_table = bd718x7_rtc_id,
 };
 
 module_platform_driver(bd70528_rtc);
 
 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
-MODULE_DESCRIPTION("BD70528 RTC driver");
+MODULE_DESCRIPTION("ROHM BD70528 and BD71828 PMIC RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:bd70528-rtc");
index 0333037..b795fe4 100644 (file)
@@ -850,7 +850,7 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
                        rtc_cmos_int_handler = cmos_interrupt;
 
                retval = request_irq(rtc_irq, rtc_cmos_int_handler,
-                               IRQF_SHARED, dev_name(&cmos_rtc.rtc->dev),
+                               0, dev_name(&cmos_rtc.rtc->dev),
                                cmos_rtc.rtc);
                if (retval < 0) {
                        dev_dbg(dev, "IRQ %d is already in use\n", rtc_irq);
@@ -1197,8 +1197,6 @@ static void rtc_wake_off(struct device *dev)
 /* Enable use_acpi_alarm mode for Intel platforms no earlier than 2015 */
 static void use_acpi_alarm_quirks(void)
 {
-       int year;
-
        if (boot_cpu_data.x86_vendor != X86_VENDOR_INTEL)
                return;
 
@@ -1208,8 +1206,10 @@ static void use_acpi_alarm_quirks(void)
        if (!is_hpet_enabled())
                return;
 
-       if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2015)
-               use_acpi_alarm = true;
+       if (dmi_get_bios_year() < 2015)
+               return;
+
+       use_acpi_alarm = true;
 }
 #else
 static inline void use_acpi_alarm_quirks(void) { }
@@ -1305,7 +1305,7 @@ static int cmos_pnp_probe(struct pnp_dev *pnp, const struct pnp_device_id *id)
                 * hardcode it on systems with a legacy PIC.
                 */
                if (nr_legacy_irqs())
-                       irq = 8;
+                       irq = RTC_IRQ;
 #endif
                return cmos_do_probe(&pnp->dev,
                                pnp_get_resource(pnp, IORESOURCE_IO, 0), irq);
index d043d30..f7343c2 100644 (file)
@@ -5,7 +5,6 @@
 // Author: Stephen Barber <smbarber@chromium.org>
 
 #include <linux/kernel.h>
-#include <linux/mfd/cros_ec.h>
 #include <linux/module.h>
 #include <linux/platform_data/cros_ec_commands.h>
 #include <linux/platform_data/cros_ec_proto.h>
index d21004a..ba14342 100644 (file)
@@ -75,7 +75,6 @@ static const struct spi_device_id ds1343_id[] = {
 MODULE_DEVICE_TABLE(spi, ds1343_id);
 
 struct ds1343_priv {
-       struct spi_device *spi;
        struct rtc_device *rtc;
        struct regmap *map;
        int irq;
@@ -362,12 +361,13 @@ static int ds1343_probe(struct spi_device *spi)
        if (!priv)
                return -ENOMEM;
 
-       priv->spi = spi;
-
        /* RTC DS1347 works in spi mode 3 and
-        * its chip select is active high
+        * its chip select is active high. Active high should be defined as
+        * "inverse polarity" as GPIO-based chip selects can be logically
+        * active high but inverted by the GPIO library.
         */
-       spi->mode = SPI_MODE_3 | SPI_CS_HIGH;
+       spi->mode |= SPI_MODE_3;
+       spi->mode ^= SPI_CS_HIGH;
        spi->bits_per_word = 8;
        res = spi_setup(spi);
        if (res)
index 443f6d0..0fb79c4 100644 (file)
@@ -78,7 +78,6 @@
 struct hym8563 {
        struct i2c_client       *client;
        struct rtc_device       *rtc;
-       bool                    valid;
 #ifdef CONFIG_COMMON_CLK
        struct clk_hw           clkout_hw;
 #endif
@@ -91,19 +90,19 @@ struct hym8563 {
 static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
 {
        struct i2c_client *client = to_i2c_client(dev);
-       struct hym8563 *hym8563 = i2c_get_clientdata(client);
        u8 buf[7];
        int ret;
 
-       if (!hym8563->valid) {
-               dev_warn(&client->dev, "no valid clock/calendar values available\n");
-               return -EPERM;
-       }
-
        ret = i2c_smbus_read_i2c_block_data(client, HYM8563_SEC, 7, buf);
        if (ret < 0)
                return ret;
 
+       if (buf[0] & HYM8563_SEC_VL) {
+               dev_warn(&client->dev,
+                        "no valid clock/calendar values available\n");
+               return -EINVAL;
+       }
+
        tm->tm_sec = bcd2bin(buf[0] & HYM8563_SEC_MASK);
        tm->tm_min = bcd2bin(buf[1] & HYM8563_MIN_MASK);
        tm->tm_hour = bcd2bin(buf[2] & HYM8563_HOUR_MASK);
@@ -118,7 +117,6 @@ static int hym8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
 static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
 {
        struct i2c_client *client = to_i2c_client(dev);
-       struct hym8563 *hym8563 = i2c_get_clientdata(client);
        u8 buf[7];
        int ret;
 
@@ -157,8 +155,6 @@ static int hym8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
        if (ret < 0)
                return ret;
 
-       hym8563->valid = true;
-
        return 0;
 }
 
@@ -556,9 +552,8 @@ static int hym8563_probe(struct i2c_client *client,
        if (ret < 0)
                return ret;
 
-       hym8563->valid = !(ret & HYM8563_SEC_VL);
        dev_dbg(&client->dev, "rtc information is %s\n",
-               hym8563->valid ? "valid" : "invalid");
+               (ret & HYM8563_SEC_VL) ? "invalid" : "valid");
 
        hym8563->rtc = devm_rtc_device_register(&client->dev, client->name,
                                                &hym8563_rtc_ops, THIS_MODULE);
index 07b30a3..6b24ac9 100644 (file)
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * MOXA ART RTC driver.
  *
@@ -7,10 +8,6 @@
  *
  * Based on code from
  * Moxa Technology Co., Ltd. <www.moxa.com>
- *
- * This file is licensed under the terms of the GNU General Public
- * License version 2.  This program is licensed "as is" without any
- * warranty of any kind, whether express or implied.
  */
 
 #include <linux/init.h>
index 9135e21..cda238d 100644 (file)
@@ -297,15 +297,7 @@ static int mtk_rtc_probe(struct platform_device *pdev)
 
        rtc->rtc_dev->ops = &mtk_rtc_ops;
 
-       ret = rtc_register_device(rtc->rtc_dev);
-       if (ret)
-               goto out_free_irq;
-
-       return 0;
-
-out_free_irq:
-       free_irq(rtc->irq, rtc);
-       return ret;
+       return rtc_register_device(rtc->rtc_dev);
 }
 
 #ifdef CONFIG_PM_SLEEP
index 988a4df..d4ed20f 100644 (file)
@@ -616,7 +616,7 @@ static int rtc_pinconf_get(struct pinctrl_dev *pctldev,
                break;
        default:
                return -ENOTSUPP;
-       };
+       }
 
        *config = pinconf_to_config_packed(param, arg);
 
index ba5baac..4e50d67 100644 (file)
@@ -199,11 +199,9 @@ static int pcf2127_rtc_ioctl(struct device *dev,
                if (ret)
                        return ret;
 
-               touser = touser & PCF2127_BIT_CTRL3_BLF ? 1 : 0;
+               touser = touser & PCF2127_BIT_CTRL3_BLF ? RTC_VL_BACKUP_LOW : 0;
 
-               if (copy_to_user((void __user *)arg, &touser, sizeof(int)))
-                       return -EFAULT;
-               return 0;
+               return put_user(touser, (unsigned int __user *)arg);
        default:
                return -ENOIOCTLCMD;
        }
index 1afa6d9..1db17ba 100644 (file)
@@ -289,21 +289,9 @@ static int pcf85063_ioctl(struct device *dev, unsigned int cmd,
                if (ret < 0)
                        return ret;
 
-               if (status & PCF85063_REG_SC_OS)
-                       dev_warn(&pcf85063->rtc->dev, "Voltage low, data loss detected.\n");
+               status = status & PCF85063_REG_SC_OS ? RTC_VL_DATA_INVALID : 0;
 
-               status &= PCF85063_REG_SC_OS;
-
-               if (copy_to_user((void __user *)arg, &status, sizeof(int)))
-                       return -EFAULT;
-
-               return 0;
-
-       case RTC_VL_CLR:
-               ret = regmap_update_bits(pcf85063->regmap, PCF85063_REG_SC,
-                                        PCF85063_REG_SC_OS, 0);
-
-               return ret;
+               return put_user(status, (unsigned int __user *)arg);
 
        default:
                return -ENOIOCTLCMD;
index b24c908..47e0f41 100644 (file)
@@ -282,11 +282,11 @@ static int pcf8523_rtc_ioctl(struct device *dev, unsigned int cmd,
                ret = pcf8523_voltage_low(client);
                if (ret < 0)
                        return ret;
+               if (ret)
+                       ret = RTC_VL_BACKUP_LOW;
 
-               if (copy_to_user((void __user *)arg, &ret, sizeof(int)))
-                       return -EFAULT;
+               return put_user(ret, (unsigned int __user *)arg);
 
-               return 0;
        default:
                return -ENOIOCTLCMD;
        }
index 3c322f3..2dc30ea 100644 (file)
@@ -22,8 +22,8 @@
 
 #define PCF8563_REG_ST1                0x00 /* status */
 #define PCF8563_REG_ST2                0x01
-#define PCF8563_BIT_AIE                (1 << 1)
-#define PCF8563_BIT_AF         (1 << 3)
+#define PCF8563_BIT_AIE                BIT(1)
+#define PCF8563_BIT_AF         BIT(3)
 #define PCF8563_BITS_ST2_N     (7 << 5)
 
 #define PCF8563_REG_SC         0x02 /* datetime */
@@ -76,7 +76,6 @@ struct pcf8563 {
         * 1970...2069.
         */
        int c_polarity; /* 0: MO_C=1 means 19xx, otherwise MO_C=1 means 20xx */
-       int voltage_low; /* incicates if a low_voltage was detected */
 
        struct i2c_client *client;
 #ifdef CONFIG_COMMON_CLK
@@ -208,7 +207,6 @@ static int pcf8563_rtc_read_time(struct device *dev, struct rtc_time *tm)
                return err;
 
        if (buf[PCF8563_REG_SC] & PCF8563_SC_LV) {
-               pcf8563->voltage_low = 1;
                dev_err(&client->dev,
                        "low voltage detected, date/time is not reliable.\n");
                return -EINVAL;
@@ -276,43 +274,23 @@ static int pcf8563_rtc_set_time(struct device *dev, struct rtc_time *tm)
                                9 - PCF8563_REG_SC, buf + PCF8563_REG_SC);
 }
 
-#ifdef CONFIG_RTC_INTF_DEV
 static int pcf8563_rtc_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
-       struct pcf8563 *pcf8563 = i2c_get_clientdata(to_i2c_client(dev));
-       struct rtc_time tm;
+       struct i2c_client *client = to_i2c_client(dev);
+       int ret;
 
        switch (cmd) {
        case RTC_VL_READ:
-               if (pcf8563->voltage_low)
-                       dev_info(dev, "low voltage detected, date/time is not reliable.\n");
-
-               if (copy_to_user((void __user *)arg, &pcf8563->voltage_low,
-                                       sizeof(int)))
-                       return -EFAULT;
-               return 0;
-       case RTC_VL_CLR:
-               /*
-                * Clear the VL bit in the seconds register in case
-                * the time has not been set already (which would
-                * have cleared it). This does not really matter
-                * because of the cached voltage_low value but do it
-                * anyway for consistency.
-                */
-               if (pcf8563_rtc_read_time(dev, &tm))
-                       pcf8563_rtc_set_time(dev, &tm);
-
-               /* Clear the cached value. */
-               pcf8563->voltage_low = 0;
+               ret = i2c_smbus_read_byte_data(client, PCF8563_REG_SC);
+               if (ret < 0)
+                       return ret;
 
-               return 0;
+               return put_user(ret & PCF8563_SC_LV ? RTC_VL_DATA_INVALID : 0,
+                               (unsigned int __user *)arg);
        default:
                return -ENOIOCTLCMD;
        }
 }
-#else
-#define pcf8563_rtc_ioctl NULL
-#endif
 
 static int pcf8563_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *tm)
 {
index 6b7b3a6..a0ddc86 100644 (file)
@@ -428,21 +428,8 @@ static int rv3028_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
                if (ret < 0)
                        return ret;
 
-               if (status & RV3028_STATUS_PORF)
-                       dev_warn(&rv3028->rtc->dev, "Voltage low, data loss detected.\n");
-
-               status &= RV3028_STATUS_PORF;
-
-               if (copy_to_user((void __user *)arg, &status, sizeof(int)))
-                       return -EFAULT;
-
-               return 0;
-
-       case RTC_VL_CLR:
-               ret = regmap_update_bits(rv3028->regmap, RV3028_STATUS,
-                                        RV3028_STATUS_PORF, 0);
-
-               return ret;
+               status = status & RV3028_STATUS_PORF ? RTC_VL_DATA_INVALID : 0;
+               return put_user(status, (unsigned int __user *)arg);
 
        default:
                return -ENOIOCTLCMD;
index 4cdf658..6271823 100644 (file)
 #define RV3029_CONTROL_E2P_TOV_MASK    0x3F /* XTAL turnover temp mask */
 
 /* user ram section */
-#define RV3029_USR1_RAM_PAGE           0x38
-#define RV3029_USR1_SECTION_LEN                0x04
-#define RV3029_USR2_RAM_PAGE           0x3C
-#define RV3029_USR2_SECTION_LEN                0x04
+#define RV3029_RAM_PAGE                        0x38
+#define RV3029_RAM_SECTION_LEN         8
 
 struct rv3029_data {
        struct device           *dev;
@@ -121,77 +119,13 @@ struct rv3029_data {
        int irq;
 };
 
-static int rv3029_read_regs(struct device *dev, u8 reg, u8 *buf,
-                           unsigned int len)
-{
-       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
-
-       if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-           (reg + len > RV3029_USR1_RAM_PAGE + 8))
-               return -EINVAL;
-
-       return regmap_bulk_read(rv3029->regmap, reg, buf, len);
-}
-
-static int rv3029_write_regs(struct device *dev, u8 reg, u8 const buf[],
-                            unsigned int len)
-{
-       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
-
-       if ((reg > RV3029_USR1_RAM_PAGE + 7) ||
-           (reg + len > RV3029_USR1_RAM_PAGE + 8))
-               return -EINVAL;
-
-       return regmap_bulk_write(rv3029->regmap, reg, buf, len);
-}
-
-static int rv3029_update_bits(struct device *dev, u8 reg, u8 mask, u8 set)
-{
-       u8 buf;
-       int ret;
-
-       ret = rv3029_read_regs(dev, reg, &buf, 1);
-       if (ret < 0)
-               return ret;
-       buf &= ~mask;
-       buf |= set & mask;
-       ret = rv3029_write_regs(dev, reg, &buf, 1);
-       if (ret < 0)
-               return ret;
-
-       return 0;
-}
-
-static int rv3029_get_sr(struct device *dev, u8 *buf)
-{
-       int ret = rv3029_read_regs(dev, RV3029_STATUS, buf, 1);
-
-       if (ret < 0)
-               return -EIO;
-       dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
-       return 0;
-}
-
-static int rv3029_set_sr(struct device *dev, u8 val)
-{
-       u8 buf[1];
-       int sr;
-
-       buf[0] = val;
-       sr = rv3029_write_regs(dev, RV3029_STATUS, buf, 1);
-       dev_dbg(dev, "status = 0x%.2x (%d)\n", buf[0], buf[0]);
-       if (sr < 0)
-               return -EIO;
-       return 0;
-}
-
-static int rv3029_eeprom_busywait(struct device *dev)
+static int rv3029_eeprom_busywait(struct rv3029_data *rv3029)
 {
+       unsigned int sr;
        int i, ret;
-       u8 sr;
 
        for (i = 100; i > 0; i--) {
-               ret = rv3029_get_sr(dev, &sr);
+               ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
                if (ret < 0)
                        break;
                if (!(sr & RV3029_STATUS_EEBUSY))
@@ -199,126 +133,128 @@ static int rv3029_eeprom_busywait(struct device *dev)
                usleep_range(1000, 10000);
        }
        if (i <= 0) {
-               dev_err(dev, "EEPROM busy wait timeout.\n");
+               dev_err(rv3029->dev, "EEPROM busy wait timeout.\n");
                return -ETIMEDOUT;
        }
 
        return ret;
 }
 
-static int rv3029_eeprom_exit(struct device *dev)
+static int rv3029_eeprom_exit(struct rv3029_data *rv3029)
 {
        /* Re-enable eeprom refresh */
-       return rv3029_update_bits(dev, RV3029_ONOFF_CTRL,
+       return regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
                                  RV3029_ONOFF_CTRL_EERE,
                                  RV3029_ONOFF_CTRL_EERE);
 }
 
-static int rv3029_eeprom_enter(struct device *dev)
+static int rv3029_eeprom_enter(struct rv3029_data *rv3029)
 {
+       unsigned int sr;
        int ret;
-       u8 sr;
 
        /* Check whether we are in the allowed voltage range. */
-       ret = rv3029_get_sr(dev, &sr);
+       ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
        if (ret < 0)
                return ret;
-       if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
+       if (sr & RV3029_STATUS_VLOW2)
+               return -ENODEV;
+       if (sr & RV3029_STATUS_VLOW1) {
                /* We clear the bits and retry once just in case
                 * we had a brown out in early startup.
                 */
-               sr &= ~RV3029_STATUS_VLOW1;
-               sr &= ~RV3029_STATUS_VLOW2;
-               ret = rv3029_set_sr(dev, sr);
+               ret = regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+                                        RV3029_STATUS_VLOW1, 0);
                if (ret < 0)
                        return ret;
                usleep_range(1000, 10000);
-               ret = rv3029_get_sr(dev, &sr);
+               ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
                if (ret < 0)
                        return ret;
-               if (sr & (RV3029_STATUS_VLOW1 | RV3029_STATUS_VLOW2)) {
-                       dev_err(dev,
+               if (sr & RV3029_STATUS_VLOW1) {
+                       dev_err(rv3029->dev,
                                "Supply voltage is too low to safely access the EEPROM.\n");
                        return -ENODEV;
                }
        }
 
        /* Disable eeprom refresh. */
-       ret = rv3029_update_bits(dev, RV3029_ONOFF_CTRL, RV3029_ONOFF_CTRL_EERE,
-                                0);
+       ret = regmap_update_bits(rv3029->regmap, RV3029_ONOFF_CTRL,
+                                RV3029_ONOFF_CTRL_EERE, 0);
        if (ret < 0)
                return ret;
 
        /* Wait for any previous eeprom accesses to finish. */
-       ret = rv3029_eeprom_busywait(dev);
+       ret = rv3029_eeprom_busywait(rv3029);
        if (ret < 0)
-               rv3029_eeprom_exit(dev);
+               rv3029_eeprom_exit(rv3029);
 
        return ret;
 }
 
-static int rv3029_eeprom_read(struct device *dev, u8 reg,
+static int rv3029_eeprom_read(struct rv3029_data *rv3029, u8 reg,
                              u8 buf[], size_t len)
 {
        int ret, err;
 
-       err = rv3029_eeprom_enter(dev);
+       err = rv3029_eeprom_enter(rv3029);
        if (err < 0)
                return err;
 
-       ret = rv3029_read_regs(dev, reg, buf, len);
+       ret = regmap_bulk_read(rv3029->regmap, reg, buf, len);
 
-       err = rv3029_eeprom_exit(dev);
+       err = rv3029_eeprom_exit(rv3029);
        if (err < 0)
                return err;
 
        return ret;
 }
 
-static int rv3029_eeprom_write(struct device *dev, u8 reg,
+static int rv3029_eeprom_write(struct rv3029_data *rv3029, u8 reg,
                               u8 const buf[], size_t len)
 {
+       unsigned int tmp;
        int ret, err;
        size_t i;
-       u8 tmp;
 
-       err = rv3029_eeprom_enter(dev);
+       err = rv3029_eeprom_enter(rv3029);
        if (err < 0)
                return err;
 
        for (i = 0; i < len; i++, reg++) {
-               ret = rv3029_read_regs(dev, reg, &tmp, 1);
+               ret = regmap_read(rv3029->regmap, reg, &tmp);
                if (ret < 0)
                        break;
                if (tmp != buf[i]) {
-                       ret = rv3029_write_regs(dev, reg, &buf[i], 1);
+                       tmp = buf[i];
+                       ret = regmap_write(rv3029->regmap, reg, tmp);
                        if (ret < 0)
                                break;
                }
-               ret = rv3029_eeprom_busywait(dev);
+               ret = rv3029_eeprom_busywait(rv3029);
                if (ret < 0)
                        break;
        }
 
-       err = rv3029_eeprom_exit(dev);
+       err = rv3029_eeprom_exit(rv3029);
        if (err < 0)
                return err;
 
        return ret;
 }
 
-static int rv3029_eeprom_update_bits(struct device *dev,
+static int rv3029_eeprom_update_bits(struct rv3029_data *rv3029,
                                     u8 reg, u8 mask, u8 set)
 {
        u8 buf;
        int ret;
 
-       ret = rv3029_eeprom_read(dev, reg, &buf, 1);
+       ret = rv3029_eeprom_read(rv3029, reg, &buf, 1);
        if (ret < 0)
                return ret;
        buf &= ~mask;
        buf |= set & mask;
-       ret = rv3029_eeprom_write(dev, reg, &buf, 1);
+       ret = rv3029_eeprom_write(rv3029, reg, &buf, 1);
        if (ret < 0)
                return ret;
 
@@ -330,20 +266,20 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
        struct device *dev = dev_id;
        struct rv3029_data *rv3029 = dev_get_drvdata(dev);
        struct mutex *lock = &rv3029->rtc->ops_lock;
+       unsigned int flags, controls;
        unsigned long events = 0;
-       u8 flags, controls;
        int ret;
 
        mutex_lock(lock);
 
-       ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+       ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
        if (ret) {
                dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
                mutex_unlock(lock);
                return IRQ_NONE;
        }
 
-       ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
+       ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
        if (ret) {
                dev_warn(dev, "Read IRQ Flags Register error %d\n", ret);
                mutex_unlock(lock);
@@ -358,8 +294,8 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
 
        if (events) {
                rtc_update_irq(rv3029->rtc, 1, events);
-               rv3029_write_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
-               rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
+               regmap_write(rv3029->regmap, RV3029_IRQ_FLAGS, flags);
+               regmap_write(rv3029->regmap, RV3029_IRQ_CTRL, controls);
        }
        mutex_unlock(lock);
 
@@ -368,22 +304,22 @@ static irqreturn_t rv3029_handle_irq(int irq, void *dev_id)
 
 static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 {
-       u8 buf[1];
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+       unsigned int sr;
        int ret;
        u8 regs[RV3029_WATCH_SECTION_LEN] = { 0, };
 
-       ret = rv3029_get_sr(dev, buf);
-       if (ret < 0) {
-               dev_err(dev, "%s: reading SR failed\n", __func__);
-               return -EIO;
-       }
+       ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
+       if (ret < 0)
+               return ret;
+
+       if (sr & (RV3029_STATUS_VLOW2 | RV3029_STATUS_PON))
+               return -EINVAL;
 
-       ret = rv3029_read_regs(dev, RV3029_W_SEC, regs,
+       ret = regmap_bulk_read(rv3029->regmap, RV3029_W_SEC, regs,
                               RV3029_WATCH_SECTION_LEN);
-       if (ret < 0) {
-               dev_err(dev, "%s: reading RTC section failed\n", __func__);
+       if (ret < 0)
                return ret;
-       }
 
        tm->tm_sec = bcd2bin(regs[RV3029_W_SEC - RV3029_W_SEC]);
        tm->tm_min = bcd2bin(regs[RV3029_W_MINUTES - RV3029_W_SEC]);
@@ -411,34 +347,24 @@ static int rv3029_read_time(struct device *dev, struct rtc_time *tm)
 
 static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
        struct rtc_time *const tm = &alarm->time;
+       unsigned int controls, flags;
        int ret;
-       u8 regs[8], controls, flags;
-
-       ret = rv3029_get_sr(dev, regs);
-       if (ret < 0) {
-               dev_err(dev, "%s: reading SR failed\n", __func__);
-               return -EIO;
-       }
+       u8 regs[8];
 
-       ret = rv3029_read_regs(dev, RV3029_A_SC, regs,
+       ret = regmap_bulk_read(rv3029->regmap, RV3029_A_SC, regs,
                               RV3029_ALARM_SECTION_LEN);
-
-       if (ret < 0) {
-               dev_err(dev, "%s: reading alarm section failed\n", __func__);
+       if (ret < 0)
                return ret;
-       }
 
-       ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
-       if (ret) {
-               dev_err(dev, "Read IRQ Control Register error %d\n", ret);
+       ret = regmap_read(rv3029->regmap, RV3029_IRQ_CTRL, &controls);
+       if (ret)
                return ret;
-       }
-       ret = rv3029_read_regs(dev, RV3029_IRQ_FLAGS, &flags, 1);
-       if (ret < 0) {
-               dev_err(dev, "Read IRQ Flags Register error %d\n", ret);
+
+       ret = regmap_read(rv3029->regmap, RV3029_IRQ_FLAGS, &flags);
+       if (ret < 0)
                return ret;
-       }
 
        tm->tm_sec = bcd2bin(regs[RV3029_A_SC - RV3029_A_SC] & 0x7f);
        tm->tm_min = bcd2bin(regs[RV3029_A_MN - RV3029_A_SC] & 0x7f);
@@ -456,50 +382,20 @@ static int rv3029_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 
 static int rv3029_alarm_irq_enable(struct device *dev, unsigned int enable)
 {
-       int ret;
-       u8 controls;
-
-       ret = rv3029_read_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
-       if (ret < 0) {
-               dev_warn(dev, "Read IRQ Control Register error %d\n", ret);
-               return ret;
-       }
-
-       /* enable/disable AIE irq */
-       if (enable)
-               controls |= RV3029_IRQ_CTRL_AIE;
-       else
-               controls &= ~RV3029_IRQ_CTRL_AIE;
-
-       ret = rv3029_write_regs(dev, RV3029_IRQ_CTRL, &controls, 1);
-       if (ret < 0) {
-               dev_err(dev, "can't update INT reg\n");
-               return ret;
-       }
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
 
-       return 0;
+       return regmap_update_bits(rv3029->regmap, RV3029_IRQ_CTRL,
+                                 RV3029_IRQ_CTRL_AIE,
+                                 enable ? RV3029_IRQ_CTRL_AIE : 0);
 }
 
 static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
 {
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
        struct rtc_time *const tm = &alarm->time;
        int ret;
        u8 regs[8];
 
-       /*
-        * The clock has an 8 bit wide bcd-coded register (they never learn)
-        * for the year. tm_year is an offset from 1900 and we are interested
-        * in the 2000-2099 range, so any value less than 100 is invalid.
-       */
-       if (tm->tm_year < 100)
-               return -EINVAL;
-
-       ret = rv3029_get_sr(dev, regs);
-       if (ret < 0) {
-               dev_err(dev, "%s: reading SR failed\n", __func__);
-               return -EIO;
-       }
-
        /* Activate all the alarms with AE_x bit */
        regs[RV3029_A_SC - RV3029_A_SC] = bin2bcd(tm->tm_sec) | RV3029_A_AE_X;
        regs[RV3029_A_MN - RV3029_A_SC] = bin2bcd(tm->tm_min) | RV3029_A_AE_X;
@@ -515,39 +411,20 @@ static int rv3029_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
                | RV3029_A_AE_X;
 
        /* Write the alarm */
-       ret = rv3029_write_regs(dev, RV3029_A_SC, regs,
+       ret = regmap_bulk_write(rv3029->regmap, RV3029_A_SC, regs,
                                RV3029_ALARM_SECTION_LEN);
        if (ret < 0)
                return ret;
 
-       if (alarm->enabled) {
-               /* enable AIE irq */
-               ret = rv3029_alarm_irq_enable(dev, 1);
-               if (ret)
-                       return ret;
-       } else {
-               /* disable AIE irq */
-               ret = rv3029_alarm_irq_enable(dev, 0);
-               if (ret)
-                       return ret;
-       }
-
-       return 0;
+       return rv3029_alarm_irq_enable(dev, alarm->enabled);
 }
 
 static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
 {
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
        u8 regs[8];
        int ret;
 
-       /*
-        * The clock has an 8 bit wide bcd-coded register (they never learn)
-        * for the year. tm_year is an offset from 1900 and we are interested
-        * in the 2000-2099 range, so any value less than 100 is invalid.
-       */
-       if (tm->tm_year < 100)
-               return -EINVAL;
-
        regs[RV3029_W_SEC - RV3029_W_SEC] = bin2bcd(tm->tm_sec);
        regs[RV3029_W_MINUTES - RV3029_W_SEC] = bin2bcd(tm->tm_min);
        regs[RV3029_W_HOURS - RV3029_W_SEC] = bin2bcd(tm->tm_hour);
@@ -556,24 +433,55 @@ static int rv3029_set_time(struct device *dev, struct rtc_time *tm)
        regs[RV3029_W_DAYS - RV3029_W_SEC] = bin2bcd(tm->tm_wday + 1) & 0x7;
        regs[RV3029_W_YEARS - RV3029_W_SEC] = bin2bcd(tm->tm_year - 100);
 
-       ret = rv3029_write_regs(dev, RV3029_W_SEC, regs,
+       ret = regmap_bulk_write(rv3029->regmap, RV3029_W_SEC, regs,
                                RV3029_WATCH_SECTION_LEN);
        if (ret < 0)
                return ret;
 
-       ret = rv3029_get_sr(dev, regs);
-       if (ret < 0) {
-               dev_err(dev, "%s: reading SR failed\n", __func__);
-               return ret;
-       }
-       /* clear PON bit */
-       ret = rv3029_set_sr(dev, (regs[0] & ~RV3029_STATUS_PON));
-       if (ret < 0) {
-               dev_err(dev, "%s: reading SR failed\n", __func__);
-               return ret;
+       /* clear PON and VLOW2 bits */
+       return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+                                 RV3029_STATUS_PON | RV3029_STATUS_VLOW2, 0);
+}
+
+static int rv3029_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
+{
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+       unsigned long vl = 0;
+       int sr, ret = 0;
+
+       switch (cmd) {
+       case RTC_VL_READ:
+               ret = regmap_read(rv3029->regmap, RV3029_STATUS, &sr);
+               if (ret < 0)
+                       return ret;
+
+               if (sr & RV3029_STATUS_VLOW1)
+                       vl = RTC_VL_ACCURACY_LOW;
+
+               if (sr & (RV3029_STATUS_VLOW2 | RV3029_STATUS_PON))
+                       vl |= RTC_VL_DATA_INVALID;
+
+               return put_user(vl, (unsigned int __user *)arg);
+
+       case RTC_VL_CLR:
+               return regmap_update_bits(rv3029->regmap, RV3029_STATUS,
+                                         RV3029_STATUS_VLOW1, 0);
+
+       default:
+               return -ENOIOCTLCMD;
        }
+}
 
-       return 0;
+static int rv3029_nvram_write(void *priv, unsigned int offset, void *val,
+                             size_t bytes)
+{
+       return regmap_bulk_write(priv, RV3029_RAM_PAGE + offset, val, bytes);
+}
+
+static int rv3029_nvram_read(void *priv, unsigned int offset, void *val,
+                            size_t bytes)
+{
+       return regmap_bulk_read(priv, RV3029_RAM_PAGE + offset, val, bytes);
 }
 
 static const struct rv3029_trickle_tab_elem {
@@ -635,6 +543,7 @@ static const struct rv3029_trickle_tab_elem {
 
 static void rv3029_trickle_config(struct device *dev)
 {
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
        struct device_node *of_node = dev->of_node;
        const struct rv3029_trickle_tab_elem *elem;
        int i, err;
@@ -661,7 +570,7 @@ static void rv3029_trickle_config(struct device *dev)
                         "Trickle charger enabled at %d ohms resistance.\n",
                         elem->r);
        }
-       err = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
+       err = rv3029_eeprom_update_bits(rv3029, RV3029_CONTROL_E2P_EECTRL,
                                        RV3029_TRICKLE_MASK,
                                        trickle_set_bits);
        if (err < 0)
@@ -670,12 +579,12 @@ static void rv3029_trickle_config(struct device *dev)
 
 #ifdef CONFIG_RTC_DRV_RV3029_HWMON
 
-static int rv3029_read_temp(struct device *dev, int *temp_mC)
+static int rv3029_read_temp(struct rv3029_data *rv3029, int *temp_mC)
 {
+       unsigned int temp;
        int ret;
-       u8 temp;
 
-       ret = rv3029_read_regs(dev, RV3029_TEMP_PAGE, &temp, 1);
+       ret = regmap_read(rv3029->regmap, RV3029_TEMP_PAGE, &temp);
        if (ret < 0)
                return ret;
 
@@ -688,9 +597,10 @@ static ssize_t rv3029_hwmon_show_temp(struct device *dev,
                                      struct device_attribute *attr,
                                      char *buf)
 {
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
        int ret, temp_mC;
 
-       ret = rv3029_read_temp(dev, &temp_mC);
+       ret = rv3029_read_temp(rv3029, &temp_mC);
        if (ret < 0)
                return ret;
 
@@ -702,9 +612,10 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
                                                const char *buf,
                                                size_t count)
 {
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
+       unsigned int th_set_bits = 0;
        unsigned long interval_ms;
        int ret;
-       u8 th_set_bits = 0;
 
        ret = kstrtoul(buf, 10, &interval_ms);
        if (ret < 0)
@@ -715,7 +626,7 @@ static ssize_t rv3029_hwmon_set_update_interval(struct device *dev,
                if (interval_ms >= 16000)
                        th_set_bits |= RV3029_EECTRL_THP;
        }
-       ret = rv3029_eeprom_update_bits(dev, RV3029_CONTROL_E2P_EECTRL,
+       ret = rv3029_eeprom_update_bits(rv3029, RV3029_CONTROL_E2P_EECTRL,
                                        RV3029_EECTRL_THE | RV3029_EECTRL_THP,
                                        th_set_bits);
        if (ret < 0)
@@ -728,10 +639,11 @@ static ssize_t rv3029_hwmon_show_update_interval(struct device *dev,
                                                 struct device_attribute *attr,
                                                 char *buf)
 {
+       struct rv3029_data *rv3029 = dev_get_drvdata(dev);
        int ret, interval_ms;
        u8 eectrl;
 
-       ret = rv3029_eeprom_read(dev, RV3029_CONTROL_E2P_EECTRL,
+       ret = rv3029_eeprom_read(rv3029, RV3029_CONTROL_E2P_EECTRL,
                                 &eectrl, 1);
        if (ret < 0)
                return ret;
@@ -785,14 +697,23 @@ static void rv3029_hwmon_register(struct device *dev, const char *name)
 static struct rtc_class_ops rv3029_rtc_ops = {
        .read_time      = rv3029_read_time,
        .set_time       = rv3029_set_time,
+       .ioctl          = rv3029_ioctl,
 };
 
 static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
                        const char *name)
 {
        struct rv3029_data *rv3029;
+       struct nvmem_config nvmem_cfg = {
+               .name = "rv3029_nvram",
+               .word_size = 1,
+               .stride = 1,
+               .size = RV3029_RAM_SECTION_LEN,
+               .type = NVMEM_TYPE_BATTERY_BACKED,
+               .reg_read = rv3029_nvram_read,
+               .reg_write = rv3029_nvram_write,
+       };
        int rc = 0;
-       u8 buf[1];
 
        rv3029 = devm_kzalloc(dev, sizeof(*rv3029), GFP_KERNEL);
        if (!rv3029)
@@ -803,21 +724,12 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
        rv3029->dev = dev;
        dev_set_drvdata(dev, rv3029);
 
-       rc = rv3029_get_sr(dev, buf);
-       if (rc < 0) {
-               dev_err(dev, "reading status failed\n");
-               return rc;
-       }
-
        rv3029_trickle_config(dev);
        rv3029_hwmon_register(dev, name);
 
-       rv3029->rtc = devm_rtc_device_register(dev, name, &rv3029_rtc_ops,
-                                              THIS_MODULE);
-       if (IS_ERR(rv3029->rtc)) {
-               dev_err(dev, "unable to register the class device\n");
+       rv3029->rtc = devm_rtc_allocate_device(dev);
+       if (IS_ERR(rv3029->rtc))
                return PTR_ERR(rv3029->rtc);
-       }
 
        if (rv3029->irq > 0) {
                rc = devm_request_threaded_irq(dev, rv3029->irq,
@@ -834,20 +746,48 @@ static int rv3029_probe(struct device *dev, struct regmap *regmap, int irq,
                }
        }
 
+       rv3029->rtc->ops = &rv3029_rtc_ops;
+       rv3029->rtc->range_min = RTC_TIMESTAMP_BEGIN_2000;
+       rv3029->rtc->range_max = RTC_TIMESTAMP_END_2079;
+
+       rc = rtc_register_device(rv3029->rtc);
+       if (rc)
+               return rc;
+
+       nvmem_cfg.priv = rv3029->regmap;
+       rtc_nvmem_register(rv3029->rtc, &nvmem_cfg);
+
        return 0;
 }
 
+static const struct regmap_range rv3029_holes_range[] = {
+       regmap_reg_range(0x05, 0x07),
+       regmap_reg_range(0x0f, 0x0f),
+       regmap_reg_range(0x17, 0x17),
+       regmap_reg_range(0x1a, 0x1f),
+       regmap_reg_range(0x21, 0x27),
+       regmap_reg_range(0x34, 0x37),
+};
+
+static const struct regmap_access_table rv3029_regs = {
+       .no_ranges =    rv3029_holes_range,
+       .n_no_ranges =  ARRAY_SIZE(rv3029_holes_range),
+};
+
+static const struct regmap_config config = {
+       .reg_bits = 8,
+       .val_bits = 8,
+       .rd_table = &rv3029_regs,
+       .wr_table = &rv3029_regs,
+       .max_register = 0x3f,
+};
+
 #if IS_ENABLED(CONFIG_I2C)
 
 static int rv3029_i2c_probe(struct i2c_client *client,
                            const struct i2c_device_id *id)
 {
        struct regmap *regmap;
-       static const struct regmap_config config = {
-               .reg_bits = 8,
-               .val_bits = 8,
-       };
-
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK |
                                     I2C_FUNC_SMBUS_BYTE)) {
                dev_err(&client->dev, "Adapter does not support SMBUS_I2C_BLOCK or SMBUS_I2C_BYTE\n");
@@ -855,11 +795,8 @@ static int rv3029_i2c_probe(struct i2c_client *client,
        }
 
        regmap = devm_regmap_init_i2c(client, &config);
-       if (IS_ERR(regmap)) {
-               dev_err(&client->dev, "%s: regmap allocation failed: %ld\n",
-                       __func__, PTR_ERR(regmap));
+       if (IS_ERR(regmap))
                return PTR_ERR(regmap);
-       }
 
        return rv3029_probe(&client->dev, regmap, client->irq, client->name);
 }
@@ -873,24 +810,20 @@ MODULE_DEVICE_TABLE(i2c, rv3029_id);
 
 static const struct of_device_id rv3029_of_match[] = {
        { .compatible = "microcrystal,rv3029" },
-       /* Backward compatibility only, do not use compatibles below: */
-       { .compatible = "rv3029" },
-       { .compatible = "rv3029c2" },
-       { .compatible = "mc,rv3029c2" },
        { }
 };
 MODULE_DEVICE_TABLE(of, rv3029_of_match);
 
 static struct i2c_driver rv3029_driver = {
        .driver = {
-               .name = "rtc-rv3029c2",
+               .name = "rv3029",
                .of_match_table = of_match_ptr(rv3029_of_match),
        },
        .probe          = rv3029_i2c_probe,
        .id_table       = rv3029_id,
 };
 
-static int rv3029_register_driver(void)
+static int __init rv3029_register_driver(void)
 {
        return i2c_add_driver(&rv3029_driver);
 }
@@ -902,7 +835,7 @@ static void rv3029_unregister_driver(void)
 
 #else
 
-static int rv3029_register_driver(void)
+static int __init rv3029_register_driver(void)
 {
        return 0;
 }
@@ -917,18 +850,11 @@ static void rv3029_unregister_driver(void)
 
 static int rv3049_probe(struct spi_device *spi)
 {
-       static const struct regmap_config config = {
-               .reg_bits = 8,
-               .val_bits = 8,
-       };
        struct regmap *regmap;
 
        regmap = devm_regmap_init_spi(spi, &config);
-       if (IS_ERR(regmap)) {
-               dev_err(&spi->dev, "%s: regmap allocation failed: %ld\n",
-                       __func__, PTR_ERR(regmap));
+       if (IS_ERR(regmap))
                return PTR_ERR(regmap);
-       }
 
        return rv3029_probe(&spi->dev, regmap, spi->irq, "rv3049");
 }
@@ -940,24 +866,24 @@ static struct spi_driver rv3049_driver = {
        .probe   = rv3049_probe,
 };
 
-static int rv3049_register_driver(void)
+static int __init rv3049_register_driver(void)
 {
        return spi_register_driver(&rv3049_driver);
 }
 
-static void rv3049_unregister_driver(void)
+static void __exit rv3049_unregister_driver(void)
 {
        spi_unregister_driver(&rv3049_driver);
 }
 
 #else
 
-static int rv3049_register_driver(void)
+static int __init rv3049_register_driver(void)
 {
        return 0;
 }
 
-static void rv3049_unregister_driver(void)
+static void __exit rv3049_unregister_driver(void)
 {
 }
 
@@ -968,16 +894,12 @@ static int __init rv30x9_init(void)
        int ret;
 
        ret = rv3029_register_driver();
-       if (ret) {
-               pr_err("Failed to register rv3029 driver: %d\n", ret);
+       if (ret)
                return ret;
-       }
 
        ret = rv3049_register_driver();
-       if (ret) {
-               pr_err("Failed to register rv3049 driver: %d\n", ret);
+       if (ret)
                rv3029_unregister_driver();
-       }
 
        return ret;
 }
index 4960f0a..93c3a6b 100644 (file)
@@ -411,6 +411,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct rv8803_data *rv8803 = dev_get_drvdata(dev);
+       unsigned int vl = 0;
        int flags, ret = 0;
 
        switch (cmd) {
@@ -419,18 +420,15 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
                if (flags < 0)
                        return flags;
 
-               if (flags & RV8803_FLAG_V1F)
+               if (flags & RV8803_FLAG_V1F) {
                        dev_warn(&client->dev, "Voltage low, temperature compensation stopped.\n");
+                       vl = RTC_VL_ACCURACY_LOW;
+               }
 
                if (flags & RV8803_FLAG_V2F)
-                       dev_warn(&client->dev, "Voltage low, data loss detected.\n");
-
-               flags &= RV8803_FLAG_V1F | RV8803_FLAG_V2F;
+                       vl |= RTC_VL_DATA_INVALID;
 
-               if (copy_to_user((void __user *)arg, &flags, sizeof(int)))
-                       return -EFAULT;
-
-               return 0;
+               return put_user(vl, (unsigned int __user *)arg);
 
        case RTC_VL_CLR:
                mutex_lock(&rv8803->flags_lock);
@@ -440,7 +438,7 @@ static int rv8803_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
                        return flags;
                }
 
-               flags &= ~(RV8803_FLAG_V1F | RV8803_FLAG_V2F);
+               flags &= ~RV8803_FLAG_V1F;
                ret = rv8803_write_reg(client, RV8803_FLAG, flags);
                mutex_unlock(&rv8803->flags_lock);
                if (ret)
index 8102469..fe01015 100644 (file)
@@ -389,9 +389,8 @@ static int rx8010_alarm_irq_enable(struct device *dev,
 
 static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
 {
-       struct i2c_client *client = to_i2c_client(dev);
        struct rx8010_data *rx8010 = dev_get_drvdata(dev);
-       int ret, tmp;
+       int tmp;
        int flagreg;
 
        switch (cmd) {
@@ -400,24 +399,8 @@ static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
                if (flagreg < 0)
                        return flagreg;
 
-               tmp = !!(flagreg & RX8010_FLAG_VLF);
-               if (copy_to_user((void __user *)arg, &tmp, sizeof(int)))
-                       return -EFAULT;
-
-               return 0;
-
-       case RTC_VL_CLR:
-               flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG);
-               if (flagreg < 0) {
-                       return flagreg;
-               }
-
-               flagreg &= ~RX8010_FLAG_VLF;
-               ret = i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg);
-               if (ret < 0)
-                       return ret;
-
-               return 0;
+               tmp = flagreg & RX8010_FLAG_VLF ? RTC_VL_DATA_INVALID : 0;
+               return put_user(tmp, (unsigned int __user *)arg);
 
        default:
                return -ENOIOCTLCMD;
@@ -482,7 +465,7 @@ static int rx8010_probe(struct i2c_client *client,
 
        rx8010->rtc->max_user_freq = 1;
 
-       return err;
+       return 0;
 }
 
 static struct i2c_driver rx8010_driver = {
index b9bda10..a24f858 100644 (file)
@@ -67,7 +67,6 @@ static const struct i2c_device_id rx8025_id[] = {
 MODULE_DEVICE_TABLE(i2c, rx8025_id);
 
 struct rx8025_data {
-       struct i2c_client *client;
        struct rtc_device *rtc;
        u8 ctrl1;
 };
@@ -103,10 +102,10 @@ static s32 rx8025_write_regs(const struct i2c_client *client,
 
 static int rx8025_check_validity(struct device *dev)
 {
-       struct rx8025_data *rx8025 = dev_get_drvdata(dev);
+       struct i2c_client *client = to_i2c_client(dev);
        int ctrl2;
 
-       ctrl2 = rx8025_read_reg(rx8025->client, RX8025_REG_CTRL2);
+       ctrl2 = rx8025_read_reg(client, RX8025_REG_CTRL2);
        if (ctrl2 < 0)
                return ctrl2;
 
@@ -178,6 +177,7 @@ out:
 
 static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
 {
+       struct i2c_client *client = to_i2c_client(dev);
        struct rx8025_data *rx8025 = dev_get_drvdata(dev);
        u8 date[7];
        int err;
@@ -186,7 +186,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
        if (err)
                return err;
 
-       err = rx8025_read_regs(rx8025->client, RX8025_REG_SEC, 7, date);
+       err = rx8025_read_regs(client, RX8025_REG_SEC, 7, date);
        if (err)
                return err;
 
@@ -211,6 +211,7 @@ static int rx8025_get_time(struct device *dev, struct rtc_time *dt)
 
 static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
 {
+       struct i2c_client *client = to_i2c_client(dev);
        struct rx8025_data *rx8025 = dev_get_drvdata(dev);
        u8 date[7];
        int ret;
@@ -237,11 +238,11 @@ static int rx8025_set_time(struct device *dev, struct rtc_time *dt)
 
        dev_dbg(dev, "%s: write %7ph\n", __func__, date);
 
-       ret = rx8025_write_regs(rx8025->client, RX8025_REG_SEC, 7, date);
+       ret = rx8025_write_regs(client, RX8025_REG_SEC, 7, date);
        if (ret < 0)
                return ret;
 
-       return rx8025_reset_validity(rx8025->client);
+       return rx8025_reset_validity(client);
 }
 
 static int rx8025_init_client(struct i2c_client *client)
@@ -251,7 +252,7 @@ static int rx8025_init_client(struct i2c_client *client)
        int need_clear = 0;
        int err;
 
-       err = rx8025_read_regs(rx8025->client, RX8025_REG_CTRL1, 2, ctrl);
+       err = rx8025_read_regs(client, RX8025_REG_CTRL1, 2, ctrl);
        if (err)
                goto out;
 
@@ -280,8 +281,8 @@ out:
 /* Alarm support */
 static int rx8025_read_alarm(struct device *dev, struct rtc_wkalrm *t)
 {
+       struct i2c_client *client = to_i2c_client(dev);
        struct rx8025_data *rx8025 = dev_get_drvdata(dev);
-       struct i2c_client *client = rx8025->client;
        u8 ald[2];
        int ctrl2, err;
 
@@ -347,18 +348,18 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 
        if (rx8025->ctrl1 & RX8025_BIT_CTRL1_DALE) {
                rx8025->ctrl1 &= ~RX8025_BIT_CTRL1_DALE;
-               err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
+               err = rx8025_write_reg(client, RX8025_REG_CTRL1,
                                       rx8025->ctrl1);
                if (err)
                        return err;
        }
-       err = rx8025_write_regs(rx8025->client, RX8025_REG_ALDMIN, 2, ald);
+       err = rx8025_write_regs(client, RX8025_REG_ALDMIN, 2, ald);
        if (err)
                return err;
 
        if (t->enabled) {
                rx8025->ctrl1 |= RX8025_BIT_CTRL1_DALE;
-               err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
+               err = rx8025_write_reg(client, RX8025_REG_CTRL1,
                                       rx8025->ctrl1);
                if (err)
                        return err;
@@ -369,6 +370,7 @@ static int rx8025_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 
 static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
 {
+       struct i2c_client *client = to_i2c_client(dev);
        struct rx8025_data *rx8025 = dev_get_drvdata(dev);
        u8 ctrl1;
        int err;
@@ -381,7 +383,7 @@ static int rx8025_alarm_irq_enable(struct device *dev, unsigned int enabled)
 
        if (ctrl1 != rx8025->ctrl1) {
                rx8025->ctrl1 = ctrl1;
-               err = rx8025_write_reg(rx8025->client, RX8025_REG_CTRL1,
+               err = rx8025_write_reg(client, RX8025_REG_CTRL1,
                                       rx8025->ctrl1);
                if (err)
                        return err;
@@ -516,7 +518,6 @@ static int rx8025_probe(struct i2c_client *client,
        if (!rx8025)
                return -ENOMEM;
 
-       rx8025->client = client;
        i2c_set_clientdata(client, rx8025);
 
        err = rx8025_init_client(client);
index 781cabb..d774aa1 100644 (file)
@@ -897,8 +897,11 @@ static int stm32_rtc_resume(struct device *dev)
        }
 
        ret = stm32_rtc_wait_sync(rtc);
-       if (ret < 0)
+       if (ret < 0) {
+               if (rtc->data->has_pclk)
+                       clk_disable_unprepare(rtc->pclk);
                return ret;
+       }
 
        if (device_may_wakeup(dev))
                return disable_irq_wake(rtc->irq_alarm);
index 859d901..e39af2d 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/device.h>
 #include <linux/err.h>
 #include <linux/init.h>
+#include <linux/irq.h>
 #include <linux/kernel.h>
 #include <linux/mfd/tps6586x.h>
 #include <linux/module.h>
@@ -267,6 +268,8 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
        rtc->rtc->start_secs = mktime64(2009, 1, 1, 0, 0, 0);
        rtc->rtc->set_start_time = true;
 
+       irq_set_status_flags(rtc->irq, IRQ_NOAUTOEN);
+
        ret = devm_request_threaded_irq(&pdev->dev, rtc->irq, NULL,
                                tps6586x_rtc_irq,
                                IRQF_ONESHOT,
@@ -276,7 +279,6 @@ static int tps6586x_rtc_probe(struct platform_device *pdev)
                                rtc->irq, ret);
                goto fail_rtc_register;
        }
-       disable_irq(rtc->irq);
 
        ret = rtc_register_device(rtc->rtc);
        if (ret)
index 5396905..5786866 100644 (file)
@@ -94,7 +94,7 @@ static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
                 * RTC has updated the CURRENT_TIME with the time written into
                 * SET_TIME_WRITE register.
                 */
-               rtc_time64_to_tm(readl(xrtcdev->reg_base + RTC_CUR_TM), tm);
+               read_time = readl(xrtcdev->reg_base + RTC_CUR_TM);
        } else {
                /*
                 * Time written in SET_TIME_WRITE has not yet updated into
@@ -104,8 +104,8 @@ static int xlnx_rtc_read_time(struct device *dev, struct rtc_time *tm)
                 * reading.
                 */
                read_time = readl(xrtcdev->reg_base + RTC_SET_TM_RD) - 1;
-               rtc_time64_to_tm(read_time, tm);
        }
+       rtc_time64_to_tm(read_time, tm);
 
        return 0;
 }
index 8d4d69e..62a859e 100644 (file)
@@ -320,13 +320,12 @@ out_error:
 #endif                         /* CONFIG_DASD_PROFILE */
 }
 
-static const struct file_operations dasd_stats_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = dasd_stats_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = dasd_stats_proc_write,
+static const struct proc_ops dasd_stats_proc_ops = {
+       .proc_open      = dasd_stats_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = dasd_stats_proc_write,
 };
 
 /*
@@ -347,7 +346,7 @@ dasd_proc_init(void)
        dasd_statistics_entry = proc_create("statistics",
                                            S_IFREG | S_IRUGO | S_IWUSR,
                                            dasd_proc_root_entry,
-                                           &dasd_stats_proc_fops);
+                                           &dasd_stats_proc_ops);
        if (!dasd_statistics_entry)
                goto out_nostatistics;
        return 0;
index 2a3f874..da642e8 100644 (file)
@@ -398,12 +398,12 @@ cio_ignore_proc_open(struct inode *inode, struct file *file)
                                sizeof(struct ccwdev_iter));
 }
 
-static const struct file_operations cio_ignore_proc_fops = {
-       .open    = cio_ignore_proc_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = seq_release_private,
-       .write   = cio_ignore_write,
+static const struct proc_ops cio_ignore_proc_ops = {
+       .proc_open      = cio_ignore_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release_private,
+       .proc_write     = cio_ignore_write,
 };
 
 static int
@@ -412,7 +412,7 @@ cio_ignore_proc_init (void)
        struct proc_dir_entry *entry;
 
        entry = proc_create("cio_ignore", S_IFREG | S_IRUGO | S_IWUSR, NULL,
-                           &cio_ignore_proc_fops);
+                           &cio_ignore_proc_ops);
        if (!entry)
                return -ENOENT;
        return 0;
index 8318504..94edbb3 100644 (file)
@@ -1372,18 +1372,17 @@ static ssize_t cio_settle_write(struct file *file, const char __user *buf,
        return ret ? ret : count;
 }
 
-static const struct file_operations cio_settle_proc_fops = {
-       .open = nonseekable_open,
-       .write = cio_settle_write,
-       .llseek = no_llseek,
+static const struct proc_ops cio_settle_proc_ops = {
+       .proc_open      = nonseekable_open,
+       .proc_write     = cio_settle_write,
+       .proc_lseek     = no_llseek,
 };
 
 static int __init cio_settle_init(void)
 {
        struct proc_dir_entry *entry;
 
-       entry = proc_create("cio_settle", S_IWUSR, NULL,
-                           &cio_settle_proc_fops);
+       entry = proc_create("cio_settle", S_IWUSR, NULL, &cio_settle_proc_ops);
        if (!entry)
                return -ENOMEM;
        return 0;
index 52aa95c..22d2db6 100644 (file)
@@ -7,7 +7,8 @@ ap-objs := ap_bus.o ap_card.o ap_queue.o
 obj-$(subst m,y,$(CONFIG_ZCRYPT)) += ap.o
 # zcrypt_api.o and zcrypt_msgtype*.o depend on ap.o
 zcrypt-objs := zcrypt_api.o zcrypt_card.o zcrypt_queue.o
-zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o zcrypt_ccamisc.o
+zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o
+zcrypt-objs += zcrypt_ccamisc.o zcrypt_ep11misc.o
 obj-$(CONFIG_ZCRYPT) += zcrypt.o
 # adapter drivers depend on ap.o and zcrypt.o
 obj-$(CONFIG_ZCRYPT) += zcrypt_cex2c.o zcrypt_cex2a.o zcrypt_cex4.o
index d78d776..71dae64 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "zcrypt_api.h"
 #include "zcrypt_ccamisc.h"
+#include "zcrypt_ep11misc.h"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("IBM Corporation");
@@ -71,6 +72,17 @@ struct protaeskeytoken {
        u8  protkey[MAXPROTKEYSIZE]; /* the protected key blob */
 } __packed;
 
+/* inside view of a clear key token (type 0x00 version 0x02) */
+struct clearaeskeytoken {
+       u8  type;        /* 0x00 for PAES specific key tokens */
+       u8  res0[3];
+       u8  version;     /* 0x02 for clear AES key token */
+       u8  res1[3];
+       u32 keytype;     /* key type, one of the PKEY_KEYTYPE values */
+       u32 len;         /* bytes actually stored in clearkey[] */
+       u8  clearkey[0]; /* clear key value */
+} __packed;
+
 /*
  * Create a protected key from a clear key value.
  */
@@ -173,6 +185,72 @@ static int pkey_skey2pkey(const u8 *key, struct pkey_protkey *pkey)
 }
 
 /*
+ * Construct EP11 key with given clear key value.
+ */
+static int pkey_clr2ep11key(const u8 *clrkey, size_t clrkeylen,
+                           u8 *keybuf, size_t *keybuflen)
+{
+       int i, rc;
+       u16 card, dom;
+       u32 nr_apqns, *apqns = NULL;
+
+       /* build a list of apqns suitable for ep11 keys with cpacf support */
+       rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF,
+                           ZCRYPT_CEX7, EP11_API_V, NULL);
+       if (rc)
+               goto out;
+
+       /* go through the list of apqns and try to bild an ep11 key */
+       for (rc = -ENODEV, i = 0; i < nr_apqns; i++) {
+               card = apqns[i] >> 16;
+               dom = apqns[i] & 0xFFFF;
+               rc = ep11_clr2keyblob(card, dom, clrkeylen * 8,
+                                     0, clrkey, keybuf, keybuflen);
+               if (rc == 0)
+                       break;
+       }
+
+out:
+       kfree(apqns);
+       if (rc)
+               DEBUG_DBG("%s failed rc=%d\n", __func__, rc);
+       return rc;
+}
+
+/*
+ * Find card and transform EP11 secure key into protected key.
+ */
+static int pkey_ep11key2pkey(const u8 *key, struct pkey_protkey *pkey)
+{
+       int i, rc;
+       u16 card, dom;
+       u32 nr_apqns, *apqns = NULL;
+       struct ep11keyblob *kb = (struct ep11keyblob *) key;
+
+       /* build a list of apqns suitable for this key */
+       rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF,
+                           ZCRYPT_CEX7, EP11_API_V, kb->wkvp);
+       if (rc)
+               goto out;
+
+       /* go through the list of apqns and try to derive an pkey */
+       for (rc = -ENODEV, i = 0; i < nr_apqns; i++) {
+               card = apqns[i] >> 16;
+               dom = apqns[i] & 0xFFFF;
+               rc = ep11_key2protkey(card, dom, key, kb->head.len,
+                                     pkey->protkey, &pkey->len, &pkey->type);
+               if (rc == 0)
+                       break;
+       }
+
+out:
+       kfree(apqns);
+       if (rc)
+               DEBUG_DBG("%s failed rc=%d\n", __func__, rc);
+       return rc;
+}
+
+/*
  * Verify key and give back some info about the key.
  */
 static int pkey_verifykey(const struct pkey_seckey *seckey,
@@ -305,26 +383,90 @@ static int pkey_verifyprotkey(const struct pkey_protkey *protkey)
 static int pkey_nonccatok2pkey(const u8 *key, u32 keylen,
                               struct pkey_protkey *protkey)
 {
+       int rc = -EINVAL;
+       u8 *tmpbuf = NULL;
        struct keytoken_header *hdr = (struct keytoken_header *)key;
-       struct protaeskeytoken *t;
 
        switch (hdr->version) {
-       case TOKVER_PROTECTED_KEY:
-               if (keylen != sizeof(struct protaeskeytoken))
-                       return -EINVAL;
+       case TOKVER_PROTECTED_KEY: {
+               struct protaeskeytoken *t;
 
+               if (keylen != sizeof(struct protaeskeytoken))
+                       goto out;
                t = (struct protaeskeytoken *)key;
                protkey->len = t->len;
                protkey->type = t->keytype;
                memcpy(protkey->protkey, t->protkey,
                       sizeof(protkey->protkey));
-
-               return pkey_verifyprotkey(protkey);
+               rc = pkey_verifyprotkey(protkey);
+               break;
+       }
+       case TOKVER_CLEAR_KEY: {
+               struct clearaeskeytoken *t;
+               struct pkey_clrkey ckey;
+               union u_tmpbuf {
+                       u8 skey[SECKEYBLOBSIZE];
+                       u8 ep11key[MAXEP11AESKEYBLOBSIZE];
+               };
+               size_t tmpbuflen = sizeof(union u_tmpbuf);
+
+               if (keylen < sizeof(struct clearaeskeytoken))
+                       goto out;
+               t = (struct clearaeskeytoken *)key;
+               if (keylen != sizeof(*t) + t->len)
+                       goto out;
+               if ((t->keytype == PKEY_KEYTYPE_AES_128 && t->len == 16)
+                   || (t->keytype == PKEY_KEYTYPE_AES_192 && t->len == 24)
+                   || (t->keytype == PKEY_KEYTYPE_AES_256 && t->len == 32))
+                       memcpy(ckey.clrkey, t->clearkey, t->len);
+               else
+                       goto out;
+               /* alloc temp key buffer space */
+               tmpbuf = kmalloc(tmpbuflen, GFP_ATOMIC);
+               if (!tmpbuf) {
+                       rc = -ENOMEM;
+                       goto out;
+               }
+               /* try direct way with the PCKMO instruction */
+               rc = pkey_clr2protkey(t->keytype, &ckey, protkey);
+               if (rc == 0)
+                       break;
+               /* PCKMO failed, so try the CCA secure key way */
+               rc = cca_clr2seckey(0xFFFF, 0xFFFF, t->keytype,
+                                   ckey.clrkey, tmpbuf);
+               if (rc == 0)
+                       rc = pkey_skey2pkey(tmpbuf, protkey);
+               if (rc == 0)
+                       break;
+               /* if the CCA way also failed, let's try via EP11 */
+               rc = pkey_clr2ep11key(ckey.clrkey, t->len,
+                                     tmpbuf, &tmpbuflen);
+               if (rc == 0)
+                       rc = pkey_ep11key2pkey(tmpbuf, protkey);
+               /* now we should really have an protected key */
+               DEBUG_ERR("%s unable to build protected key from clear",
+                         __func__);
+               break;
+       }
+       case TOKVER_EP11_AES: {
+               if (keylen < MINEP11AESKEYBLOBSIZE)
+                       goto out;
+               /* check ep11 key for exportable as protected key */
+               rc = ep11_check_aeskeyblob(debug_info, 3, key, 0, 1);
+               if (rc)
+                       goto out;
+               rc = pkey_ep11key2pkey(key, protkey);
+               break;
+       }
        default:
                DEBUG_ERR("%s unknown/unsupported non-CCA token version %d\n",
                          __func__, hdr->version);
-               return -EINVAL;
+               rc = -EINVAL;
        }
+
+out:
+       kfree(tmpbuf);
+       return rc;
 }
 
 /*
@@ -403,6 +545,10 @@ static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
                if (*keybufsize < SECKEYBLOBSIZE)
                        return -EINVAL;
                break;
+       case PKEY_TYPE_EP11:
+               if (*keybufsize < MINEP11AESKEYBLOBSIZE)
+                       return -EINVAL;
+               break;
        default:
                return -EINVAL;
        }
@@ -419,7 +565,10 @@ static int pkey_genseckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
        for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
                card = apqns[i].card;
                dom = apqns[i].domain;
-               if (ktype == PKEY_TYPE_CCA_DATA) {
+               if (ktype == PKEY_TYPE_EP11) {
+                       rc = ep11_genaeskey(card, dom, ksize, kflags,
+                                           keybuf, keybufsize);
+               } else if (ktype == PKEY_TYPE_CCA_DATA) {
                        rc = cca_genseckey(card, dom, ksize, keybuf);
                        *keybufsize = (rc ? 0 : SECKEYBLOBSIZE);
                } else /* TOKVER_CCA_VLSC */
@@ -450,6 +599,10 @@ static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
                if (*keybufsize < SECKEYBLOBSIZE)
                        return -EINVAL;
                break;
+       case PKEY_TYPE_EP11:
+               if (*keybufsize < MINEP11AESKEYBLOBSIZE)
+                       return -EINVAL;
+               break;
        default:
                return -EINVAL;
        }
@@ -466,7 +619,10 @@ static int pkey_clr2seckey2(const struct pkey_apqn *apqns, size_t nr_apqns,
        for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
                card = apqns[i].card;
                dom = apqns[i].domain;
-               if (ktype == PKEY_TYPE_CCA_DATA) {
+               if (ktype == PKEY_TYPE_EP11) {
+                       rc = ep11_clr2keyblob(card, dom, ksize, kflags,
+                                             clrkey, keybuf, keybufsize);
+               } else if (ktype == PKEY_TYPE_CCA_DATA) {
                        rc = cca_clr2seckey(card, dom, ksize,
                                            clrkey, keybuf);
                        *keybufsize = (rc ? 0 : SECKEYBLOBSIZE);
@@ -489,11 +645,11 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
        u32 _nr_apqns, *_apqns = NULL;
        struct keytoken_header *hdr = (struct keytoken_header *)key;
 
-       if (keylen < sizeof(struct keytoken_header) ||
-           hdr->type != TOKTYPE_CCA_INTERNAL)
+       if (keylen < sizeof(struct keytoken_header))
                return -EINVAL;
 
-       if (hdr->version == TOKVER_CCA_AES) {
+       if (hdr->type == TOKTYPE_CCA_INTERNAL
+           && hdr->version == TOKVER_CCA_AES) {
                struct secaeskeytoken *t = (struct secaeskeytoken *)key;
 
                rc = cca_check_secaeskeytoken(debug_info, 3, key, 0);
@@ -521,7 +677,8 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
                *cardnr = ((struct pkey_apqn *)_apqns)->card;
                *domain = ((struct pkey_apqn *)_apqns)->domain;
 
-       } else if (hdr->version == TOKVER_CCA_VLSC) {
+       } else if (hdr->type == TOKTYPE_CCA_INTERNAL
+                  && hdr->version == TOKVER_CCA_VLSC) {
                struct cipherkeytoken *t = (struct cipherkeytoken *)key;
 
                rc = cca_check_secaescipherkey(debug_info, 3, key, 0, 1);
@@ -556,6 +713,29 @@ static int pkey_verifykey2(const u8 *key, size_t keylen,
                *cardnr = ((struct pkey_apqn *)_apqns)->card;
                *domain = ((struct pkey_apqn *)_apqns)->domain;
 
+       } else if (hdr->type == TOKTYPE_NON_CCA
+                  && hdr->version == TOKVER_EP11_AES) {
+               struct ep11keyblob *kb = (struct ep11keyblob *)key;
+
+               rc = ep11_check_aeskeyblob(debug_info, 3, key, 0, 1);
+               if (rc)
+                       goto out;
+               if (ktype)
+                       *ktype = PKEY_TYPE_EP11;
+               if (ksize)
+                       *ksize = kb->head.keybitlen;
+
+               rc = ep11_findcard2(&_apqns, &_nr_apqns, *cardnr, *domain,
+                                   ZCRYPT_CEX7, EP11_API_V, kb->wkvp);
+               if (rc)
+                       goto out;
+
+               if (flags)
+                       *flags = PKEY_FLAGS_MATCH_CUR_MKVP;
+
+               *cardnr = ((struct pkey_apqn *)_apqns)->card;
+               *domain = ((struct pkey_apqn *)_apqns)->domain;
+
        } else
                rc = -EINVAL;
 
@@ -578,30 +758,32 @@ static int pkey_keyblob2pkey2(const struct pkey_apqn *apqns, size_t nr_apqns,
        if (keylen < sizeof(struct keytoken_header))
                return -EINVAL;
 
-       switch (hdr->type) {
-       case TOKTYPE_NON_CCA:
-               return pkey_nonccatok2pkey(key, keylen, pkey);
-       case TOKTYPE_CCA_INTERNAL:
-               switch (hdr->version) {
-               case TOKVER_CCA_AES:
+       if (hdr->type == TOKTYPE_CCA_INTERNAL) {
+               if (hdr->version == TOKVER_CCA_AES) {
                        if (keylen != sizeof(struct secaeskeytoken))
                                return -EINVAL;
                        if (cca_check_secaeskeytoken(debug_info, 3, key, 0))
                                return -EINVAL;
-                       break;
-               case TOKVER_CCA_VLSC:
+               } else if (hdr->version == TOKVER_CCA_VLSC) {
                        if (keylen < hdr->len || keylen > MAXCCAVLSCTOKENSIZE)
                                return -EINVAL;
                        if (cca_check_secaescipherkey(debug_info, 3, key, 0, 1))
                                return -EINVAL;
-                       break;
-               default:
+               } else {
                        DEBUG_ERR("%s unknown CCA internal token version %d\n",
                                  __func__, hdr->version);
                        return -EINVAL;
                }
-               break;
-       default:
+       } else if (hdr->type == TOKTYPE_NON_CCA) {
+               if (hdr->version == TOKVER_EP11_AES) {
+                       if (keylen < sizeof(struct ep11keyblob))
+                               return -EINVAL;
+                       if (ep11_check_aeskeyblob(debug_info, 3, key, 0, 1))
+                               return -EINVAL;
+               } else {
+                       return pkey_nonccatok2pkey(key, keylen, pkey);
+               }
+       } else {
                DEBUG_ERR("%s unknown/unsupported blob type %d\n",
                          __func__, hdr->type);
                return -EINVAL;
@@ -611,12 +793,21 @@ static int pkey_keyblob2pkey2(const struct pkey_apqn *apqns, size_t nr_apqns,
        for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
                card = apqns[i].card;
                dom = apqns[i].domain;
-               if (hdr->version == TOKVER_CCA_AES)
+               if (hdr->type == TOKTYPE_CCA_INTERNAL
+                   && hdr->version == TOKVER_CCA_AES)
                        rc = cca_sec2protkey(card, dom, key, pkey->protkey,
                                             &pkey->len, &pkey->type);
-               else /* TOKVER_CCA_VLSC */
+               else if (hdr->type == TOKTYPE_CCA_INTERNAL
+                        && hdr->version == TOKVER_CCA_VLSC)
                        rc = cca_cipher2protkey(card, dom, key, pkey->protkey,
                                                &pkey->len, &pkey->type);
+               else { /* EP11 AES secure key blob */
+                       struct ep11keyblob *kb = (struct ep11keyblob *) key;
+
+                       rc = ep11_key2protkey(card, dom, key, kb->head.len,
+                                             pkey->protkey, &pkey->len,
+                                             &pkey->type);
+               }
                if (rc == 0)
                        break;
        }
@@ -631,12 +822,24 @@ static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags,
        u32 _nr_apqns, *_apqns = NULL;
        struct keytoken_header *hdr = (struct keytoken_header *)key;
 
-       if (keylen < sizeof(struct keytoken_header) ||
-           hdr->type != TOKTYPE_CCA_INTERNAL ||
-           flags == 0)
+       if (keylen < sizeof(struct keytoken_header) || flags == 0)
                return -EINVAL;
 
-       if (hdr->version == TOKVER_CCA_AES || hdr->version == TOKVER_CCA_VLSC) {
+       if (hdr->type == TOKTYPE_NON_CCA && hdr->version == TOKVER_EP11_AES) {
+               int minhwtype = 0, api = 0;
+               struct ep11keyblob *kb = (struct ep11keyblob *) key;
+
+               if (flags != PKEY_FLAGS_MATCH_CUR_MKVP)
+                       return -EINVAL;
+               if (kb->attr & EP11_BLOB_PKEY_EXTRACTABLE) {
+                       minhwtype = ZCRYPT_CEX7;
+                       api = EP11_API_V;
+               }
+               rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+                                   minhwtype, api, kb->wkvp);
+               if (rc)
+                       goto out;
+       } else if (hdr->type == TOKTYPE_CCA_INTERNAL) {
                int minhwtype = ZCRYPT_CEX3C;
                u64 cur_mkvp = 0, old_mkvp = 0;
 
@@ -647,7 +850,7 @@ static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags,
                                cur_mkvp = t->mkvp;
                        if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
                                old_mkvp = t->mkvp;
-               } else {
+               } else if (hdr->version == TOKVER_CCA_VLSC) {
                        struct cipherkeytoken *t = (struct cipherkeytoken *)key;
 
                        minhwtype = ZCRYPT_CEX6;
@@ -655,19 +858,24 @@ static int pkey_apqns4key(const u8 *key, size_t keylen, u32 flags,
                                cur_mkvp = t->mkvp0;
                        if (flags & PKEY_FLAGS_MATCH_ALT_MKVP)
                                old_mkvp = t->mkvp0;
+               } else {
+                       /* unknown cca internal token type */
+                       return -EINVAL;
                }
                rc = cca_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
                                   minhwtype, cur_mkvp, old_mkvp, 1);
                if (rc)
                        goto out;
-               if (apqns) {
-                       if (*nr_apqns < _nr_apqns)
-                               rc = -ENOSPC;
-                       else
-                               memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
-               }
-               *nr_apqns = _nr_apqns;
+       } else
+               return -EINVAL;
+
+       if (apqns) {
+               if (*nr_apqns < _nr_apqns)
+                       rc = -ENOSPC;
+               else
+                       memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
        }
+       *nr_apqns = _nr_apqns;
 
 out:
        kfree(_apqns);
@@ -695,14 +903,26 @@ static int pkey_apqns4keytype(enum pkey_key_type ktype,
                                   minhwtype, cur_mkvp, old_mkvp, 1);
                if (rc)
                        goto out;
-               if (apqns) {
-                       if (*nr_apqns < _nr_apqns)
-                               rc = -ENOSPC;
-                       else
-                               memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
-               }
-               *nr_apqns = _nr_apqns;
+       } else if (ktype == PKEY_TYPE_EP11) {
+               u8 *wkvp = NULL;
+
+               if (flags & PKEY_FLAGS_MATCH_CUR_MKVP)
+                       wkvp = cur_mkvp;
+               rc = ep11_findcard2(&_apqns, &_nr_apqns, 0xFFFF, 0xFFFF,
+                                   ZCRYPT_CEX7, EP11_API_V, wkvp);
+               if (rc)
+                       goto out;
+
+       } else
+               return -EINVAL;
+
+       if (apqns) {
+               if (*nr_apqns < _nr_apqns)
+                       rc = -ENOSPC;
+               else
+                       memcpy(apqns, _apqns, _nr_apqns * sizeof(u32));
        }
+       *nr_apqns = _nr_apqns;
 
 out:
        kfree(_apqns);
@@ -1357,8 +1577,9 @@ static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits,
                                            bool is_xts, char *buf, loff_t off,
                                            size_t count)
 {
-       size_t keysize;
-       int rc;
+       int i, rc, card, dom;
+       u32 nr_apqns, *apqns = NULL;
+       size_t keysize = CCACIPHERTOKENSIZE;
 
        if (off != 0 || count < CCACIPHERTOKENSIZE)
                return -EINVAL;
@@ -1366,22 +1587,31 @@ static ssize_t pkey_ccacipher_aes_attr_read(enum pkey_key_size keybits,
                if (count < 2 * CCACIPHERTOKENSIZE)
                        return -EINVAL;
 
-       keysize = CCACIPHERTOKENSIZE;
-       rc = cca_gencipherkey(-1, -1, keybits, 0, buf, &keysize);
+       /* build a list of apqns able to generate an cipher key */
+       rc = cca_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF,
+                          ZCRYPT_CEX6, 0, 0, 0);
        if (rc)
                return rc;
-       memset(buf + keysize, 0, CCACIPHERTOKENSIZE - keysize);
 
-       if (is_xts) {
-               keysize = CCACIPHERTOKENSIZE;
-               rc = cca_gencipherkey(-1, -1, keybits, 0,
-                                     buf + CCACIPHERTOKENSIZE, &keysize);
+       memset(buf, 0, is_xts ? 2 * keysize : keysize);
+
+       /* simple try all apqns from the list */
+       for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
+               card = apqns[i] >> 16;
+               dom = apqns[i] & 0xFFFF;
+               rc = cca_gencipherkey(card, dom, keybits, 0, buf, &keysize);
+               if (rc == 0)
+                       break;
+       }
                if (rc)
                        return rc;
-               memset(buf + CCACIPHERTOKENSIZE + keysize, 0,
-                      CCACIPHERTOKENSIZE - keysize);
 
-               return 2 * CCACIPHERTOKENSIZE;
+       if (is_xts) {
+               keysize = CCACIPHERTOKENSIZE;
+               buf += CCACIPHERTOKENSIZE;
+               rc = cca_gencipherkey(card, dom, keybits, 0, buf, &keysize);
+               if (rc == 0)
+                       return 2 * CCACIPHERTOKENSIZE;
        }
 
        return CCACIPHERTOKENSIZE;
@@ -1457,10 +1687,134 @@ static struct attribute_group ccacipher_attr_group = {
        .bin_attrs = ccacipher_attrs,
 };
 
+/*
+ * Sysfs attribute read function for all ep11 aes key binary attributes.
+ * The implementation can not deal with partial reads, because a new random
+ * secure key blob is generated with each read. In case of partial reads
+ * (i.e. off != 0 or count < key blob size) -EINVAL is returned.
+ * This function and the sysfs attributes using it provide EP11 key blobs
+ * padded to the upper limit of MAXEP11AESKEYBLOBSIZE which is currently
+ * 320 bytes.
+ */
+static ssize_t pkey_ep11_aes_attr_read(enum pkey_key_size keybits,
+                                      bool is_xts, char *buf, loff_t off,
+                                      size_t count)
+{
+       int i, rc, card, dom;
+       u32 nr_apqns, *apqns = NULL;
+       size_t keysize = MAXEP11AESKEYBLOBSIZE;
+
+       if (off != 0 || count < MAXEP11AESKEYBLOBSIZE)
+               return -EINVAL;
+       if (is_xts)
+               if (count < 2 * MAXEP11AESKEYBLOBSIZE)
+                       return -EINVAL;
+
+       /* build a list of apqns able to generate an cipher key */
+       rc = ep11_findcard2(&apqns, &nr_apqns, 0xFFFF, 0xFFFF,
+                           ZCRYPT_CEX7, EP11_API_V, NULL);
+       if (rc)
+               return rc;
+
+       memset(buf, 0, is_xts ? 2 * keysize : keysize);
+
+       /* simple try all apqns from the list */
+       for (i = 0, rc = -ENODEV; i < nr_apqns; i++) {
+               card = apqns[i] >> 16;
+               dom = apqns[i] & 0xFFFF;
+               rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize);
+               if (rc == 0)
+                       break;
+       }
+       if (rc)
+               return rc;
+
+       if (is_xts) {
+               keysize = MAXEP11AESKEYBLOBSIZE;
+               buf += MAXEP11AESKEYBLOBSIZE;
+               rc = ep11_genaeskey(card, dom, keybits, 0, buf, &keysize);
+               if (rc == 0)
+                       return 2 * MAXEP11AESKEYBLOBSIZE;
+       }
+
+       return MAXEP11AESKEYBLOBSIZE;
+}
+
+static ssize_t ep11_aes_128_read(struct file *filp,
+                                struct kobject *kobj,
+                                struct bin_attribute *attr,
+                                char *buf, loff_t off,
+                                size_t count)
+{
+       return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, false, buf,
+                                      off, count);
+}
+
+static ssize_t ep11_aes_192_read(struct file *filp,
+                                struct kobject *kobj,
+                                struct bin_attribute *attr,
+                                char *buf, loff_t off,
+                                size_t count)
+{
+       return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_192, false, buf,
+                                      off, count);
+}
+
+static ssize_t ep11_aes_256_read(struct file *filp,
+                                struct kobject *kobj,
+                                struct bin_attribute *attr,
+                                char *buf, loff_t off,
+                                size_t count)
+{
+       return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, false, buf,
+                                      off, count);
+}
+
+static ssize_t ep11_aes_128_xts_read(struct file *filp,
+                                    struct kobject *kobj,
+                                    struct bin_attribute *attr,
+                                    char *buf, loff_t off,
+                                    size_t count)
+{
+       return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_128, true, buf,
+                                      off, count);
+}
+
+static ssize_t ep11_aes_256_xts_read(struct file *filp,
+                                    struct kobject *kobj,
+                                    struct bin_attribute *attr,
+                                    char *buf, loff_t off,
+                                    size_t count)
+{
+       return pkey_ep11_aes_attr_read(PKEY_SIZE_AES_256, true, buf,
+                                      off, count);
+}
+
+static BIN_ATTR_RO(ep11_aes_128, MAXEP11AESKEYBLOBSIZE);
+static BIN_ATTR_RO(ep11_aes_192, MAXEP11AESKEYBLOBSIZE);
+static BIN_ATTR_RO(ep11_aes_256, MAXEP11AESKEYBLOBSIZE);
+static BIN_ATTR_RO(ep11_aes_128_xts, 2 * MAXEP11AESKEYBLOBSIZE);
+static BIN_ATTR_RO(ep11_aes_256_xts, 2 * MAXEP11AESKEYBLOBSIZE);
+
+static struct bin_attribute *ep11_attrs[] = {
+       &bin_attr_ep11_aes_128,
+       &bin_attr_ep11_aes_192,
+       &bin_attr_ep11_aes_256,
+       &bin_attr_ep11_aes_128_xts,
+       &bin_attr_ep11_aes_256_xts,
+       NULL
+};
+
+static struct attribute_group ep11_attr_group = {
+       .name      = "ep11",
+       .bin_attrs = ep11_attrs,
+};
+
 static const struct attribute_group *pkey_attr_groups[] = {
        &protkey_attr_group,
        &ccadata_attr_group,
        &ccacipher_attr_group,
+       &ep11_attr_group,
        NULL,
 };
 
index 9157e72..a42257d 100644 (file)
@@ -36,6 +36,7 @@
 #include "zcrypt_msgtype6.h"
 #include "zcrypt_msgtype50.h"
 #include "zcrypt_ccamisc.h"
+#include "zcrypt_ep11misc.h"
 
 /*
  * Module description.
@@ -849,7 +850,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
                        /* check if device is online and eligible */
                        if (!zq->online ||
                            !zq->ops->send_cprb ||
-                           (tdom != (unsigned short) AUTOSELECT &&
+                           (tdom != AUTOSEL_DOM &&
                             tdom != AP_QID_QUEUE(zq->queue->qid)))
                                continue;
                        /* check if device node has admission for this queue */
@@ -874,7 +875,7 @@ static long _zcrypt_send_cprb(struct ap_perms *perms,
 
        /* in case of auto select, provide the correct domain */
        qid = pref_zq->queue->qid;
-       if (*domain == (unsigned short) AUTOSELECT)
+       if (*domain == AUTOSEL_DOM)
                *domain = AP_QID_QUEUE(qid);
 
        rc = pref_zq->ops->send_cprb(pref_zq, xcRB, &ap_msg);
@@ -901,7 +902,7 @@ static bool is_desired_ep11_card(unsigned int dev_id,
                                 struct ep11_target_dev *targets)
 {
        while (target_num-- > 0) {
-               if (dev_id == targets->ap_id)
+               if (targets->ap_id == dev_id || targets->ap_id == AUTOSEL_AP)
                        return true;
                targets++;
        }
@@ -912,16 +913,19 @@ static bool is_desired_ep11_queue(unsigned int dev_qid,
                                  unsigned short target_num,
                                  struct ep11_target_dev *targets)
 {
+       int card = AP_QID_CARD(dev_qid), dom = AP_QID_QUEUE(dev_qid);
+
        while (target_num-- > 0) {
-               if (AP_MKQID(targets->ap_id, targets->dom_id) == dev_qid)
+               if ((targets->ap_id == card || targets->ap_id == AUTOSEL_AP) &&
+                   (targets->dom_id == dom || targets->dom_id == AUTOSEL_DOM))
                        return true;
                targets++;
        }
        return false;
 }
 
-static long zcrypt_send_ep11_cprb(struct ap_perms *perms,
-                                 struct ep11_urb *xcrb)
+static long _zcrypt_send_ep11_cprb(struct ap_perms *perms,
+                                  struct ep11_urb *xcrb)
 {
        struct zcrypt_card *zc, *pref_zc;
        struct zcrypt_queue *zq, *pref_zq;
@@ -1026,6 +1030,12 @@ out:
        return rc;
 }
 
+long zcrypt_send_ep11_cprb(struct ep11_urb *xcrb)
+{
+       return _zcrypt_send_ep11_cprb(&ap_perms, xcrb);
+}
+EXPORT_SYMBOL(zcrypt_send_ep11_cprb);
+
 static long zcrypt_rng(char *buffer)
 {
        struct zcrypt_card *zc, *pref_zc;
@@ -1366,12 +1376,12 @@ static long zcrypt_unlocked_ioctl(struct file *filp, unsigned int cmd,
                if (copy_from_user(&xcrb, uxcrb, sizeof(xcrb)))
                        return -EFAULT;
                do {
-                       rc = zcrypt_send_ep11_cprb(perms, &xcrb);
+                       rc = _zcrypt_send_ep11_cprb(perms, &xcrb);
                } while (rc == -EAGAIN);
                /* on failure: retry once again after a requested rescan */
                if ((rc == -ENODEV) && (zcrypt_process_rescan()))
                        do {
-                               rc = zcrypt_send_ep11_cprb(perms, &xcrb);
+                               rc = _zcrypt_send_ep11_cprb(perms, &xcrb);
                        } while (rc == -EAGAIN);
                if (rc)
                        ZCRYPT_DBF(DBF_DEBUG, "ioctl ZSENDEP11CPRB rc=%d\n", rc);
@@ -1885,6 +1895,7 @@ void __exit zcrypt_api_exit(void)
        zcrypt_msgtype6_exit();
        zcrypt_msgtype50_exit();
        zcrypt_ccamisc_exit();
+       zcrypt_ep11misc_exit();
        zcrypt_debug_exit();
 }
 
index d464618..599e68b 100644 (file)
@@ -140,6 +140,7 @@ struct zcrypt_ops *zcrypt_msgtype(unsigned char *, int);
 int zcrypt_api_init(void);
 void zcrypt_api_exit(void);
 long zcrypt_send_cprb(struct ica_xcRB *xcRB);
+long zcrypt_send_ep11_cprb(struct ep11_urb *urb);
 void zcrypt_device_status_mask_ext(struct zcrypt_device_status_ext *devstatus);
 int zcrypt_device_status_ext(int card, int queue,
                             struct zcrypt_device_status_ext *devstatus);
index 77b6cc7..3a9876d 100644 (file)
@@ -19,6 +19,7 @@
 
 /* For TOKTYPE_NON_CCA: */
 #define TOKVER_PROTECTED_KEY   0x01 /* Protected key token */
+#define TOKVER_CLEAR_KEY       0x02 /* Clear key token */
 
 /* For TOKTYPE_CCA_INTERNAL: */
 #define TOKVER_CCA_AES         0x04 /* CCA AES key token */
index 6fabc90..9a9d02e 100644 (file)
@@ -19,6 +19,7 @@
 #include "zcrypt_error.h"
 #include "zcrypt_cex4.h"
 #include "zcrypt_ccamisc.h"
+#include "zcrypt_ep11misc.h"
 
 #define CEX4A_MIN_MOD_SIZE       1     /*    8 bits    */
 #define CEX4A_MAX_MOD_SIZE_2K  256     /* 2048 bits    */
@@ -71,11 +72,11 @@ static struct ap_device_id zcrypt_cex4_queue_ids[] = {
 MODULE_DEVICE_TABLE(ap, zcrypt_cex4_queue_ids);
 
 /*
- * CCA card addditional device attributes
+ * CCA card additional device attributes
  */
-static ssize_t serialnr_show(struct device *dev,
-                            struct device_attribute *attr,
-                            char *buf)
+static ssize_t cca_serialnr_show(struct device *dev,
+                                struct device_attribute *attr,
+                                char *buf)
 {
        struct cca_info ci;
        struct ap_card *ac = to_ap_card(dev);
@@ -88,23 +89,25 @@ static ssize_t serialnr_show(struct device *dev,
 
        return snprintf(buf, PAGE_SIZE, "%s\n", ci.serial);
 }
-static DEVICE_ATTR_RO(serialnr);
+
+static struct device_attribute dev_attr_cca_serialnr =
+       __ATTR(serialnr, 0444, cca_serialnr_show, NULL);
 
 static struct attribute *cca_card_attrs[] = {
-       &dev_attr_serialnr.attr,
+       &dev_attr_cca_serialnr.attr,
        NULL,
 };
 
-static const struct attribute_group cca_card_attr_group = {
+static const struct attribute_group cca_card_attr_grp = {
        .attrs = cca_card_attrs,
 };
 
-/*
* CCA queue addditional device attributes
- */
-static ssize_t mkvps_show(struct device *dev,
-                         struct device_attribute *attr,
-                         char *buf)
+ /*
 * CCA queue additional device attributes
 */
+static ssize_t cca_mkvps_show(struct device *dev,
+                             struct device_attribute *attr,
+                             char *buf)
 {
        int n = 0;
        struct cca_info ci;
@@ -138,17 +141,233 @@ static ssize_t mkvps_show(struct device *dev,
 
        return n;
 }
-static DEVICE_ATTR_RO(mkvps);
+
+static struct device_attribute dev_attr_cca_mkvps =
+       __ATTR(mkvps, 0444, cca_mkvps_show, NULL);
 
 static struct attribute *cca_queue_attrs[] = {
-       &dev_attr_mkvps.attr,
+       &dev_attr_cca_mkvps.attr,
        NULL,
 };
 
-static const struct attribute_group cca_queue_attr_group = {
+static const struct attribute_group cca_queue_attr_grp = {
        .attrs = cca_queue_attrs,
 };
 
+/*
+ * EP11 card additional device attributes
+ */
+static ssize_t ep11_api_ordinalnr_show(struct device *dev,
+                                      struct device_attribute *attr,
+                                      char *buf)
+{
+       struct ep11_card_info ci;
+       struct ap_card *ac = to_ap_card(dev);
+       struct zcrypt_card *zc = ac->private;
+
+       memset(&ci, 0, sizeof(ci));
+
+       ep11_get_card_info(ac->id, &ci, zc->online);
+
+       if (ci.API_ord_nr > 0)
+               return snprintf(buf, PAGE_SIZE, "%u\n", ci.API_ord_nr);
+       else
+               return snprintf(buf, PAGE_SIZE, "\n");
+}
+
+static struct device_attribute dev_attr_ep11_api_ordinalnr =
+       __ATTR(API_ordinalnr, 0444, ep11_api_ordinalnr_show, NULL);
+
+static ssize_t ep11_fw_version_show(struct device *dev,
+                                   struct device_attribute *attr,
+                                   char *buf)
+{
+       struct ep11_card_info ci;
+       struct ap_card *ac = to_ap_card(dev);
+       struct zcrypt_card *zc = ac->private;
+
+       memset(&ci, 0, sizeof(ci));
+
+       ep11_get_card_info(ac->id, &ci, zc->online);
+
+       if (ci.FW_version > 0)
+               return snprintf(buf, PAGE_SIZE, "%d.%d\n",
+                               (int)(ci.FW_version >> 8),
+                               (int)(ci.FW_version & 0xFF));
+       else
+               return snprintf(buf, PAGE_SIZE, "\n");
+}
+
+static struct device_attribute dev_attr_ep11_fw_version =
+       __ATTR(FW_version, 0444, ep11_fw_version_show, NULL);
+
+static ssize_t ep11_serialnr_show(struct device *dev,
+                                 struct device_attribute *attr,
+                                 char *buf)
+{
+       struct ep11_card_info ci;
+       struct ap_card *ac = to_ap_card(dev);
+       struct zcrypt_card *zc = ac->private;
+
+       memset(&ci, 0, sizeof(ci));
+
+       ep11_get_card_info(ac->id, &ci, zc->online);
+
+       if (ci.serial[0])
+               return snprintf(buf, PAGE_SIZE, "%16.16s\n", ci.serial);
+       else
+               return snprintf(buf, PAGE_SIZE, "\n");
+}
+
+static struct device_attribute dev_attr_ep11_serialnr =
+       __ATTR(serialnr, 0444, ep11_serialnr_show, NULL);
+
+static const struct {
+       int         mode_bit;
+       const char *mode_txt;
+} ep11_op_modes[] = {
+       { 0, "FIPS2009" },
+       { 1, "BSI2009" },
+       { 2, "FIPS2011" },
+       { 3, "BSI2011" },
+       { 6, "BSICC2017" },
+       { 0, NULL }
+};
+
+static ssize_t ep11_card_op_modes_show(struct device *dev,
+                                      struct device_attribute *attr,
+                                      char *buf)
+{
+       int i, n = 0;
+       struct ep11_card_info ci;
+       struct ap_card *ac = to_ap_card(dev);
+       struct zcrypt_card *zc = ac->private;
+
+       memset(&ci, 0, sizeof(ci));
+
+       ep11_get_card_info(ac->id, &ci, zc->online);
+
+       for (i = 0; ep11_op_modes[i].mode_txt; i++) {
+               if (ci.op_mode & (1 << ep11_op_modes[i].mode_bit)) {
+                       if (n > 0)
+                               buf[n++] = ' ';
+                       n += snprintf(buf + n, PAGE_SIZE - n,
+                                     "%s", ep11_op_modes[i].mode_txt);
+               }
+       }
+       n += snprintf(buf + n, PAGE_SIZE - n, "\n");
+
+       return n;
+}
+
+static struct device_attribute dev_attr_ep11_card_op_modes =
+       __ATTR(op_modes, 0444, ep11_card_op_modes_show, NULL);
+
+static struct attribute *ep11_card_attrs[] = {
+       &dev_attr_ep11_api_ordinalnr.attr,
+       &dev_attr_ep11_fw_version.attr,
+       &dev_attr_ep11_serialnr.attr,
+       &dev_attr_ep11_card_op_modes.attr,
+       NULL,
+};
+
+static const struct attribute_group ep11_card_attr_grp = {
+       .attrs = ep11_card_attrs,
+};
+
+/*
+ * EP11 queue additional device attributes
+ */
+
+static ssize_t ep11_mkvps_show(struct device *dev,
+                              struct device_attribute *attr,
+                              char *buf)
+{
+       int n = 0;
+       struct ep11_domain_info di;
+       struct zcrypt_queue *zq = to_ap_queue(dev)->private;
+       static const char * const cwk_state[] = { "invalid", "valid" };
+       static const char * const nwk_state[] = { "empty", "uncommitted",
+                                                 "committed" };
+
+       memset(&di, 0, sizeof(di));
+
+       if (zq->online)
+               ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
+                                    AP_QID_QUEUE(zq->queue->qid),
+                                    &di);
+
+       if (di.cur_wk_state == '0') {
+               n = snprintf(buf, PAGE_SIZE, "WK CUR: %s -\n",
+                            cwk_state[di.cur_wk_state - '0']);
+       } else if (di.cur_wk_state == '1') {
+               n = snprintf(buf, PAGE_SIZE, "WK CUR: %s 0x",
+                            cwk_state[di.cur_wk_state - '0']);
+               bin2hex(buf + n, di.cur_wkvp, sizeof(di.cur_wkvp));
+               n += 2 * sizeof(di.cur_wkvp);
+               n += snprintf(buf + n, PAGE_SIZE - n, "\n");
+       } else
+               n = snprintf(buf, PAGE_SIZE, "WK CUR: - -\n");
+
+       if (di.new_wk_state == '0') {
+               n += snprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s -\n",
+                             nwk_state[di.new_wk_state - '0']);
+       } else if (di.new_wk_state >= '1' && di.new_wk_state <= '2') {
+               n += snprintf(buf + n, PAGE_SIZE - n, "WK NEW: %s 0x",
+                             nwk_state[di.new_wk_state - '0']);
+               bin2hex(buf + n, di.new_wkvp, sizeof(di.new_wkvp));
+               n += 2 * sizeof(di.new_wkvp);
+               n += snprintf(buf + n, PAGE_SIZE - n, "\n");
+       } else
+               n += snprintf(buf + n, PAGE_SIZE - n, "WK NEW: - -\n");
+
+       return n;
+}
+
+static struct device_attribute dev_attr_ep11_mkvps =
+       __ATTR(mkvps, 0444, ep11_mkvps_show, NULL);
+
+static ssize_t ep11_queue_op_modes_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       int i, n = 0;
+       struct ep11_domain_info di;
+       struct zcrypt_queue *zq = to_ap_queue(dev)->private;
+
+       memset(&di, 0, sizeof(di));
+
+       if (zq->online)
+               ep11_get_domain_info(AP_QID_CARD(zq->queue->qid),
+                                    AP_QID_QUEUE(zq->queue->qid),
+                                    &di);
+
+       for (i = 0; ep11_op_modes[i].mode_txt; i++) {
+               if (di.op_mode & (1 << ep11_op_modes[i].mode_bit)) {
+                       if (n > 0)
+                               buf[n++] = ' ';
+                       n += snprintf(buf + n, PAGE_SIZE - n,
+                                     "%s", ep11_op_modes[i].mode_txt);
+               }
+       }
+       n += snprintf(buf + n, PAGE_SIZE - n, "\n");
+
+       return n;
+}
+
+static struct device_attribute dev_attr_ep11_queue_op_modes =
+       __ATTR(op_modes, 0444, ep11_queue_op_modes_show, NULL);
+
+static struct attribute *ep11_queue_attrs[] = {
+       &dev_attr_ep11_mkvps.attr,
+       &dev_attr_ep11_queue_op_modes.attr,
+       NULL,
+};
+
+static const struct attribute_group ep11_queue_attr_grp = {
+       .attrs = ep11_queue_attrs,
+};
+
 /**
  * Probe function for CEX4/CEX5/CEX6/CEX7 card device. It always
  * accepts the AP device since the bus_match already checked
@@ -313,7 +532,12 @@ static int zcrypt_cex4_card_probe(struct ap_device *ap_dev)
 
        if (ap_test_bit(&ac->functions, AP_FUNC_COPRO)) {
                rc = sysfs_create_group(&ap_dev->device.kobj,
-                                       &cca_card_attr_group);
+                                       &cca_card_attr_grp);
+               if (rc)
+                       zcrypt_card_unregister(zc);
+       } else if (ap_test_bit(&ac->functions, AP_FUNC_EP11)) {
+               rc = sysfs_create_group(&ap_dev->device.kobj,
+                                       &ep11_card_attr_grp);
                if (rc)
                        zcrypt_card_unregister(zc);
        }
@@ -332,7 +556,9 @@ static void zcrypt_cex4_card_remove(struct ap_device *ap_dev)
        struct zcrypt_card *zc = ac->private;
 
        if (ap_test_bit(&ac->functions, AP_FUNC_COPRO))
-               sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_group);
+               sysfs_remove_group(&ap_dev->device.kobj, &cca_card_attr_grp);
+       else if (ap_test_bit(&ac->functions, AP_FUNC_EP11))
+               sysfs_remove_group(&ap_dev->device.kobj, &ep11_card_attr_grp);
        if (zc)
                zcrypt_card_unregister(zc);
 }
@@ -394,7 +620,12 @@ static int zcrypt_cex4_queue_probe(struct ap_device *ap_dev)
 
        if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO)) {
                rc = sysfs_create_group(&ap_dev->device.kobj,
-                                       &cca_queue_attr_group);
+                                       &cca_queue_attr_grp);
+               if (rc)
+                       zcrypt_queue_unregister(zq);
+       } else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11)) {
+               rc = sysfs_create_group(&ap_dev->device.kobj,
+                                       &ep11_queue_attr_grp);
                if (rc)
                        zcrypt_queue_unregister(zq);
        }
@@ -413,7 +644,9 @@ static void zcrypt_cex4_queue_remove(struct ap_device *ap_dev)
        struct zcrypt_queue *zq = aq->private;
 
        if (ap_test_bit(&aq->card->functions, AP_FUNC_COPRO))
-               sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_group);
+               sysfs_remove_group(&ap_dev->device.kobj, &cca_queue_attr_grp);
+       else if (ap_test_bit(&aq->card->functions, AP_FUNC_EP11))
+               sysfs_remove_group(&ap_dev->device.kobj, &ep11_queue_attr_grp);
        if (zq)
                zcrypt_queue_unregister(zq);
 }
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.c b/drivers/s390/crypto/zcrypt_ep11misc.c
new file mode 100644 (file)
index 0000000..d4caf46
--- /dev/null
@@ -0,0 +1,1293 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ *  Copyright IBM Corp. 2019
+ *  Author(s): Harald Freudenberger <freude@linux.ibm.com>
+ *
+ *  Collection of EP11 misc functions used by zcrypt and pkey
+ */
+
+#define KMSG_COMPONENT "zcrypt"
+#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/random.h>
+#include <asm/zcrypt.h>
+#include <asm/pkey.h>
+
+#include "ap_bus.h"
+#include "zcrypt_api.h"
+#include "zcrypt_debug.h"
+#include "zcrypt_msgtype6.h"
+#include "zcrypt_ep11misc.h"
+#include "zcrypt_ccamisc.h"
+
+#define DEBUG_DBG(...) ZCRYPT_DBF(DBF_DEBUG, ##__VA_ARGS__)
+#define DEBUG_INFO(...) ZCRYPT_DBF(DBF_INFO, ##__VA_ARGS__)
+#define DEBUG_WARN(...) ZCRYPT_DBF(DBF_WARN, ##__VA_ARGS__)
+#define DEBUG_ERR(...) ZCRYPT_DBF(DBF_ERR, ##__VA_ARGS__)
+
+/* default iv used here */
+static const u8 def_iv[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+                              0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
+
+/* ep11 card info cache */
+struct card_list_entry {
+       struct list_head list;
+       u16 cardnr;
+       struct ep11_card_info info;
+};
+static LIST_HEAD(card_list);
+static DEFINE_SPINLOCK(card_list_lock);
+
+static int card_cache_fetch(u16 cardnr, struct ep11_card_info *ci)
+{
+       int rc = -ENOENT;
+       struct card_list_entry *ptr;
+
+       spin_lock_bh(&card_list_lock);
+       list_for_each_entry(ptr, &card_list, list) {
+               if (ptr->cardnr == cardnr) {
+                       memcpy(ci, &ptr->info, sizeof(*ci));
+                       rc = 0;
+                       break;
+               }
+       }
+       spin_unlock_bh(&card_list_lock);
+
+       return rc;
+}
+
+static void card_cache_update(u16 cardnr, const struct ep11_card_info *ci)
+{
+       int found = 0;
+       struct card_list_entry *ptr;
+
+       spin_lock_bh(&card_list_lock);
+       list_for_each_entry(ptr, &card_list, list) {
+               if (ptr->cardnr == cardnr) {
+                       memcpy(&ptr->info, ci, sizeof(*ci));
+                       found = 1;
+                       break;
+               }
+       }
+       if (!found) {
+               ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC);
+               if (!ptr) {
+                       spin_unlock_bh(&card_list_lock);
+                       return;
+               }
+               ptr->cardnr = cardnr;
+               memcpy(&ptr->info, ci, sizeof(*ci));
+               list_add(&ptr->list, &card_list);
+       }
+       spin_unlock_bh(&card_list_lock);
+}
+
+static void card_cache_scrub(u16 cardnr)
+{
+       struct card_list_entry *ptr;
+
+       spin_lock_bh(&card_list_lock);
+       list_for_each_entry(ptr, &card_list, list) {
+               if (ptr->cardnr == cardnr) {
+                       list_del(&ptr->list);
+                       kfree(ptr);
+                       break;
+               }
+       }
+       spin_unlock_bh(&card_list_lock);
+}
+
+static void __exit card_cache_free(void)
+{
+       struct card_list_entry *ptr, *pnext;
+
+       spin_lock_bh(&card_list_lock);
+       list_for_each_entry_safe(ptr, pnext, &card_list, list) {
+               list_del(&ptr->list);
+               kfree(ptr);
+       }
+       spin_unlock_bh(&card_list_lock);
+}
+
+/*
+ * Simple check if the key blob is a valid EP11 secure AES key.
+ */
+int ep11_check_aeskeyblob(debug_info_t *dbg, int dbflvl,
+                         const u8 *key, int keybitsize,
+                         int checkcpacfexport)
+{
+       struct ep11keyblob *kb = (struct ep11keyblob *) key;
+
+#define DBF(...) debug_sprintf_event(dbg, dbflvl, ##__VA_ARGS__)
+
+       if (kb->head.type != TOKTYPE_NON_CCA) {
+               if (dbg)
+                       DBF("%s key check failed, type 0x%02x != 0x%02x\n",
+                           __func__, (int) kb->head.type, TOKTYPE_NON_CCA);
+               return -EINVAL;
+       }
+       if (kb->head.version != TOKVER_EP11_AES) {
+               if (dbg)
+                       DBF("%s key check failed, version 0x%02x != 0x%02x\n",
+                           __func__, (int) kb->head.version, TOKVER_EP11_AES);
+               return -EINVAL;
+       }
+       if (kb->version != EP11_STRUCT_MAGIC) {
+               if (dbg)
+                       DBF("%s key check failed, magic 0x%04x != 0x%04x\n",
+                           __func__, (int) kb->version, EP11_STRUCT_MAGIC);
+               return -EINVAL;
+       }
+       switch (kb->head.keybitlen) {
+       case 128:
+       case 192:
+       case 256:
+               break;
+       default:
+               if (dbg)
+                       DBF("%s key check failed, keybitlen %d invalid\n",
+                           __func__, (int) kb->head.keybitlen);
+               return -EINVAL;
+       }
+       if (keybitsize > 0 && keybitsize != (int) kb->head.keybitlen) {
+               DBF("%s key check failed, keybitsize %d\n",
+                   __func__, keybitsize);
+               return -EINVAL;
+       }
+       if (checkcpacfexport && !(kb->attr & EP11_BLOB_PKEY_EXTRACTABLE)) {
+               if (dbg)
+                       DBF("%s key check failed, PKEY_EXTRACTABLE is 0\n",
+                           __func__);
+               return -EINVAL;
+       }
+#undef DBF
+
+       return 0;
+}
+EXPORT_SYMBOL(ep11_check_aeskeyblob);
+
+/*
+ * Helper function which calls zcrypt_send_ep11_cprb with
+ * memory management segment adjusted to kernel space
+ * so that the copy_from_user called within this
+ * function do in fact copy from kernel space.
+ */
+static inline int _zcrypt_send_ep11_cprb(struct ep11_urb *urb)
+{
+       int rc;
+       mm_segment_t old_fs = get_fs();
+
+       set_fs(KERNEL_DS);
+       rc = zcrypt_send_ep11_cprb(urb);
+       set_fs(old_fs);
+
+       return rc;
+}
+
+/*
+ * Allocate and prepare ep11 cprb plus additional payload.
+ */
+static inline struct ep11_cprb *alloc_cprb(size_t payload_len)
+{
+       size_t len = sizeof(struct ep11_cprb) + payload_len;
+       struct ep11_cprb *cprb;
+
+       cprb = kmalloc(len, GFP_KERNEL);
+       if (!cprb)
+               return NULL;
+
+       memset(cprb, 0, len);
+       cprb->cprb_len = sizeof(struct ep11_cprb);
+       cprb->cprb_ver_id = 0x04;
+       memcpy(cprb->func_id, "T4", 2);
+       cprb->ret_code = 0xFFFFFFFF;
+       cprb->payload_len = payload_len;
+
+       return cprb;
+}
+
+/*
+ * Some helper functions related to ASN1 encoding.
+ * Limited to length info <= 2 byte.
+ */
+
+#define ASN1TAGLEN(x) (2 + (x) + ((x) > 127 ? 1 : 0) + ((x) > 255 ? 1 : 0))
+
+static int asn1tag_write(u8 *ptr, u8 tag, const u8 *pvalue, u16 valuelen)
+{
+       ptr[0] = tag;
+       if (valuelen > 255) {
+               ptr[1] = 0x82;
+               *((u16 *)(ptr + 2)) = valuelen;
+               memcpy(ptr + 4, pvalue, valuelen);
+               return 4 + valuelen;
+       }
+       if (valuelen > 127) {
+               ptr[1] = 0x81;
+               ptr[2] = (u8) valuelen;
+               memcpy(ptr + 3, pvalue, valuelen);
+               return 3 + valuelen;
+       }
+       ptr[1] = (u8) valuelen;
+       memcpy(ptr + 2, pvalue, valuelen);
+       return 2 + valuelen;
+}
+
+/* EP11 payload > 127 bytes starts with this struct */
+struct pl_head {
+       u8  tag;
+       u8  lenfmt;
+       u16 len;
+       u8  func_tag;
+       u8  func_len;
+       u32 func;
+       u8  dom_tag;
+       u8  dom_len;
+       u32 dom;
+} __packed;
+
+/* prep ep11 payload head helper function */
+static inline void prep_head(struct pl_head *h,
+                            size_t pl_size, int api, int func)
+{
+       h->tag = 0x30;
+       h->lenfmt = 0x82;
+       h->len = pl_size - 4;
+       h->func_tag = 0x04;
+       h->func_len = sizeof(u32);
+       h->func = (api << 16) + func;
+       h->dom_tag = 0x04;
+       h->dom_len = sizeof(u32);
+}
+
+/* prep urb helper function */
+static inline void prep_urb(struct ep11_urb *u,
+                           struct ep11_target_dev *t, int nt,
+                           struct ep11_cprb *req, size_t req_len,
+                           struct ep11_cprb *rep, size_t rep_len)
+{
+       u->targets = (u8 __user *) t;
+       u->targets_num = nt;
+       u->req = (u8 __user *) req;
+       u->req_len = req_len;
+       u->resp = (u8 __user *) rep;
+       u->resp_len = rep_len;
+}
+
+/* Check ep11 reply payload, return 0 or suggested errno value. */
+static int check_reply_pl(const u8 *pl, const char *func)
+{
+       int len;
+       u32 ret;
+
+       /* start tag */
+       if (*pl++ != 0x30) {
+               DEBUG_ERR("%s reply start tag mismatch\n", func);
+               return -EIO;
+       }
+
+       /* payload length format */
+       if (*pl < 127) {
+               len = *pl;
+               pl++;
+       } else if (*pl == 0x81) {
+               pl++;
+               len = *pl;
+               pl++;
+       } else if (*pl == 0x82) {
+               pl++;
+               len = *((u16 *)pl);
+               pl += 2;
+       } else {
+               DEBUG_ERR("%s reply start tag lenfmt mismatch 0x%02hhx\n",
+                         func, *pl);
+               return -EIO;
+       }
+
+       /* len should cover at least 3 fields with 32 bit value each */
+       if (len < 3 * 6) {
+               DEBUG_ERR("%s reply length %d too small\n", func, len);
+               return -EIO;
+       }
+
+       /* function tag, length and value */
+       if (pl[0] != 0x04 || pl[1] != 0x04) {
+               DEBUG_ERR("%s function tag or length mismatch\n", func);
+               return -EIO;
+       }
+       pl += 6;
+
+       /* dom tag, length and value */
+       if (pl[0] != 0x04 || pl[1] != 0x04) {
+               DEBUG_ERR("%s dom tag or length mismatch\n", func);
+               return -EIO;
+       }
+       pl += 6;
+
+       /* return value tag, length and value */
+       if (pl[0] != 0x04 || pl[1] != 0x04) {
+               DEBUG_ERR("%s return value tag or length mismatch\n", func);
+               return -EIO;
+       }
+       pl += 2;
+       ret = *((u32 *)pl);
+       if (ret != 0) {
+               DEBUG_ERR("%s return value 0x%04x != 0\n", func, ret);
+               return -EIO;
+       }
+
+       return 0;
+}
+
+
+/*
+ * Helper function which does an ep11 query with given query type.
+ */
+static int ep11_query_info(u16 cardnr, u16 domain, u32 query_type,
+                          size_t buflen, u8 *buf)
+{
+       struct ep11_info_req_pl {
+               struct pl_head head;
+               u8  query_type_tag;
+               u8  query_type_len;
+               u32 query_type;
+               u8  query_subtype_tag;
+               u8  query_subtype_len;
+               u32 query_subtype;
+       } __packed * req_pl;
+       struct ep11_info_rep_pl {
+               struct pl_head head;
+               u8  rc_tag;
+               u8  rc_len;
+               u32 rc;
+               u8  data_tag;
+               u8  data_lenfmt;
+               u16 data_len;
+       } __packed * rep_pl;
+       struct ep11_cprb *req = NULL, *rep = NULL;
+       struct ep11_target_dev target;
+       struct ep11_urb *urb = NULL;
+       int api = 1, rc = -ENOMEM;
+
+       /* request cprb and payload */
+       req = alloc_cprb(sizeof(struct ep11_info_req_pl));
+       if (!req)
+               goto out;
+       req_pl = (struct ep11_info_req_pl *) (((u8 *) req) + sizeof(*req));
+       prep_head(&req_pl->head, sizeof(*req_pl), api, 38); /* get xcp info */
+       req_pl->query_type_tag = 0x04;
+       req_pl->query_type_len = sizeof(u32);
+       req_pl->query_type = query_type;
+       req_pl->query_subtype_tag = 0x04;
+       req_pl->query_subtype_len = sizeof(u32);
+
+       /* reply cprb and payload */
+       rep = alloc_cprb(sizeof(struct ep11_info_rep_pl) + buflen);
+       if (!rep)
+               goto out;
+       rep_pl = (struct ep11_info_rep_pl *) (((u8 *) rep) + sizeof(*rep));
+
+       /* urb and target */
+       urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
+       if (!urb)
+               goto out;
+       target.ap_id = cardnr;
+       target.dom_id = domain;
+       prep_urb(urb, &target, 1,
+                req, sizeof(*req) + sizeof(*req_pl),
+                rep, sizeof(*rep) + sizeof(*rep_pl) + buflen);
+
+       rc = _zcrypt_send_ep11_cprb(urb);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
+                       __func__, (int) cardnr, (int) domain, rc);
+               goto out;
+       }
+
+       rc = check_reply_pl((u8 *)rep_pl, __func__);
+       if (rc)
+               goto out;
+       if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {
+               DEBUG_ERR("%s unknown reply data format\n", __func__);
+               rc = -EIO;
+               goto out;
+       }
+       if (rep_pl->data_len > buflen) {
+               DEBUG_ERR("%s mismatch between reply data len and buffer len\n",
+                         __func__);
+               rc = -ENOSPC;
+               goto out;
+       }
+
+       memcpy(buf, ((u8 *) rep_pl) + sizeof(*rep_pl), rep_pl->data_len);
+
+out:
+       kfree(req);
+       kfree(rep);
+       kfree(urb);
+       return rc;
+}
+
+/*
+ * Provide information about an EP11 card.
+ */
+int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify)
+{
+       int rc;
+       struct ep11_module_query_info {
+               u32 API_ord_nr;
+               u32 firmware_id;
+               u8  FW_major_vers;
+               u8  FW_minor_vers;
+               u8  CSP_major_vers;
+               u8  CSP_minor_vers;
+               u8  fwid[32];
+               u8  xcp_config_hash[32];
+               u8  CSP_config_hash[32];
+               u8  serial[16];
+               u8  module_date_time[16];
+               u64 op_mode;
+               u32 PKCS11_flags;
+               u32 ext_flags;
+               u32 domains;
+               u32 sym_state_bytes;
+               u32 digest_state_bytes;
+               u32 pin_blob_bytes;
+               u32 SPKI_bytes;
+               u32 priv_key_blob_bytes;
+               u32 sym_blob_bytes;
+               u32 max_payload_bytes;
+               u32 CP_profile_bytes;
+               u32 max_CP_index;
+       } __packed * pmqi = NULL;
+
+       rc = card_cache_fetch(card, info);
+       if (rc || verify) {
+               pmqi = kmalloc(sizeof(*pmqi), GFP_KERNEL);
+               if (!pmqi)
+                       return -ENOMEM;
+               rc = ep11_query_info(card, AUTOSEL_DOM,
+                                    0x01 /* module info query */,
+                                    sizeof(*pmqi), (u8 *) pmqi);
+               if (rc) {
+                       if (rc == -ENODEV)
+                               card_cache_scrub(card);
+                       goto out;
+               }
+               memset(info, 0, sizeof(*info));
+               info->API_ord_nr = pmqi->API_ord_nr;
+               info->FW_version =
+                       (pmqi->FW_major_vers << 8) + pmqi->FW_minor_vers;
+               memcpy(info->serial, pmqi->serial, sizeof(info->serial));
+               info->op_mode = pmqi->op_mode;
+               card_cache_update(card, info);
+       }
+
+out:
+       kfree(pmqi);
+       return rc;
+}
+EXPORT_SYMBOL(ep11_get_card_info);
+
+/*
+ * Provide information about a domain within an EP11 card.
+ */
+int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info)
+{
+       int rc;
+       struct ep11_domain_query_info {
+               u32 dom_index;
+               u8  cur_WK_VP[32];
+               u8  new_WK_VP[32];
+               u32 dom_flags;
+               u64 op_mode;
+       } __packed * p_dom_info;
+
+       p_dom_info = kmalloc(sizeof(*p_dom_info), GFP_KERNEL);
+       if (!p_dom_info)
+               return -ENOMEM;
+
+       rc = ep11_query_info(card, domain, 0x03 /* domain info query */,
+                            sizeof(*p_dom_info), (u8 *) p_dom_info);
+       if (rc)
+               goto out;
+
+       memset(info, 0, sizeof(*info));
+       info->cur_wk_state = '0';
+       info->new_wk_state = '0';
+       if (p_dom_info->dom_flags & 0x10 /* left imprint mode */) {
+               if (p_dom_info->dom_flags & 0x02 /* cur wk valid */) {
+                       info->cur_wk_state = '1';
+                       memcpy(info->cur_wkvp, p_dom_info->cur_WK_VP, 32);
+               }
+               if (p_dom_info->dom_flags & 0x04 /* new wk present */
+                   || p_dom_info->dom_flags & 0x08 /* new wk committed */) {
+                       info->new_wk_state =
+                               p_dom_info->dom_flags & 0x08 ? '2' : '1';
+                       memcpy(info->new_wkvp, p_dom_info->new_WK_VP, 32);
+               }
+       }
+       info->op_mode = p_dom_info->op_mode;
+
+out:
+       kfree(p_dom_info);
+       return rc;
+}
+EXPORT_SYMBOL(ep11_get_domain_info);
+
+/*
+ * Default EP11 AES key generate attributes, used when no keygenflags given:
+ * XCP_BLOB_ENCRYPT | XCP_BLOB_DECRYPT | XCP_BLOB_PROTKEY_EXTRACTABLE
+ */
+#define KEY_ATTR_DEFAULTS 0x00200c00
+
+int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+                  u8 *keybuf, size_t *keybufsize)
+{
+       struct keygen_req_pl {
+               struct pl_head head;
+               u8  var_tag;
+               u8  var_len;
+               u32 var;
+               u8  keybytes_tag;
+               u8  keybytes_len;
+               u32 keybytes;
+               u8  mech_tag;
+               u8  mech_len;
+               u32 mech;
+               u8  attr_tag;
+               u8  attr_len;
+               u32 attr_header;
+               u32 attr_bool_mask;
+               u32 attr_bool_bits;
+               u32 attr_val_len_type;
+               u32 attr_val_len_value;
+               u8  pin_tag;
+               u8  pin_len;
+       } __packed * req_pl;
+       struct keygen_rep_pl {
+               struct pl_head head;
+               u8  rc_tag;
+               u8  rc_len;
+               u32 rc;
+               u8  data_tag;
+               u8  data_lenfmt;
+               u16 data_len;
+               u8  data[512];
+       } __packed * rep_pl;
+       struct ep11_cprb *req = NULL, *rep = NULL;
+       struct ep11_target_dev target;
+       struct ep11_urb *urb = NULL;
+       struct ep11keyblob *kb;
+       int api, rc = -ENOMEM;
+
+       switch (keybitsize) {
+       case 128:
+       case 192:
+       case 256:
+               break;
+       default:
+               DEBUG_ERR(
+                       "%s unknown/unsupported keybitsize %d\n",
+                       __func__, keybitsize);
+               rc = -EINVAL;
+               goto out;
+       }
+
+       /* request cprb and payload */
+       req = alloc_cprb(sizeof(struct keygen_req_pl));
+       if (!req)
+               goto out;
+       req_pl = (struct keygen_req_pl *) (((u8 *) req) + sizeof(*req));
+       api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1;
+       prep_head(&req_pl->head, sizeof(*req_pl), api, 21); /* GenerateKey */
+       req_pl->var_tag = 0x04;
+       req_pl->var_len = sizeof(u32);
+       req_pl->keybytes_tag = 0x04;
+       req_pl->keybytes_len = sizeof(u32);
+       req_pl->keybytes = keybitsize / 8;
+       req_pl->mech_tag = 0x04;
+       req_pl->mech_len = sizeof(u32);
+       req_pl->mech = 0x00001080; /* CKM_AES_KEY_GEN */
+       req_pl->attr_tag = 0x04;
+       req_pl->attr_len = 5 * sizeof(u32);
+       req_pl->attr_header = 0x10010000;
+       req_pl->attr_bool_mask = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
+       req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
+       req_pl->attr_val_len_type = 0x00000161; /* CKA_VALUE_LEN */
+       req_pl->attr_val_len_value = keybitsize / 8;
+       req_pl->pin_tag = 0x04;
+
+       /* reply cprb and payload */
+       rep = alloc_cprb(sizeof(struct keygen_rep_pl));
+       if (!rep)
+               goto out;
+       rep_pl = (struct keygen_rep_pl *) (((u8 *) rep) + sizeof(*rep));
+
+       /* urb and target */
+       urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
+       if (!urb)
+               goto out;
+       target.ap_id = card;
+       target.dom_id = domain;
+       prep_urb(urb, &target, 1,
+                req, sizeof(*req) + sizeof(*req_pl),
+                rep, sizeof(*rep) + sizeof(*rep_pl));
+
+       rc = _zcrypt_send_ep11_cprb(urb);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
+                       __func__, (int) card, (int) domain, rc);
+               goto out;
+       }
+
+       rc = check_reply_pl((u8 *)rep_pl, __func__);
+       if (rc)
+               goto out;
+       if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {
+               DEBUG_ERR("%s unknown reply data format\n", __func__);
+               rc = -EIO;
+               goto out;
+       }
+       if (rep_pl->data_len > *keybufsize) {
+               DEBUG_ERR("%s mismatch reply data len / key buffer len\n",
+                         __func__);
+               rc = -ENOSPC;
+               goto out;
+       }
+
+       /* copy key blob and set header values */
+       memcpy(keybuf, rep_pl->data, rep_pl->data_len);
+       *keybufsize = rep_pl->data_len;
+       kb = (struct ep11keyblob *) keybuf;
+       kb->head.type = TOKTYPE_NON_CCA;
+       kb->head.len = rep_pl->data_len;
+       kb->head.version = TOKVER_EP11_AES;
+       kb->head.keybitlen = keybitsize;
+
+out:
+       kfree(req);
+       kfree(rep);
+       kfree(urb);
+       return rc;
+}
+EXPORT_SYMBOL(ep11_genaeskey);
+
+static int ep11_cryptsingle(u16 card, u16 domain,
+                           u16 mode, u32 mech, const u8 *iv,
+                           const u8 *key, size_t keysize,
+                           const u8 *inbuf, size_t inbufsize,
+                           u8 *outbuf, size_t *outbufsize)
+{
+       struct crypt_req_pl {
+               struct pl_head head;
+               u8  var_tag;
+               u8  var_len;
+               u32 var;
+               u8  mech_tag;
+               u8  mech_len;
+               u32 mech;
+               /*
+                * maybe followed by iv data
+                * followed by key tag + key blob
+                * followed by plaintext tag + plaintext
+                */
+       } __packed * req_pl;
+       struct crypt_rep_pl {
+               struct pl_head head;
+               u8  rc_tag;
+               u8  rc_len;
+               u32 rc;
+               u8  data_tag;
+               u8  data_lenfmt;
+               /* data follows */
+       } __packed * rep_pl;
+       struct ep11_cprb *req = NULL, *rep = NULL;
+       struct ep11_target_dev target;
+       struct ep11_urb *urb = NULL;
+       size_t req_pl_size, rep_pl_size;
+       int n, api = 1, rc = -ENOMEM;
+       u8 *p;
+
+       /* the simple asn1 coding used has length limits */
+       if (keysize > 0xFFFF || inbufsize > 0xFFFF)
+               return -EINVAL;
+
+       /* request cprb and payload */
+       req_pl_size = sizeof(struct crypt_req_pl) + (iv ? 16 : 0)
+               + ASN1TAGLEN(keysize) + ASN1TAGLEN(inbufsize);
+       req = alloc_cprb(req_pl_size);
+       if (!req)
+               goto out;
+       req_pl = (struct crypt_req_pl *) (((u8 *) req) + sizeof(*req));
+       prep_head(&req_pl->head, req_pl_size, api, (mode ? 20 : 19));
+       req_pl->var_tag = 0x04;
+       req_pl->var_len = sizeof(u32);
+       /* mech is mech + mech params (iv here) */
+       req_pl->mech_tag = 0x04;
+       req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);
+       req_pl->mech = (mech ? mech : 0x00001085); /* CKM_AES_CBC_PAD */
+       p = ((u8 *) req_pl) + sizeof(*req_pl);
+       if (iv) {
+               memcpy(p, iv, 16);
+               p += 16;
+       }
+       /* key and input data */
+       p += asn1tag_write(p, 0x04, key, keysize);
+       p += asn1tag_write(p, 0x04, inbuf, inbufsize);
+
+       /* reply cprb and payload, assume out data size <= in data size + 32 */
+       rep_pl_size = sizeof(struct crypt_rep_pl) + ASN1TAGLEN(inbufsize + 32);
+       rep = alloc_cprb(rep_pl_size);
+       if (!rep)
+               goto out;
+       rep_pl = (struct crypt_rep_pl *) (((u8 *) rep) + sizeof(*rep));
+
+       /* urb and target */
+       urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
+       if (!urb)
+               goto out;
+       target.ap_id = card;
+       target.dom_id = domain;
+       prep_urb(urb, &target, 1,
+                req, sizeof(*req) + req_pl_size,
+                rep, sizeof(*rep) + rep_pl_size);
+
+       rc = _zcrypt_send_ep11_cprb(urb);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
+                       __func__, (int) card, (int) domain, rc);
+               goto out;
+       }
+
+       rc = check_reply_pl((u8 *)rep_pl, __func__);
+       if (rc)
+               goto out;
+       if (rep_pl->data_tag != 0x04) {
+               DEBUG_ERR("%s unknown reply data format\n", __func__);
+               rc = -EIO;
+               goto out;
+       }
+       p = ((u8 *) rep_pl) + sizeof(*rep_pl);
+       if (rep_pl->data_lenfmt <= 127)
+               n = rep_pl->data_lenfmt;
+       else if (rep_pl->data_lenfmt == 0x81)
+               n = *p++;
+       else if (rep_pl->data_lenfmt == 0x82) {
+               n = *((u16 *) p);
+               p += 2;
+       } else {
+               DEBUG_ERR("%s unknown reply data length format 0x%02hhx\n",
+                         __func__, rep_pl->data_lenfmt);
+               rc = -EIO;
+               goto out;
+       }
+       if (n > *outbufsize) {
+               DEBUG_ERR("%s mismatch reply data len %d / output buffer %zu\n",
+                         __func__, n, *outbufsize);
+               rc = -ENOSPC;
+               goto out;
+       }
+
+       memcpy(outbuf, p, n);
+       *outbufsize = n;
+
+out:
+       kfree(req);
+       kfree(rep);
+       kfree(urb);
+       return rc;
+}
+
+static int ep11_unwrapkey(u16 card, u16 domain,
+                         const u8 *kek, size_t keksize,
+                         const u8 *enckey, size_t enckeysize,
+                         u32 mech, const u8 *iv,
+                         u32 keybitsize, u32 keygenflags,
+                         u8 *keybuf, size_t *keybufsize)
+{
+       struct uw_req_pl {
+               struct pl_head head;
+               u8  attr_tag;
+               u8  attr_len;
+               u32 attr_header;
+               u32 attr_bool_mask;
+               u32 attr_bool_bits;
+               u32 attr_key_type;
+               u32 attr_key_type_value;
+               u32 attr_val_len;
+               u32 attr_val_len_value;
+               u8  mech_tag;
+               u8  mech_len;
+               u32 mech;
+               /*
+                * maybe followed by iv data
+                * followed by kek tag + kek blob
+                * followed by empty mac tag
+                * followed by empty pin tag
+                * followed by encryted key tag + bytes
+                */
+       } __packed * req_pl;
+       struct uw_rep_pl {
+               struct pl_head head;
+               u8  rc_tag;
+               u8  rc_len;
+               u32 rc;
+               u8  data_tag;
+               u8  data_lenfmt;
+               u16 data_len;
+               u8  data[512];
+       } __packed * rep_pl;
+       struct ep11_cprb *req = NULL, *rep = NULL;
+       struct ep11_target_dev target;
+       struct ep11_urb *urb = NULL;
+       struct ep11keyblob *kb;
+       size_t req_pl_size;
+       int api, rc = -ENOMEM;
+       u8 *p;
+
+       /* request cprb and payload */
+       req_pl_size = sizeof(struct uw_req_pl) + (iv ? 16 : 0)
+               + ASN1TAGLEN(keksize) + 4 + ASN1TAGLEN(enckeysize);
+       req = alloc_cprb(req_pl_size);
+       if (!req)
+               goto out;
+       req_pl = (struct uw_req_pl *) (((u8 *) req) + sizeof(*req));
+       api = (!keygenflags || keygenflags & 0x00200000) ? 4 : 1;
+       prep_head(&req_pl->head, req_pl_size, api, 34); /* UnwrapKey */
+       req_pl->attr_tag = 0x04;
+       req_pl->attr_len = 7 * sizeof(u32);
+       req_pl->attr_header = 0x10020000;
+       req_pl->attr_bool_mask = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
+       req_pl->attr_bool_bits = keygenflags ? keygenflags : KEY_ATTR_DEFAULTS;
+       req_pl->attr_key_type = 0x00000100; /* CKA_KEY_TYPE */
+       req_pl->attr_key_type_value = 0x0000001f; /* CKK_AES */
+       req_pl->attr_val_len = 0x00000161; /* CKA_VALUE_LEN */
+       req_pl->attr_val_len_value = keybitsize / 8;
+       /* mech is mech + mech params (iv here) */
+       req_pl->mech_tag = 0x04;
+       req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);
+       req_pl->mech = (mech ? mech : 0x00001085); /* CKM_AES_CBC_PAD */
+       p = ((u8 *) req_pl) + sizeof(*req_pl);
+       if (iv) {
+               memcpy(p, iv, 16);
+               p += 16;
+       }
+       /* kek */
+       p += asn1tag_write(p, 0x04, kek, keksize);
+       /* empty mac key tag */
+       *p++ = 0x04;
+       *p++ = 0;
+       /* empty pin tag */
+       *p++ = 0x04;
+       *p++ = 0;
+       /* encrytped key value tag and bytes */
+       p += asn1tag_write(p, 0x04, enckey, enckeysize);
+
+       /* reply cprb and payload */
+       rep = alloc_cprb(sizeof(struct uw_rep_pl));
+       if (!rep)
+               goto out;
+       rep_pl = (struct uw_rep_pl *) (((u8 *) rep) + sizeof(*rep));
+
+       /* urb and target */
+       urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
+       if (!urb)
+               goto out;
+       target.ap_id = card;
+       target.dom_id = domain;
+       prep_urb(urb, &target, 1,
+                req, sizeof(*req) + req_pl_size,
+                rep, sizeof(*rep) + sizeof(*rep_pl));
+
+       rc = _zcrypt_send_ep11_cprb(urb);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
+                       __func__, (int) card, (int) domain, rc);
+               goto out;
+       }
+
+       rc = check_reply_pl((u8 *)rep_pl, __func__);
+       if (rc)
+               goto out;
+       if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {
+               DEBUG_ERR("%s unknown reply data format\n", __func__);
+               rc = -EIO;
+               goto out;
+       }
+       if (rep_pl->data_len > *keybufsize) {
+               DEBUG_ERR("%s mismatch reply data len / key buffer len\n",
+                         __func__);
+               rc = -ENOSPC;
+               goto out;
+       }
+
+       /* copy key blob and set header values */
+       memcpy(keybuf, rep_pl->data, rep_pl->data_len);
+       *keybufsize = rep_pl->data_len;
+       kb = (struct ep11keyblob *) keybuf;
+       kb->head.type = TOKTYPE_NON_CCA;
+       kb->head.len = rep_pl->data_len;
+       kb->head.version = TOKVER_EP11_AES;
+       kb->head.keybitlen = keybitsize;
+
+out:
+       kfree(req);
+       kfree(rep);
+       kfree(urb);
+       return rc;
+}
+
+static int ep11_wrapkey(u16 card, u16 domain,
+                       const u8 *key, size_t keysize,
+                       u32 mech, const u8 *iv,
+                       u8 *databuf, size_t *datasize)
+{
+       struct wk_req_pl {
+               struct pl_head head;
+               u8  var_tag;
+               u8  var_len;
+               u32 var;
+               u8  mech_tag;
+               u8  mech_len;
+               u32 mech;
+               /*
+                * followed by iv data
+                * followed by key tag + key blob
+                * followed by dummy kek param
+                * followed by dummy mac param
+                */
+       } __packed * req_pl;
+       struct wk_rep_pl {
+               struct pl_head head;
+               u8  rc_tag;
+               u8  rc_len;
+               u32 rc;
+               u8  data_tag;
+               u8  data_lenfmt;
+               u16 data_len;
+               u8  data[512];
+       } __packed * rep_pl;
+       struct ep11_cprb *req = NULL, *rep = NULL;
+       struct ep11_target_dev target;
+       struct ep11_urb *urb = NULL;
+       struct ep11keyblob *kb;
+       size_t req_pl_size;
+       int api, rc = -ENOMEM;
+       u8 *p;
+
+       /* request cprb and payload */
+       req_pl_size = sizeof(struct wk_req_pl) + (iv ? 16 : 0)
+               + ASN1TAGLEN(keysize) + 4;
+       req = alloc_cprb(req_pl_size);
+       if (!req)
+               goto out;
+       if (!mech || mech == 0x80060001)
+               req->flags |= 0x20; /* CPACF_WRAP needs special bit */
+       req_pl = (struct wk_req_pl *) (((u8 *) req) + sizeof(*req));
+       api = (!mech || mech == 0x80060001) ? 4 : 1; /* CKM_IBM_CPACF_WRAP */
+       prep_head(&req_pl->head, req_pl_size, api, 33); /* WrapKey */
+       req_pl->var_tag = 0x04;
+       req_pl->var_len = sizeof(u32);
+       /* mech is mech + mech params (iv here) */
+       req_pl->mech_tag = 0x04;
+       req_pl->mech_len = sizeof(u32) + (iv ? 16 : 0);
+       req_pl->mech = (mech ? mech : 0x80060001); /* CKM_IBM_CPACF_WRAP */
+       p = ((u8 *) req_pl) + sizeof(*req_pl);
+       if (iv) {
+               memcpy(p, iv, 16);
+               p += 16;
+       }
+       /* key blob */
+       p += asn1tag_write(p, 0x04, key, keysize);
+       /* maybe the key argument needs the head data cleaned out */
+       kb = (struct ep11keyblob *)(p - keysize);
+       if (kb->head.version == TOKVER_EP11_AES)
+               memset(&kb->head, 0, sizeof(kb->head));
+       /* empty kek tag */
+       *p++ = 0x04;
+       *p++ = 0;
+       /* empty mac tag */
+       *p++ = 0x04;
+       *p++ = 0;
+
+       /* reply cprb and payload */
+       rep = alloc_cprb(sizeof(struct wk_rep_pl));
+       if (!rep)
+               goto out;
+       rep_pl = (struct wk_rep_pl *) (((u8 *) rep) + sizeof(*rep));
+
+       /* urb and target */
+       urb = kmalloc(sizeof(struct ep11_urb), GFP_KERNEL);
+       if (!urb)
+               goto out;
+       target.ap_id = card;
+       target.dom_id = domain;
+       prep_urb(urb, &target, 1,
+                req, sizeof(*req) + req_pl_size,
+                rep, sizeof(*rep) + sizeof(*rep_pl));
+
+       rc = _zcrypt_send_ep11_cprb(urb);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s zcrypt_send_ep11_cprb(card=%d dom=%d) failed, rc=%d\n",
+                       __func__, (int) card, (int) domain, rc);
+               goto out;
+       }
+
+       rc = check_reply_pl((u8 *)rep_pl, __func__);
+       if (rc)
+               goto out;
+       if (rep_pl->data_tag != 0x04 || rep_pl->data_lenfmt != 0x82) {
+               DEBUG_ERR("%s unknown reply data format\n", __func__);
+               rc = -EIO;
+               goto out;
+       }
+       if (rep_pl->data_len > *datasize) {
+               DEBUG_ERR("%s mismatch reply data len / data buffer len\n",
+                         __func__);
+               rc = -ENOSPC;
+               goto out;
+       }
+
+       /* copy the data from the cprb to the data buffer */
+       memcpy(databuf, rep_pl->data, rep_pl->data_len);
+       *datasize = rep_pl->data_len;
+
+out:
+       kfree(req);
+       kfree(rep);
+       kfree(urb);
+       return rc;
+}
+
+int ep11_clr2keyblob(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+                    const u8 *clrkey, u8 *keybuf, size_t *keybufsize)
+{
+       int rc;
+       struct ep11keyblob *kb;
+       u8 encbuf[64], *kek = NULL;
+       size_t clrkeylen, keklen, encbuflen = sizeof(encbuf);
+
+       if (keybitsize == 128 || keybitsize == 192 || keybitsize == 256)
+               clrkeylen = keybitsize / 8;
+       else {
+               DEBUG_ERR(
+                       "%s unknown/unsupported keybitsize %d\n",
+                       __func__, keybitsize);
+               return -EINVAL;
+       }
+
+       /* allocate memory for the temp kek */
+       keklen = MAXEP11AESKEYBLOBSIZE;
+       kek = kmalloc(keklen, GFP_ATOMIC);
+       if (!kek) {
+               rc = -ENOMEM;
+               goto out;
+       }
+
+       /* Step 1: generate AES 256 bit random kek key */
+       rc = ep11_genaeskey(card, domain, 256,
+                           0x00006c00, /* EN/DECRYTP, WRAP/UNWRAP */
+                           kek, &keklen);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s generate kek key failed, rc=%d\n",
+                       __func__, rc);
+               goto out;
+       }
+       kb = (struct ep11keyblob *) kek;
+       memset(&kb->head, 0, sizeof(kb->head));
+
+       /* Step 2: encrypt clear key value with the kek key */
+       rc = ep11_cryptsingle(card, domain, 0, 0, def_iv, kek, keklen,
+                             clrkey, clrkeylen, encbuf, &encbuflen);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s encrypting key value with kek key failed, rc=%d\n",
+                       __func__, rc);
+               goto out;
+       }
+
+       /* Step 3: import the encrypted key value as a new key */
+       rc = ep11_unwrapkey(card, domain, kek, keklen,
+                           encbuf, encbuflen, 0, def_iv,
+                           keybitsize, 0, keybuf, keybufsize);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s importing key value as new key failed,, rc=%d\n",
+                       __func__, rc);
+               goto out;
+       }
+
+out:
+       kfree(kek);
+       return rc;
+}
+EXPORT_SYMBOL(ep11_clr2keyblob);
+
+int ep11_key2protkey(u16 card, u16 dom, const u8 *key, size_t keylen,
+                    u8 *protkey, u32 *protkeylen, u32 *protkeytype)
+{
+       int rc = -EIO;
+       u8 *wkbuf = NULL;
+       size_t wkbuflen = 256;
+       struct wk_info {
+               u16 version;
+               u8  res1[16];
+               u32 pkeytype;
+               u32 pkeybitsize;
+               u64 pkeysize;
+               u8  res2[8];
+               u8  pkey[0];
+       } __packed * wki;
+
+       /* alloc temp working buffer */
+       wkbuf = kmalloc(wkbuflen, GFP_ATOMIC);
+       if (!wkbuf)
+               return -ENOMEM;
+
+       /* ep11 secure key -> protected key + info */
+       rc = ep11_wrapkey(card, dom, key, keylen,
+                         0, def_iv, wkbuf, &wkbuflen);
+       if (rc) {
+               DEBUG_ERR(
+                       "%s rewrapping ep11 key to pkey failed, rc=%d\n",
+                       __func__, rc);
+               goto out;
+       }
+       wki = (struct wk_info *) wkbuf;
+
+       /* check struct version and pkey type */
+       if (wki->version != 1 || wki->pkeytype != 1) {
+               DEBUG_ERR("%s wk info version %d or pkeytype %d mismatch.\n",
+                         __func__, (int) wki->version, (int) wki->pkeytype);
+               rc = -EIO;
+               goto out;
+       }
+
+       /* copy the tanslated protected key */
+       switch (wki->pkeysize) {
+       case 16+32:
+               /* AES 128 protected key */
+               if (protkeytype)
+                       *protkeytype = PKEY_KEYTYPE_AES_128;
+               break;
+       case 24+32:
+               /* AES 192 protected key */
+               if (protkeytype)
+                       *protkeytype = PKEY_KEYTYPE_AES_192;
+               break;
+       case 32+32:
+               /* AES 256 protected key */
+               if (protkeytype)
+                       *protkeytype = PKEY_KEYTYPE_AES_256;
+               break;
+       default:
+               DEBUG_ERR("%s unknown/unsupported pkeysize %d\n",
+                         __func__, (int) wki->pkeysize);
+               rc = -EIO;
+               goto out;
+       }
+       memcpy(protkey, wki->pkey, wki->pkeysize);
+       if (protkeylen)
+               *protkeylen = (u32) wki->pkeysize;
+       rc = 0;
+
+out:
+       kfree(wkbuf);
+       return rc;
+}
+EXPORT_SYMBOL(ep11_key2protkey);
+
+int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
+                  int minhwtype, int minapi, const u8 *wkvp)
+{
+       struct zcrypt_device_status_ext *device_status;
+       u32 *_apqns = NULL, _nr_apqns = 0;
+       int i, card, dom, rc = -ENOMEM;
+       struct ep11_domain_info edi;
+       struct ep11_card_info eci;
+
+       /* fetch status of all crypto cards */
+       device_status = kmalloc_array(MAX_ZDEV_ENTRIES_EXT,
+                                     sizeof(struct zcrypt_device_status_ext),
+                                     GFP_KERNEL);
+       if (!device_status)
+               return -ENOMEM;
+       zcrypt_device_status_mask_ext(device_status);
+
+       /* allocate 1k space for up to 256 apqns */
+       _apqns = kmalloc_array(256, sizeof(u32), GFP_KERNEL);
+       if (!_apqns) {
+               kfree(device_status);
+               return -ENOMEM;
+       }
+
+       /* walk through all the crypto apqnss */
+       for (i = 0; i < MAX_ZDEV_ENTRIES_EXT; i++) {
+               card = AP_QID_CARD(device_status[i].qid);
+               dom = AP_QID_QUEUE(device_status[i].qid);
+               /* check online state */
+               if (!device_status[i].online)
+                       continue;
+               /* check for ep11 functions */
+               if (!(device_status[i].functions & 0x01))
+                       continue;
+               /* check cardnr */
+               if (cardnr != 0xFFFF && card != cardnr)
+                       continue;
+               /* check domain */
+               if (domain != 0xFFFF && dom != domain)
+                       continue;
+               /* check min hardware type */
+               if (minhwtype && device_status[i].hwtype < minhwtype)
+                       continue;
+               /* check min api version if given */
+               if (minapi > 0) {
+                       if (ep11_get_card_info(card, &eci, 0))
+                               continue;
+                       if (minapi > eci.API_ord_nr)
+                               continue;
+               }
+               /* check wkvp if given */
+               if (wkvp) {
+                       if (ep11_get_domain_info(card, dom, &edi))
+                               continue;
+                       if (edi.cur_wk_state != '1')
+                               continue;
+                       if (memcmp(wkvp, edi.cur_wkvp, 16))
+                               continue;
+               }
+               /* apqn passed all filtering criterons, add to the array */
+               if (_nr_apqns < 256)
+                       _apqns[_nr_apqns++] = (((u16)card) << 16) | ((u16) dom);
+       }
+
+       /* nothing found ? */
+       if (!_nr_apqns) {
+               kfree(_apqns);
+               rc = -ENODEV;
+       } else {
+               /* no re-allocation, simple return the _apqns array */
+               *apqns = _apqns;
+               *nr_apqns = _nr_apqns;
+               rc = 0;
+       }
+
+       kfree(device_status);
+       return rc;
+}
+EXPORT_SYMBOL(ep11_findcard2);
+
+void __exit zcrypt_ep11misc_exit(void)
+{
+       card_cache_free();
+}
diff --git a/drivers/s390/crypto/zcrypt_ep11misc.h b/drivers/s390/crypto/zcrypt_ep11misc.h
new file mode 100644 (file)
index 0000000..e3ed5ed
--- /dev/null
@@ -0,0 +1,124 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ *  Copyright IBM Corp. 2019
+ *  Author(s): Harald Freudenberger <freude@linux.ibm.com>
+ *
+ *  Collection of EP11 misc functions used by zcrypt and pkey
+ */
+
+#ifndef _ZCRYPT_EP11MISC_H_
+#define _ZCRYPT_EP11MISC_H_
+
+#include <asm/zcrypt.h>
+#include <asm/pkey.h>
+
+#define TOKVER_EP11_AES  0x03  /* EP11 AES key blob */
+
+#define EP11_API_V 4  /* highest known and supported EP11 API version */
+
+#define EP11_STRUCT_MAGIC 0x1234
+#define EP11_BLOB_PKEY_EXTRACTABLE 0x200000
+
+/* inside view of an EP11 secure key blob */
+struct ep11keyblob {
+       union {
+               u8 session[32];
+               struct {
+                       u8  type;      /* 0x00 (TOKTYPE_NON_CCA) */
+                       u8  res0;      /* unused */
+                       u16 len;       /* total length in bytes of this blob */
+                       u8  version;   /* 0x06 (TOKVER_EP11_AES) */
+                       u8  res1;      /* unused */
+                       u16 keybitlen; /* clear key bit len, 0 for unknown */
+               } head;
+       };
+       u8  wkvp[16];  /* wrapping key verification pattern */
+       u64 attr;      /* boolean key attributes */
+       u64 mode;      /* mode bits */
+       u16 version;   /* 0x1234, EP11_STRUCT_MAGIC */
+       u8  iv[14];
+       u8  encrypted_key_data[144];
+       u8  mac[32];
+} __packed;
+
+/*
+ * Simple check if the key blob is a valid EP11 secure AES key.
+ * If keybitsize is given, the bitsize of the key is also checked.
+ * If checkcpacfexport is enabled, the key is also checked for the
+ * attributes needed to export this key for CPACF use.
+ * Returns 0 on success or errno value on failure.
+ */
+int ep11_check_aeskeyblob(debug_info_t *dbg, int dbflvl,
+                         const u8 *key, int keybitsize,
+                         int checkcpacfexport);
+
+/* EP11 card info struct */
+struct ep11_card_info {
+       u32  API_ord_nr;    /* API ordinal number */
+       u16  FW_version;    /* Firmware major and minor version */
+       char serial[16];    /* serial number string (16 ascii, no 0x00 !) */
+       u64  op_mode;       /* card operational mode(s) */
+};
+
+/* EP11 domain info struct */
+struct ep11_domain_info {
+       char cur_wk_state;  /* '0' invalid, '1' valid */
+       char new_wk_state;  /* '0' empty, '1' uncommitted, '2' committed */
+       u8   cur_wkvp[32];  /* current wrapping key verification pattern */
+       u8   new_wkvp[32];  /* new wrapping key verification pattern */
+       u64  op_mode;       /* domain operational mode(s) */
+};
+
+/*
+ * Provide information about an EP11 card.
+ */
+int ep11_get_card_info(u16 card, struct ep11_card_info *info, int verify);
+
+/*
+ * Provide information about a domain within an EP11 card.
+ */
+int ep11_get_domain_info(u16 card, u16 domain, struct ep11_domain_info *info);
+
+/*
+ * Generate (random) EP11 AES secure key.
+ */
+int ep11_genaeskey(u16 card, u16 domain, u32 keybitsize, u32 keygenflags,
+                  u8 *keybuf, size_t *keybufsize);
+
+/*
+ * Generate EP11 AES secure key with given clear key value.
+ */
+int ep11_clr2keyblob(u16 cardnr, u16 domain, u32 keybitsize, u32 keygenflags,
+                    const u8 *clrkey, u8 *keybuf, size_t *keybufsize);
+
+/*
+ * Derive proteced key from EP11 AES secure key blob.
+ */
+int ep11_key2protkey(u16 cardnr, u16 domain, const u8 *key, size_t keylen,
+                    u8 *protkey, u32 *protkeylen, u32 *protkeytype);
+
+/*
+ * Build a list of ep11 apqns meeting the following constrains:
+ * - apqn is online and is in fact an EP11 apqn
+ * - if cardnr is not FFFF only apqns with this cardnr
+ * - if domain is not FFFF only apqns with this domainnr
+ * - if minhwtype > 0 only apqns with hwtype >= minhwtype
+ * - if minapi > 0 only apqns with API_ord_nr >= minapi
+ * - if wkvp != NULL only apqns where the wkvp (EP11_WKVPLEN bytes) matches
+ *   to the first EP11_WKVPLEN bytes of the wkvp of the current wrapping
+ *   key for this domain. When a wkvp is given there will aways be a re-fetch
+ *   of the domain info for the potential apqn - so this triggers an request
+ *   reply to each apqn eligible.
+ * The array of apqn entries is allocated with kmalloc and returned in *apqns;
+ * the number of apqns stored into the list is returned in *nr_apqns. One apqn
+ * entry is simple a 32 bit value with 16 bit cardnr and 16 bit domain nr and
+ * may be casted to struct pkey_apqn. The return value is either 0 for success
+ * or a negative errno value. If no apqn meeting the criterias is found,
+ * -ENODEV is returned.
+ */
+int ep11_findcard2(u32 **apqns, u32 *nr_apqns, u16 cardnr, u16 domain,
+                  int minhwtype, int minapi, const u8 *wkvp);
+
+void zcrypt_ep11misc_exit(void);
+
+#endif /* _ZCRYPT_EP11MISC_H_ */
index 80c5a23..7b49e2e 100644 (file)
@@ -617,6 +617,13 @@ static const struct file_operations esas2r_proc_fops = {
        .unlocked_ioctl = esas2r_proc_ioctl,
 };
 
+static const struct proc_ops esas2r_proc_ops = {
+       .proc_ioctl             = esas2r_proc_ioctl,
+#ifdef CONFIG_COMPAT
+       .proc_compat_ioctl      = compat_ptr_ioctl,
+#endif
+};
+
 static struct Scsi_Host *esas2r_proc_host;
 static int esas2r_proc_major;
 
@@ -728,7 +735,7 @@ const char *esas2r_info(struct Scsi_Host *sh)
 
                        pde = proc_create(ATTONODE_NAME, 0,
                                          sh->hostt->proc_dir,
-                                         &esas2r_proc_fops);
+                                         &esas2r_proc_ops);
 
                        if (!pde) {
                                esas2r_log_dev(ESAS2R_LOG_WARN,
index acb8218..fd4b5ac 100644 (file)
@@ -7604,7 +7604,6 @@ megasas_resume(struct pci_dev *pdev)
        int rval;
        struct Scsi_Host *host;
        struct megasas_instance *instance;
-       int irq_flags = PCI_IRQ_LEGACY;
        u32 status_reg;
 
        instance = pci_get_drvdata(pdev);
@@ -7673,16 +7672,15 @@ megasas_resume(struct pci_dev *pdev)
        atomic_set(&instance->ldio_outstanding, 0);
 
        /* Now re-enable MSI-X */
-       if (instance->msix_vectors) {
-               irq_flags = PCI_IRQ_MSIX;
-               if (instance->smp_affinity_enable)
-                       irq_flags |= PCI_IRQ_AFFINITY;
-       }
-       rval = pci_alloc_irq_vectors(instance->pdev, 1,
-                                    instance->msix_vectors ?
-                                    instance->msix_vectors : 1, irq_flags);
-       if (rval < 0)
-               goto fail_reenable_msix;
+       if (instance->msix_vectors)
+               megasas_alloc_irq_vectors(instance);
+
+       if (!instance->msix_vectors) {
+               rval = pci_alloc_irq_vectors(instance->pdev, 1, 1,
+                                            PCI_IRQ_LEGACY);
+               if (rval < 0)
+                       goto fail_reenable_msix;
+       }
 
        megasas_setup_reply_map(instance);
 
index 98dcdbd..d1d95f1 100644 (file)
@@ -2377,7 +2377,7 @@ mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, void *piomb)
                                ts->buf_valid_size = sizeof(*resp);
                        } else
                                PM8001_IO_DBG(pm8001_ha,
-                                       pm8001_printk("response to large\n"));
+                                       pm8001_printk("response too large\n"));
                }
                if (pm8001_dev)
                        pm8001_dev->running_req--;
index e5500bb..88a56e8 100644 (file)
@@ -2519,12 +2519,6 @@ qla83xx_fw_dump_failed:
 /*                         Driver Debug Functions.                          */
 /****************************************************************************/
 
-static inline int
-ql_mask_match(uint level)
-{
-       return (level & ql2xextended_error_logging) == level;
-}
-
 /*
  * This function is for formatting and logging debug information.
  * It is to be used when vha is available. It formats the message
index bb01b68..433e955 100644 (file)
@@ -374,3 +374,9 @@ extern int qla24xx_dump_ram(struct qla_hw_data *, uint32_t, uint32_t *,
 extern void qla24xx_pause_risc(struct device_reg_24xx __iomem *,
        struct qla_hw_data *);
 extern int qla24xx_soft_reset(struct qla_hw_data *);
+
+static inline int
+ql_mask_match(uint level)
+{
+       return (level & ql2xextended_error_logging) == level;
+}
index e7bad0b..e40705d 100644 (file)
@@ -1939,6 +1939,18 @@ static void qla24xx_nvme_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
                inbuf = (uint32_t *)&sts->nvme_ersp_data;
                outbuf = (uint32_t *)fd->rspaddr;
                iocb->u.nvme.rsp_pyld_len = le16_to_cpu(sts->nvme_rsp_pyld_len);
+               if (unlikely(iocb->u.nvme.rsp_pyld_len >
+                   sizeof(struct nvme_fc_ersp_iu))) {
+                       if (ql_mask_match(ql_dbg_io)) {
+                               WARN_ONCE(1, "Unexpected response payload length %u.\n",
+                                   iocb->u.nvme.rsp_pyld_len);
+                               ql_log(ql_log_warn, fcport->vha, 0x5100,
+                                   "Unexpected response payload length %u.\n",
+                                   iocb->u.nvme.rsp_pyld_len);
+                       }
+                       iocb->u.nvme.rsp_pyld_len =
+                           sizeof(struct nvme_fc_ersp_iu);
+               }
                iter = iocb->u.nvme.rsp_pyld_len >> 2;
                for (; iter; iter--)
                        *outbuf++ = swab32(*inbuf++);
index df14597..eed3102 100644 (file)
@@ -736,13 +736,12 @@ out:
        return err;
 }
 
-static const struct file_operations scsi_devinfo_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = proc_scsi_devinfo_open,
-       .read           = seq_read,
-       .write          = proc_scsi_devinfo_write,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops scsi_devinfo_proc_ops = {
+       .proc_open      = proc_scsi_devinfo_open,
+       .proc_read      = seq_read,
+       .proc_write     = proc_scsi_devinfo_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 #endif /* CONFIG_SCSI_PROC_FS */
 
@@ -867,7 +866,7 @@ int __init scsi_init_devinfo(void)
        }
 
 #ifdef CONFIG_SCSI_PROC_FS
-       p = proc_create("scsi/device_info", 0, NULL, &scsi_devinfo_proc_fops);
+       p = proc_create("scsi/device_info", 0, NULL, &scsi_devinfo_proc_ops);
        if (!p) {
                error = -ENOMEM;
                goto out;
index 5b31322..d6982d3 100644 (file)
@@ -83,12 +83,12 @@ static int proc_scsi_host_open(struct inode *inode, struct file *file)
                                4 * PAGE_SIZE);
 }
 
-static const struct file_operations proc_scsi_fops = {
-       .open = proc_scsi_host_open,
-       .release = single_release,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .write = proc_scsi_host_write
+static const struct proc_ops proc_scsi_ops = {
+       .proc_open      = proc_scsi_host_open,
+       .proc_release   = single_release,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = proc_scsi_host_write
 };
 
 /**
@@ -146,7 +146,7 @@ void scsi_proc_host_add(struct Scsi_Host *shost)
 
        sprintf(name,"%d", shost->host_no);
        p = proc_create_data(name, S_IRUGO | S_IWUSR,
-               sht->proc_dir, &proc_scsi_fops, shost);
+               sht->proc_dir, &proc_scsi_ops, shost);
        if (!p)
                printk(KERN_ERR "%s: Failed to register host %d in"
                       "%s\n", __func__, shost->host_no,
@@ -436,13 +436,12 @@ static int proc_scsi_open(struct inode *inode, struct file *file)
        return seq_open(file, &scsi_seq_ops);
 }
 
-static const struct file_operations proc_scsi_operations = {
-       .owner          = THIS_MODULE,
-       .open           = proc_scsi_open,
-       .read           = seq_read,
-       .write          = proc_scsi_write,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops scsi_scsi_proc_ops = {
+       .proc_open      = proc_scsi_open,
+       .proc_read      = seq_read,
+       .proc_write     = proc_scsi_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 /**
@@ -456,7 +455,7 @@ int __init scsi_init_procfs(void)
        if (!proc_scsi)
                goto err1;
 
-       pde = proc_create("scsi/scsi", 0, NULL, &proc_scsi_operations);
+       pde = proc_create("scsi/scsi", 0, NULL, &scsi_scsi_proc_ops);
        if (!pde)
                goto err2;
 
index bafeaf7..4e6af59 100644 (file)
@@ -2322,25 +2322,23 @@ static int sg_proc_seq_show_int(struct seq_file *s, void *v);
 static int sg_proc_single_open_adio(struct inode *inode, struct file *file);
 static ssize_t sg_proc_write_adio(struct file *filp, const char __user *buffer,
                                  size_t count, loff_t *off);
-static const struct file_operations adio_fops = {
-       .owner = THIS_MODULE,
-       .open = sg_proc_single_open_adio,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .write = sg_proc_write_adio,
-       .release = single_release,
+static const struct proc_ops adio_proc_ops = {
+       .proc_open      = sg_proc_single_open_adio,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = sg_proc_write_adio,
+       .proc_release   = single_release,
 };
 
 static int sg_proc_single_open_dressz(struct inode *inode, struct file *file);
 static ssize_t sg_proc_write_dressz(struct file *filp, 
                const char __user *buffer, size_t count, loff_t *off);
-static const struct file_operations dressz_fops = {
-       .owner = THIS_MODULE,
-       .open = sg_proc_single_open_dressz,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .write = sg_proc_write_dressz,
-       .release = single_release,
+static const struct proc_ops dressz_proc_ops = {
+       .proc_open      = sg_proc_single_open_dressz,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = sg_proc_write_dressz,
+       .proc_release   = single_release,
 };
 
 static int sg_proc_seq_show_version(struct seq_file *s, void *v);
@@ -2381,9 +2379,9 @@ sg_proc_init(void)
        if (!p)
                return 1;
 
-       proc_create("allow_dio", S_IRUGO | S_IWUSR, p, &adio_fops);
+       proc_create("allow_dio", S_IRUGO | S_IWUSR, p, &adio_proc_ops);
        proc_create_seq("debug", S_IRUGO, p, &debug_seq_ops);
-       proc_create("def_reserved_size", S_IRUGO | S_IWUSR, p, &dressz_fops);
+       proc_create("def_reserved_size", S_IRUGO | S_IWUSR, p, &dressz_proc_ops);
        proc_create_single("device_hdr", S_IRUGO, p, sg_proc_seq_show_devhdr);
        proc_create_seq("devices", S_IRUGO, p, &dev_seq_ops);
        proc_create_seq("device_strs", S_IRUGO, p, &devstrs_seq_ops);
index dde2eb0..cfe3803 100644 (file)
@@ -546,7 +546,7 @@ static inline bool ufs_is_valid_unit_desc_lun(struct ufs_dev_info *dev_info,
                u8 lun)
 {
        if (!dev_info || !dev_info->max_lu_supported) {
-               pr_err("Max General LU supported by UFS isn't initilized\n");
+               pr_err("Max General LU supported by UFS isn't initialized\n");
                return false;
        }
 
index 096a83c..55a1f57 100644 (file)
@@ -66,8 +66,9 @@ static const struct at91_soc __initconst socs[] = {
        AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"),
        AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"),
        AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"),
-       AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_EXID_MATCH,
-                "sam9x60", "sam9x60"),
+#endif
+#ifdef CONFIG_SOC_SAM9X60
+       AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_EXID_MATCH, "sam9x60", "sam9x60"),
 #endif
 #ifdef CONFIG_SOC_SAMA5
        AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D21CU_EXID_MATCH,
index d326915..61731e0 100644 (file)
@@ -63,7 +63,7 @@ static const int b15_cpubiuctrl_regs[] = {
        [CPU_WRITEBACK_CTRL_REG] = -1,
 };
 
-/* Odd cases, e.g: 7260 */
+/* Odd cases, e.g: 7260A0 */
 static const int b53_cpubiuctrl_no_wb_regs[] = {
        [CPU_CREDIT_REG] = 0x0b0,
        [CPU_MCP_FLOW_REG] = 0x0b4,
@@ -76,6 +76,12 @@ static const int b53_cpubiuctrl_regs[] = {
        [CPU_WRITEBACK_CTRL_REG] = 0x22c,
 };
 
+static const int a72_cpubiuctrl_regs[] = {
+       [CPU_CREDIT_REG] = 0x18,
+       [CPU_MCP_FLOW_REG] = 0x1c,
+       [CPU_WRITEBACK_CTRL_REG] = 0x20,
+};
+
 #define NUM_CPU_BIUCTRL_REGS   3
 
 static int __init mcp_write_pairing_set(void)
@@ -101,25 +107,29 @@ static int __init mcp_write_pairing_set(void)
        return 0;
 }
 
-static const u32 b53_mach_compat[] = {
+static const u32 a72_b53_mach_compat[] = {
+       0x7211,
+       0x7216,
+       0x7255,
+       0x7260,
        0x7268,
        0x7271,
        0x7278,
 };
 
-static void __init mcp_b53_set(void)
+static void __init mcp_a72_b53_set(void)
 {
        unsigned int i;
        u32 reg;
 
        reg = brcmstb_get_family_id();
 
-       for (i = 0; i < ARRAY_SIZE(b53_mach_compat); i++) {
-               if (BRCM_ID(reg) == b53_mach_compat[i])
+       for (i = 0; i < ARRAY_SIZE(a72_b53_mach_compat); i++) {
+               if (BRCM_ID(reg) == a72_b53_mach_compat[i])
                        break;
        }
 
-       if (i == ARRAY_SIZE(b53_mach_compat))
+       if (i == ARRAY_SIZE(a72_b53_mach_compat))
                return;
 
        /* Set all 3 MCP interfaces to 8 credits */
@@ -157,6 +167,7 @@ static void __init mcp_b53_set(void)
 static int __init setup_hifcpubiuctrl_regs(struct device_node *np)
 {
        struct device_node *cpu_dn;
+       u32 family_id;
        int ret = 0;
 
        cpubiuctrl_base = of_iomap(np, 0);
@@ -179,13 +190,16 @@ static int __init setup_hifcpubiuctrl_regs(struct device_node *np)
                cpubiuctrl_regs = b15_cpubiuctrl_regs;
        else if (of_device_is_compatible(cpu_dn, "brcm,brahma-b53"))
                cpubiuctrl_regs = b53_cpubiuctrl_regs;
+       else if (of_device_is_compatible(cpu_dn, "arm,cortex-a72"))
+               cpubiuctrl_regs = a72_cpubiuctrl_regs;
        else {
                pr_err("unsupported CPU\n");
                ret = -EINVAL;
        }
        of_node_put(cpu_dn);
 
-       if (BRCM_ID(brcmstb_get_family_id()) == 0x7260)
+       family_id = brcmstb_get_family_id();
+       if (BRCM_ID(family_id) == 0x7260 && BRCM_REV(family_id) == 0)
                cpubiuctrl_regs = b53_cpubiuctrl_no_wb_regs;
 out:
        of_node_put(np);
@@ -248,7 +262,7 @@ static int __init brcmstb_biuctrl_init(void)
                return ret;
        }
 
-       mcp_b53_set();
+       mcp_a72_b53_set();
 #ifdef CONFIG_PM_SLEEP
        register_syscore_ops(&brcmstb_cpu_credit_syscore_ops);
 #endif
index cfa4b29..357c580 100644 (file)
@@ -5,7 +5,8 @@
 
 config QUICC_ENGINE
        bool "QUICC Engine (QE) framework support"
-       depends on FSL_SOC && PPC32
+       depends on OF && HAS_IOMEM
+       depends on PPC || ARM || ARM64 || COMPILE_TEST
        select GENERIC_ALLOCATOR
        select CRC32
        help
index f0c29ed..ed75198 100644 (file)
@@ -41,13 +41,13 @@ static void qe_gpio_save_regs(struct of_mm_gpio_chip *mm_gc)
                container_of(mm_gc, struct qe_gpio_chip, mm_gc);
        struct qe_pio_regs __iomem *regs = mm_gc->regs;
 
-       qe_gc->cpdata = in_be32(&regs->cpdata);
+       qe_gc->cpdata = qe_ioread32be(&regs->cpdata);
        qe_gc->saved_regs.cpdata = qe_gc->cpdata;
-       qe_gc->saved_regs.cpdir1 = in_be32(&regs->cpdir1);
-       qe_gc->saved_regs.cpdir2 = in_be32(&regs->cpdir2);
-       qe_gc->saved_regs.cppar1 = in_be32(&regs->cppar1);
-       qe_gc->saved_regs.cppar2 = in_be32(&regs->cppar2);
-       qe_gc->saved_regs.cpodr = in_be32(&regs->cpodr);
+       qe_gc->saved_regs.cpdir1 = qe_ioread32be(&regs->cpdir1);
+       qe_gc->saved_regs.cpdir2 = qe_ioread32be(&regs->cpdir2);
+       qe_gc->saved_regs.cppar1 = qe_ioread32be(&regs->cppar1);
+       qe_gc->saved_regs.cppar2 = qe_ioread32be(&regs->cppar2);
+       qe_gc->saved_regs.cpodr = qe_ioread32be(&regs->cpodr);
 }
 
 static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
@@ -56,7 +56,7 @@ static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio)
        struct qe_pio_regs __iomem *regs = mm_gc->regs;
        u32 pin_mask = 1 << (QE_PIO_PINS - 1 - gpio);
 
-       return !!(in_be32(&regs->cpdata) & pin_mask);
+       return !!(qe_ioread32be(&regs->cpdata) & pin_mask);
 }
 
 static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
@@ -74,7 +74,7 @@ static void qe_gpio_set(struct gpio_chip *gc, unsigned int gpio, int val)
        else
                qe_gc->cpdata &= ~pin_mask;
 
-       out_be32(&regs->cpdata, qe_gc->cpdata);
+       qe_iowrite32be(qe_gc->cpdata, &regs->cpdata);
 
        spin_unlock_irqrestore(&qe_gc->lock, flags);
 }
@@ -101,7 +101,7 @@ static void qe_gpio_set_multiple(struct gpio_chip *gc,
                }
        }
 
-       out_be32(&regs->cpdata, qe_gc->cpdata);
+       qe_iowrite32be(qe_gc->cpdata, &regs->cpdata);
 
        spin_unlock_irqrestore(&qe_gc->lock, flags);
 }
@@ -160,7 +160,6 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
 {
        struct qe_pin *qe_pin;
        struct gpio_chip *gc;
-       struct of_mm_gpio_chip *mm_gc;
        struct qe_gpio_chip *qe_gc;
        int err;
        unsigned long flags;
@@ -186,7 +185,6 @@ struct qe_pin *qe_pin_request(struct device_node *np, int index)
                goto err0;
        }
 
-       mm_gc = to_of_mm_gpio_chip(gc);
        qe_gc = gpiochip_get_data(gc);
 
        spin_lock_irqsave(&qe_gc->lock, flags);
@@ -255,11 +253,15 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin)
        spin_lock_irqsave(&qe_gc->lock, flags);
 
        if (second_reg) {
-               clrsetbits_be32(&regs->cpdir2, mask2, sregs->cpdir2 & mask2);
-               clrsetbits_be32(&regs->cppar2, mask2, sregs->cppar2 & mask2);
+               qe_clrsetbits_be32(&regs->cpdir2, mask2,
+                                  sregs->cpdir2 & mask2);
+               qe_clrsetbits_be32(&regs->cppar2, mask2,
+                                  sregs->cppar2 & mask2);
        } else {
-               clrsetbits_be32(&regs->cpdir1, mask2, sregs->cpdir1 & mask2);
-               clrsetbits_be32(&regs->cppar1, mask2, sregs->cppar1 & mask2);
+               qe_clrsetbits_be32(&regs->cpdir1, mask2,
+                                  sregs->cpdir1 & mask2);
+               qe_clrsetbits_be32(&regs->cppar1, mask2,
+                                  sregs->cppar1 & mask2);
        }
 
        if (sregs->cpdata & mask1)
@@ -267,8 +269,8 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin)
        else
                qe_gc->cpdata &= ~mask1;
 
-       out_be32(&regs->cpdata, qe_gc->cpdata);
-       clrsetbits_be32(&regs->cpodr, mask1, sregs->cpodr & mask1);
+       qe_iowrite32be(qe_gc->cpdata, &regs->cpdata);
+       qe_clrsetbits_be32(&regs->cpodr, mask1, sregs->cpodr & mask1);
 
        spin_unlock_irqrestore(&qe_gc->lock, flags);
 }
index 417df7e..96c2057 100644 (file)
 #include <linux/module.h>
 #include <linux/delay.h>
 #include <linux/ioport.h>
+#include <linux/iopoll.h>
 #include <linux/crc32.h>
 #include <linux/mod_devicetable.h>
 #include <linux/of_platform.h>
-#include <asm/irq.h>
-#include <asm/page.h>
-#include <asm/pgtable.h>
 #include <soc/fsl/qe/immap_qe.h>
 #include <soc/fsl/qe/qe.h>
-#include <asm/prom.h>
-#include <asm/rheap.h>
 
 static void qe_snums_init(void);
 static int qe_sdma_init(void);
@@ -108,11 +104,12 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
 {
        unsigned long flags;
        u8 mcn_shift = 0, dev_shift = 0;
-       u32 ret;
+       u32 val;
+       int ret;
 
        spin_lock_irqsave(&qe_lock, flags);
        if (cmd == QE_RESET) {
-               out_be32(&qe_immr->cp.cecr, (u32) (cmd | QE_CR_FLG));
+               qe_iowrite32be((u32)(cmd | QE_CR_FLG), &qe_immr->cp.cecr);
        } else {
                if (cmd == QE_ASSIGN_PAGE) {
                        /* Here device is the SNUM, not sub-block */
@@ -129,20 +126,18 @@ int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
                                mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
                }
 
-               out_be32(&qe_immr->cp.cecdr, cmd_input);
-               out_be32(&qe_immr->cp.cecr,
-                        (cmd | QE_CR_FLG | ((u32) device << dev_shift) | (u32)
-                         mcn_protocol << mcn_shift));
+               qe_iowrite32be(cmd_input, &qe_immr->cp.cecdr);
+               qe_iowrite32be((cmd | QE_CR_FLG | ((u32)device << dev_shift) | (u32)mcn_protocol << mcn_shift),
+                              &qe_immr->cp.cecr);
        }
 
        /* wait for the QE_CR_FLG to clear */
-       ret = spin_event_timeout((in_be32(&qe_immr->cp.cecr) & QE_CR_FLG) == 0,
-                          100, 0);
-       /* On timeout (e.g. failure), the expression will be false (ret == 0),
-          otherwise it will be true (ret == 1). */
+       ret = readx_poll_timeout_atomic(qe_ioread32be, &qe_immr->cp.cecr, val,
+                                       (val & QE_CR_FLG) == 0, 0, 100);
+       /* On timeout, ret is -ETIMEDOUT, otherwise it will be 0. */
        spin_unlock_irqrestore(&qe_lock, flags);
 
-       return ret == 1;
+       return ret == 0;
 }
 EXPORT_SYMBOL(qe_issue_cmd);
 
@@ -164,8 +159,7 @@ static unsigned int brg_clk = 0;
 unsigned int qe_get_brg_clk(void)
 {
        struct device_node *qe;
-       int size;
-       const u32 *prop;
+       u32 brg;
        unsigned int mod;
 
        if (brg_clk)
@@ -175,9 +169,8 @@ unsigned int qe_get_brg_clk(void)
        if (!qe)
                return brg_clk;
 
-       prop = of_get_property(qe, "brg-frequency", &size);
-       if (prop && size == sizeof(*prop))
-               brg_clk = *prop;
+       if (!of_property_read_u32(qe, "brg-frequency", &brg))
+               brg_clk = brg;
 
        of_node_put(qe);
 
@@ -197,6 +190,14 @@ EXPORT_SYMBOL(qe_get_brg_clk);
 #define PVR_VER_836x   0x8083
 #define PVR_VER_832x   0x8084
 
+static bool qe_general4_errata(void)
+{
+#ifdef CONFIG_PPC32
+       return pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x);
+#endif
+       return false;
+}
+
 /* Program the BRG to the given sampling rate and multiplier
  *
  * @brg: the BRG, QE_BRG1 - QE_BRG16
@@ -223,14 +224,14 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
        /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
           that the BRG divisor must be even if you're not using divide-by-16
           mode. */
-       if (pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x))
+       if (qe_general4_errata())
                if (!div16 && (divisor & 1) && (divisor > 3))
                        divisor++;
 
        tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
                QE_BRGC_ENABLE | div16;
 
-       out_be32(&qe_immr->brg.brgc[brg - QE_BRG1], tempval);
+       qe_iowrite32be(tempval, &qe_immr->brg.brgc[brg - QE_BRG1]);
 
        return 0;
 }
@@ -364,22 +365,20 @@ EXPORT_SYMBOL(qe_put_snum);
 static int qe_sdma_init(void)
 {
        struct sdma __iomem *sdma = &qe_immr->sdma;
-       static unsigned long sdma_buf_offset = (unsigned long)-ENOMEM;
-
-       if (!sdma)
-               return -ENODEV;
+       static s32 sdma_buf_offset = -ENOMEM;
 
        /* allocate 2 internal temporary buffers (512 bytes size each) for
         * the SDMA */
-       if (IS_ERR_VALUE(sdma_buf_offset)) {
+       if (sdma_buf_offset < 0) {
                sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
-               if (IS_ERR_VALUE(sdma_buf_offset))
+               if (sdma_buf_offset < 0)
                        return -ENOMEM;
        }
 
-       out_be32(&sdma->sdebcr, (u32) sdma_buf_offset & QE_SDEBCR_BA_MASK);
-       out_be32(&sdma->sdmr, (QE_SDMR_GLB_1_MSK |
-                                       (0x1 << QE_SDMR_CEN_SHIFT)));
+       qe_iowrite32be((u32)sdma_buf_offset & QE_SDEBCR_BA_MASK,
+                      &sdma->sdebcr);
+       qe_iowrite32be((QE_SDMR_GLB_1_MSK | (0x1 << QE_SDMR_CEN_SHIFT)),
+                      &sdma->sdmr);
 
        return 0;
 }
@@ -417,14 +416,14 @@ static void qe_upload_microcode(const void *base,
                        "uploading microcode '%s'\n", ucode->id);
 
        /* Use auto-increment */
-       out_be32(&qe_immr->iram.iadd, be32_to_cpu(ucode->iram_offset) |
-               QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR);
+       qe_iowrite32be(be32_to_cpu(ucode->iram_offset) | QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR,
+                      &qe_immr->iram.iadd);
 
        for (i = 0; i < be32_to_cpu(ucode->count); i++)
-               out_be32(&qe_immr->iram.idata, be32_to_cpu(code[i]));
+               qe_iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata);
        
        /* Set I-RAM Ready Register */
-       out_be32(&qe_immr->iram.iready, be32_to_cpu(QE_IRAM_READY));
+       qe_iowrite32be(be32_to_cpu(QE_IRAM_READY), &qe_immr->iram.iready);
 }
 
 /*
@@ -509,7 +508,7 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
         * If the microcode calls for it, split the I-RAM.
         */
        if (!firmware->split)
-               setbits16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
+               qe_setbits_be16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
 
        if (firmware->soc.model)
                printk(KERN_INFO
@@ -543,11 +542,13 @@ int qe_upload_firmware(const struct qe_firmware *firmware)
                        u32 trap = be32_to_cpu(ucode->traps[j]);
 
                        if (trap)
-                               out_be32(&qe_immr->rsp[i].tibcr[j], trap);
+                               qe_iowrite32be(trap,
+                                              &qe_immr->rsp[i].tibcr[j]);
                }
 
                /* Enable traps */
-               out_be32(&qe_immr->rsp[i].eccr, be32_to_cpu(ucode->eccr));
+               qe_iowrite32be(be32_to_cpu(ucode->eccr),
+                              &qe_immr->rsp[i].eccr);
        }
 
        qe_firmware_uploaded = 1;
@@ -565,11 +566,9 @@ EXPORT_SYMBOL(qe_upload_firmware);
 struct qe_firmware_info *qe_get_firmware_info(void)
 {
        static int initialized;
-       struct property *prop;
        struct device_node *qe;
        struct device_node *fw = NULL;
        const char *sprop;
-       unsigned int i;
 
        /*
         * If we haven't checked yet, and a driver hasn't uploaded a firmware
@@ -603,20 +602,11 @@ struct qe_firmware_info *qe_get_firmware_info(void)
                strlcpy(qe_firmware_info.id, sprop,
                        sizeof(qe_firmware_info.id));
 
-       prop = of_find_property(fw, "extended-modes", NULL);
-       if (prop && (prop->length == sizeof(u64))) {
-               const u64 *iprop = prop->value;
-
-               qe_firmware_info.extended_modes = *iprop;
-       }
+       of_property_read_u64(fw, "extended-modes",
+                            &qe_firmware_info.extended_modes);
 
-       prop = of_find_property(fw, "virtual-traps", NULL);
-       if (prop && (prop->length == 32)) {
-               const u32 *iprop = prop->value;
-
-               for (i = 0; i < ARRAY_SIZE(qe_firmware_info.vtraps); i++)
-                       qe_firmware_info.vtraps[i] = iprop[i];
-       }
+       of_property_read_u32_array(fw, "virtual-traps", qe_firmware_info.vtraps,
+                                  ARRAY_SIZE(qe_firmware_info.vtraps));
 
        of_node_put(fw);
 
@@ -627,17 +617,13 @@ EXPORT_SYMBOL(qe_get_firmware_info);
 unsigned int qe_get_num_of_risc(void)
 {
        struct device_node *qe;
-       int size;
        unsigned int num_of_risc = 0;
-       const u32 *prop;
 
        qe = qe_get_device_node();
        if (!qe)
                return num_of_risc;
 
-       prop = of_get_property(qe, "fsl,qe-num-riscs", &size);
-       if (prop && size == sizeof(*prop))
-               num_of_risc = *prop;
+       of_property_read_u32(qe, "fsl,qe-num-riscs", &num_of_risc);
 
        of_node_put(qe);
 
index 83e85e6..a81a1a7 100644 (file)
@@ -32,7 +32,7 @@ static phys_addr_t muram_pbase;
 
 struct muram_block {
        struct list_head head;
-       unsigned long start;
+       s32 start;
        int size;
 };
 
@@ -110,34 +110,30 @@ out_muram:
  * @algo: algorithm for alloc.
  * @data: data for genalloc's algorithm.
  *
- * This function returns an offset into the muram area.
+ * This function returns a non-negative offset into the muram area, or
+ * a negative errno on failure.
  */
-static unsigned long cpm_muram_alloc_common(unsigned long size,
-               genpool_algo_t algo, void *data)
+static s32 cpm_muram_alloc_common(unsigned long size,
+                                 genpool_algo_t algo, void *data)
 {
        struct muram_block *entry;
-       unsigned long start;
-
-       if (!muram_pool && cpm_muram_init())
-               goto out2;
+       s32 start;
 
+       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
+       if (!entry)
+               return -ENOMEM;
        start = gen_pool_alloc_algo(muram_pool, size, algo, data);
-       if (!start)
-               goto out2;
+       if (!start) {
+               kfree(entry);
+               return -ENOMEM;
+       }
        start = start - GENPOOL_OFFSET;
        memset_io(cpm_muram_addr(start), 0, size);
-       entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
-       if (!entry)
-               goto out1;
        entry->start = start;
        entry->size = size;
        list_add(&entry->head, &muram_block_list);
 
        return start;
-out1:
-       gen_pool_free(muram_pool, start, size);
-out2:
-       return (unsigned long)-ENOMEM;
 }
 
 /*
@@ -145,13 +141,14 @@ out2:
  * @size: number of bytes to allocate
  * @align: requested alignment, in bytes
  *
- * This function returns an offset into the muram area.
+ * This function returns a non-negative offset into the muram area, or
+ * a negative errno on failure.
  * Use cpm_dpram_addr() to get the virtual address of the area.
  * Use cpm_muram_free() to free the allocation.
  */
-unsigned long cpm_muram_alloc(unsigned long size, unsigned long align)
+s32 cpm_muram_alloc(unsigned long size, unsigned long align)
 {
-       unsigned long start;
+       s32 start;
        unsigned long flags;
        struct genpool_data_align muram_pool_data;
 
@@ -168,12 +165,15 @@ EXPORT_SYMBOL(cpm_muram_alloc);
  * cpm_muram_free - free a chunk of multi-user ram
  * @offset: The beginning of the chunk as returned by cpm_muram_alloc().
  */
-int cpm_muram_free(unsigned long offset)
+void cpm_muram_free(s32 offset)
 {
        unsigned long flags;
        int size;
        struct muram_block *tmp;
 
+       if (offset < 0)
+               return;
+
        size = 0;
        spin_lock_irqsave(&cpm_muram_lock, flags);
        list_for_each_entry(tmp, &muram_block_list, head) {
@@ -186,7 +186,6 @@ int cpm_muram_free(unsigned long offset)
        }
        gen_pool_free(muram_pool, offset + GENPOOL_OFFSET, size);
        spin_unlock_irqrestore(&cpm_muram_lock, flags);
-       return size;
 }
 EXPORT_SYMBOL(cpm_muram_free);
 
@@ -194,13 +193,14 @@ EXPORT_SYMBOL(cpm_muram_free);
  * cpm_muram_alloc_fixed - reserve a specific region of multi-user ram
  * @offset: offset of allocation start address
  * @size: number of bytes to allocate
- * This function returns an offset into the muram area
+ * This function returns @offset if the area was available, a negative
+ * errno otherwise.
  * Use cpm_dpram_addr() to get the virtual address of the area.
  * Use cpm_muram_free() to free the allocation.
  */
-unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size)
+s32 cpm_muram_alloc_fixed(unsigned long offset, unsigned long size)
 {
-       unsigned long start;
+       s32 start;
        unsigned long flags;
        struct genpool_data_fixed muram_pool_data_fixed;
 
index 9bac546..0dd5bdb 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/errno.h>
+#include <linux/irq.h>
 #include <linux/reboot.h>
 #include <linux/slab.h>
 #include <linux/stddef.h>
 #include <linux/spinlock.h>
 #include <asm/irq.h>
 #include <asm/io.h>
-#include <soc/fsl/qe/qe_ic.h>
+#include <soc/fsl/qe/qe.h>
+
+#define NR_QE_IC_INTS          64
+
+/* QE IC registers offset */
+#define QEIC_CICR              0x00
+#define QEIC_CIVEC             0x04
+#define QEIC_CIPXCC            0x10
+#define QEIC_CIPYCC            0x14
+#define QEIC_CIPWCC            0x18
+#define QEIC_CIPZCC            0x1c
+#define QEIC_CIMR              0x20
+#define QEIC_CRIMR             0x24
+#define QEIC_CIPRTA            0x30
+#define QEIC_CIPRTB            0x34
+#define QEIC_CHIVEC            0x60
+
+struct qe_ic {
+       /* Control registers offset */
+       u32 __iomem *regs;
+
+       /* The remapper for this QEIC */
+       struct irq_domain *irqhost;
+
+       /* The "linux" controller struct */
+       struct irq_chip hc_irq;
+
+       /* VIRQ numbers of QE high/low irqs */
+       unsigned int virq_high;
+       unsigned int virq_low;
+};
 
-#include "qe_ic.h"
+/*
+ * QE interrupt controller internal structure
+ */
+struct qe_ic_info {
+       /* Location of this source at the QIMR register */
+       u32     mask;
+
+       /* Mask register offset */
+       u32     mask_reg;
+
+       /*
+        * For grouped interrupts sources - the interrupt code as
+        * appears at the group priority register
+        */
+       u8      pri_code;
+
+       /* Group priority register offset */
+       u32     pri_reg;
+};
 
 static DEFINE_RAW_SPINLOCK(qe_ic_lock);
 
@@ -171,15 +220,15 @@ static struct qe_ic_info qe_ic_info[] = {
                },
 };
 
-static inline u32 qe_ic_read(volatile __be32  __iomem * base, unsigned int reg)
+static inline u32 qe_ic_read(__be32  __iomem *base, unsigned int reg)
 {
-       return in_be32(base + (reg >> 2));
+       return qe_ioread32be(base + (reg >> 2));
 }
 
-static inline void qe_ic_write(volatile __be32  __iomem * base, unsigned int reg,
+static inline void qe_ic_write(__be32  __iomem *base, unsigned int reg,
                               u32 value)
 {
-       out_be32(base + (reg >> 2), value);
+       qe_iowrite32be(value, base + (reg >> 2));
 }
 
 static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
@@ -281,8 +330,8 @@ static const struct irq_domain_ops qe_ic_host_ops = {
        .xlate = irq_domain_xlate_onetwocell,
 };
 
-/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
-unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
+/* Return an interrupt vector or 0 if no interrupt is pending. */
+static unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
 {
        int irq;
 
@@ -292,13 +341,13 @@ unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
        irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
 
        if (irq == 0)
-               return NO_IRQ;
+               return 0;
 
        return irq_linear_revmap(qe_ic->irqhost, irq);
 }
 
-/* Return an interrupt vector or NO_IRQ if no interrupt is pending. */
-unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
+/* Return an interrupt vector or 0 if no interrupt is pending. */
+static unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
 {
        int irq;
 
@@ -308,18 +357,60 @@ unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
        irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
 
        if (irq == 0)
-               return NO_IRQ;
+               return 0;
 
        return irq_linear_revmap(qe_ic->irqhost, irq);
 }
 
-void __init qe_ic_init(struct device_node *node, unsigned int flags,
-                      void (*low_handler)(struct irq_desc *desc),
-                      void (*high_handler)(struct irq_desc *desc))
+static void qe_ic_cascade_low(struct irq_desc *desc)
+{
+       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
+       unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+
+       if (cascade_irq != 0)
+               generic_handle_irq(cascade_irq);
+
+       if (chip->irq_eoi)
+               chip->irq_eoi(&desc->irq_data);
+}
+
+static void qe_ic_cascade_high(struct irq_desc *desc)
+{
+       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
+       unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+
+       if (cascade_irq != 0)
+               generic_handle_irq(cascade_irq);
+
+       if (chip->irq_eoi)
+               chip->irq_eoi(&desc->irq_data);
+}
+
+static void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
 {
+       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
+       unsigned int cascade_irq;
+       struct irq_chip *chip = irq_desc_get_chip(desc);
+
+       cascade_irq = qe_ic_get_high_irq(qe_ic);
+       if (cascade_irq == 0)
+               cascade_irq = qe_ic_get_low_irq(qe_ic);
+
+       if (cascade_irq != 0)
+               generic_handle_irq(cascade_irq);
+
+       chip->irq_eoi(&desc->irq_data);
+}
+
+static void __init qe_ic_init(struct device_node *node)
+{
+       void (*low_handler)(struct irq_desc *desc);
+       void (*high_handler)(struct irq_desc *desc);
        struct qe_ic *qe_ic;
        struct resource res;
-       u32 temp = 0, ret, high_active = 0;
+       u32 ret;
 
        ret = of_address_to_resource(node, 0, &res);
        if (ret)
@@ -343,166 +434,42 @@ void __init qe_ic_init(struct device_node *node, unsigned int flags,
        qe_ic->virq_high = irq_of_parse_and_map(node, 0);
        qe_ic->virq_low = irq_of_parse_and_map(node, 1);
 
-       if (qe_ic->virq_low == NO_IRQ) {
+       if (!qe_ic->virq_low) {
                printk(KERN_ERR "Failed to map QE_IC low IRQ\n");
                kfree(qe_ic);
                return;
        }
-
-       /* default priority scheme is grouped. If spread mode is    */
-       /* required, configure cicr accordingly.                    */
-       if (flags & QE_IC_SPREADMODE_GRP_W)
-               temp |= CICR_GWCC;
-       if (flags & QE_IC_SPREADMODE_GRP_X)
-               temp |= CICR_GXCC;
-       if (flags & QE_IC_SPREADMODE_GRP_Y)
-               temp |= CICR_GYCC;
-       if (flags & QE_IC_SPREADMODE_GRP_Z)
-               temp |= CICR_GZCC;
-       if (flags & QE_IC_SPREADMODE_GRP_RISCA)
-               temp |= CICR_GRTA;
-       if (flags & QE_IC_SPREADMODE_GRP_RISCB)
-               temp |= CICR_GRTB;
-
-       /* choose destination signal for highest priority interrupt */
-       if (flags & QE_IC_HIGH_SIGNAL) {
-               temp |= (SIGNAL_HIGH << CICR_HPIT_SHIFT);
-               high_active = 1;
+       if (qe_ic->virq_high != qe_ic->virq_low) {
+               low_handler = qe_ic_cascade_low;
+               high_handler = qe_ic_cascade_high;
+       } else {
+               low_handler = qe_ic_cascade_muxed_mpic;
+               high_handler = NULL;
        }
 
-       qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
+       qe_ic_write(qe_ic->regs, QEIC_CICR, 0);
 
        irq_set_handler_data(qe_ic->virq_low, qe_ic);
        irq_set_chained_handler(qe_ic->virq_low, low_handler);
 
-       if (qe_ic->virq_high != NO_IRQ &&
-                       qe_ic->virq_high != qe_ic->virq_low) {
+       if (qe_ic->virq_high && qe_ic->virq_high != qe_ic->virq_low) {
                irq_set_handler_data(qe_ic->virq_high, qe_ic);
                irq_set_chained_handler(qe_ic->virq_high, high_handler);
        }
 }
 
-void qe_ic_set_highest_priority(unsigned int virq, int high)
+static int __init qe_ic_of_init(void)
 {
-       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
-       unsigned int src = virq_to_hw(virq);
-       u32 temp = 0;
-
-       temp = qe_ic_read(qe_ic->regs, QEIC_CICR);
-
-       temp &= ~CICR_HP_MASK;
-       temp |= src << CICR_HP_SHIFT;
-
-       temp &= ~CICR_HPIT_MASK;
-       temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << CICR_HPIT_SHIFT;
-
-       qe_ic_write(qe_ic->regs, QEIC_CICR, temp);
-}
-
-/* Set Priority level within its group, from 1 to 8 */
-int qe_ic_set_priority(unsigned int virq, unsigned int priority)
-{
-       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
-       unsigned int src = virq_to_hw(virq);
-       u32 temp;
+       struct device_node *np;
 
-       if (priority > 8 || priority == 0)
-               return -EINVAL;
-       if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
-                     "%s: Invalid hw irq number for QEIC\n", __func__))
-               return -EINVAL;
-       if (qe_ic_info[src].pri_reg == 0)
-               return -EINVAL;
-
-       temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].pri_reg);
-
-       if (priority < 4) {
-               temp &= ~(0x7 << (32 - priority * 3));
-               temp |= qe_ic_info[src].pri_code << (32 - priority * 3);
-       } else {
-               temp &= ~(0x7 << (24 - priority * 3));
-               temp |= qe_ic_info[src].pri_code << (24 - priority * 3);
+       np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
+       if (!np) {
+               np = of_find_node_by_type(NULL, "qeic");
+               if (!np)
+                       return -ENODEV;
        }
-
-       qe_ic_write(qe_ic->regs, qe_ic_info[src].pri_reg, temp);
-
+       qe_ic_init(np);
+       of_node_put(np);
        return 0;
 }
-
-/* Set a QE priority to use high irq, only priority 1~2 can use high irq */
-int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high)
-{
-       struct qe_ic *qe_ic = qe_ic_from_irq(virq);
-       unsigned int src = virq_to_hw(virq);
-       u32 temp, control_reg = QEIC_CICNR, shift = 0;
-
-       if (priority > 2 || priority == 0)
-               return -EINVAL;
-       if (WARN_ONCE(src >= ARRAY_SIZE(qe_ic_info),
-                     "%s: Invalid hw irq number for QEIC\n", __func__))
-               return -EINVAL;
-
-       switch (qe_ic_info[src].pri_reg) {
-       case QEIC_CIPZCC:
-               shift = CICNR_ZCC1T_SHIFT;
-               break;
-       case QEIC_CIPWCC:
-               shift = CICNR_WCC1T_SHIFT;
-               break;
-       case QEIC_CIPYCC:
-               shift = CICNR_YCC1T_SHIFT;
-               break;
-       case QEIC_CIPXCC:
-               shift = CICNR_XCC1T_SHIFT;
-               break;
-       case QEIC_CIPRTA:
-               shift = CRICR_RTA1T_SHIFT;
-               control_reg = QEIC_CRICR;
-               break;
-       case QEIC_CIPRTB:
-               shift = CRICR_RTB1T_SHIFT;
-               control_reg = QEIC_CRICR;
-               break;
-       default:
-               return -EINVAL;
-       }
-
-       shift += (2 - priority) * 2;
-       temp = qe_ic_read(qe_ic->regs, control_reg);
-       temp &= ~(SIGNAL_MASK << shift);
-       temp |= (high ? SIGNAL_HIGH : SIGNAL_LOW) << shift;
-       qe_ic_write(qe_ic->regs, control_reg, temp);
-
-       return 0;
-}
-
-static struct bus_type qe_ic_subsys = {
-       .name = "qe_ic",
-       .dev_name = "qe_ic",
-};
-
-static struct device device_qe_ic = {
-       .id = 0,
-       .bus = &qe_ic_subsys,
-};
-
-static int __init init_qe_ic_sysfs(void)
-{
-       int rc;
-
-       printk(KERN_DEBUG "Registering qe_ic with sysfs...\n");
-
-       rc = subsys_system_register(&qe_ic_subsys, NULL);
-       if (rc) {
-               printk(KERN_ERR "Failed registering qe_ic sys class\n");
-               return -ENODEV;
-       }
-       rc = device_register(&device_qe_ic);
-       if (rc) {
-               printk(KERN_ERR "Failed registering qe_ic sys device\n");
-               return -ENODEV;
-       }
-       return 0;
-}
-
-subsys_initcall(init_qe_ic_sysfs);
+subsys_initcall(qe_ic_of_init);
diff --git a/drivers/soc/fsl/qe/qe_ic.h b/drivers/soc/fsl/qe/qe_ic.h
deleted file mode 100644 (file)
index 08c6956..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * drivers/soc/fsl/qe/qe_ic.h
- *
- * QUICC ENGINE Interrupt Controller Header
- *
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Author: Li Yang <leoli@freescale.com>
- * Based on code from Shlomi Gridish <gridish@freescale.com>
- */
-#ifndef _POWERPC_SYSDEV_QE_IC_H
-#define _POWERPC_SYSDEV_QE_IC_H
-
-#include <soc/fsl/qe/qe_ic.h>
-
-#define NR_QE_IC_INTS          64
-
-/* QE IC registers offset */
-#define QEIC_CICR              0x00
-#define QEIC_CIVEC             0x04
-#define QEIC_CRIPNR            0x08
-#define QEIC_CIPNR             0x0c
-#define QEIC_CIPXCC            0x10
-#define QEIC_CIPYCC            0x14
-#define QEIC_CIPWCC            0x18
-#define QEIC_CIPZCC            0x1c
-#define QEIC_CIMR              0x20
-#define QEIC_CRIMR             0x24
-#define QEIC_CICNR             0x28
-#define QEIC_CIPRTA            0x30
-#define QEIC_CIPRTB            0x34
-#define QEIC_CRICR             0x3c
-#define QEIC_CHIVEC            0x60
-
-/* Interrupt priority registers */
-#define CIPCC_SHIFT_PRI0       29
-#define CIPCC_SHIFT_PRI1       26
-#define CIPCC_SHIFT_PRI2       23
-#define CIPCC_SHIFT_PRI3       20
-#define CIPCC_SHIFT_PRI4       13
-#define CIPCC_SHIFT_PRI5       10
-#define CIPCC_SHIFT_PRI6       7
-#define CIPCC_SHIFT_PRI7       4
-
-/* CICR priority modes */
-#define CICR_GWCC              0x00040000
-#define CICR_GXCC              0x00020000
-#define CICR_GYCC              0x00010000
-#define CICR_GZCC              0x00080000
-#define CICR_GRTA              0x00200000
-#define CICR_GRTB              0x00400000
-#define CICR_HPIT_SHIFT                8
-#define CICR_HPIT_MASK         0x00000300
-#define CICR_HP_SHIFT          24
-#define CICR_HP_MASK           0x3f000000
-
-/* CICNR */
-#define CICNR_WCC1T_SHIFT      20
-#define CICNR_ZCC1T_SHIFT      28
-#define CICNR_YCC1T_SHIFT      12
-#define CICNR_XCC1T_SHIFT      4
-
-/* CRICR */
-#define CRICR_RTA1T_SHIFT      20
-#define CRICR_RTB1T_SHIFT      28
-
-/* Signal indicator */
-#define SIGNAL_MASK            3
-#define SIGNAL_HIGH            2
-#define SIGNAL_LOW             0
-
-struct qe_ic {
-       /* Control registers offset */
-       volatile u32 __iomem *regs;
-
-       /* The remapper for this QEIC */
-       struct irq_domain *irqhost;
-
-       /* The "linux" controller struct */
-       struct irq_chip hc_irq;
-
-       /* VIRQ numbers of QE high/low irqs */
-       unsigned int virq_high;
-       unsigned int virq_low;
-};
-
-/*
- * QE interrupt controller internal structure
- */
-struct qe_ic_info {
-       u32     mask;     /* location of this source at the QIMR register. */
-       u32     mask_reg; /* Mask register offset */
-       u8      pri_code; /* for grouped interrupts sources - the interrupt
-                            code as appears at the group priority register */
-       u32     pri_reg;  /* Group priority register offset */
-};
-
-#endif /* _POWERPC_SYSDEV_QE_IC_H */
index 3657e29..11ea08e 100644 (file)
@@ -18,8 +18,6 @@
 
 #include <asm/io.h>
 #include <soc/fsl/qe/qe.h>
-#include <asm/prom.h>
-#include <sysdev/fsl_soc.h>
 
 #undef DEBUG
 
@@ -30,7 +28,7 @@ int par_io_init(struct device_node *np)
 {
        struct resource res;
        int ret;
-       const u32 *num_ports;
+       u32 num_ports;
 
        /* Map Parallel I/O ports registers */
        ret = of_address_to_resource(np, 0, &res);
@@ -38,9 +36,8 @@ int par_io_init(struct device_node *np)
                return ret;
        par_io = ioremap(res.start, resource_size(&res));
 
-       num_ports = of_get_property(np, "num-ports", NULL);
-       if (num_ports)
-               num_par_io_ports = *num_ports;
+       if (!of_property_read_u32(np, "num-ports", &num_ports))
+               num_par_io_ports = num_ports;
 
        return 0;
 }
@@ -57,16 +54,16 @@ void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir,
        pin_mask1bit = (u32) (1 << (QE_PIO_PINS - (pin + 1)));
 
        /* Set open drain, if required */
-       tmp_val = in_be32(&par_io->cpodr);
+       tmp_val = qe_ioread32be(&par_io->cpodr);
        if (open_drain)
-               out_be32(&par_io->cpodr, pin_mask1bit | tmp_val);
+               qe_iowrite32be(pin_mask1bit | tmp_val, &par_io->cpodr);
        else
-               out_be32(&par_io->cpodr, ~pin_mask1bit & tmp_val);
+               qe_iowrite32be(~pin_mask1bit & tmp_val, &par_io->cpodr);
 
        /* define direction */
        tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
-               in_be32(&par_io->cpdir2) :
-               in_be32(&par_io->cpdir1);
+               qe_ioread32be(&par_io->cpdir2) :
+               qe_ioread32be(&par_io->cpdir1);
 
        /* get all bits mask for 2 bit per port */
        pin_mask2bits = (u32) (0x3 << (QE_PIO_PINS -
@@ -78,34 +75,30 @@ void __par_io_config_pin(struct qe_pio_regs __iomem *par_io, u8 pin, int dir,
 
        /* clear and set 2 bits mask */
        if (pin > (QE_PIO_PINS / 2) - 1) {
-               out_be32(&par_io->cpdir2,
-                        ~pin_mask2bits & tmp_val);
+               qe_iowrite32be(~pin_mask2bits & tmp_val, &par_io->cpdir2);
                tmp_val &= ~pin_mask2bits;
-               out_be32(&par_io->cpdir2, new_mask2bits | tmp_val);
+               qe_iowrite32be(new_mask2bits | tmp_val, &par_io->cpdir2);
        } else {
-               out_be32(&par_io->cpdir1,
-                        ~pin_mask2bits & tmp_val);
+               qe_iowrite32be(~pin_mask2bits & tmp_val, &par_io->cpdir1);
                tmp_val &= ~pin_mask2bits;
-               out_be32(&par_io->cpdir1, new_mask2bits | tmp_val);
+               qe_iowrite32be(new_mask2bits | tmp_val, &par_io->cpdir1);
        }
        /* define pin assignment */
        tmp_val = (pin > (QE_PIO_PINS / 2) - 1) ?
-               in_be32(&par_io->cppar2) :
-               in_be32(&par_io->cppar1);
+               qe_ioread32be(&par_io->cppar2) :
+               qe_ioread32be(&par_io->cppar1);
 
        new_mask2bits = (u32) (assignment << (QE_PIO_PINS -
                        (pin % (QE_PIO_PINS / 2) + 1) * 2));
        /* clear and set 2 bits mask */
        if (pin > (QE_PIO_PINS / 2) - 1) {
-               out_be32(&par_io->cppar2,
-                        ~pin_mask2bits & tmp_val);
+               qe_iowrite32be(~pin_mask2bits & tmp_val, &par_io->cppar2);
                tmp_val &= ~pin_mask2bits;
-               out_be32(&par_io->cppar2, new_mask2bits | tmp_val);
+               qe_iowrite32be(new_mask2bits | tmp_val, &par_io->cppar2);
        } else {
-               out_be32(&par_io->cppar1,
-                        ~pin_mask2bits & tmp_val);
+               qe_iowrite32be(~pin_mask2bits & tmp_val, &par_io->cppar1);
                tmp_val &= ~pin_mask2bits;
-               out_be32(&par_io->cppar1, new_mask2bits | tmp_val);
+               qe_iowrite32be(new_mask2bits | tmp_val, &par_io->cppar1);
        }
 }
 EXPORT_SYMBOL(__par_io_config_pin);
@@ -133,12 +126,12 @@ int par_io_data_set(u8 port, u8 pin, u8 val)
        /* calculate pin location */
        pin_mask = (u32) (1 << (QE_PIO_PINS - 1 - pin));
 
-       tmp_val = in_be32(&par_io[port].cpdata);
+       tmp_val = qe_ioread32be(&par_io[port].cpdata);
 
        if (val == 0)           /* clear */
-               out_be32(&par_io[port].cpdata, ~pin_mask & tmp_val);
+               qe_iowrite32be(~pin_mask & tmp_val, &par_io[port].cpdata);
        else                    /* set */
-               out_be32(&par_io[port].cpdata, pin_mask | tmp_val);
+               qe_iowrite32be(pin_mask | tmp_val, &par_io[port].cpdata);
 
        return 0;
 }
@@ -147,23 +140,20 @@ EXPORT_SYMBOL(par_io_data_set);
 int par_io_of_config(struct device_node *np)
 {
        struct device_node *pio;
-       const phandle *ph;
        int pio_map_len;
-       const unsigned int *pio_map;
+       const __be32 *pio_map;
 
        if (par_io == NULL) {
                printk(KERN_ERR "par_io not initialized\n");
                return -1;
        }
 
-       ph = of_get_property(np, "pio-handle", NULL);
-       if (ph == NULL) {
+       pio = of_parse_phandle(np, "pio-handle", 0);
+       if (pio == NULL) {
                printk(KERN_ERR "pio-handle not available\n");
                return -1;
        }
 
-       pio = of_find_node_by_phandle(*ph);
-
        pio_map = of_get_property(pio, "pio-map", &pio_map_len);
        if (pio_map == NULL) {
                printk(KERN_ERR "pio-map is not set!\n");
@@ -176,9 +166,15 @@ int par_io_of_config(struct device_node *np)
        }
 
        while (pio_map_len > 0) {
-               par_io_config_pin((u8) pio_map[0], (u8) pio_map[1],
-                               (int) pio_map[2], (int) pio_map[3],
-                               (int) pio_map[4], (int) pio_map[5]);
+               u8 port        = be32_to_cpu(pio_map[0]);
+               u8 pin         = be32_to_cpu(pio_map[1]);
+               int dir        = be32_to_cpu(pio_map[2]);
+               int open_drain = be32_to_cpu(pio_map[3]);
+               int assignment = be32_to_cpu(pio_map[4]);
+               int has_irq    = be32_to_cpu(pio_map[5]);
+
+               par_io_config_pin(port, pin, dir, open_drain,
+                                 assignment, has_irq);
                pio_map += 6;
                pio_map_len -= 6;
        }
index e37ebc3..7d7d78d 100644 (file)
@@ -169,10 +169,10 @@ void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info)
                                    &siram[siram_entry_id * 32 + 0x200 +  i]);
        }
 
-       setbits16(&siram[(siram_entry_id * 32) + (utdm->num_of_ts - 1)],
-                 SIR_LAST);
-       setbits16(&siram[(siram_entry_id * 32) + 0x200 + (utdm->num_of_ts - 1)],
-                 SIR_LAST);
+       qe_setbits_be16(&siram[(siram_entry_id * 32) + (utdm->num_of_ts - 1)],
+                       SIR_LAST);
+       qe_setbits_be16(&siram[(siram_entry_id * 32) + 0x200 + (utdm->num_of_ts - 1)],
+                       SIR_LAST);
 
        /* Set SIxMR register */
        sixmr = SIMR_SAD(siram_entry_id);
index 024d239..90157ac 100644 (file)
@@ -15,7 +15,6 @@
 #include <linux/spinlock.h>
 #include <linux/export.h>
 
-#include <asm/irq.h>
 #include <asm/io.h>
 #include <soc/fsl/qe/immap_qe.h>
 #include <soc/fsl/qe/qe.h>
@@ -35,8 +34,8 @@ int ucc_set_qe_mux_mii_mng(unsigned int ucc_num)
                return -EINVAL;
 
        spin_lock_irqsave(&cmxgcr_lock, flags);
-       clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
-               ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
+       qe_clrsetbits_be32(&qe_immr->qmx.cmxgcr, QE_CMXGCR_MII_ENET_MNG,
+                          ucc_num << QE_CMXGCR_MII_ENET_MNG_SHIFT);
        spin_unlock_irqrestore(&cmxgcr_lock, flags);
 
        return 0;
@@ -80,8 +79,8 @@ int ucc_set_type(unsigned int ucc_num, enum ucc_speed_type speed)
                return -EINVAL;
        }
 
-       clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
-               UCC_GUEMR_SET_RESERVED3 | speed);
+       qe_clrsetbits_8(guemr, UCC_GUEMR_MODE_MASK,
+                       UCC_GUEMR_SET_RESERVED3 | speed);
 
        return 0;
 }
@@ -109,9 +108,9 @@ int ucc_mux_set_grant_tsa_bkpt(unsigned int ucc_num, int set, u32 mask)
        get_cmxucr_reg(ucc_num, &cmxucr, &reg_num, &shift);
 
        if (set)
-               setbits32(cmxucr, mask << shift);
+               qe_setbits_be32(cmxucr, mask << shift);
        else
-               clrbits32(cmxucr, mask << shift);
+               qe_clrbits_be32(cmxucr, mask << shift);
 
        return 0;
 }
@@ -207,8 +206,8 @@ int ucc_set_qe_mux_rxtx(unsigned int ucc_num, enum qe_clock clock,
        if (mode == COMM_DIR_RX)
                shift += 4;
 
-       clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
-               clock_bits << shift);
+       qe_clrsetbits_be32(cmxucr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
+                          clock_bits << shift);
 
        return 0;
 }
@@ -540,8 +539,8 @@ int ucc_set_tdm_rxtx_clk(u32 tdm_num, enum qe_clock clock,
        cmxs1cr = (tdm_num < 4) ? &qe_mux_reg->cmxsi1cr_l :
                                  &qe_mux_reg->cmxsi1cr_h;
 
-       qe_clrsetbits32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
-                       clock_bits << shift);
+       qe_clrsetbits_be32(cmxs1cr, QE_CMXUCR_TX_CLK_SRC_MASK << shift,
+                          clock_bits << shift);
 
        return 0;
 }
@@ -650,9 +649,9 @@ int ucc_set_tdm_rxtx_sync(u32 tdm_num, enum qe_clock clock,
 
        shift = ucc_get_tdm_sync_shift(mode, tdm_num);
 
-       qe_clrsetbits32(&qe_mux_reg->cmxsi1syr,
-                       QE_CMXUCR_TX_CLK_SRC_MASK << shift,
-                       source << shift);
+       qe_clrsetbits_be32(&qe_mux_reg->cmxsi1syr,
+                          QE_CMXUCR_TX_CLK_SRC_MASK << shift,
+                          source << shift);
 
        return 0;
 }
index af4d80e..ad6193e 100644 (file)
@@ -29,41 +29,42 @@ void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
        printk(KERN_INFO "Base address: 0x%p\n", uccf->uf_regs);
 
        printk(KERN_INFO "gumr  : addr=0x%p, val=0x%08x\n",
-                 &uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
+                 &uccf->uf_regs->gumr, qe_ioread32be(&uccf->uf_regs->gumr));
        printk(KERN_INFO "upsmr : addr=0x%p, val=0x%08x\n",
-                 &uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
+                 &uccf->uf_regs->upsmr, qe_ioread32be(&uccf->uf_regs->upsmr));
        printk(KERN_INFO "utodr : addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
+                 &uccf->uf_regs->utodr, qe_ioread16be(&uccf->uf_regs->utodr));
        printk(KERN_INFO "udsr  : addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
+                 &uccf->uf_regs->udsr, qe_ioread16be(&uccf->uf_regs->udsr));
        printk(KERN_INFO "ucce  : addr=0x%p, val=0x%08x\n",
-                 &uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
+                 &uccf->uf_regs->ucce, qe_ioread32be(&uccf->uf_regs->ucce));
        printk(KERN_INFO "uccm  : addr=0x%p, val=0x%08x\n",
-                 &uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
+                 &uccf->uf_regs->uccm, qe_ioread32be(&uccf->uf_regs->uccm));
        printk(KERN_INFO "uccs  : addr=0x%p, val=0x%02x\n",
-                 &uccf->uf_regs->uccs, in_8(&uccf->uf_regs->uccs));
+                 &uccf->uf_regs->uccs, qe_ioread8(&uccf->uf_regs->uccs));
        printk(KERN_INFO "urfb  : addr=0x%p, val=0x%08x\n",
-                 &uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
+                 &uccf->uf_regs->urfb, qe_ioread32be(&uccf->uf_regs->urfb));
        printk(KERN_INFO "urfs  : addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
+                 &uccf->uf_regs->urfs, qe_ioread16be(&uccf->uf_regs->urfs));
        printk(KERN_INFO "urfet : addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
+                 &uccf->uf_regs->urfet, qe_ioread16be(&uccf->uf_regs->urfet));
        printk(KERN_INFO "urfset: addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->urfset, in_be16(&uccf->uf_regs->urfset));
+                 &uccf->uf_regs->urfset,
+                 qe_ioread16be(&uccf->uf_regs->urfset));
        printk(KERN_INFO "utfb  : addr=0x%p, val=0x%08x\n",
-                 &uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
+                 &uccf->uf_regs->utfb, qe_ioread32be(&uccf->uf_regs->utfb));
        printk(KERN_INFO "utfs  : addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
+                 &uccf->uf_regs->utfs, qe_ioread16be(&uccf->uf_regs->utfs));
        printk(KERN_INFO "utfet : addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
+                 &uccf->uf_regs->utfet, qe_ioread16be(&uccf->uf_regs->utfet));
        printk(KERN_INFO "utftt : addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
+                 &uccf->uf_regs->utftt, qe_ioread16be(&uccf->uf_regs->utftt));
        printk(KERN_INFO "utpt  : addr=0x%p, val=0x%04x\n",
-                 &uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
+                 &uccf->uf_regs->utpt, qe_ioread16be(&uccf->uf_regs->utpt));
        printk(KERN_INFO "urtry : addr=0x%p, val=0x%08x\n",
-                 &uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
+                 &uccf->uf_regs->urtry, qe_ioread32be(&uccf->uf_regs->urtry));
        printk(KERN_INFO "guemr : addr=0x%p, val=0x%02x\n",
-                 &uccf->uf_regs->guemr, in_8(&uccf->uf_regs->guemr));
+                 &uccf->uf_regs->guemr, qe_ioread8(&uccf->uf_regs->guemr));
 }
 EXPORT_SYMBOL(ucc_fast_dump_regs);
 
@@ -85,7 +86,7 @@ EXPORT_SYMBOL(ucc_fast_get_qe_cr_subblock);
 
 void ucc_fast_transmit_on_demand(struct ucc_fast_private * uccf)
 {
-       out_be16(&uccf->uf_regs->utodr, UCC_FAST_TOD);
+       qe_iowrite16be(UCC_FAST_TOD, &uccf->uf_regs->utodr);
 }
 EXPORT_SYMBOL(ucc_fast_transmit_on_demand);
 
@@ -97,7 +98,7 @@ void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
        uf_regs = uccf->uf_regs;
 
        /* Enable reception and/or transmission on this UCC. */
-       gumr = in_be32(&uf_regs->gumr);
+       gumr = qe_ioread32be(&uf_regs->gumr);
        if (mode & COMM_DIR_TX) {
                gumr |= UCC_FAST_GUMR_ENT;
                uccf->enabled_tx = 1;
@@ -106,7 +107,7 @@ void ucc_fast_enable(struct ucc_fast_private * uccf, enum comm_dir mode)
                gumr |= UCC_FAST_GUMR_ENR;
                uccf->enabled_rx = 1;
        }
-       out_be32(&uf_regs->gumr, gumr);
+       qe_iowrite32be(gumr, &uf_regs->gumr);
 }
 EXPORT_SYMBOL(ucc_fast_enable);
 
@@ -118,7 +119,7 @@ void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
        uf_regs = uccf->uf_regs;
 
        /* Disable reception and/or transmission on this UCC. */
-       gumr = in_be32(&uf_regs->gumr);
+       gumr = qe_ioread32be(&uf_regs->gumr);
        if (mode & COMM_DIR_TX) {
                gumr &= ~UCC_FAST_GUMR_ENT;
                uccf->enabled_tx = 0;
@@ -127,7 +128,7 @@ void ucc_fast_disable(struct ucc_fast_private * uccf, enum comm_dir mode)
                gumr &= ~UCC_FAST_GUMR_ENR;
                uccf->enabled_rx = 0;
        }
-       out_be32(&uf_regs->gumr, gumr);
+       qe_iowrite32be(gumr, &uf_regs->gumr);
 }
 EXPORT_SYMBOL(ucc_fast_disable);
 
@@ -196,6 +197,8 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
                        __func__);
                return -ENOMEM;
        }
+       uccf->ucc_fast_tx_virtual_fifo_base_offset = -1;
+       uccf->ucc_fast_rx_virtual_fifo_base_offset = -1;
 
        /* Fill fast UCC structure */
        uccf->uf_info = uf_info;
@@ -259,15 +262,14 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
        gumr |= uf_info->tenc;
        gumr |= uf_info->tcrc;
        gumr |= uf_info->mode;
-       out_be32(&uf_regs->gumr, gumr);
+       qe_iowrite32be(gumr, &uf_regs->gumr);
 
        /* Allocate memory for Tx Virtual Fifo */
        uccf->ucc_fast_tx_virtual_fifo_base_offset =
            qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
-       if (IS_ERR_VALUE(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
+       if (uccf->ucc_fast_tx_virtual_fifo_base_offset < 0) {
                printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO\n",
                        __func__);
-               uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
                ucc_fast_free(uccf);
                return -ENOMEM;
        }
@@ -277,24 +279,25 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
                qe_muram_alloc(uf_info->urfs +
                           UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
                           UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
-       if (IS_ERR_VALUE(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
+       if (uccf->ucc_fast_rx_virtual_fifo_base_offset < 0) {
                printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO\n",
                        __func__);
-               uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
                ucc_fast_free(uccf);
                return -ENOMEM;
        }
 
        /* Set Virtual Fifo registers */
-       out_be16(&uf_regs->urfs, uf_info->urfs);
-       out_be16(&uf_regs->urfet, uf_info->urfet);
-       out_be16(&uf_regs->urfset, uf_info->urfset);
-       out_be16(&uf_regs->utfs, uf_info->utfs);
-       out_be16(&uf_regs->utfet, uf_info->utfet);
-       out_be16(&uf_regs->utftt, uf_info->utftt);
+       qe_iowrite16be(uf_info->urfs, &uf_regs->urfs);
+       qe_iowrite16be(uf_info->urfet, &uf_regs->urfet);
+       qe_iowrite16be(uf_info->urfset, &uf_regs->urfset);
+       qe_iowrite16be(uf_info->utfs, &uf_regs->utfs);
+       qe_iowrite16be(uf_info->utfet, &uf_regs->utfet);
+       qe_iowrite16be(uf_info->utftt, &uf_regs->utftt);
        /* utfb, urfb are offsets from MURAM base */
-       out_be32(&uf_regs->utfb, uccf->ucc_fast_tx_virtual_fifo_base_offset);
-       out_be32(&uf_regs->urfb, uccf->ucc_fast_rx_virtual_fifo_base_offset);
+       qe_iowrite32be(uccf->ucc_fast_tx_virtual_fifo_base_offset,
+                      &uf_regs->utfb);
+       qe_iowrite32be(uccf->ucc_fast_rx_virtual_fifo_base_offset,
+                      &uf_regs->urfb);
 
        /* Mux clocking */
        /* Grant Support */
@@ -362,14 +365,14 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
        }
 
        /* Set interrupt mask register at UCC level. */
-       out_be32(&uf_regs->uccm, uf_info->uccm_mask);
+       qe_iowrite32be(uf_info->uccm_mask, &uf_regs->uccm);
 
        /* First, clear anything pending at UCC level,
         * otherwise, old garbage may come through
         * as soon as the dam is opened. */
 
        /* Writing '1' clears */
-       out_be32(&uf_regs->ucce, 0xffffffff);
+       qe_iowrite32be(0xffffffff, &uf_regs->ucce);
 
        *uccf_ret = uccf;
        return 0;
@@ -381,11 +384,8 @@ void ucc_fast_free(struct ucc_fast_private * uccf)
        if (!uccf)
                return;
 
-       if (uccf->ucc_fast_tx_virtual_fifo_base_offset)
-               qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset);
-
-       if (uccf->ucc_fast_rx_virtual_fifo_base_offset)
-               qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);
+       qe_muram_free(uccf->ucc_fast_tx_virtual_fifo_base_offset);
+       qe_muram_free(uccf->ucc_fast_rx_virtual_fifo_base_offset);
 
        if (uccf->uf_regs)
                iounmap(uccf->uf_regs);
index 34f0ec3..274d344 100644 (file)
@@ -78,7 +78,7 @@ void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
        us_regs = uccs->us_regs;
 
        /* Enable reception and/or transmission on this UCC. */
-       gumr_l = in_be32(&us_regs->gumr_l);
+       gumr_l = qe_ioread32be(&us_regs->gumr_l);
        if (mode & COMM_DIR_TX) {
                gumr_l |= UCC_SLOW_GUMR_L_ENT;
                uccs->enabled_tx = 1;
@@ -87,7 +87,7 @@ void ucc_slow_enable(struct ucc_slow_private * uccs, enum comm_dir mode)
                gumr_l |= UCC_SLOW_GUMR_L_ENR;
                uccs->enabled_rx = 1;
        }
-       out_be32(&us_regs->gumr_l, gumr_l);
+       qe_iowrite32be(gumr_l, &us_regs->gumr_l);
 }
 EXPORT_SYMBOL(ucc_slow_enable);
 
@@ -99,7 +99,7 @@ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
        us_regs = uccs->us_regs;
 
        /* Disable reception and/or transmission on this UCC. */
-       gumr_l = in_be32(&us_regs->gumr_l);
+       gumr_l = qe_ioread32be(&us_regs->gumr_l);
        if (mode & COMM_DIR_TX) {
                gumr_l &= ~UCC_SLOW_GUMR_L_ENT;
                uccs->enabled_tx = 0;
@@ -108,7 +108,7 @@ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
                gumr_l &= ~UCC_SLOW_GUMR_L_ENR;
                uccs->enabled_rx = 0;
        }
-       out_be32(&us_regs->gumr_l, gumr_l);
+       qe_iowrite32be(gumr_l, &us_regs->gumr_l);
 }
 EXPORT_SYMBOL(ucc_slow_disable);
 
@@ -154,6 +154,9 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
                        __func__);
                return -ENOMEM;
        }
+       uccs->rx_base_offset = -1;
+       uccs->tx_base_offset = -1;
+       uccs->us_pram_offset = -1;
 
        /* Fill slow UCC structure */
        uccs->us_info = us_info;
@@ -179,7 +182,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
        /* Get PRAM base */
        uccs->us_pram_offset =
                qe_muram_alloc(UCC_SLOW_PRAM_SIZE, ALIGNMENT_OF_UCC_SLOW_PRAM);
-       if (IS_ERR_VALUE(uccs->us_pram_offset)) {
+       if (uccs->us_pram_offset < 0) {
                printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __func__);
                ucc_slow_free(uccs);
                return -ENOMEM;
@@ -198,7 +201,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
                return ret;
        }
 
-       out_be16(&uccs->us_pram->mrblr, us_info->max_rx_buf_length);
+       qe_iowrite16be(us_info->max_rx_buf_length, &uccs->us_pram->mrblr);
 
        INIT_LIST_HEAD(&uccs->confQ);
 
@@ -206,10 +209,9 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
        uccs->rx_base_offset =
                qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
                                QE_ALIGNMENT_OF_BD);
-       if (IS_ERR_VALUE(uccs->rx_base_offset)) {
+       if (uccs->rx_base_offset < 0) {
                printk(KERN_ERR "%s: cannot allocate %u RX BDs\n", __func__,
                        us_info->rx_bd_ring_len);
-               uccs->rx_base_offset = 0;
                ucc_slow_free(uccs);
                return -ENOMEM;
        }
@@ -217,9 +219,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
        uccs->tx_base_offset =
                qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
                        QE_ALIGNMENT_OF_BD);
-       if (IS_ERR_VALUE(uccs->tx_base_offset)) {
+       if (uccs->tx_base_offset < 0) {
                printk(KERN_ERR "%s: cannot allocate TX BDs", __func__);
-               uccs->tx_base_offset = 0;
                ucc_slow_free(uccs);
                return -ENOMEM;
        }
@@ -228,27 +229,27 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
        bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset);
        for (i = 0; i < us_info->tx_bd_ring_len - 1; i++) {
                /* clear bd buffer */
-               out_be32(&bd->buf, 0);
+               qe_iowrite32be(0, &bd->buf);
                /* set bd status and length */
-               out_be32((u32 *) bd, 0);
+               qe_iowrite32be(0, (u32 *)bd);
                bd++;
        }
        /* for last BD set Wrap bit */
-       out_be32(&bd->buf, 0);
-       out_be32((u32 *) bd, cpu_to_be32(T_W));
+       qe_iowrite32be(0, &bd->buf);
+       qe_iowrite32be(cpu_to_be32(T_W), (u32 *)bd);
 
        /* Init Rx bds */
        bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
        for (i = 0; i < us_info->rx_bd_ring_len - 1; i++) {
                /* set bd status and length */
-               out_be32((u32*)bd, 0);
+               qe_iowrite32be(0, (u32 *)bd);
                /* clear bd buffer */
-               out_be32(&bd->buf, 0);
+               qe_iowrite32be(0, &bd->buf);
                bd++;
        }
        /* for last BD set Wrap bit */
-       out_be32((u32*)bd, cpu_to_be32(R_W));
-       out_be32(&bd->buf, 0);
+       qe_iowrite32be(cpu_to_be32(R_W), (u32 *)bd);
+       qe_iowrite32be(0, &bd->buf);
 
        /* Set GUMR (For more details see the hardware spec.). */
        /* gumr_h */
@@ -269,7 +270,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
                gumr |= UCC_SLOW_GUMR_H_TXSY;
        if (us_info->rtsm)
                gumr |= UCC_SLOW_GUMR_H_RTSM;
-       out_be32(&us_regs->gumr_h, gumr);
+       qe_iowrite32be(gumr, &us_regs->gumr_h);
 
        /* gumr_l */
        gumr = us_info->tdcr | us_info->rdcr | us_info->tenc | us_info->renc |
@@ -282,7 +283,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
                gumr |= UCC_SLOW_GUMR_L_TINV;
        if (us_info->tend)
                gumr |= UCC_SLOW_GUMR_L_TEND;
-       out_be32(&us_regs->gumr_l, gumr);
+       qe_iowrite32be(gumr, &us_regs->gumr_l);
 
        /* Function code registers */
 
@@ -292,8 +293,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
        uccs->us_pram->rbmr = UCC_BMR_BO_BE;
 
        /* rbase, tbase are offsets from MURAM base */
-       out_be16(&uccs->us_pram->rbase, uccs->rx_base_offset);
-       out_be16(&uccs->us_pram->tbase, uccs->tx_base_offset);
+       qe_iowrite16be(uccs->rx_base_offset, &uccs->us_pram->rbase);
+       qe_iowrite16be(uccs->tx_base_offset, &uccs->us_pram->tbase);
 
        /* Mux clocking */
        /* Grant Support */
@@ -323,14 +324,14 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
        }
 
        /* Set interrupt mask register at UCC level. */
-       out_be16(&us_regs->uccm, us_info->uccm_mask);
+       qe_iowrite16be(us_info->uccm_mask, &us_regs->uccm);
 
        /* First, clear anything pending at UCC level,
         * otherwise, old garbage may come through
         * as soon as the dam is opened. */
 
        /* Writing '1' clears */
-       out_be16(&us_regs->ucce, 0xffff);
+       qe_iowrite16be(0xffff, &us_regs->ucce);
 
        /* Issue QE Init command */
        if (us_info->init_tx && us_info->init_rx)
@@ -352,14 +353,9 @@ void ucc_slow_free(struct ucc_slow_private * uccs)
        if (!uccs)
                return;
 
-       if (uccs->rx_base_offset)
-               qe_muram_free(uccs->rx_base_offset);
-
-       if (uccs->tx_base_offset)
-               qe_muram_free(uccs->tx_base_offset);
-
-       if (uccs->us_pram)
-               qe_muram_free(uccs->us_pram_offset);
+       qe_muram_free(uccs->rx_base_offset);
+       qe_muram_free(uccs->tx_base_offset);
+       qe_muram_free(uccs->us_pram_offset);
 
        if (uccs->us_regs)
                iounmap(uccs->us_regs);
index 32d8269..890f236 100644 (file)
@@ -43,7 +43,7 @@ int qe_usb_clock_set(enum qe_clock clk, int rate)
 
        spin_lock_irqsave(&cmxgcr_lock, flags);
 
-       clrsetbits_be32(&mux->cmxgcr, QE_CMXGCR_USBCS, val);
+       qe_clrsetbits_be32(&mux->cmxgcr, QE_CMXGCR_USBCS, val);
 
        spin_unlock_irqrestore(&cmxgcr_lock, flags);
 
index 8aaebf1..0281ef9 100644 (file)
@@ -10,7 +10,7 @@ config IMX_GPCV2_PM_DOMAINS
 
 config IMX_SCU_SOC
        bool "i.MX System Controller Unit SoC info support"
-       depends on IMX_SCU
+       depends on IMX_SCU || COMPILE_TEST
        select SOC_BUS
        help
          If you say yes here you get support for the NXP i.MX System
index d84ed73..719e1f1 100644 (file)
@@ -142,10 +142,16 @@ static const struct imx8_soc_data imx8mn_soc_data = {
        .soc_revision = imx8mm_soc_revision,
 };
 
+static const struct imx8_soc_data imx8mp_soc_data = {
+       .name = "i.MX8MP",
+       .soc_revision = imx8mm_soc_revision,
+};
+
 static const struct of_device_id imx8_soc_match[] = {
        { .compatible = "fsl,imx8mq", .data = &imx8mq_soc_data, },
        { .compatible = "fsl,imx8mm", .data = &imx8mm_soc_data, },
        { .compatible = "fsl,imx8mn", .data = &imx8mn_soc_data, },
+       { .compatible = "fsl,imx8mp", .data = &imx8mp_soc_data, },
        { }
 };
 
@@ -204,6 +210,9 @@ static int __init imx8_soc_init(void)
                goto free_serial_number;
        }
 
+       pr_info("SoC: %s revision %s\n", soc_dev_attr->soc_id,
+               soc_dev_attr->revision);
+
        if (IS_ENABLED(CONFIG_ARM_IMX_CPUFREQ_DT))
                platform_device_register_simple("imx-cpufreq-dt", -1, NULL, 0);
 
index 9add0fd..de20e6c 100644 (file)
@@ -12,8 +12,6 @@
 #define CMDQ_WRITE_ENABLE_MASK BIT(0)
 #define CMDQ_POLL_ENABLE_MASK  BIT(0)
 #define CMDQ_EOC_IRQ_EN                BIT(0)
-#define CMDQ_EOC_CMD           ((u64)((CMDQ_CODE_EOC << CMDQ_OP_CODE_SHIFT)) \
-                               << 32 | CMDQ_EOC_IRQ_EN)
 
 struct cmdq_instruction {
        union {
index 79d8265..d0a73e7 100644 (file)
@@ -45,13 +45,13 @@ config QCOM_GLINK_SSR
          neighboring subsystems going up or down.
 
 config QCOM_GSBI
-        tristate "QCOM General Serial Bus Interface"
-        depends on ARCH_QCOM || COMPILE_TEST
-        select MFD_SYSCON
-        help
-          Say y here to enable GSBI support.  The GSBI provides control
-          functions for connecting the underlying serial UART, SPI, and I2C
-          devices to the output pins.
+       tristate "QCOM General Serial Bus Interface"
+       depends on ARCH_QCOM || COMPILE_TEST
+       select MFD_SYSCON
+       help
+         Say y here to enable GSBI support.  The GSBI provides control
+         functions for connecting the underlying serial UART, SPI, and I2C
+         devices to the output pins.
 
 config QCOM_LLCC
        tristate "Qualcomm Technologies, Inc. LLCC driver"
@@ -71,10 +71,10 @@ config QCOM_OCMEM
        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.
+         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"
@@ -198,8 +198,8 @@ config QCOM_APR
        depends on ARCH_QCOM || COMPILE_TEST
        depends on RPMSG
        help
-          Enable APR IPC protocol support between
-          application processor and QDSP6. APR is
-          used by audio driver to configure QDSP6
-          ASM, ADM and AFE modules.
+         Enable APR IPC protocol support between
+         application processor and QDSP6. APR is
+         used by audio driver to configure QDSP6
+         ASM, ADM and AFE modules.
 endmenu
index f9e309f..1a03eaa 100644 (file)
@@ -655,8 +655,12 @@ int qmi_handle_init(struct qmi_handle *qmi, size_t recv_buf_size,
 
        qmi->sock = qmi_sock_create(qmi, &qmi->sq);
        if (IS_ERR(qmi->sock)) {
-               pr_err("failed to create QMI socket\n");
-               ret = PTR_ERR(qmi->sock);
+               if (PTR_ERR(qmi->sock) == -EAFNOSUPPORT) {
+                       ret = -EPROBE_DEFER;
+               } else {
+                       pr_err("failed to create QMI socket\n");
+                       ret = PTR_ERR(qmi->sock);
+               }
                goto err_destroy_wq;
        }
 
index 5741ec3..4d264d0 100644 (file)
@@ -93,6 +93,7 @@ static struct rpmhpd sdm845_mx = {
 
 static struct rpmhpd sdm845_mx_ao = {
        .pd = { .name = "mx_ao", },
+       .active_only = true,
        .peer = &sdm845_mx,
        .res_name = "mx.lvl",
 };
@@ -107,6 +108,7 @@ static struct rpmhpd sdm845_cx = {
 
 static struct rpmhpd sdm845_cx_ao = {
        .pd = { .name = "cx_ao", },
+       .active_only = true,
        .peer = &sdm845_cx,
        .parent = &sdm845_mx_ao.pd,
        .res_name = "cx.lvl",
@@ -129,8 +131,62 @@ static const struct rpmhpd_desc sdm845_desc = {
        .num_pds = ARRAY_SIZE(sdm845_rpmhpds),
 };
 
+/* SM8150 RPMH powerdomains */
+
+static struct rpmhpd sm8150_mmcx_ao;
+static struct rpmhpd sm8150_mmcx = {
+       .pd = { .name = "mmcx", },
+       .peer = &sm8150_mmcx_ao,
+       .res_name = "mmcx.lvl",
+};
+
+static struct rpmhpd sm8150_mmcx_ao = {
+       .pd = { .name = "mmcx_ao", },
+       .active_only = true,
+       .peer = &sm8150_mmcx,
+       .res_name = "mmcx.lvl",
+};
+
+static struct rpmhpd *sm8150_rpmhpds[] = {
+       [SM8150_MSS] = &sdm845_mss,
+       [SM8150_EBI] = &sdm845_ebi,
+       [SM8150_LMX] = &sdm845_lmx,
+       [SM8150_LCX] = &sdm845_lcx,
+       [SM8150_GFX] = &sdm845_gfx,
+       [SM8150_MX] = &sdm845_mx,
+       [SM8150_MX_AO] = &sdm845_mx_ao,
+       [SM8150_CX] = &sdm845_cx,
+       [SM8150_CX_AO] = &sdm845_cx_ao,
+       [SM8150_MMCX] = &sm8150_mmcx,
+       [SM8150_MMCX_AO] = &sm8150_mmcx_ao,
+};
+
+static const struct rpmhpd_desc sm8150_desc = {
+       .rpmhpds = sm8150_rpmhpds,
+       .num_pds = ARRAY_SIZE(sm8150_rpmhpds),
+};
+
+/* SC7180 RPMH powerdomains */
+static struct rpmhpd *sc7180_rpmhpds[] = {
+       [SC7180_CX] = &sdm845_cx,
+       [SC7180_CX_AO] = &sdm845_cx_ao,
+       [SC7180_GFX] = &sdm845_gfx,
+       [SC7180_MX] = &sdm845_mx,
+       [SC7180_MX_AO] = &sdm845_mx_ao,
+       [SC7180_LMX] = &sdm845_lmx,
+       [SC7180_LCX] = &sdm845_lcx,
+       [SC7180_MSS] = &sdm845_mss,
+};
+
+static const struct rpmhpd_desc sc7180_desc = {
+       .rpmhpds = sc7180_rpmhpds,
+       .num_pds = ARRAY_SIZE(sc7180_rpmhpds),
+};
+
 static const struct of_device_id rpmhpd_match_table[] = {
+       { .compatible = "qcom,sc7180-rpmhpd", .data = &sc7180_desc },
        { .compatible = "qcom,sdm845-rpmhpd", .data = &sdm845_desc },
+       { .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc },
        { }
 };
 
index f93492b..ba2b8b5 100644 (file)
@@ -192,21 +192,25 @@ config ARCH_R8A774C0
        help
          This enables support for the Renesas RZ/G2E SoC.
 
+config ARCH_R8A77950
+       bool
+
+config ARCH_R8A77951
+       bool
+
 config ARCH_R8A7795
        bool "Renesas R-Car H3 SoC Platform"
+       select ARCH_R8A77950
+       select ARCH_R8A77951
        select ARCH_RCAR_GEN3
        select SYSC_R8A7795
        help
          This enables support for the Renesas R-Car H3 SoC.
 
 config ARCH_R8A77960
-       bool
+       bool "Renesas R-Car M3-W SoC Platform"
        select ARCH_RCAR_GEN3
        select SYSC_R8A77960
-
-config ARCH_R8A7796
-       bool "Renesas R-Car M3-W SoC Platform"
-       select ARCH_R8A77960
        help
          This enables support for the Renesas R-Car M3-W SoC.
 
index 14d05a0..2af2e0d 100644 (file)
@@ -21,7 +21,7 @@ static int rcar_rst_enable_wdt_reset(void __iomem *base)
 
 struct rst_config {
        unsigned int modemr;            /* Mode Monitoring Register Offset */
-       int (*configure)(void *base);   /* Platform specific configuration */
+       int (*configure)(void __iomem *base);   /* Platform specific config */
 };
 
 static const struct rst_config rcar_rst_gen1 __initconst = {
index 27fc59b..c7a2003 100644 (file)
@@ -1,6 +1,6 @@
 # SPDX-License-Identifier: GPL-2.0
 #
-# SAMSUNG SoC drivers
+# Samsung SoC drivers
 #
 menuconfig SOC_SAMSUNG
        bool "Samsung SoC driver support" if COMPILE_TEST
index b89c26a..2dad496 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *           http://www.samsung.com/
  *
- * EXYNOS - CHIP ID support
+ * Exynos - CHIP ID support
  * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
  * Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
  */
index d34ca20..17304fa 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2011-2014 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com/
 //
-// EXYNOS - CPU PMU(Power Management Unit) support
+// Exynos - CPU PMU(Power Management Unit) support
 
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -110,10 +110,8 @@ EXPORT_SYMBOL_GPL(exynos_get_pmu_regmap);
 static int exynos_pmu_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
-       struct resource *res;
 
-       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       pmu_base_addr = devm_ioremap_resource(dev, res);
+       pmu_base_addr = devm_platform_ioremap_resource(pdev, 0);
        if (IS_ERR(pmu_base_addr))
                return PTR_ERR(pmu_base_addr);
 
index 977e4da..5e851f3 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * Header for EXYNOS PMU Driver support
+ * Header for Exynos PMU Driver support
  */
 
 #ifndef __EXYNOS_PMU_H
index 275d348..30f230e 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2011-2015 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com/
 //
-// EXYNOS3250 - CPU PMU (Power Management Unit) support
+// Exynos3250 - CPU PMU (Power Management Unit) support
 
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
index a7cdbf1..cb35103 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2011-2015 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com/
 //
-// EXYNOS4 - CPU PMU(Power Management Unit) support
+// Exynos4 - CPU PMU(Power Management Unit) support
 
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
index 19b38e0..7a2d50b 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2011-2015 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com/
 //
-// EXYNOS5250 - CPU PMU (Power Management Unit) support
+// Exynos5250 - CPU PMU (Power Management Unit) support
 
 #include <linux/soc/samsung/exynos-regs-pmu.h>
 #include <linux/soc/samsung/exynos-pmu.h>
index b236d3b..6fedcd7 100644 (file)
@@ -3,7 +3,7 @@
 // Copyright (c) 2011-2015 Samsung Electronics Co., Ltd.
 //             http://www.samsung.com/
 //
-// EXYNOS5420 - CPU PMU (Power Management Unit) support
+// Exynos5420 - CPU PMU (Power Management Unit) support
 
 #include <linux/pm.h>
 #include <linux/soc/samsung/exynos-regs-pmu.h>
index 84bd615..3693532 100644 (file)
@@ -126,6 +126,7 @@ config SOC_TEGRA_FUSE
        def_bool y
        depends on ARCH_TEGRA
        select SOC_BUS
+       select TEGRA20_APB_DMA if ARCH_TEGRA_2x_SOC
 
 config SOC_TEGRA_FLOWCTRL
        bool
index 606abbe..802717b 100644 (file)
@@ -49,6 +49,9 @@ static struct tegra_fuse *fuse = &(struct tegra_fuse) {
 };
 
 static const struct of_device_id tegra_fuse_match[] = {
+#ifdef CONFIG_ARCH_TEGRA_194_SOC
+       { .compatible = "nvidia,tegra194-efuse", .data = &tegra194_fuse_soc },
+#endif
 #ifdef CONFIG_ARCH_TEGRA_186_SOC
        { .compatible = "nvidia,tegra186-efuse", .data = &tegra186_fuse_soc },
 #endif
index b8daaf5..f68f4e1 100644 (file)
@@ -320,3 +320,32 @@ const struct tegra_fuse_soc tegra186_fuse_soc = {
        .num_lookups = ARRAY_SIZE(tegra186_fuse_lookups),
 };
 #endif
+
+#if defined(CONFIG_ARCH_TEGRA_194_SOC)
+static const struct nvmem_cell_lookup tegra194_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 tegra194_fuse_info = {
+       .read = tegra30_fuse_read,
+       .size = 0x300,
+       .spare = 0x280,
+};
+
+const struct tegra_fuse_soc tegra194_fuse_soc = {
+       .init = tegra30_fuse_init,
+       .info = &tegra194_fuse_info,
+       .lookups = tegra194_fuse_lookups,
+       .num_lookups = ARRAY_SIZE(tegra194_fuse_lookups),
+};
+#endif
index 0f74c2c..94a059e 100644 (file)
@@ -108,4 +108,8 @@ extern const struct tegra_fuse_soc tegra210_fuse_soc;
 extern const struct tegra_fuse_soc tegra186_fuse_soc;
 #endif
 
+#ifdef CONFIG_ARCH_TEGRA_194_SOC
+extern const struct tegra_fuse_soc tegra194_fuse_soc;
+#endif
+
 #endif
index a2fd6cc..089d934 100644 (file)
 #define PMC_STRAPPING_OPT_A_RAM_CODE_MASK_SHORT        \
        (0x3 << PMC_STRAPPING_OPT_A_RAM_CODE_SHIFT)
 
-static void __iomem *apbmisc_base;
-static void __iomem *strapping_base;
 static bool long_ram_code;
+static u32 strapping;
+static u32 chipid;
 
 u32 tegra_read_chipid(void)
 {
-       if (!apbmisc_base) {
-               WARN(1, "Tegra Chip ID not yet available\n");
-               return 0;
-       }
+       WARN(!chipid, "Tegra ABP MISC not yet available\n");
 
-       return readl_relaxed(apbmisc_base + 4);
+       return chipid;
 }
 
 u8 tegra_get_chip_id(void)
@@ -42,10 +39,9 @@ u8 tegra_get_chip_id(void)
 
 u32 tegra_read_straps(void)
 {
-       if (strapping_base)
-               return readl_relaxed(strapping_base);
-       else
-               return 0;
+       WARN(!chipid, "Tegra ABP MISC not yet available\n");
+
+       return strapping;
 }
 
 u32 tegra_read_ram_code(void)
@@ -63,6 +59,7 @@ u32 tegra_read_ram_code(void)
 static const struct of_device_id apbmisc_match[] __initconst = {
        { .compatible = "nvidia,tegra20-apbmisc", },
        { .compatible = "nvidia,tegra186-misc", },
+       { .compatible = "nvidia,tegra194-misc", },
        {},
 };
 
@@ -103,6 +100,7 @@ void __init tegra_init_revision(void)
 
 void __init tegra_init_apbmisc(void)
 {
+       void __iomem *apbmisc_base, *strapping_base;
        struct resource apbmisc, straps;
        struct device_node *np;
 
@@ -123,7 +121,7 @@ void __init tegra_init_apbmisc(void)
                        apbmisc.flags = IORESOURCE_MEM;
 
                        /* strapping options */
-                       if (tegra_get_chip_id() == TEGRA124) {
+                       if (of_machine_is_compatible("nvidia,tegra124")) {
                                straps.start = 0x7000e864;
                                straps.end = 0x7000e867;
                        } else {
@@ -160,12 +158,20 @@ void __init tegra_init_apbmisc(void)
        }
 
        apbmisc_base = ioremap(apbmisc.start, resource_size(&apbmisc));
-       if (!apbmisc_base)
+       if (!apbmisc_base) {
                pr_err("failed to map APBMISC registers\n");
+       } else {
+               chipid = readl_relaxed(apbmisc_base + 4);
+               iounmap(apbmisc_base);
+       }
 
        strapping_base = ioremap(straps.start, resource_size(&straps));
-       if (!strapping_base)
+       if (!strapping_base) {
                pr_err("failed to map strapping options registers\n");
+       } else {
+               strapping = readl_relaxed(strapping_base);
+               iounmap(strapping_base);
+       }
 
        long_ram_code = of_property_read_bool(np, "nvidia,long-ram-code");
 }
index ea0eede..367a71a 100644 (file)
@@ -162,6 +162,9 @@ static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
                        core_target_uV = max(rtc_uV - max_spread, core_target_uV);
                }
 
+               if (core_uV == core_target_uV)
+                       goto update_rtc;
+
                err = regulator_set_voltage_rdev(core_rdev,
                                                 core_target_uV,
                                                 core_max_uV,
@@ -170,7 +173,7 @@ static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
                        return err;
 
                core_uV = core_target_uV;
-
+update_rtc:
                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);
@@ -179,6 +182,9 @@ static int tegra20_core_rtc_update(struct tegra_regulator_coupler *tegra,
                        rtc_target_uV = max(core_uV - max_spread, rtc_target_uV);
                }
 
+               if (rtc_uV == rtc_target_uV)
+                       continue;
+
                err = regulator_set_voltage_rdev(rtc_rdev,
                                                 rtc_target_uV,
                                                 rtc_max_uV,
index 8e623ff..7f21f31 100644 (file)
@@ -209,6 +209,9 @@ static int tegra30_voltage_update(struct tegra_regulator_coupler *tegra,
                        cpu_target_uV = max(core_uV - max_spread, cpu_target_uV);
                }
 
+               if (cpu_uV == cpu_target_uV)
+                       goto update_core;
+
                err = regulator_set_voltage_rdev(cpu_rdev,
                                                 cpu_target_uV,
                                                 cpu_max_uV,
@@ -231,6 +234,9 @@ update_core:
                        core_target_uV = max(core_target_uV, core_uV - core_max_step);
                }
 
+               if (core_uV == core_target_uV)
+                       continue;
+
                err = regulator_set_voltage_rdev(core_rdev,
                                                 core_target_uV,
                                                 core_max_uV,
index 1ccc906..37f3db6 100644 (file)
@@ -25,6 +25,8 @@
 
 static struct knav_device *kdev;
 static DEFINE_MUTEX(knav_dev_lock);
+#define knav_dev_lock_held() \
+       lockdep_is_held(&knav_dev_lock)
 
 /* Queue manager register indices in DTS */
 #define KNAV_QUEUE_PEEK_REG_INDEX      0
@@ -52,8 +54,9 @@ static DEFINE_MUTEX(knav_dev_lock);
 #define knav_queue_idx_to_inst(kdev, idx)                      \
        (kdev->instances + (idx << kdev->inst_shift))
 
-#define for_each_handle_rcu(qh, inst)                  \
-       list_for_each_entry_rcu(qh, &inst->handles, list)
+#define for_each_handle_rcu(qh, inst)                          \
+       list_for_each_entry_rcu(qh, &inst->handles, list,       \
+                               knav_dev_lock_held())
 
 #define for_each_instance(idx, inst, kdev)             \
        for (idx = 0, inst = kdev->instances;           \
index 01e76b5..223f1f9 100644 (file)
@@ -21,11 +21,15 @@ config ZYNQMP_POWER
        bool "Enable Xilinx Zynq MPSoC Power Management driver"
        depends on PM && ARCH_ZYNQMP
        default y
+       select MAILBOX
+       select ZYNQMP_IPI_MBOX
        help
          Say yes to enable power management support for ZyqnMP SoC.
          This driver uses firmware driver as an interface for power
          management request to firmware. It registers isr to handle
-         power management callbacks from firmware.
+         power management callbacks from firmware. It registers mailbox client
+         to handle power management callbacks from firmware.
+
          If in doubt, say N.
 
 config ZYNQMP_PM_DOMAINS
index 1b9d144..0922789 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Xilinx Zynq MPSoC Power Management
  *
- *  Copyright (C) 2014-2018 Xilinx, Inc.
+ *  Copyright (C) 2014-2019 Xilinx, Inc.
  *
  *  Davorin Mista <davorin.mista@aggios.com>
  *  Jolly Shah <jollys@xilinx.com>
 #include <linux/suspend.h>
 
 #include <linux/firmware/xlnx-zynqmp.h>
+#include <linux/mailbox/zynqmp-ipi-message.h>
+
+/**
+ * struct zynqmp_pm_work_struct - Wrapper for struct work_struct
+ * @callback_work:     Work structure
+ * @args:              Callback arguments
+ */
+struct zynqmp_pm_work_struct {
+       struct work_struct callback_work;
+       u32 args[CB_ARG_CNT];
+};
+
+static struct zynqmp_pm_work_struct *zynqmp_pm_init_suspend_work;
+static struct mbox_chan *rx_chan;
+static const struct zynqmp_eemi_ops *eemi_ops;
 
 enum pm_suspend_mode {
        PM_SUSPEND_MODE_FIRST = 0,
@@ -31,7 +46,6 @@ static const char *const suspend_modes[] = {
 };
 
 static enum pm_suspend_mode suspend_mode = PM_SUSPEND_MODE_STD;
-static const struct zynqmp_eemi_ops *eemi_ops;
 
 enum pm_api_cb_id {
        PM_INIT_SUSPEND_CB = 30,
@@ -68,6 +82,53 @@ static irqreturn_t zynqmp_pm_isr(int irq, void *data)
        return IRQ_HANDLED;
 }
 
+static void ipi_receive_callback(struct mbox_client *cl, void *data)
+{
+       struct zynqmp_ipi_message *msg = (struct zynqmp_ipi_message *)data;
+       u32 payload[CB_PAYLOAD_SIZE];
+       int ret;
+
+       memcpy(payload, msg->data, sizeof(msg->len));
+       /* First element is callback API ID, others are callback arguments */
+       if (payload[0] == PM_INIT_SUSPEND_CB) {
+               if (work_pending(&zynqmp_pm_init_suspend_work->callback_work))
+                       return;
+
+               /* Copy callback arguments into work's structure */
+               memcpy(zynqmp_pm_init_suspend_work->args, &payload[1],
+                      sizeof(zynqmp_pm_init_suspend_work->args));
+
+               queue_work(system_unbound_wq,
+                          &zynqmp_pm_init_suspend_work->callback_work);
+
+               /* Send NULL message to mbox controller to ack the message */
+               ret = mbox_send_message(rx_chan, NULL);
+               if (ret)
+                       pr_err("IPI ack failed. Error %d\n", ret);
+       }
+}
+
+/**
+ * zynqmp_pm_init_suspend_work_fn - Initialize suspend
+ * @work:      Pointer to work_struct
+ *
+ * Bottom-half of PM callback IRQ handler.
+ */
+static void zynqmp_pm_init_suspend_work_fn(struct work_struct *work)
+{
+       struct zynqmp_pm_work_struct *pm_work =
+               container_of(work, struct zynqmp_pm_work_struct, callback_work);
+
+       if (pm_work->args[0] == SUSPEND_SYSTEM_SHUTDOWN) {
+               orderly_poweroff(true);
+       } else if (pm_work->args[0] == SUSPEND_POWER_REQUEST) {
+               pm_suspend(PM_SUSPEND_MEM);
+       } else {
+               pr_err("%s Unsupported InitSuspendCb reason code %d.\n",
+                      __func__, pm_work->args[0]);
+       }
+}
+
 static ssize_t suspend_mode_show(struct device *dev,
                                 struct device_attribute *attr, char *buf)
 {
@@ -119,6 +180,7 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
 {
        int ret, irq;
        u32 pm_api_version;
+       struct mbox_client *client;
 
        eemi_ops = zynqmp_pm_get_eemi_ops();
        if (IS_ERR(eemi_ops))
@@ -134,17 +196,46 @@ static int zynqmp_pm_probe(struct platform_device *pdev)
        if (pm_api_version < ZYNQMP_PM_VERSION)
                return -ENODEV;
 
-       irq = platform_get_irq(pdev, 0);
-       if (irq <= 0)
-               return -ENXIO;
-
-       ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, zynqmp_pm_isr,
-                                       IRQF_NO_SUSPEND | IRQF_ONESHOT,
-                                       dev_name(&pdev->dev), &pdev->dev);
-       if (ret) {
-               dev_err(&pdev->dev, "devm_request_threaded_irq '%d' failed "
-                       "with %d\n", irq, ret);
-               return ret;
+       if (of_find_property(pdev->dev.of_node, "mboxes", NULL)) {
+               zynqmp_pm_init_suspend_work =
+                       devm_kzalloc(&pdev->dev,
+                                    sizeof(struct zynqmp_pm_work_struct),
+                                    GFP_KERNEL);
+               if (!zynqmp_pm_init_suspend_work)
+                       return -ENOMEM;
+
+               INIT_WORK(&zynqmp_pm_init_suspend_work->callback_work,
+                         zynqmp_pm_init_suspend_work_fn);
+               client = devm_kzalloc(&pdev->dev, sizeof(*client), GFP_KERNEL);
+               if (!client)
+                       return -ENOMEM;
+
+               client->dev = &pdev->dev;
+               client->rx_callback = ipi_receive_callback;
+
+               rx_chan = mbox_request_channel_byname(client, "rx");
+               if (IS_ERR(rx_chan)) {
+                       dev_err(&pdev->dev, "Failed to request rx channel\n");
+                       return IS_ERR(rx_chan);
+               }
+       } else if (of_find_property(pdev->dev.of_node, "interrupts", NULL)) {
+               irq = platform_get_irq(pdev, 0);
+               if (irq <= 0)
+                       return -ENXIO;
+
+               ret = devm_request_threaded_irq(&pdev->dev, irq, NULL,
+                                               zynqmp_pm_isr,
+                                               IRQF_NO_SUSPEND | IRQF_ONESHOT,
+                                               dev_name(&pdev->dev),
+                                               &pdev->dev);
+               if (ret) {
+                       dev_err(&pdev->dev, "devm_request_threaded_irq '%d' "
+                                           "failed with %d\n", irq, ret);
+                       return ret;
+               }
+       } else {
+               dev_err(&pdev->dev, "Required property not found in DT node\n");
+               return -ENOENT;
        }
 
        ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr);
@@ -160,6 +251,9 @@ static int zynqmp_pm_remove(struct platform_device *pdev)
 {
        sysfs_remove_file(&pdev->dev.kobj, &dev_attr_suspend_mode.attr);
 
+       if (!rx_chan)
+               mbox_free_channel(rx_chan);
+
        return 0;
 }
 
index c7266ef..1f59beb 100644 (file)
@@ -646,8 +646,7 @@ static int orion_spi_probe(struct platform_device *pdev)
 
        /* The following clock is only used by some SoCs */
        spi->axi_clk = devm_clk_get(&pdev->dev, "axi");
-       if (IS_ERR(spi->axi_clk) &&
-           PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) {
+       if (PTR_ERR(spi->axi_clk) == -EPROBE_DEFER) {
                status = -EPROBE_DEFER;
                goto out_rel_clk;
        }
index 4a6c3f6..aa9dab8 100644 (file)
@@ -264,12 +264,12 @@ static int open_debug_level(struct inode *inode, struct file *file)
        return single_open(file, show_debug_level, NULL);
 }
 
-static const struct file_operations fops = {
-       .open = open_debug_level,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .write = write_debug_level,
-       .release = single_release,
+static const struct proc_ops debug_level_proc_ops = {
+       .proc_open      = open_debug_level,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = write_debug_level,
+       .proc_release   = single_release,
 };
 
 int __init ieee80211_debug_init(void)
@@ -284,7 +284,7 @@ int __init ieee80211_debug_init(void)
                                " proc directory\n");
                return -EIO;
        }
-       e = proc_create("debug_level", 0644, ieee80211_proc, &fops);
+       e = proc_create("debug_level", 0644, ieee80211_proc, &debug_level_proc_ops);
        if (!e) {
                remove_proc_entry(DRV_NAME, init_net.proc_net);
                ieee80211_proc = NULL;
index b830e0a..99698b8 100644 (file)
@@ -534,13 +534,13 @@ static void optee_smccc_hvc(unsigned long a0, unsigned long a1,
        arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
 }
 
-static optee_invoke_fn *get_invoke_func(struct device_node *np)
+static optee_invoke_fn *get_invoke_func(struct device *dev)
 {
        const char *method;
 
-       pr_info("probing for conduit method from DT.\n");
+       pr_info("probing for conduit method.\n");
 
-       if (of_property_read_string(np, "method", &method)) {
+       if (device_property_read_string(dev, "method", &method)) {
                pr_warn("missing \"method\" property\n");
                return ERR_PTR(-ENXIO);
        }
@@ -554,7 +554,37 @@ static optee_invoke_fn *get_invoke_func(struct device_node *np)
        return ERR_PTR(-EINVAL);
 }
 
-static struct optee *optee_probe(struct device_node *np)
+static int optee_remove(struct platform_device *pdev)
+{
+       struct optee *optee = platform_get_drvdata(pdev);
+
+       /*
+        * Ask OP-TEE to free all cached shared memory objects to decrease
+        * reference counters and also avoid wild pointers in secure world
+        * into the old shared memory range.
+        */
+       optee_disable_shm_cache(optee);
+
+       /*
+        * The two devices have to be unregistered before we can free the
+        * other resources.
+        */
+       tee_device_unregister(optee->supp_teedev);
+       tee_device_unregister(optee->teedev);
+
+       tee_shm_pool_free(optee->pool);
+       if (optee->memremaped_shm)
+               memunmap(optee->memremaped_shm);
+       optee_wait_queue_exit(&optee->wait_queue);
+       optee_supp_uninit(&optee->supp);
+       mutex_destroy(&optee->call_queue.mutex);
+
+       kfree(optee);
+
+       return 0;
+}
+
+static int optee_probe(struct platform_device *pdev)
 {
        optee_invoke_fn *invoke_fn;
        struct tee_shm_pool *pool = ERR_PTR(-EINVAL);
@@ -564,25 +594,25 @@ static struct optee *optee_probe(struct device_node *np)
        u32 sec_caps;
        int rc;
 
-       invoke_fn = get_invoke_func(np);
+       invoke_fn = get_invoke_func(&pdev->dev);
        if (IS_ERR(invoke_fn))
-               return (void *)invoke_fn;
+               return PTR_ERR(invoke_fn);
 
        if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
                pr_warn("api uid mismatch\n");
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
 
        optee_msg_get_os_revision(invoke_fn);
 
        if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
                pr_warn("api revision mismatch\n");
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
 
        if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
                pr_warn("capabilities mismatch\n");
-               return ERR_PTR(-EINVAL);
+               return -EINVAL;
        }
 
        /*
@@ -598,7 +628,7 @@ static struct optee *optee_probe(struct device_node *np)
                pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
 
        if (IS_ERR(pool))
-               return (void *)pool;
+               return PTR_ERR(pool);
 
        optee = kzalloc(sizeof(*optee), GFP_KERNEL);
        if (!optee) {
@@ -643,7 +673,16 @@ 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");
 
-       return optee;
+       platform_set_drvdata(pdev, optee);
+
+       rc = optee_enumerate_devices();
+       if (rc) {
+               optee_remove(pdev);
+               return rc;
+       }
+
+       pr_info("initialized driver\n");
+       return 0;
 err:
        if (optee) {
                /*
@@ -659,92 +698,28 @@ err:
                tee_shm_pool_free(pool);
        if (memremaped_shm)
                memunmap(memremaped_shm);
-       return ERR_PTR(rc);
-}
-
-static void optee_remove(struct optee *optee)
-{
-       /*
-        * Ask OP-TEE to free all cached shared memory objects to decrease
-        * reference counters and also avoid wild pointers in secure world
-        * into the old shared memory range.
-        */
-       optee_disable_shm_cache(optee);
-
-       /*
-        * The two devices has to be unregistered before we can free the
-        * other resources.
-        */
-       tee_device_unregister(optee->supp_teedev);
-       tee_device_unregister(optee->teedev);
-
-       tee_shm_pool_free(optee->pool);
-       if (optee->memremaped_shm)
-               memunmap(optee->memremaped_shm);
-       optee_wait_queue_exit(&optee->wait_queue);
-       optee_supp_uninit(&optee->supp);
-       mutex_destroy(&optee->call_queue.mutex);
-
-       kfree(optee);
+       return rc;
 }
 
-static const struct of_device_id optee_match[] = {
+static const struct of_device_id optee_dt_match[] = {
        { .compatible = "linaro,optee-tz" },
        {},
 };
-
-static struct optee *optee_svc;
-
-static int __init optee_driver_init(void)
-{
-       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");
-       if (!fw_np)
-               return -ENODEV;
-
-       np = of_find_matching_node(fw_np, optee_match);
-       if (!np || !of_device_is_available(np)) {
-               of_node_put(np);
-               return -ENODEV;
-       }
-
-       optee = optee_probe(np);
-       of_node_put(np);
-
-       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;
-}
-module_init(optee_driver_init);
-
-static void __exit optee_driver_exit(void)
-{
-       struct optee *optee = optee_svc;
-
-       optee_svc = NULL;
-       if (optee)
-               optee_remove(optee);
-}
-module_exit(optee_driver_exit);
+MODULE_DEVICE_TABLE(of, optee_dt_match);
+
+static struct platform_driver optee_driver = {
+       .probe  = optee_probe,
+       .remove = optee_remove,
+       .driver = {
+               .name = "optee",
+               .of_match_table = optee_dt_match,
+       },
+};
+module_platform_driver(optee_driver);
 
 MODULE_AUTHOR("Linaro");
 MODULE_DESCRIPTION("OP-TEE driver");
 MODULE_SUPPORTED_DEVICE("");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:optee");
index 4c405f1..d5a39e1 100644 (file)
@@ -47,7 +47,7 @@ static int serial8250_ioc3_probe(struct platform_device *pdev)
        if (!data)
                return -ENOMEM;
 
-       membase = devm_ioremap_nocache(&pdev->dev, r->start, resource_size(r));
+       membase = devm_ioremap(&pdev->dev, r->start, resource_size(r));
        if (!membase)
                return -ENOMEM;
 
index 2e151a4..3c8c662 100644 (file)
 #include <soc/fsl/qe/ucc_slow.h>
 
 #include <linux/firmware.h>
-#include <asm/reg.h>
+#include <soc/fsl/cpm.h>
+
+#ifdef CONFIG_PPC32
+#include <asm/reg.h> /* mfspr, SPRN_SVR */
+#endif
 
 /*
  * The GUMR flag for Soft UART.  This would normally be defined in qe.h,
@@ -257,11 +261,11 @@ static unsigned int qe_uart_tx_empty(struct uart_port *port)
        struct qe_bd *bdp = qe_port->tx_bd_base;
 
        while (1) {
-               if (in_be16(&bdp->status) & BD_SC_READY)
+               if (qe_ioread16be(&bdp->status) & BD_SC_READY)
                        /* This BD is not done, so return "not done" */
                        return 0;
 
-               if (in_be16(&bdp->status) & BD_SC_WRAP)
+               if (qe_ioread16be(&bdp->status) & BD_SC_WRAP)
                        /*
                         * This BD is done and it's the last one, so return
                         * "done"
@@ -307,7 +311,7 @@ static void qe_uart_stop_tx(struct uart_port *port)
        struct uart_qe_port *qe_port =
                container_of(port, struct uart_qe_port, port);
 
-       clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX);
+       qe_clrbits_be16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX);
 }
 
 /*
@@ -337,13 +341,13 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
                /* Pick next descriptor and fill from buffer */
                bdp = qe_port->tx_cur;
 
-               p = qe2cpu_addr(bdp->buf, qe_port);
+               p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
 
                *p++ = port->x_char;
-               out_be16(&bdp->length, 1);
-               setbits16(&bdp->status, BD_SC_READY);
+               qe_iowrite16be(1, &bdp->length);
+               qe_setbits_be16(&bdp->status, BD_SC_READY);
                /* Get next BD. */
-               if (in_be16(&bdp->status) & BD_SC_WRAP)
+               if (qe_ioread16be(&bdp->status) & BD_SC_WRAP)
                        bdp = qe_port->tx_bd_base;
                else
                        bdp++;
@@ -362,10 +366,10 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
        /* Pick next descriptor and fill from buffer */
        bdp = qe_port->tx_cur;
 
-       while (!(in_be16(&bdp->status) & BD_SC_READY) &&
+       while (!(qe_ioread16be(&bdp->status) & BD_SC_READY) &&
               (xmit->tail != xmit->head)) {
                count = 0;
-               p = qe2cpu_addr(bdp->buf, qe_port);
+               p = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
                while (count < qe_port->tx_fifosize) {
                        *p++ = xmit->buf[xmit->tail];
                        xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
@@ -375,11 +379,11 @@ static int qe_uart_tx_pump(struct uart_qe_port *qe_port)
                                break;
                }
 
-               out_be16(&bdp->length, count);
-               setbits16(&bdp->status, BD_SC_READY);
+               qe_iowrite16be(count, &bdp->length);
+               qe_setbits_be16(&bdp->status, BD_SC_READY);
 
                /* Get next BD. */
-               if (in_be16(&bdp->status) & BD_SC_WRAP)
+               if (qe_ioread16be(&bdp->status) & BD_SC_WRAP)
                        bdp = qe_port->tx_bd_base;
                else
                        bdp++;
@@ -412,12 +416,12 @@ static void qe_uart_start_tx(struct uart_port *port)
                container_of(port, struct uart_qe_port, port);
 
        /* If we currently are transmitting, then just return */
-       if (in_be16(&qe_port->uccp->uccm) & UCC_UART_UCCE_TX)
+       if (qe_ioread16be(&qe_port->uccp->uccm) & UCC_UART_UCCE_TX)
                return;
 
        /* Otherwise, pump the port and start transmission */
        if (qe_uart_tx_pump(qe_port))
-               setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX);
+               qe_setbits_be16(&qe_port->uccp->uccm, UCC_UART_UCCE_TX);
 }
 
 /*
@@ -428,7 +432,7 @@ static void qe_uart_stop_rx(struct uart_port *port)
        struct uart_qe_port *qe_port =
                container_of(port, struct uart_qe_port, port);
 
-       clrbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX);
+       qe_clrbits_be16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX);
 }
 
 /* Start or stop sending  break signal
@@ -467,14 +471,14 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
         */
        bdp = qe_port->rx_cur;
        while (1) {
-               status = in_be16(&bdp->status);
+               status = qe_ioread16be(&bdp->status);
 
                /* If this one is empty, then we assume we've read them all */
                if (status & BD_SC_EMPTY)
                        break;
 
                /* get number of characters, and check space in RX buffer */
-               i = in_be16(&bdp->length);
+               i = qe_ioread16be(&bdp->length);
 
                /* If we don't have enough room in RX buffer for the entire BD,
                 * then we try later, which will be the next RX interrupt.
@@ -485,7 +489,7 @@ static void qe_uart_int_rx(struct uart_qe_port *qe_port)
                }
 
                /* get pointer */
-               cp = qe2cpu_addr(bdp->buf, qe_port);
+               cp = qe2cpu_addr(be32_to_cpu(bdp->buf), qe_port);
 
                /* loop through the buffer */
                while (i-- > 0) {
@@ -505,9 +509,10 @@ error_return:
                }
 
                /* This BD is ready to be used again. Clear status. get next */
-               clrsetbits_be16(&bdp->status, BD_SC_BR | BD_SC_FR | BD_SC_PR |
-                       BD_SC_OV | BD_SC_ID, BD_SC_EMPTY);
-               if (in_be16(&bdp->status) & BD_SC_WRAP)
+               qe_clrsetbits_be16(&bdp->status,
+                                  BD_SC_BR | BD_SC_FR | BD_SC_PR | BD_SC_OV | BD_SC_ID,
+                                  BD_SC_EMPTY);
+               if (qe_ioread16be(&bdp->status) & BD_SC_WRAP)
                        bdp = qe_port->rx_bd_base;
                else
                        bdp++;
@@ -564,8 +569,8 @@ static irqreturn_t qe_uart_int(int irq, void *data)
        u16 events;
 
        /* Clear the interrupts */
-       events = in_be16(&uccp->ucce);
-       out_be16(&uccp->ucce, events);
+       events = qe_ioread16be(&uccp->ucce);
+       qe_iowrite16be(events, &uccp->ucce);
 
        if (events & UCC_UART_UCCE_BRKE)
                uart_handle_break(&qe_port->port);
@@ -596,17 +601,17 @@ static void qe_uart_initbd(struct uart_qe_port *qe_port)
        bdp = qe_port->rx_bd_base;
        qe_port->rx_cur = qe_port->rx_bd_base;
        for (i = 0; i < (qe_port->rx_nrfifos - 1); i++) {
-               out_be16(&bdp->status, BD_SC_EMPTY | BD_SC_INTRPT);
-               out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
-               out_be16(&bdp->length, 0);
+               qe_iowrite16be(BD_SC_EMPTY | BD_SC_INTRPT, &bdp->status);
+               qe_iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf);
+               qe_iowrite16be(0, &bdp->length);
                bd_virt += qe_port->rx_fifosize;
                bdp++;
        }
 
        /* */
-       out_be16(&bdp->status, BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT);
-       out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
-       out_be16(&bdp->length, 0);
+       qe_iowrite16be(BD_SC_WRAP | BD_SC_EMPTY | BD_SC_INTRPT, &bdp->status);
+       qe_iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf);
+       qe_iowrite16be(0, &bdp->length);
 
        /* Set the physical address of the host memory
         * buffers in the buffer descriptors, and the
@@ -617,21 +622,21 @@ static void qe_uart_initbd(struct uart_qe_port *qe_port)
        qe_port->tx_cur = qe_port->tx_bd_base;
        bdp = qe_port->tx_bd_base;
        for (i = 0; i < (qe_port->tx_nrfifos - 1); i++) {
-               out_be16(&bdp->status, BD_SC_INTRPT);
-               out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
-               out_be16(&bdp->length, 0);
+               qe_iowrite16be(BD_SC_INTRPT, &bdp->status);
+               qe_iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf);
+               qe_iowrite16be(0, &bdp->length);
                bd_virt += qe_port->tx_fifosize;
                bdp++;
        }
 
        /* Loopback requires the preamble bit to be set on the first TX BD */
 #ifdef LOOPBACK
-       setbits16(&qe_port->tx_cur->status, BD_SC_P);
+       qe_setbits_be16(&qe_port->tx_cur->status, BD_SC_P);
 #endif
 
-       out_be16(&bdp->status, BD_SC_WRAP | BD_SC_INTRPT);
-       out_be32(&bdp->buf, cpu2qe_addr(bd_virt, qe_port));
-       out_be16(&bdp->length, 0);
+       qe_iowrite16be(BD_SC_WRAP | BD_SC_INTRPT, &bdp->status);
+       qe_iowrite32be(cpu2qe_addr(bd_virt, qe_port), &bdp->buf);
+       qe_iowrite16be(0, &bdp->length);
 }
 
 /*
@@ -653,78 +658,74 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
        ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX);
 
        /* Program the UCC UART parameter RAM */
-       out_8(&uccup->common.rbmr, UCC_BMR_GBL | UCC_BMR_BO_BE);
-       out_8(&uccup->common.tbmr, UCC_BMR_GBL | UCC_BMR_BO_BE);
-       out_be16(&uccup->common.mrblr, qe_port->rx_fifosize);
-       out_be16(&uccup->maxidl, 0x10);
-       out_be16(&uccup->brkcr, 1);
-       out_be16(&uccup->parec, 0);
-       out_be16(&uccup->frmec, 0);
-       out_be16(&uccup->nosec, 0);
-       out_be16(&uccup->brkec, 0);
-       out_be16(&uccup->uaddr[0], 0);
-       out_be16(&uccup->uaddr[1], 0);
-       out_be16(&uccup->toseq, 0);
+       qe_iowrite8(UCC_BMR_GBL | UCC_BMR_BO_BE, &uccup->common.rbmr);
+       qe_iowrite8(UCC_BMR_GBL | UCC_BMR_BO_BE, &uccup->common.tbmr);
+       qe_iowrite16be(qe_port->rx_fifosize, &uccup->common.mrblr);
+       qe_iowrite16be(0x10, &uccup->maxidl);
+       qe_iowrite16be(1, &uccup->brkcr);
+       qe_iowrite16be(0, &uccup->parec);
+       qe_iowrite16be(0, &uccup->frmec);
+       qe_iowrite16be(0, &uccup->nosec);
+       qe_iowrite16be(0, &uccup->brkec);
+       qe_iowrite16be(0, &uccup->uaddr[0]);
+       qe_iowrite16be(0, &uccup->uaddr[1]);
+       qe_iowrite16be(0, &uccup->toseq);
        for (i = 0; i < 8; i++)
-               out_be16(&uccup->cchars[i], 0xC000);
-       out_be16(&uccup->rccm, 0xc0ff);
+               qe_iowrite16be(0xC000, &uccup->cchars[i]);
+       qe_iowrite16be(0xc0ff, &uccup->rccm);
 
        /* Configure the GUMR registers for UART */
        if (soft_uart) {
                /* Soft-UART requires a 1X multiplier for TX */
-               clrsetbits_be32(&uccp->gumr_l,
-                       UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
-                       UCC_SLOW_GUMR_L_RDCR_MASK,
-                       UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 |
-                       UCC_SLOW_GUMR_L_RDCR_16);
-
-               clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW,
-                       UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX);
+               qe_clrsetbits_be32(&uccp->gumr_l,
+                                  UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | UCC_SLOW_GUMR_L_RDCR_MASK,
+                                  UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_1 | UCC_SLOW_GUMR_L_RDCR_16);
+
+               qe_clrsetbits_be32(&uccp->gumr_h, UCC_SLOW_GUMR_H_RFW,
+                                  UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX);
        } else {
-               clrsetbits_be32(&uccp->gumr_l,
-                       UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
-                       UCC_SLOW_GUMR_L_RDCR_MASK,
-                       UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 |
-                       UCC_SLOW_GUMR_L_RDCR_16);
-
-               clrsetbits_be32(&uccp->gumr_h,
-                       UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX,
-                       UCC_SLOW_GUMR_H_RFW);
+               qe_clrsetbits_be32(&uccp->gumr_l,
+                                  UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | UCC_SLOW_GUMR_L_RDCR_MASK,
+                                  UCC_SLOW_GUMR_L_MODE_UART | UCC_SLOW_GUMR_L_TDCR_16 | UCC_SLOW_GUMR_L_RDCR_16);
+
+               qe_clrsetbits_be32(&uccp->gumr_h,
+                                  UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX,
+                                  UCC_SLOW_GUMR_H_RFW);
        }
 
 #ifdef LOOPBACK
-       clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK,
-               UCC_SLOW_GUMR_L_DIAG_LOOP);
-       clrsetbits_be32(&uccp->gumr_h,
-               UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_RSYN,
-               UCC_SLOW_GUMR_H_CDS);
+       qe_clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK,
+                          UCC_SLOW_GUMR_L_DIAG_LOOP);
+       qe_clrsetbits_be32(&uccp->gumr_h,
+                          UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_RSYN,
+                          UCC_SLOW_GUMR_H_CDS);
 #endif
 
        /* Disable rx interrupts  and clear all pending events.  */
-       out_be16(&uccp->uccm, 0);
-       out_be16(&uccp->ucce, 0xffff);
-       out_be16(&uccp->udsr, 0x7e7e);
+       qe_iowrite16be(0, &uccp->uccm);
+       qe_iowrite16be(0xffff, &uccp->ucce);
+       qe_iowrite16be(0x7e7e, &uccp->udsr);
 
        /* Initialize UPSMR */
-       out_be16(&uccp->upsmr, 0);
+       qe_iowrite16be(0, &uccp->upsmr);
 
        if (soft_uart) {
-               out_be16(&uccup->supsmr, 0x30);
-               out_be16(&uccup->res92, 0);
-               out_be32(&uccup->rx_state, 0);
-               out_be32(&uccup->rx_cnt, 0);
-               out_8(&uccup->rx_bitmark, 0);
-               out_8(&uccup->rx_length, 10);
-               out_be32(&uccup->dump_ptr, 0x4000);
-               out_8(&uccup->rx_temp_dlst_qe, 0);
-               out_be32(&uccup->rx_frame_rem, 0);
-               out_8(&uccup->rx_frame_rem_size, 0);
+               qe_iowrite16be(0x30, &uccup->supsmr);
+               qe_iowrite16be(0, &uccup->res92);
+               qe_iowrite32be(0, &uccup->rx_state);
+               qe_iowrite32be(0, &uccup->rx_cnt);
+               qe_iowrite8(0, &uccup->rx_bitmark);
+               qe_iowrite8(10, &uccup->rx_length);
+               qe_iowrite32be(0x4000, &uccup->dump_ptr);
+               qe_iowrite8(0, &uccup->rx_temp_dlst_qe);
+               qe_iowrite32be(0, &uccup->rx_frame_rem);
+               qe_iowrite8(0, &uccup->rx_frame_rem_size);
                /* Soft-UART requires TX to be 1X */
-               out_8(&uccup->tx_mode,
-                       UCC_UART_TX_STATE_UART | UCC_UART_TX_STATE_X1);
-               out_be16(&uccup->tx_state, 0);
-               out_8(&uccup->resD4, 0);
-               out_be16(&uccup->resD5, 0);
+               qe_iowrite8(UCC_UART_TX_STATE_UART | UCC_UART_TX_STATE_X1,
+                           &uccup->tx_mode);
+               qe_iowrite16be(0, &uccup->tx_state);
+               qe_iowrite8(0, &uccup->resD4);
+               qe_iowrite16be(0, &uccup->resD5);
 
                /* Set UART mode.
                 * Enable receive and transmit.
@@ -738,22 +739,19 @@ static void qe_uart_init_ucc(struct uart_qe_port *qe_port)
                 * ...
                 * 6.Receiver must use 16x over sampling
                 */
-               clrsetbits_be32(&uccp->gumr_l,
-                       UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK |
-                       UCC_SLOW_GUMR_L_RDCR_MASK,
-                       UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_16 |
-                       UCC_SLOW_GUMR_L_RDCR_16);
+               qe_clrsetbits_be32(&uccp->gumr_l,
+                                  UCC_SLOW_GUMR_L_MODE_MASK | UCC_SLOW_GUMR_L_TDCR_MASK | UCC_SLOW_GUMR_L_RDCR_MASK,
+                                  UCC_SLOW_GUMR_L_MODE_QMC | UCC_SLOW_GUMR_L_TDCR_16 | UCC_SLOW_GUMR_L_RDCR_16);
 
-               clrsetbits_be32(&uccp->gumr_h,
-                       UCC_SLOW_GUMR_H_RFW | UCC_SLOW_GUMR_H_RSYN,
-                       UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX |
-                       UCC_SLOW_GUMR_H_TTX | UCC_SLOW_GUMR_H_TFL);
+               qe_clrsetbits_be32(&uccp->gumr_h,
+                                  UCC_SLOW_GUMR_H_RFW | UCC_SLOW_GUMR_H_RSYN,
+                                  UCC_SLOW_GUMR_H_SUART | UCC_SLOW_GUMR_H_TRX | UCC_SLOW_GUMR_H_TTX | UCC_SLOW_GUMR_H_TFL);
 
 #ifdef LOOPBACK
-               clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK,
-                               UCC_SLOW_GUMR_L_DIAG_LOOP);
-               clrbits32(&uccp->gumr_h, UCC_SLOW_GUMR_H_CTSP |
-                         UCC_SLOW_GUMR_H_CDS);
+               qe_clrsetbits_be32(&uccp->gumr_l, UCC_SLOW_GUMR_L_DIAG_MASK,
+                                  UCC_SLOW_GUMR_L_DIAG_LOOP);
+               qe_clrbits_be32(&uccp->gumr_h,
+                               UCC_SLOW_GUMR_H_CTSP | UCC_SLOW_GUMR_H_CDS);
 #endif
 
                cecr_subblock = ucc_slow_get_qe_cr_subblock(qe_port->ucc_num);
@@ -796,7 +794,7 @@ static int qe_uart_startup(struct uart_port *port)
        }
 
        /* Startup rx-int */
-       setbits16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX);
+       qe_setbits_be16(&qe_port->uccp->uccm, UCC_UART_UCCE_RX);
        ucc_slow_enable(qe_port->us_private, COMM_DIR_RX_AND_TX);
 
        return 0;
@@ -832,7 +830,7 @@ static void qe_uart_shutdown(struct uart_port *port)
 
        /* Stop uarts */
        ucc_slow_disable(qe_port->us_private, COMM_DIR_RX_AND_TX);
-       clrbits16(&uccp->uccm, UCC_UART_UCCE_TX | UCC_UART_UCCE_RX);
+       qe_clrbits_be16(&uccp->uccm, UCC_UART_UCCE_TX | UCC_UART_UCCE_RX);
 
        /* Shut them really down and reinit buffer descriptors */
        ucc_slow_graceful_stop_tx(qe_port->us_private);
@@ -852,9 +850,9 @@ static void qe_uart_set_termios(struct uart_port *port,
        struct ucc_slow __iomem *uccp = qe_port->uccp;
        unsigned int baud;
        unsigned long flags;
-       u16 upsmr = in_be16(&uccp->upsmr);
+       u16 upsmr = qe_ioread16be(&uccp->upsmr);
        struct ucc_uart_pram __iomem *uccup = qe_port->uccup;
-       u16 supsmr = in_be16(&uccup->supsmr);
+       u16 supsmr = qe_ioread16be(&uccup->supsmr);
        u8 char_length = 2; /* 1 + CL + PEN + 1 + SL */
 
        /* Character length programmed into the mode register is the
@@ -952,10 +950,10 @@ static void qe_uart_set_termios(struct uart_port *port,
        /* Update the per-port timeout. */
        uart_update_timeout(port, termios->c_cflag, baud);
 
-       out_be16(&uccp->upsmr, upsmr);
+       qe_iowrite16be(upsmr, &uccp->upsmr);
        if (soft_uart) {
-               out_be16(&uccup->supsmr, supsmr);
-               out_8(&uccup->rx_length, char_length);
+               qe_iowrite16be(supsmr, &uccup->supsmr);
+               qe_iowrite8(char_length, &uccup->rx_length);
 
                /* Soft-UART requires a 1X multiplier for TX */
                qe_setbrg(qe_port->us_info.rx_clock, baud, 16);
@@ -1097,6 +1095,8 @@ static const struct uart_ops qe_uart_pops = {
        .verify_port    = qe_uart_verify_port,
 };
 
+
+#ifdef CONFIG_PPC32
 /*
  * Obtain the SOC model number and revision level
  *
@@ -1184,70 +1184,86 @@ static void uart_firmware_cont(const struct firmware *fw, void *context)
        release_firmware(fw);
 }
 
-static int ucc_uart_probe(struct platform_device *ofdev)
+static int soft_uart_init(struct platform_device *ofdev)
 {
        struct device_node *np = ofdev->dev.of_node;
-       const unsigned int *iprop;      /* Integer OF properties */
-       const char *sprop;      /* String OF properties */
-       struct uart_qe_port *qe_port = NULL;
-       struct resource res;
+       struct qe_firmware_info *qe_fw_info;
        int ret;
 
-       /*
-        * Determine if we need Soft-UART mode
-        */
        if (of_find_property(np, "soft-uart", NULL)) {
                dev_dbg(&ofdev->dev, "using Soft-UART mode\n");
                soft_uart = 1;
+       } else {
+               return 0;
        }
 
-       /*
-        * If we are using Soft-UART, determine if we need to upload the
-        * firmware, too.
-        */
-       if (soft_uart) {
-               struct qe_firmware_info *qe_fw_info;
-
-               qe_fw_info = qe_get_firmware_info();
-
-               /* Check if the firmware has been uploaded. */
-               if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) {
-                       firmware_loaded = 1;
-               } else {
-                       char filename[32];
-                       unsigned int soc;
-                       unsigned int rev_h;
-                       unsigned int rev_l;
-
-                       soc = soc_info(&rev_h, &rev_l);
-                       if (!soc) {
-                               dev_err(&ofdev->dev, "unknown CPU model\n");
-                               return -ENXIO;
-                       }
-                       sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin",
-                               soc, rev_h, rev_l);
-
-                       dev_info(&ofdev->dev, "waiting for firmware %s\n",
-                               filename);
+       qe_fw_info = qe_get_firmware_info();
 
-                       /*
-                        * We call request_firmware_nowait instead of
-                        * request_firmware so that the driver can load and
-                        * initialize the ports without holding up the rest of
-                        * the kernel.  If hotplug support is enabled in the
-                        * kernel, then we use it.
-                        */
-                       ret = request_firmware_nowait(THIS_MODULE,
-                               FW_ACTION_HOTPLUG, filename, &ofdev->dev,
-                               GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
-                       if (ret) {
-                               dev_err(&ofdev->dev,
-                                       "could not load firmware %s\n",
-                                       filename);
-                               return ret;
-                       }
+       /* Check if the firmware has been uploaded. */
+       if (qe_fw_info && strstr(qe_fw_info->id, "Soft-UART")) {
+               firmware_loaded = 1;
+       } else {
+               char filename[32];
+               unsigned int soc;
+               unsigned int rev_h;
+               unsigned int rev_l;
+
+               soc = soc_info(&rev_h, &rev_l);
+               if (!soc) {
+                       dev_err(&ofdev->dev, "unknown CPU model\n");
+                       return -ENXIO;
+               }
+               sprintf(filename, "fsl_qe_ucode_uart_%u_%u%u.bin",
+                       soc, rev_h, rev_l);
+
+               dev_info(&ofdev->dev, "waiting for firmware %s\n",
+                        filename);
+
+               /*
+                * We call request_firmware_nowait instead of
+                * request_firmware so that the driver can load and
+                * initialize the ports without holding up the rest of
+                * the kernel.  If hotplug support is enabled in the
+                * kernel, then we use it.
+                */
+               ret = request_firmware_nowait(THIS_MODULE,
+                                             FW_ACTION_HOTPLUG, filename, &ofdev->dev,
+                                             GFP_KERNEL, &ofdev->dev, uart_firmware_cont);
+               if (ret) {
+                       dev_err(&ofdev->dev,
+                               "could not load firmware %s\n",
+                               filename);
+                       return ret;
                }
        }
+       return 0;
+}
+
+#else /* !CONFIG_PPC32 */
+
+static int soft_uart_init(struct platform_device *ofdev)
+{
+       return 0;
+}
+
+#endif
+
+
+static int ucc_uart_probe(struct platform_device *ofdev)
+{
+       struct device_node *np = ofdev->dev.of_node;
+       const char *sprop;      /* String OF properties */
+       struct uart_qe_port *qe_port = NULL;
+       struct resource res;
+       u32 val;
+       int ret;
+
+       /*
+        * Determine if we need Soft-UART mode
+        */
+       ret = soft_uart_init(ofdev);
+       if (ret)
+               return ret;
 
        qe_port = kzalloc(sizeof(struct uart_qe_port), GFP_KERNEL);
        if (!qe_port) {
@@ -1270,23 +1286,20 @@ static int ucc_uart_probe(struct platform_device *ofdev)
 
        /* Get the UCC number (device ID) */
        /* UCCs are numbered 1-7 */
-       iprop = of_get_property(np, "cell-index", NULL);
-       if (!iprop) {
-               iprop = of_get_property(np, "device-id", NULL);
-               if (!iprop) {
-                       dev_err(&ofdev->dev, "UCC is unspecified in "
-                               "device tree\n");
+       if (of_property_read_u32(np, "cell-index", &val)) {
+               if (of_property_read_u32(np, "device-id", &val)) {
+                       dev_err(&ofdev->dev, "UCC is unspecified in device tree\n");
                        ret = -EINVAL;
                        goto out_free;
                }
        }
 
-       if ((*iprop < 1) || (*iprop > UCC_MAX_NUM)) {
-               dev_err(&ofdev->dev, "no support for UCC%u\n", *iprop);
+       if (val < 1 || val > UCC_MAX_NUM) {
+               dev_err(&ofdev->dev, "no support for UCC%u\n", val);
                ret = -ENODEV;
                goto out_free;
        }
-       qe_port->ucc_num = *iprop - 1;
+       qe_port->ucc_num = val - 1;
 
        /*
         * In the future, we should not require the BRG to be specified in the
@@ -1330,13 +1343,12 @@ static int ucc_uart_probe(struct platform_device *ofdev)
        }
 
        /* Get the port number, numbered 0-3 */
-       iprop = of_get_property(np, "port-number", NULL);
-       if (!iprop) {
+       if (of_property_read_u32(np, "port-number", &val)) {
                dev_err(&ofdev->dev, "missing port-number in device tree\n");
                ret = -EINVAL;
                goto out_free;
        }
-       qe_port->port.line = *iprop;
+       qe_port->port.line = val;
        if (qe_port->port.line >= UCC_MAX_UART) {
                dev_err(&ofdev->dev, "port-number must be 0-%u\n",
                        UCC_MAX_UART - 1);
@@ -1366,31 +1378,36 @@ static int ucc_uart_probe(struct platform_device *ofdev)
                }
        }
 
-       iprop = of_get_property(np, "brg-frequency", NULL);
-       if (!iprop) {
+       if (of_property_read_u32(np, "brg-frequency", &val)) {
                dev_err(&ofdev->dev,
                       "missing brg-frequency in device tree\n");
                ret = -EINVAL;
                goto out_np;
        }
 
-       if (*iprop)
-               qe_port->port.uartclk = *iprop;
+       if (val)
+               qe_port->port.uartclk = val;
        else {
+               if (!IS_ENABLED(CONFIG_PPC32)) {
+                       dev_err(&ofdev->dev,
+                               "invalid brg-frequency in device tree\n");
+                       ret = -EINVAL;
+                       goto out_np;
+               }
+
                /*
                 * Older versions of U-Boot do not initialize the brg-frequency
                 * property, so in this case we assume the BRG frequency is
                 * half the QE bus frequency.
                 */
-               iprop = of_get_property(np, "bus-frequency", NULL);
-               if (!iprop) {
+               if (of_property_read_u32(np, "bus-frequency", &val)) {
                        dev_err(&ofdev->dev,
                                "missing QE bus-frequency in device tree\n");
                        ret = -EINVAL;
                        goto out_np;
                }
-               if (*iprop)
-                       qe_port->port.uartclk = *iprop / 2;
+               if (val)
+                       qe_port->port.uartclk = val / 2;
                else {
                        dev_err(&ofdev->dev,
                                "invalid QE bus-frequency in device tree\n");
index 1d4f317..f724962 100644 (file)
@@ -1101,15 +1101,15 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct file_operations proc_sysrq_trigger_operations = {
-       .write          = write_sysrq_trigger,
-       .llseek         = noop_llseek,
+static const struct proc_ops sysrq_trigger_proc_ops = {
+       .proc_write     = write_sysrq_trigger,
+       .proc_lseek     = noop_llseek,
 };
 
 static void sysrq_init_procfs(void)
 {
        if (!proc_create("sysrq-trigger", S_IWUSR, NULL,
-                        &proc_sysrq_trigger_operations))
+                        &sysrq_trigger_proc_ops))
                pr_err("Failed to register proc interface\n");
 }
 
index 6f8b67e..6171d28 100644 (file)
@@ -1488,7 +1488,7 @@ enum {
        Opt_gid,
 };
 
-static const struct fs_parameter_spec ffs_fs_param_specs[] = {
+static const struct fs_parameter_spec ffs_fs_fs_parameters[] = {
        fsparam_bool    ("no_disconnect",       Opt_no_disconnect),
        fsparam_u32     ("rmode",               Opt_rmode),
        fsparam_u32     ("fmode",               Opt_fmode),
@@ -1498,11 +1498,6 @@ static const struct fs_parameter_spec ffs_fs_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description ffs_fs_fs_parameters = {
-       .name           = "kAFS",
-       .specs          = ffs_fs_param_specs,
-};
-
 static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct ffs_sb_fill_data *data = fc->fs_private;
@@ -1511,7 +1506,7 @@ static int ffs_fs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 
        ENTER();
 
-       opt = fs_parse(fc, &ffs_fs_fs_parameters, param, &result);
+       opt = fs_parse(fc, ffs_fs_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -1643,7 +1638,7 @@ static struct file_system_type ffs_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "functionfs",
        .init_fs_context = ffs_fs_init_fs_context,
-       .parameters     = &ffs_fs_fs_parameters,
+       .parameters     = ffs_fs_fs_parameters,
        .kill_sb        = ffs_fs_kill_sb,
 };
 MODULE_ALIAS_FS("functionfs");
index 04c142c..64de9f1 100644 (file)
@@ -72,7 +72,7 @@ static rndis_resp_t *rndis_add_response(struct rndis_params *params,
 
 #ifdef CONFIG_USB_GADGET_DEBUG_FILES
 
-static const struct file_operations rndis_proc_fops;
+static const struct proc_ops rndis_proc_ops;
 
 #endif /* CONFIG_USB_GADGET_DEBUG_FILES */
 
@@ -902,7 +902,7 @@ struct rndis_params *rndis_register(void (*resp_avail)(void *v), void *v)
 
                sprintf(name, NAME_TEMPLATE, i);
                proc_entry = proc_create_data(name, 0660, NULL,
-                                             &rndis_proc_fops, params);
+                                             &rndis_proc_ops, params);
                if (!proc_entry) {
                        kfree(params);
                        rndis_put_nr(i);
@@ -1164,13 +1164,12 @@ static int rndis_proc_open(struct inode *inode, struct file *file)
        return single_open(file, rndis_proc_show, PDE_DATA(inode));
 }
 
-static const struct file_operations rndis_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = rndis_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = rndis_proc_write,
+static const struct proc_ops rndis_proc_ops = {
+       .proc_open      = rndis_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = rndis_proc_write,
 };
 
 #define        NAME_TEMPLATE "driver/rndis-%03d"
index 7570c76..8ad14e5 100644 (file)
@@ -74,7 +74,7 @@ static ssize_t create_store(struct kobject *kobj, struct device *dev,
        return count;
 }
 
-MDEV_TYPE_ATTR_WO(create);
+static MDEV_TYPE_ATTR_WO(create);
 
 static void mdev_type_release(struct kobject *kobj)
 {
index f2983f0..df4d960 100644 (file)
@@ -97,8 +97,10 @@ static void vfio_pci_nvgpu_release(struct vfio_pci_device *vdev,
 
        /* If there were any mappings at all... */
        if (data->mm) {
-               ret = mm_iommu_put(data->mm, data->mem);
-               WARN_ON(ret);
+               if (data->mem) {
+                       ret = mm_iommu_put(data->mm, data->mem);
+                       WARN_ON(ret);
+               }
 
                mmdrop(data->mm);
        }
@@ -159,7 +161,7 @@ static int vfio_pci_nvgpu_mmap(struct vfio_pci_device *vdev,
        data->useraddr = vma->vm_start;
        data->mm = current->mm;
 
-       atomic_inc(&data->mm->mm_count);
+       mmgrab(data->mm);
        ret = (int) mm_iommu_newdev(data->mm, data->useraddr,
                        vma_pages(vma), data->gpu_hpa, &data->mem);
 
index 40d4fb9..abdca90 100644 (file)
@@ -24,7 +24,7 @@
 #define MDIO_AN_INT            0x8002
 #define MDIO_AN_INTMASK                0x8001
 
-static unsigned int xmdio_read(void *ioaddr, unsigned int mmd,
+static unsigned int xmdio_read(void __iomem *ioaddr, unsigned int mmd,
                               unsigned int reg)
 {
        unsigned int mmd_address, value;
@@ -35,7 +35,7 @@ static unsigned int xmdio_read(void *ioaddr, unsigned int mmd,
        return value;
 }
 
-static void xmdio_write(void *ioaddr, unsigned int mmd,
+static void xmdio_write(void __iomem *ioaddr, unsigned int mmd,
                        unsigned int reg, unsigned int value)
 {
        unsigned int mmd_address;
index 26cef65..16b3adc 100644 (file)
@@ -79,7 +79,7 @@ static long tce_iommu_mm_set(struct tce_container *container)
        }
        BUG_ON(!current->mm);
        container->mm = current->mm;
-       atomic_inc(&container->mm->mm_count);
+       mmgrab(container->mm);
 
        return 0;
 }
index 94ccb90..8a4361e 100644 (file)
@@ -11,7 +11,6 @@
 #include <linux/backlight.h>
 #include <linux/delay.h>
 #include <linux/fb.h>
-#include <linux/gpio.h>
 #include <linux/lcd.h>
 #include <linux/module.h>
 #include <linux/spi/spi.h>
index d344fb0..d5d5fb4 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/fb.h>
-#include <linux/gpio.h>
+#include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
 #include <linux/module.h>
 #include <linux/platform_data/bd6107.h>
@@ -71,6 +71,7 @@ struct bd6107 {
        struct i2c_client *client;
        struct backlight_device *backlight;
        struct bd6107_platform_data *pdata;
+       struct gpio_desc *reset;
 };
 
 static int bd6107_write(struct bd6107 *bd, u8 reg, u8 data)
@@ -94,9 +95,10 @@ static int bd6107_backlight_update_status(struct backlight_device *backlight)
                bd6107_write(bd, BD6107_MAINCNT1, brightness);
                bd6107_write(bd, BD6107_LEDCNT1, BD6107_LEDCNT1_LEDONOFF1);
        } else {
-               gpio_set_value(bd->pdata->reset, 0);
+               /* Assert the reset line (gpiolib will handle active low) */
+               gpiod_set_value(bd->reset, 1);
                msleep(24);
-               gpio_set_value(bd->pdata->reset, 1);
+               gpiod_set_value(bd->reset, 0);
        }
 
        return 0;
@@ -125,8 +127,8 @@ static int bd6107_probe(struct i2c_client *client,
        struct bd6107 *bd;
        int ret;
 
-       if (pdata == NULL || !pdata->reset) {
-               dev_err(&client->dev, "No reset GPIO in platform data\n");
+       if (pdata == NULL) {
+               dev_err(&client->dev, "No platform data\n");
                return -EINVAL;
        }
 
@@ -144,10 +146,16 @@ static int bd6107_probe(struct i2c_client *client,
        bd->client = client;
        bd->pdata = pdata;
 
-       ret = devm_gpio_request_one(&client->dev, pdata->reset,
-                                   GPIOF_DIR_OUT | GPIOF_INIT_LOW, "reset");
-       if (ret < 0) {
+       /*
+        * Request the reset GPIO line with GPIOD_OUT_HIGH meaning asserted,
+        * so in the machine descriptor table (or other hardware description),
+        * the line should be flagged as active low so this will assert
+        * the reset.
+        */
+       bd->reset = devm_gpiod_get(&client->dev, "reset", GPIOD_OUT_HIGH);
+       if (IS_ERR(bd->reset)) {
                dev_err(&client->dev, "unable to request reset GPIO\n");
+               ret = PTR_ERR(bd->reset);
                return ret;
        }
 
index d46052d..3d276b3 100644 (file)
@@ -956,8 +956,8 @@ static int wled_configure(struct wled *wled, int version)
        struct wled_config *cfg = &wled->cfg;
        struct device *dev = wled->dev;
        const __be32 *prop_addr;
-       u32 size, val, c, string_len;
-       int rc, i, j;
+       u32 size, val, c;
+       int rc, i, j, string_len;
 
        const struct wled_u32_opts *u32_opts = NULL;
        const struct wled_u32_opts wled3_opts[] = {
index aa9541b..f65991a 100644 (file)
@@ -2215,6 +2215,7 @@ config FB_HYPERV
        select FB_CFB_COPYAREA
        select FB_CFB_IMAGEBLIT
        select FB_DEFERRED_IO
+       select DMA_CMA if HAVE_DMA_CONTIGUOUS && CMA
        help
          This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
 
index afe9fd7..f47d50e 100644 (file)
  * "set-vmvideo" command. For example
  *     set-vmvideo -vmname name -horizontalresolution:1920 \
  * -verticalresolution:1200 -resolutiontype single
+ *
+ * Gen 1 VMs also support direct using VM's physical memory for framebuffer.
+ * It could improve the efficiency and performance for framebuffer and VM.
+ * This requires to allocate contiguous physical memory from Linux kernel's
+ * CMA memory allocator. To enable this, supply a kernel parameter to give
+ * enough memory space to CMA allocator for framebuffer. For example:
+ *    cma=130m
+ * This gives 130MB memory to CMA allocator that can be allocated to
+ * framebuffer. For reference, 8K resolution (7680x4320) takes about
+ * 127MB memory.
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -228,7 +238,6 @@ struct synthvid_msg {
 } __packed;
 
 
-
 /* FB driver definitions and structures */
 #define HVFB_WIDTH 1152 /* default screen width */
 #define HVFB_HEIGHT 864 /* default screen height */
@@ -258,12 +267,15 @@ struct hvfb_par {
        /* If true, the VSC notifies the VSP on every framebuffer change */
        bool synchronous_fb;
 
+       /* If true, need to copy from deferred IO mem to framebuffer mem */
+       bool need_docopy;
+
        struct notifier_block hvfb_panic_nb;
 
        /* Memory for deferred IO and frame buffer itself */
        unsigned char *dio_vp;
        unsigned char *mmio_vp;
-       unsigned long mmio_pp;
+       phys_addr_t mmio_pp;
 
        /* Dirty rectangle, protected by delayed_refresh_lock */
        int x1, y1, x2, y2;
@@ -434,7 +446,7 @@ static void synthvid_deferred_io(struct fb_info *p,
                maxy = max_t(int, maxy, y2);
 
                /* Copy from dio space to mmio address */
-               if (par->fb_ready)
+               if (par->fb_ready && par->need_docopy)
                        hvfb_docopy(par, start, PAGE_SIZE);
        }
 
@@ -751,12 +763,12 @@ static void hvfb_update_work(struct work_struct *w)
                return;
 
        /* Copy the dirty rectangle to frame buffer memory */
-       for (j = y1; j < y2; j++) {
-               hvfb_docopy(par,
-                           j * info->fix.line_length +
-                           (x1 * screen_depth / 8),
-                           (x2 - x1) * screen_depth / 8);
-       }
+       if (par->need_docopy)
+               for (j = y1; j < y2; j++)
+                       hvfb_docopy(par,
+                                   j * info->fix.line_length +
+                                   (x1 * screen_depth / 8),
+                                   (x2 - x1) * screen_depth / 8);
 
        /* Refresh */
        if (par->fb_ready && par->update)
@@ -801,7 +813,8 @@ static int hvfb_on_panic(struct notifier_block *nb,
        par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
        par->synchronous_fb = true;
        info = par->info;
-       hvfb_docopy(par, 0, dio_fb_size);
+       if (par->need_docopy)
+               hvfb_docopy(par, 0, dio_fb_size);
        synthvid_update(info, 0, 0, INT_MAX, INT_MAX);
 
        return NOTIFY_DONE;
@@ -940,6 +953,62 @@ static void hvfb_get_option(struct fb_info *info)
        return;
 }
 
+/*
+ * Allocate enough contiguous physical memory.
+ * Return physical address if succeeded or -1 if failed.
+ */
+static phys_addr_t hvfb_get_phymem(struct hv_device *hdev,
+                                  unsigned int request_size)
+{
+       struct page *page = NULL;
+       dma_addr_t dma_handle;
+       void *vmem;
+       phys_addr_t paddr = 0;
+       unsigned int order = get_order(request_size);
+
+       if (request_size == 0)
+               return -1;
+
+       if (order < MAX_ORDER) {
+               /* Call alloc_pages if the size is less than 2^MAX_ORDER */
+               page = alloc_pages(GFP_KERNEL | __GFP_ZERO, order);
+               if (!page)
+                       return -1;
+
+               paddr = (page_to_pfn(page) << PAGE_SHIFT);
+       } else {
+               /* Allocate from CMA */
+               hdev->device.coherent_dma_mask = DMA_BIT_MASK(64);
+
+               vmem = dma_alloc_coherent(&hdev->device,
+                                         round_up(request_size, PAGE_SIZE),
+                                         &dma_handle,
+                                         GFP_KERNEL | __GFP_NOWARN);
+
+               if (!vmem)
+                       return -1;
+
+               paddr = virt_to_phys(vmem);
+       }
+
+       return paddr;
+}
+
+/* Release contiguous physical memory */
+static void hvfb_release_phymem(struct hv_device *hdev,
+                               phys_addr_t paddr, unsigned int size)
+{
+       unsigned int order = get_order(size);
+
+       if (order < MAX_ORDER)
+               __free_pages(pfn_to_page(paddr >> PAGE_SHIFT), order);
+       else
+               dma_free_coherent(&hdev->device,
+                                 round_up(size, PAGE_SIZE),
+                                 phys_to_virt(paddr),
+                                 paddr);
+}
+
 
 /* Get framebuffer memory from Hyper-V video pci space */
 static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
@@ -949,22 +1018,61 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
        void __iomem *fb_virt;
        int gen2vm = efi_enabled(EFI_BOOT);
        resource_size_t pot_start, pot_end;
+       phys_addr_t paddr;
        int ret;
 
-       dio_fb_size =
-               screen_width * screen_height * screen_depth / 8;
+       info->apertures = alloc_apertures(1);
+       if (!info->apertures)
+               return -ENOMEM;
 
-       if (gen2vm) {
-               pot_start = 0;
-               pot_end = -1;
-       } else {
+       if (!gen2vm) {
                pdev = pci_get_device(PCI_VENDOR_ID_MICROSOFT,
-                             PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
+                       PCI_DEVICE_ID_HYPERV_VIDEO, NULL);
                if (!pdev) {
                        pr_err("Unable to find PCI Hyper-V video\n");
+                       kfree(info->apertures);
                        return -ENODEV;
                }
 
+               info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
+               info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
+
+               /*
+                * For Gen 1 VM, we can directly use the contiguous memory
+                * from VM. If we succeed, deferred IO happens directly
+                * on this allocated framebuffer memory, avoiding extra
+                * memory copy.
+                */
+               paddr = hvfb_get_phymem(hdev, screen_fb_size);
+               if (paddr != (phys_addr_t) -1) {
+                       par->mmio_pp = paddr;
+                       par->mmio_vp = par->dio_vp = __va(paddr);
+
+                       info->fix.smem_start = paddr;
+                       info->fix.smem_len = screen_fb_size;
+                       info->screen_base = par->mmio_vp;
+                       info->screen_size = screen_fb_size;
+
+                       par->need_docopy = false;
+                       goto getmem_done;
+               }
+               pr_info("Unable to allocate enough contiguous physical memory on Gen 1 VM. Using MMIO instead.\n");
+       } else {
+               info->apertures->ranges[0].base = screen_info.lfb_base;
+               info->apertures->ranges[0].size = screen_info.lfb_size;
+       }
+
+       /*
+        * Cannot use the contiguous physical memory.
+        * Allocate mmio space for framebuffer.
+        */
+       dio_fb_size =
+               screen_width * screen_height * screen_depth / 8;
+
+       if (gen2vm) {
+               pot_start = 0;
+               pot_end = -1;
+       } else {
                if (!(pci_resource_flags(pdev, 0) & IORESOURCE_MEM) ||
                    pci_resource_len(pdev, 0) < screen_fb_size) {
                        pr_err("Resource not available or (0x%lx < 0x%lx)\n",
@@ -993,20 +1101,6 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
        if (par->dio_vp == NULL)
                goto err3;
 
-       info->apertures = alloc_apertures(1);
-       if (!info->apertures)
-               goto err4;
-
-       if (gen2vm) {
-               info->apertures->ranges[0].base = screen_info.lfb_base;
-               info->apertures->ranges[0].size = screen_info.lfb_size;
-               remove_conflicting_framebuffers(info->apertures,
-                                               KBUILD_MODNAME, false);
-       } else {
-               info->apertures->ranges[0].base = pci_resource_start(pdev, 0);
-               info->apertures->ranges[0].size = pci_resource_len(pdev, 0);
-       }
-
        /* Physical address of FB device */
        par->mmio_pp = par->mem->start;
        /* Virtual address of FB device */
@@ -1017,13 +1111,15 @@ static int hvfb_getmem(struct hv_device *hdev, struct fb_info *info)
        info->screen_base = par->dio_vp;
        info->screen_size = dio_fb_size;
 
+getmem_done:
+       remove_conflicting_framebuffers(info->apertures,
+                                       KBUILD_MODNAME, false);
        if (!gen2vm)
                pci_dev_put(pdev);
+       kfree(info->apertures);
 
        return 0;
 
-err4:
-       vfree(par->dio_vp);
 err3:
        iounmap(fb_virt);
 err2:
@@ -1032,18 +1128,25 @@ err2:
 err1:
        if (!gen2vm)
                pci_dev_put(pdev);
+       kfree(info->apertures);
 
        return -ENOMEM;
 }
 
 /* Release the framebuffer */
-static void hvfb_putmem(struct fb_info *info)
+static void hvfb_putmem(struct hv_device *hdev, struct fb_info *info)
 {
        struct hvfb_par *par = info->par;
 
-       vfree(par->dio_vp);
-       iounmap(info->screen_base);
-       vmbus_free_mmio(par->mem->start, screen_fb_size);
+       if (par->need_docopy) {
+               vfree(par->dio_vp);
+               iounmap(info->screen_base);
+               vmbus_free_mmio(par->mem->start, screen_fb_size);
+       } else {
+               hvfb_release_phymem(hdev, info->fix.smem_start,
+                                   screen_fb_size);
+       }
+
        par->mem = NULL;
 }
 
@@ -1062,6 +1165,7 @@ static int hvfb_probe(struct hv_device *hdev,
        par = info->par;
        par->info = info;
        par->fb_ready = false;
+       par->need_docopy = true;
        init_completion(&par->wait);
        INIT_DELAYED_WORK(&par->dwork, hvfb_update_work);
 
@@ -1147,7 +1251,7 @@ static int hvfb_probe(struct hv_device *hdev,
 
 error:
        fb_deferred_io_cleanup(info);
-       hvfb_putmem(info);
+       hvfb_putmem(hdev, info);
 error2:
        vmbus_close(hdev->channel);
 error1:
@@ -1177,7 +1281,7 @@ static int hvfb_remove(struct hv_device *hdev)
        vmbus_close(hdev->channel);
        hv_set_drvdata(hdev, NULL);
 
-       hvfb_putmem(info);
+       hvfb_putmem(hdev, info);
        framebuffer_release(info);
 
        return 0;
@@ -1194,6 +1298,7 @@ static int hvfb_suspend(struct hv_device *hdev)
        fb_set_suspend(info, 1);
 
        cancel_delayed_work_sync(&par->dwork);
+       cancel_delayed_work_sync(&info->deferred_work);
 
        par->update_saved = par->update;
        par->update = false;
@@ -1227,6 +1332,7 @@ static int hvfb_resume(struct hv_device *hdev)
        par->fb_ready = true;
        par->update = par->update_saved;
 
+       schedule_delayed_work(&info->deferred_work, info->fbdefio->delay);
        schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
 
        /* 0 means do resume */
index 08a17eb..370bf25 100644 (file)
@@ -1017,7 +1017,7 @@ static int imxfb_probe(struct platform_device *pdev)
        }
 
        fbi->lcd_pwr = devm_regulator_get(&pdev->dev, "lcd");
-       if (IS_ERR(fbi->lcd_pwr) && (PTR_ERR(fbi->lcd_pwr) == -EPROBE_DEFER)) {
+       if (PTR_ERR(fbi->lcd_pwr) == -EPROBE_DEFER) {
                ret = -EPROBE_DEFER;
                goto failed_lcd;
        }
index f815f98..852673c 100644 (file)
@@ -1173,13 +1173,12 @@ static ssize_t viafb_dvp0_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations viafb_dvp0_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = viafb_dvp0_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = viafb_dvp0_proc_write,
+static const struct proc_ops viafb_dvp0_proc_ops = {
+       .proc_open      = viafb_dvp0_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = viafb_dvp0_proc_write,
 };
 
 static int viafb_dvp1_proc_show(struct seq_file *m, void *v)
@@ -1238,13 +1237,12 @@ static ssize_t viafb_dvp1_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations viafb_dvp1_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = viafb_dvp1_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = viafb_dvp1_proc_write,
+static const struct proc_ops viafb_dvp1_proc_ops = {
+       .proc_open      = viafb_dvp1_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = viafb_dvp1_proc_write,
 };
 
 static int viafb_dfph_proc_show(struct seq_file *m, void *v)
@@ -1273,13 +1271,12 @@ static ssize_t viafb_dfph_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations viafb_dfph_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = viafb_dfph_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = viafb_dfph_proc_write,
+static const struct proc_ops viafb_dfph_proc_ops = {
+       .proc_open      = viafb_dfph_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = viafb_dfph_proc_write,
 };
 
 static int viafb_dfpl_proc_show(struct seq_file *m, void *v)
@@ -1308,13 +1305,12 @@ static ssize_t viafb_dfpl_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations viafb_dfpl_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = viafb_dfpl_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = viafb_dfpl_proc_write,
+static const struct proc_ops viafb_dfpl_proc_ops = {
+       .proc_open      = viafb_dfpl_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = viafb_dfpl_proc_write,
 };
 
 static int viafb_vt1636_proc_show(struct seq_file *m, void *v)
@@ -1444,13 +1440,12 @@ static ssize_t viafb_vt1636_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations viafb_vt1636_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = viafb_vt1636_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = viafb_vt1636_proc_write,
+static const struct proc_ops viafb_vt1636_proc_ops = {
+       .proc_open      = viafb_vt1636_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = viafb_vt1636_proc_write,
 };
 
 #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
@@ -1522,13 +1517,12 @@ static ssize_t viafb_iga1_odev_proc_write(struct file *file,
        return res;
 }
 
-static const struct file_operations viafb_iga1_odev_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = viafb_iga1_odev_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = viafb_iga1_odev_proc_write,
+static const struct proc_ops viafb_iga1_odev_proc_ops = {
+       .proc_open      = viafb_iga1_odev_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = viafb_iga1_odev_proc_write,
 };
 
 static int viafb_iga2_odev_proc_show(struct seq_file *m, void *v)
@@ -1562,13 +1556,12 @@ static ssize_t viafb_iga2_odev_proc_write(struct file *file,
        return res;
 }
 
-static const struct file_operations viafb_iga2_odev_proc_fops = {
-       .owner          = THIS_MODULE,
-       .open           = viafb_iga2_odev_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = viafb_iga2_odev_proc_write,
+static const struct proc_ops viafb_iga2_odev_proc_ops = {
+       .proc_open      = viafb_iga2_odev_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = viafb_iga2_odev_proc_write,
 };
 
 #define IS_VT1636(lvds_chip)   ((lvds_chip).lvds_chip_name == VT1636_LVDS)
@@ -1580,14 +1573,14 @@ static void viafb_init_proc(struct viafb_shared *shared)
        shared->proc_entry = viafb_entry;
        if (viafb_entry) {
 #ifdef CONFIG_FB_VIA_DIRECT_PROCFS
-               proc_create("dvp0", 0, viafb_entry, &viafb_dvp0_proc_fops);
-               proc_create("dvp1", 0, viafb_entry, &viafb_dvp1_proc_fops);
-               proc_create("dfph", 0, viafb_entry, &viafb_dfph_proc_fops);
-               proc_create("dfpl", 0, viafb_entry, &viafb_dfpl_proc_fops);
+               proc_create("dvp0", 0, viafb_entry, &viafb_dvp0_proc_ops);
+               proc_create("dvp1", 0, viafb_entry, &viafb_dvp1_proc_ops);
+               proc_create("dfph", 0, viafb_entry, &viafb_dfph_proc_ops);
+               proc_create("dfpl", 0, viafb_entry, &viafb_dfpl_proc_ops);
                if (IS_VT1636(shared->chip_info.lvds_chip_info)
                        || IS_VT1636(shared->chip_info.lvds_chip_info2))
                        proc_create("vt1636", 0, viafb_entry,
-                               &viafb_vt1636_proc_fops);
+                                   &viafb_vt1636_proc_ops);
 #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
 
                proc_create_single("supported_output_devices", 0, viafb_entry,
@@ -1595,11 +1588,11 @@ static void viafb_init_proc(struct viafb_shared *shared)
                iga1_entry = proc_mkdir("iga1", viafb_entry);
                shared->iga1_proc_entry = iga1_entry;
                proc_create("output_devices", 0, iga1_entry,
-                       &viafb_iga1_odev_proc_fops);
+                           &viafb_iga1_odev_proc_ops);
                iga2_entry = proc_mkdir("iga2", viafb_entry);
                shared->iga2_proc_entry = iga2_entry;
                proc_create("output_devices", 0, iga2_entry,
-                       &viafb_iga2_odev_proc_fops);
+                           &viafb_iga2_odev_proc_ops);
        }
 }
 static void viafb_remove_proc(struct viafb_shared *shared)
index 93f995f..7bfe365 100644 (file)
@@ -158,6 +158,8 @@ static void set_page_pfns(struct virtio_balloon *vb,
 {
        unsigned int i;
 
+       BUILD_BUG_ON(VIRTIO_BALLOON_PAGES_PER_PAGE > VIRTIO_BALLOON_ARRAY_PFNS_MAX);
+
        /*
         * Set balloon pfns pointing at this page.
         * Note that the first pfn points at start of the page.
@@ -475,7 +477,9 @@ static int init_vqs(struct virtio_balloon *vb)
        names[VIRTIO_BALLOON_VQ_INFLATE] = "inflate";
        callbacks[VIRTIO_BALLOON_VQ_DEFLATE] = balloon_ack;
        names[VIRTIO_BALLOON_VQ_DEFLATE] = "deflate";
+       callbacks[VIRTIO_BALLOON_VQ_STATS] = NULL;
        names[VIRTIO_BALLOON_VQ_STATS] = NULL;
+       callbacks[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
        names[VIRTIO_BALLOON_VQ_FREE_PAGE] = NULL;
 
        if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_STATS_VQ)) {
@@ -899,8 +903,7 @@ static int virtballoon_probe(struct virtio_device *vdev)
        vb->vb_dev_info.inode = alloc_anon_inode(balloon_mnt->mnt_sb);
        if (IS_ERR(vb->vb_dev_info.inode)) {
                err = PTR_ERR(vb->vb_dev_info.inode);
-               kern_unmount(balloon_mnt);
-               goto out_del_vqs;
+               goto out_kern_unmount;
        }
        vb->vb_dev_info.inode->i_mapping->a_ops = &balloon_aops;
 #endif
@@ -911,13 +914,13 @@ static int virtballoon_probe(struct virtio_device *vdev)
                 */
                if (virtqueue_get_vring_size(vb->free_page_vq) < 2) {
                        err = -ENOSPC;
-                       goto out_del_vqs;
+                       goto out_iput;
                }
                vb->balloon_wq = alloc_workqueue("balloon-wq",
                                        WQ_FREEZABLE | WQ_CPU_INTENSIVE, 0);
                if (!vb->balloon_wq) {
                        err = -ENOMEM;
-                       goto out_del_vqs;
+                       goto out_iput;
                }
                INIT_WORK(&vb->report_free_page_work, report_free_page_func);
                vb->cmd_id_received_cache = VIRTIO_BALLOON_CMD_ID_STOP;
@@ -951,6 +954,12 @@ static int virtballoon_probe(struct virtio_device *vdev)
 out_del_balloon_wq:
        if (virtio_has_feature(vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
                destroy_workqueue(vb->balloon_wq);
+out_iput:
+#ifdef CONFIG_BALLOON_COMPACTION
+       iput(vb->vb_dev_info.inode);
+out_kern_unmount:
+       kern_unmount(balloon_mnt);
+#endif
 out_del_vqs:
        vdev->config->del_vqs(vdev);
 out_free_vb:
@@ -966,6 +975,10 @@ static void remove_common(struct virtio_balloon *vb)
                leak_balloon(vb, vb->num_pages);
        update_balloon_size(vb);
 
+       /* There might be free pages that are being reported: release them. */
+       if (virtio_has_feature(vb->vdev, VIRTIO_BALLOON_F_FREE_PAGE_HINT))
+               return_free_pages_to_mm(vb, ULONG_MAX);
+
        /* Now we reset the device so we can clean up the queues. */
        vb->vdev->config->reset(vb->vdev);
 
index e09edb5..97d5725 100644 (file)
@@ -531,18 +531,9 @@ static void virtio_mmio_release_dev(struct device *_d)
 static int virtio_mmio_probe(struct platform_device *pdev)
 {
        struct virtio_mmio_device *vm_dev;
-       struct resource *mem;
        unsigned long magic;
        int rc;
 
-       mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       if (!mem)
-               return -EINVAL;
-
-       if (!devm_request_mem_region(&pdev->dev, mem->start,
-                       resource_size(mem), pdev->name))
-               return -EBUSY;
-
        vm_dev = devm_kzalloc(&pdev->dev, sizeof(*vm_dev), GFP_KERNEL);
        if (!vm_dev)
                return -ENOMEM;
@@ -554,9 +545,9 @@ static int virtio_mmio_probe(struct platform_device *pdev)
        INIT_LIST_HEAD(&vm_dev->virtqueues);
        spin_lock_init(&vm_dev->lock);
 
-       vm_dev->base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem));
-       if (vm_dev->base == NULL)
-               return -EFAULT;
+       vm_dev->base = devm_platform_ioremap_resource(pdev, 0);
+       if (IS_ERR(vm_dev->base))
+               return PTR_ERR(vm_dev->base);
 
        /* Check magic value */
        magic = readl(vm_dev->base + VIRTIO_MMIO_MAGIC_VALUE);
index f2862f6..222d630 100644 (file)
@@ -294,7 +294,7 @@ static int vp_find_vqs_msix(struct virtio_device *vdev, unsigned nvqs,
                /* Best option: one for change interrupt, one per vq. */
                nvectors = 1;
                for (i = 0; i < nvqs; ++i)
-                       if (callbacks[i])
+                       if (names[i] && callbacks[i])
                                ++nvectors;
        } else {
                /* Second best: one for change, shared for all vqs. */
index abfe34d..298d545 100644 (file)
 #define AT91_WDT_MR            0x04                    /* Watchdog Mode Register */
 #define  AT91_WDT_WDV          (0xfffUL << 0)          /* Counter Value */
 #define  AT91_WDT_SET_WDV(x)   ((x) & AT91_WDT_WDV)
+#define  AT91_SAM9X60_PERIODRST        BIT(4)          /* Period Reset */
+#define  AT91_SAM9X60_RPTHRST  BIT(5)          /* Minimum Restart Period */
 #define  AT91_WDT_WDFIEN       BIT(12)         /* Fault Interrupt Enable */
+#define  AT91_SAM9X60_WDDIS    BIT(12)         /* Watchdog Disable */
 #define  AT91_WDT_WDRSTEN      BIT(13)         /* Reset Processor */
 #define  AT91_WDT_WDRPROC      BIT(14)         /* Timer Restart */
 #define  AT91_WDT_WDDIS                BIT(15)         /* Watchdog Disable */
 #define  AT91_WDT_WDUNF                BIT(0)          /* Watchdog Underflow */
 #define  AT91_WDT_WDERR                BIT(1)          /* Watchdog Error */
 
+/* Watchdog Timer Value Register */
+#define AT91_SAM9X60_VR                0x08
+
+/* Watchdog Window Level Register */
+#define AT91_SAM9X60_WLR       0x0c
+/* Watchdog Period Value */
+#define  AT91_SAM9X60_COUNTER  (0xfffUL << 0)
+#define  AT91_SAM9X60_SET_COUNTER(x)   ((x) & AT91_SAM9X60_COUNTER)
+
+/* Interrupt Enable Register */
+#define AT91_SAM9X60_IER       0x14
+/* Period Interrupt Enable */
+#define  AT91_SAM9X60_PERINT   BIT(0)
+/* Interrupt Disable Register */
+#define AT91_SAM9X60_IDR       0x18
+/* Interrupt Status Register */
+#define AT91_SAM9X60_ISR       0x1c
+
 #endif
index 06bd4e1..672b184 100644 (file)
@@ -369,9 +369,8 @@ static int cdns_wdt_probe(struct platform_device *pdev)
                return ret;
        platform_set_drvdata(pdev, wdt);
 
-       dev_info(dev, "Xilinx Watchdog Timer at %p with timeout %ds%s\n",
-                wdt->regs, cdns_wdt_device->timeout,
-                nowayout ? ", nowayout" : "");
+       dev_info(dev, "Xilinx Watchdog Timer with timeout %ds%s\n",
+                cdns_wdt_device->timeout, nowayout ? ", nowayout" : "");
 
        return 0;
 }
index e149e66..47eefe0 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/platform_device.h>
 #include <linux/uaccess.h>
 #include <linux/slab.h>
+#include <linux/i2c.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/mfd/da9062/registers.h>
@@ -147,12 +148,13 @@ static int da9062_wdt_restart(struct watchdog_device *wdd, unsigned long action,
                              void *data)
 {
        struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd);
+       struct i2c_client *client = to_i2c_client(wdt->hw->dev);
        int ret;
 
-       ret = regmap_write(wdt->hw->regmap,
-                          DA9062AA_CONTROL_F,
-                          DA9062AA_SHUTDOWN_MASK);
-       if (ret)
+       /* Don't use regmap because it is not atomic safe */
+       ret = i2c_smbus_write_byte_data(client, DA9062AA_CONTROL_F,
+                                       DA9062AA_SHUTDOWN_MASK);
+       if (ret < 0)
                dev_alert(wdt->hw->dev, "Failed to shutdown (err = %d)\n",
                          ret);
 
@@ -212,6 +214,7 @@ static int da9062_wdt_probe(struct platform_device *pdev)
        watchdog_set_restart_priority(&wdt->wdtdev, 128);
 
        watchdog_set_drvdata(&wdt->wdtdev, wdt);
+       dev_set_drvdata(dev, &wdt->wdtdev);
 
        ret = devm_watchdog_register_device(dev, &wdt->wdtdev);
        if (ret < 0)
@@ -220,10 +223,34 @@ static int da9062_wdt_probe(struct platform_device *pdev)
        return da9062_wdt_ping(&wdt->wdtdev);
 }
 
+static int __maybe_unused da9062_wdt_suspend(struct device *dev)
+{
+       struct watchdog_device *wdd = dev_get_drvdata(dev);
+
+       if (watchdog_active(wdd))
+               return da9062_wdt_stop(wdd);
+
+       return 0;
+}
+
+static int __maybe_unused da9062_wdt_resume(struct device *dev)
+{
+       struct watchdog_device *wdd = dev_get_drvdata(dev);
+
+       if (watchdog_active(wdd))
+               return da9062_wdt_start(wdd);
+
+       return 0;
+}
+
+static SIMPLE_DEV_PM_OPS(da9062_wdt_pm_ops,
+                        da9062_wdt_suspend, da9062_wdt_resume);
+
 static struct platform_driver da9062_wdt_driver = {
        .probe = da9062_wdt_probe,
        .driver = {
                .name = "da9062-watchdog",
+               .pm = &da9062_wdt_pm_ops,
                .of_match_table = da9062_compatible_id_table,
        },
 };
index fef7c61..fba21de 100644 (file)
@@ -114,7 +114,15 @@ static int dw_wdt_set_timeout(struct watchdog_device *wdd, unsigned int top_s)
        writel(top_val | top_val << WDOG_TIMEOUT_RANGE_TOPINIT_SHIFT,
               dw_wdt->regs + WDOG_TIMEOUT_RANGE_REG_OFFSET);
 
-       wdd->timeout = dw_wdt_top_in_seconds(dw_wdt, top_val);
+       /*
+        * In case users set bigger timeout value than HW can support,
+        * kernel(watchdog_dev.c) helps to feed watchdog before
+        * wdd->max_hw_heartbeat_ms
+        */
+       if (top_s * 1000 <= wdd->max_hw_heartbeat_ms)
+               wdd->timeout = dw_wdt_top_in_seconds(dw_wdt, top_val);
+       else
+               wdd->timeout = top_s;
 
        return 0;
 }
@@ -135,6 +143,7 @@ static int dw_wdt_start(struct watchdog_device *wdd)
        struct dw_wdt *dw_wdt = to_dw_wdt(wdd);
 
        dw_wdt_set_timeout(wdd, wdd->timeout);
+       dw_wdt_ping(&dw_wdt->wdd);
        dw_wdt_arm_system_reset(dw_wdt);
 
        return 0;
index a4b71eb..f3bf3ea 100644 (file)
@@ -67,6 +67,7 @@
 #define IT8726_ID      0x8726  /* the data sheet suggest wrongly 0x8716 */
 #define IT8728_ID      0x8728
 #define IT8783_ID      0x8783
+#define IT8786_ID      0x8786
 
 /* GPIO Configuration Registers LDN=0x07 */
 #define WDTCTRL                0x71
@@ -294,6 +295,7 @@ static int __init it87_wdt_init(void)
        case IT8721_ID:
        case IT8728_ID:
        case IT8783_ID:
+       case IT8786_ID:
                max_units = 65535;
                break;
        case IT8705_ID:
index 9c3d003..d6a6393 100644 (file)
@@ -9,6 +9,9 @@
  * Based on sunxi_wdt.c
  */
 
+#include <dt-bindings/reset-controller/mt2712-resets.h>
+#include <dt-bindings/reset-controller/mt8183-resets.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/module.h>
 #include <linux/moduleparam.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/platform_device.h>
+#include <linux/reset-controller.h>
 #include <linux/types.h>
 #include <linux/watchdog.h>
-#include <linux/delay.h>
 
 #define WDT_MAX_TIMEOUT                31
 #define WDT_MIN_TIMEOUT                1
@@ -44,6 +48,9 @@
 #define WDT_SWRST              0x14
 #define WDT_SWRST_KEY          0x1209
 
+#define WDT_SWSYSRST           0x18U
+#define WDT_SWSYS_RST_KEY      0x88000000
+
 #define DRV_NAME               "mtk-wdt"
 #define DRV_VERSION            "1.0"
 
@@ -53,8 +60,94 @@ static unsigned int timeout;
 struct mtk_wdt_dev {
        struct watchdog_device wdt_dev;
        void __iomem *wdt_base;
+       spinlock_t lock; /* protects WDT_SWSYSRST reg */
+       struct reset_controller_dev rcdev;
+};
+
+struct mtk_wdt_data {
+       int toprgu_sw_rst_num;
 };
 
+static const struct mtk_wdt_data mt2712_data = {
+       .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM,
+};
+
+static const struct mtk_wdt_data mt8183_data = {
+       .toprgu_sw_rst_num = MT8183_TOPRGU_SW_RST_NUM,
+};
+
+static int toprgu_reset_update(struct reset_controller_dev *rcdev,
+                              unsigned long id, bool assert)
+{
+       unsigned int tmp;
+       unsigned long flags;
+       struct mtk_wdt_dev *data =
+                container_of(rcdev, struct mtk_wdt_dev, rcdev);
+
+       spin_lock_irqsave(&data->lock, flags);
+
+       tmp = readl(data->wdt_base + WDT_SWSYSRST);
+       if (assert)
+               tmp |= BIT(id);
+       else
+               tmp &= ~BIT(id);
+       tmp |= WDT_SWSYS_RST_KEY;
+       writel(tmp, data->wdt_base + WDT_SWSYSRST);
+
+       spin_unlock_irqrestore(&data->lock, flags);
+
+       return 0;
+}
+
+static int toprgu_reset_assert(struct reset_controller_dev *rcdev,
+                              unsigned long id)
+{
+       return toprgu_reset_update(rcdev, id, true);
+}
+
+static int toprgu_reset_deassert(struct reset_controller_dev *rcdev,
+                                unsigned long id)
+{
+       return toprgu_reset_update(rcdev, id, false);
+}
+
+static int toprgu_reset(struct reset_controller_dev *rcdev,
+                       unsigned long id)
+{
+       int ret;
+
+       ret = toprgu_reset_assert(rcdev, id);
+       if (ret)
+               return ret;
+
+       return toprgu_reset_deassert(rcdev, id);
+}
+
+static const struct reset_control_ops toprgu_reset_ops = {
+       .assert = toprgu_reset_assert,
+       .deassert = toprgu_reset_deassert,
+       .reset = toprgu_reset,
+};
+
+static int toprgu_register_reset_controller(struct platform_device *pdev,
+                                           int rst_num)
+{
+       int ret;
+       struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev);
+
+       spin_lock_init(&mtk_wdt->lock);
+
+       mtk_wdt->rcdev.owner = THIS_MODULE;
+       mtk_wdt->rcdev.nr_resets = rst_num;
+       mtk_wdt->rcdev.ops = &toprgu_reset_ops;
+       mtk_wdt->rcdev.of_node = pdev->dev.of_node;
+       ret = devm_reset_controller_register(&pdev->dev, &mtk_wdt->rcdev);
+       if (ret != 0)
+               dev_err(&pdev->dev,
+                       "couldn't register wdt reset controller: %d\n", ret);
+       return ret;
+}
+
 static int mtk_wdt_restart(struct watchdog_device *wdt_dev,
                           unsigned long action, void *data)
 {
@@ -155,6 +248,7 @@ static int mtk_wdt_probe(struct platform_device *pdev)
 {
        struct device *dev = &pdev->dev;
        struct mtk_wdt_dev *mtk_wdt;
+       const struct mtk_wdt_data *wdt_data;
        int err;
 
        mtk_wdt = devm_kzalloc(dev, sizeof(*mtk_wdt), GFP_KERNEL);
@@ -190,6 +284,13 @@ static int mtk_wdt_probe(struct platform_device *pdev)
        dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n",
                 mtk_wdt->wdt_dev.timeout, nowayout);
 
+       wdt_data = of_device_get_match_data(dev);
+       if (wdt_data) {
+               err = toprgu_register_reset_controller(pdev,
+                                                      wdt_data->toprgu_sw_rst_num);
+               if (err)
+                       return err;
+       }
        return 0;
 }
 
@@ -218,7 +319,9 @@ static int mtk_wdt_resume(struct device *dev)
 #endif
 
 static const struct of_device_id mtk_wdt_dt_ids[] = {
+       { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data },
        { .compatible = "mediatek,mt6589-wdt" },
+       { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, mtk_wdt_dt_ids);
index a494543..eb47fe5 100644 (file)
@@ -246,7 +246,7 @@ static int qcom_wdt_probe(struct platform_device *pdev)
        }
 
        /* check if there is pretimeout support */
-       irq = platform_get_irq(pdev, 0);
+       irq = platform_get_irq_optional(pdev, 0);
        if (irq > 0) {
                ret = devm_request_irq(dev, irq, qcom_wdt_isr,
                                       IRQF_TRIGGER_RISING,
index d193a60..e5d11d6 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * Driver for Atmel SAMA5D4 Watchdog Timer
  *
- * Copyright (C) 2015 Atmel Corporation
+ * Copyright (C) 2015-2019 Microchip Technology Inc. and its subsidiaries
  */
 
 #include <linux/delay.h>
@@ -11,6 +11,7 @@
 #include <linux/kernel.h>
 #include <linux/module.h>
 #include <linux/of.h>
+#include <linux/of_device.h>
 #include <linux/of_irq.h>
 #include <linux/platform_device.h>
 #include <linux/reboot.h>
@@ -29,7 +30,10 @@ struct sama5d4_wdt {
        struct watchdog_device  wdd;
        void __iomem            *reg_base;
        u32                     mr;
+       u32                     ir;
        unsigned long           last_ping;
+       bool                    need_irq;
+       bool                    sam9x60_support;
 };
 
 static int wdt_timeout;
@@ -78,7 +82,12 @@ static int sama5d4_wdt_start(struct watchdog_device *wdd)
 {
        struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
 
-       wdt->mr &= ~AT91_WDT_WDDIS;
+       if (wdt->sam9x60_support) {
+               writel_relaxed(wdt->ir, wdt->reg_base + AT91_SAM9X60_IER);
+               wdt->mr &= ~AT91_SAM9X60_WDDIS;
+       } else {
+               wdt->mr &= ~AT91_WDT_WDDIS;
+       }
        wdt_write(wdt, AT91_WDT_MR, wdt->mr);
 
        return 0;
@@ -88,7 +97,12 @@ static int sama5d4_wdt_stop(struct watchdog_device *wdd)
 {
        struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
 
-       wdt->mr |= AT91_WDT_WDDIS;
+       if (wdt->sam9x60_support) {
+               writel_relaxed(wdt->ir, wdt->reg_base + AT91_SAM9X60_IDR);
+               wdt->mr |= AT91_SAM9X60_WDDIS;
+       } else {
+               wdt->mr |= AT91_WDT_WDDIS;
+       }
        wdt_write(wdt, AT91_WDT_MR, wdt->mr);
 
        return 0;
@@ -109,6 +123,14 @@ static int sama5d4_wdt_set_timeout(struct watchdog_device *wdd,
        struct sama5d4_wdt *wdt = watchdog_get_drvdata(wdd);
        u32 value = WDT_SEC2TICKS(timeout);
 
+       if (wdt->sam9x60_support) {
+               wdt_write(wdt, AT91_SAM9X60_WLR,
+                         AT91_SAM9X60_SET_COUNTER(value));
+
+               wdd->timeout = timeout;
+               return 0;
+       }
+
        wdt->mr &= ~AT91_WDT_WDV;
        wdt->mr |= AT91_WDT_SET_WDV(value);
 
@@ -143,8 +165,14 @@ static const struct watchdog_ops sama5d4_wdt_ops = {
 static irqreturn_t sama5d4_wdt_irq_handler(int irq, void *dev_id)
 {
        struct sama5d4_wdt *wdt = platform_get_drvdata(dev_id);
+       u32 reg;
 
-       if (wdt_read(wdt, AT91_WDT_SR)) {
+       if (wdt->sam9x60_support)
+               reg = wdt_read(wdt, AT91_SAM9X60_ISR);
+       else
+               reg = wdt_read(wdt, AT91_WDT_SR);
+
+       if (reg) {
                pr_crit("Atmel Watchdog Software Reset\n");
                emergency_restart();
                pr_crit("Reboot didn't succeed\n");
@@ -157,13 +185,14 @@ static int of_sama5d4_wdt_init(struct device_node *np, struct sama5d4_wdt *wdt)
 {
        const char *tmp;
 
-       wdt->mr = AT91_WDT_WDDIS;
+       if (wdt->sam9x60_support)
+               wdt->mr = AT91_SAM9X60_WDDIS;
+       else
+               wdt->mr = AT91_WDT_WDDIS;
 
        if (!of_property_read_string(np, "atmel,watchdog-type", &tmp) &&
            !strcmp(tmp, "software"))
-               wdt->mr |= AT91_WDT_WDFIEN;
-       else
-               wdt->mr |= AT91_WDT_WDRSTEN;
+               wdt->need_irq = true;
 
        if (of_property_read_bool(np, "atmel,idle-halt"))
                wdt->mr |= AT91_WDT_WDIDLEHLT;
@@ -176,21 +205,46 @@ static int of_sama5d4_wdt_init(struct device_node *np, struct sama5d4_wdt *wdt)
 
 static int sama5d4_wdt_init(struct sama5d4_wdt *wdt)
 {
-       u32 reg;
+       u32 reg, val;
+
+       val = WDT_SEC2TICKS(WDT_DEFAULT_TIMEOUT);
        /*
         * When booting and resuming, the bootloader may have changed the
         * watchdog configuration.
         * If the watchdog is already running, we can safely update it.
         * Else, we have to disable it properly.
         */
-       if (wdt_enabled) {
-               wdt_write_nosleep(wdt, AT91_WDT_MR, wdt->mr);
-       } else {
+       if (!wdt_enabled) {
                reg = wdt_read(wdt, AT91_WDT_MR);
-               if (!(reg & AT91_WDT_WDDIS))
+               if (wdt->sam9x60_support && (!(reg & AT91_SAM9X60_WDDIS)))
+                       wdt_write_nosleep(wdt, AT91_WDT_MR,
+                                         reg | AT91_SAM9X60_WDDIS);
+               else if (!wdt->sam9x60_support &&
+                        (!(reg & AT91_WDT_WDDIS)))
                        wdt_write_nosleep(wdt, AT91_WDT_MR,
                                          reg | AT91_WDT_WDDIS);
        }
+
+       if (wdt->sam9x60_support) {
+               if (wdt->need_irq)
+                       wdt->ir = AT91_SAM9X60_PERINT;
+               else
+                       wdt->mr |= AT91_SAM9X60_PERIODRST;
+
+               wdt_write(wdt, AT91_SAM9X60_IER, wdt->ir);
+               wdt_write(wdt, AT91_SAM9X60_WLR, AT91_SAM9X60_SET_COUNTER(val));
+       } else {
+               wdt->mr |= AT91_WDT_SET_WDD(WDT_SEC2TICKS(MAX_WDT_TIMEOUT));
+               wdt->mr |= AT91_WDT_SET_WDV(val);
+
+               if (wdt->need_irq)
+                       wdt->mr |= AT91_WDT_WDFIEN;
+               else
+                       wdt->mr |= AT91_WDT_WDRSTEN;
+       }
+
+       wdt_write_nosleep(wdt, AT91_WDT_MR, wdt->mr);
+
        return 0;
 }
 
@@ -201,7 +255,6 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
        struct sama5d4_wdt *wdt;
        void __iomem *regs;
        u32 irq = 0;
-       u32 timeout;
        int ret;
 
        wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL);
@@ -215,6 +268,8 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
        wdd->min_timeout = MIN_WDT_TIMEOUT;
        wdd->max_timeout = MAX_WDT_TIMEOUT;
        wdt->last_ping = jiffies;
+       wdt->sam9x60_support = of_device_is_compatible(dev->of_node,
+                                                      "microchip,sam9x60-wdt");
 
        watchdog_set_drvdata(wdd, wdt);
 
@@ -224,15 +279,19 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
 
        wdt->reg_base = regs;
 
-       irq = irq_of_parse_and_map(dev->of_node, 0);
-       if (!irq)
-               dev_warn(dev, "failed to get IRQ from DT\n");
-
        ret = of_sama5d4_wdt_init(dev->of_node, wdt);
        if (ret)
                return ret;
 
-       if ((wdt->mr & AT91_WDT_WDFIEN) && irq) {
+       if (wdt->need_irq) {
+               irq = irq_of_parse_and_map(dev->of_node, 0);
+               if (!irq) {
+                       dev_warn(dev, "failed to get IRQ from DT\n");
+                       wdt->need_irq = false;
+               }
+       }
+
+       if (wdt->need_irq) {
                ret = devm_request_irq(dev, irq, sama5d4_wdt_irq_handler,
                                       IRQF_SHARED | IRQF_IRQPOLL |
                                       IRQF_NO_SUSPEND, pdev->name, pdev);
@@ -244,11 +303,6 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
 
        watchdog_init_timeout(wdd, wdt_timeout, dev);
 
-       timeout = WDT_SEC2TICKS(wdd->timeout);
-
-       wdt->mr |= AT91_WDT_SET_WDD(WDT_SEC2TICKS(MAX_WDT_TIMEOUT));
-       wdt->mr |= AT91_WDT_SET_WDV(timeout);
-
        ret = sama5d4_wdt_init(wdt);
        if (ret)
                return ret;
@@ -269,7 +323,12 @@ static int sama5d4_wdt_probe(struct platform_device *pdev)
 }
 
 static const struct of_device_id sama5d4_wdt_of_match[] = {
-       { .compatible = "atmel,sama5d4-wdt", },
+       {
+               .compatible = "atmel,sama5d4-wdt",
+       },
+       {
+               .compatible = "microchip,sam9x60-wdt",
+       },
        { }
 };
 MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match);
index a3a3290..25188d6 100644 (file)
@@ -262,6 +262,24 @@ static int stm32_iwdg_probe(struct platform_device *pdev)
        watchdog_set_nowayout(wdd, WATCHDOG_NOWAYOUT);
        watchdog_init_timeout(wdd, 0, dev);
 
+       /*
+        * In case of CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED is set
+        * (Means U-Boot/bootloaders leaves the watchdog running)
+        * When we get here we should make a decision to prevent
+        * any side effects before user space daemon will take care of it.
+        * The best option, taking into consideration that there is no
+        * way to read values back from hardware, is to enforce watchdog
+        * being run with deterministic values.
+        */
+       if (IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) {
+               ret = stm32_iwdg_start(wdd);
+               if (ret)
+                       return ret;
+
+               /* Make sure the watchdog is serviced */
+               set_bit(WDOG_HW_RUNNING, &wdd->status);
+       }
+
        ret = devm_watchdog_register_device(dev, wdd);
        if (ret)
                return ret;
index 21e8085..861daf4 100644 (file)
@@ -147,6 +147,25 @@ int watchdog_init_timeout(struct watchdog_device *wdd,
 }
 EXPORT_SYMBOL_GPL(watchdog_init_timeout);
 
+static int watchdog_reboot_notifier(struct notifier_block *nb,
+                                   unsigned long code, void *data)
+{
+       struct watchdog_device *wdd;
+
+       wdd = container_of(nb, struct watchdog_device, reboot_nb);
+       if (code == SYS_DOWN || code == SYS_HALT) {
+               if (watchdog_active(wdd)) {
+                       int ret;
+
+                       ret = wdd->ops->stop(wdd);
+                       if (ret)
+                               return NOTIFY_BAD;
+               }
+       }
+
+       return NOTIFY_DONE;
+}
+
 static int watchdog_restart_notifier(struct notifier_block *nb,
                                     unsigned long action, void *data)
 {
@@ -235,6 +254,19 @@ static int __watchdog_register_device(struct watchdog_device *wdd)
                }
        }
 
+       if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
+               wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
+
+               ret = register_reboot_notifier(&wdd->reboot_nb);
+               if (ret) {
+                       pr_err("watchdog%d: Cannot register reboot notifier (%d)\n",
+                              wdd->id, ret);
+                       watchdog_dev_unregister(wdd);
+                       ida_simple_remove(&watchdog_ida, id);
+                       return ret;
+               }
+       }
+
        if (wdd->ops->restart) {
                wdd->restart_nb.notifier_call = watchdog_restart_notifier;
 
@@ -289,6 +321,9 @@ static void __watchdog_unregister_device(struct watchdog_device *wdd)
        if (wdd->ops->restart)
                unregister_restart_handler(&wdd->restart_nb);
 
+       if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status))
+               unregister_reboot_notifier(&wdd->reboot_nb);
+
        watchdog_dev_unregister(wdd);
        ida_simple_remove(&watchdog_ida, wdd->id);
 }
index 4b2a854..8b5c742 100644 (file)
@@ -38,7 +38,6 @@
 #include <linux/miscdevice.h>  /* For handling misc devices */
 #include <linux/module.h>      /* For module stuff/... */
 #include <linux/mutex.h>       /* For mutexes */
-#include <linux/reboot.h>      /* For reboot notifier */
 #include <linux/slab.h>                /* For memory functions */
 #include <linux/types.h>       /* For standard types (like size_t) */
 #include <linux/watchdog.h>    /* For watchdog specific items */
@@ -1097,25 +1096,6 @@ static void watchdog_cdev_unregister(struct watchdog_device *wdd)
        put_device(&wd_data->dev);
 }
 
-static int watchdog_reboot_notifier(struct notifier_block *nb,
-                                   unsigned long code, void *data)
-{
-       struct watchdog_device *wdd;
-
-       wdd = container_of(nb, struct watchdog_device, reboot_nb);
-       if (code == SYS_DOWN || code == SYS_HALT) {
-               if (watchdog_active(wdd)) {
-                       int ret;
-
-                       ret = wdd->ops->stop(wdd);
-                       if (ret)
-                               return NOTIFY_BAD;
-               }
-       }
-
-       return NOTIFY_DONE;
-}
-
 /*
  *     watchdog_dev_register: register a watchdog device
  *     @wdd: watchdog device
@@ -1134,22 +1114,8 @@ int watchdog_dev_register(struct watchdog_device *wdd)
                return ret;
 
        ret = watchdog_register_pretimeout(wdd);
-       if (ret) {
+       if (ret)
                watchdog_cdev_unregister(wdd);
-               return ret;
-       }
-
-       if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
-               wdd->reboot_nb.notifier_call = watchdog_reboot_notifier;
-
-               ret = devm_register_reboot_notifier(&wdd->wd_data->dev,
-                                                   &wdd->reboot_nb);
-               if (ret) {
-                       pr_err("watchdog%d: Cannot register reboot notifier (%d)\n",
-                              wdd->id, ret);
-                       watchdog_dev_unregister(wdd);
-               }
-       }
 
        return ret;
 }
index 4fc83e3..0258415 100644 (file)
@@ -1006,19 +1006,19 @@ static int gntdev_mmap(struct file *flip, struct vm_area_struct *vma)
        }
        mutex_unlock(&priv->lock);
 
-       /*
-        * gntdev takes the address of the PTE in find_grant_ptes() and passes
-        * it to the hypervisor in gntdev_map_grant_pages(). The purpose of
-        * the notifier is to prevent the hypervisor pointer to the PTE from
-        * going stale.
-        *
-        * Since this vma's mappings can't be touched without the mmap_sem,
-        * and we are holding it now, there is no need for the notifier_range
-        * locking pattern.
-        */
-       mmu_interval_read_begin(&map->notifier);
-
        if (use_ptemod) {
+               /*
+                * gntdev takes the address of the PTE in find_grant_ptes() and
+                * passes it to the hypervisor in gntdev_map_grant_pages(). The
+                * purpose of the notifier is to prevent the hypervisor pointer
+                * to the PTE from going stale.
+                *
+                * Since this vma's mappings can't be touched without the
+                * mmap_sem, and we are holding it now, there is no need for
+                * the notifier_range locking pattern.
+                */
+               mmu_interval_read_begin(&map->notifier);
+
                map->pages_vm_start = vma->vm_start;
                err = apply_to_page_range(vma->vm_mm, vma->vm_start,
                                          vma->vm_end - vma->vm_start,
index 6d12fc3..a8d2443 100644 (file)
@@ -94,7 +94,7 @@ static void watch_target(struct xenbus_watch *watch,
                                  "%llu", &static_max) == 1))
                        static_max >>= PAGE_SHIFT - 10;
                else
-                       static_max = new_target;
+                       static_max = balloon_stats.current_pages;
 
                target_diff = (xen_pv_domain() || xen_initial_domain()) ? 0
                                : static_max - balloon_stats.target_pages;
index 6011171..b20e43e 100644 (file)
@@ -286,6 +286,43 @@ int xen_pcibk_config_write(struct pci_dev *dev, int offset, int size, u32 value)
        return xen_pcibios_err_to_errno(err);
 }
 
+int xen_pcibk_get_interrupt_type(struct pci_dev *dev)
+{
+       int err;
+       u16 val;
+       int ret = 0;
+
+       err = pci_read_config_word(dev, PCI_COMMAND, &val);
+       if (err)
+               return err;
+       if (!(val & PCI_COMMAND_INTX_DISABLE))
+               ret |= INTERRUPT_TYPE_INTX;
+
+       /*
+        * Do not trust dev->msi(x)_enabled here, as enabling could be done
+        * bypassing the pci_*msi* functions, by the qemu.
+        */
+       if (dev->msi_cap) {
+               err = pci_read_config_word(dev,
+                               dev->msi_cap + PCI_MSI_FLAGS,
+                               &val);
+               if (err)
+                       return err;
+               if (val & PCI_MSI_FLAGS_ENABLE)
+                       ret |= INTERRUPT_TYPE_MSI;
+       }
+       if (dev->msix_cap) {
+               err = pci_read_config_word(dev,
+                               dev->msix_cap + PCI_MSIX_FLAGS,
+                               &val);
+               if (err)
+                       return err;
+               if (val & PCI_MSIX_FLAGS_ENABLE)
+                       ret |= INTERRUPT_TYPE_MSIX;
+       }
+       return ret;
+}
+
 void xen_pcibk_config_free_dyn_fields(struct pci_dev *dev)
 {
        struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
index 22db630..28c4518 100644 (file)
@@ -65,6 +65,11 @@ struct config_field_entry {
        void *data;
 };
 
+#define INTERRUPT_TYPE_NONE (1<<0)
+#define INTERRUPT_TYPE_INTX (1<<1)
+#define INTERRUPT_TYPE_MSI  (1<<2)
+#define INTERRUPT_TYPE_MSIX (1<<3)
+
 extern bool xen_pcibk_permissive;
 
 #define OFFSET(cfg_entry) ((cfg_entry)->base_offset+(cfg_entry)->field->offset)
@@ -126,4 +131,6 @@ int xen_pcibk_config_capability_init(void);
 int xen_pcibk_config_header_add_fields(struct pci_dev *dev);
 int xen_pcibk_config_capability_add_fields(struct pci_dev *dev);
 
+int xen_pcibk_get_interrupt_type(struct pci_dev *dev);
+
 #endif                         /* __XEN_PCIBACK_CONF_SPACE_H__ */
index e569413..22f13ab 100644 (file)
@@ -189,6 +189,85 @@ static const struct config_field caplist_pm[] = {
        {}
 };
 
+static struct msi_msix_field_config {
+       u16          enable_bit; /* bit for enabling MSI/MSI-X */
+       unsigned int int_type;   /* interrupt type for exclusiveness check */
+} msi_field_config = {
+       .enable_bit     = PCI_MSI_FLAGS_ENABLE,
+       .int_type       = INTERRUPT_TYPE_MSI,
+}, msix_field_config = {
+       .enable_bit     = PCI_MSIX_FLAGS_ENABLE,
+       .int_type       = INTERRUPT_TYPE_MSIX,
+};
+
+static void *msi_field_init(struct pci_dev *dev, int offset)
+{
+       return &msi_field_config;
+}
+
+static void *msix_field_init(struct pci_dev *dev, int offset)
+{
+       return &msix_field_config;
+}
+
+static int msi_msix_flags_write(struct pci_dev *dev, int offset, u16 new_value,
+                               void *data)
+{
+       int err;
+       u16 old_value;
+       const struct msi_msix_field_config *field_config = data;
+       const struct xen_pcibk_dev_data *dev_data = pci_get_drvdata(dev);
+
+       if (xen_pcibk_permissive || dev_data->permissive)
+               goto write;
+
+       err = pci_read_config_word(dev, offset, &old_value);
+       if (err)
+               return err;
+
+       if (new_value == old_value)
+               return 0;
+
+       if (!dev_data->allow_interrupt_control ||
+           (new_value ^ old_value) & ~field_config->enable_bit)
+               return PCIBIOS_SET_FAILED;
+
+       if (new_value & field_config->enable_bit) {
+               /* don't allow enabling together with other interrupt types */
+               int int_type = xen_pcibk_get_interrupt_type(dev);
+
+               if (int_type == INTERRUPT_TYPE_NONE ||
+                   int_type == field_config->int_type)
+                       goto write;
+               return PCIBIOS_SET_FAILED;
+       }
+
+write:
+       return pci_write_config_word(dev, offset, new_value);
+}
+
+static const struct config_field caplist_msix[] = {
+       {
+               .offset    = PCI_MSIX_FLAGS,
+               .size      = 2,
+               .init      = msix_field_init,
+               .u.w.read  = xen_pcibk_read_config_word,
+               .u.w.write = msi_msix_flags_write,
+       },
+       {}
+};
+
+static const struct config_field caplist_msi[] = {
+       {
+               .offset    = PCI_MSI_FLAGS,
+               .size      = 2,
+               .init      = msi_field_init,
+               .u.w.read  = xen_pcibk_read_config_word,
+               .u.w.write = msi_msix_flags_write,
+       },
+       {}
+};
+
 static struct xen_pcibk_config_capability xen_pcibk_config_capability_pm = {
        .capability = PCI_CAP_ID_PM,
        .fields = caplist_pm,
@@ -197,11 +276,21 @@ static struct xen_pcibk_config_capability xen_pcibk_config_capability_vpd = {
        .capability = PCI_CAP_ID_VPD,
        .fields = caplist_vpd,
 };
+static struct xen_pcibk_config_capability xen_pcibk_config_capability_msi = {
+       .capability = PCI_CAP_ID_MSI,
+       .fields = caplist_msi,
+};
+static struct xen_pcibk_config_capability xen_pcibk_config_capability_msix = {
+       .capability = PCI_CAP_ID_MSIX,
+       .fields = caplist_msix,
+};
 
 int xen_pcibk_config_capability_init(void)
 {
        register_capability(&xen_pcibk_config_capability_vpd);
        register_capability(&xen_pcibk_config_capability_pm);
+       register_capability(&xen_pcibk_config_capability_msi);
+       register_capability(&xen_pcibk_config_capability_msix);
 
        return 0;
 }
index 10ae24b..fb4fccb 100644 (file)
@@ -117,6 +117,25 @@ static int command_write(struct pci_dev *dev, int offset, u16 value, void *data)
                pci_clear_mwi(dev);
        }
 
+       if (dev_data && dev_data->allow_interrupt_control) {
+               if ((cmd->val ^ value) & PCI_COMMAND_INTX_DISABLE) {
+                       if (value & PCI_COMMAND_INTX_DISABLE) {
+                               pci_intx(dev, 0);
+                       } else {
+                               /* Do not allow enabling INTx together with MSI or MSI-X. */
+                               switch (xen_pcibk_get_interrupt_type(dev)) {
+                               case INTERRUPT_TYPE_NONE:
+                                       pci_intx(dev, 1);
+                                       break;
+                               case INTERRUPT_TYPE_INTX:
+                                       break;
+                               default:
+                                       return PCIBIOS_SET_FAILED;
+                               }
+                       }
+               }
+       }
+
        cmd->val = value;
 
        if (!xen_pcibk_permissive && (!dev_data || !dev_data->permissive))
index 097410a..7af93d6 100644 (file)
@@ -304,6 +304,8 @@ void pcistub_put_pci_dev(struct pci_dev *dev)
        xen_pcibk_config_reset_dev(dev);
        xen_pcibk_config_free_dyn_fields(dev);
 
+       dev_data->allow_interrupt_control = 0;
+
        xen_unregister_device_domain_owner(dev);
 
        spin_lock_irqsave(&found_psdev->lock, flags);
@@ -1431,6 +1433,65 @@ static ssize_t permissive_show(struct device_driver *drv, char *buf)
 }
 static DRIVER_ATTR_RW(permissive);
 
+static ssize_t allow_interrupt_control_store(struct device_driver *drv,
+                                            const char *buf, size_t count)
+{
+       int domain, bus, slot, func;
+       int err;
+       struct pcistub_device *psdev;
+       struct xen_pcibk_dev_data *dev_data;
+
+       err = str_to_slot(buf, &domain, &bus, &slot, &func);
+       if (err)
+               goto out;
+
+       psdev = pcistub_device_find(domain, bus, slot, func);
+       if (!psdev) {
+               err = -ENODEV;
+               goto out;
+       }
+
+       dev_data = pci_get_drvdata(psdev->dev);
+       /* the driver data for a device should never be null at this point */
+       if (!dev_data) {
+               err = -ENXIO;
+               goto release;
+       }
+       dev_data->allow_interrupt_control = 1;
+release:
+       pcistub_device_put(psdev);
+out:
+       if (!err)
+               err = count;
+       return err;
+}
+
+static ssize_t allow_interrupt_control_show(struct device_driver *drv,
+                                           char *buf)
+{
+       struct pcistub_device *psdev;
+       struct xen_pcibk_dev_data *dev_data;
+       size_t count = 0;
+       unsigned long flags;
+
+       spin_lock_irqsave(&pcistub_devices_lock, flags);
+       list_for_each_entry(psdev, &pcistub_devices, dev_list) {
+               if (count >= PAGE_SIZE)
+                       break;
+               if (!psdev->dev)
+                       continue;
+               dev_data = pci_get_drvdata(psdev->dev);
+               if (!dev_data || !dev_data->allow_interrupt_control)
+                       continue;
+               count +=
+                   scnprintf(buf + count, PAGE_SIZE - count, "%s\n",
+                             pci_name(psdev->dev));
+       }
+       spin_unlock_irqrestore(&pcistub_devices_lock, flags);
+       return count;
+}
+static DRIVER_ATTR_RW(allow_interrupt_control);
+
 static void pcistub_exit(void)
 {
        driver_remove_file(&xen_pcibk_pci_driver.driver, &driver_attr_new_slot);
@@ -1441,6 +1502,8 @@ static void pcistub_exit(void)
        driver_remove_file(&xen_pcibk_pci_driver.driver,
                           &driver_attr_permissive);
        driver_remove_file(&xen_pcibk_pci_driver.driver,
+                          &driver_attr_allow_interrupt_control);
+       driver_remove_file(&xen_pcibk_pci_driver.driver,
                           &driver_attr_irq_handlers);
        driver_remove_file(&xen_pcibk_pci_driver.driver,
                           &driver_attr_irq_handler_state);
@@ -1530,6 +1593,9 @@ static int __init pcistub_init(void)
        if (!err)
                err = driver_create_file(&xen_pcibk_pci_driver.driver,
                                         &driver_attr_permissive);
+       if (!err)
+               err = driver_create_file(&xen_pcibk_pci_driver.driver,
+                                        &driver_attr_allow_interrupt_control);
 
        if (!err)
                err = driver_create_file(&xen_pcibk_pci_driver.driver,
index 263c059..ce1077e 100644 (file)
@@ -45,6 +45,7 @@ struct xen_pcibk_dev_data {
        struct list_head config_fields;
        struct pci_saved_state *pci_saved_state;
        unsigned int permissive:1;
+       unsigned int allow_interrupt_control:1;
        unsigned int warned_on_write:1;
        unsigned int enable_intx:1;
        unsigned int isr_on:1; /* Whether the IRQ handler is installed. */
index 378486b..66975da 100644 (file)
@@ -239,7 +239,9 @@ int xenbus_dev_probe(struct device *_dev)
                goto fail;
        }
 
+       spin_lock(&dev->reclaim_lock);
        err = drv->probe(dev, id);
+       spin_unlock(&dev->reclaim_lock);
        if (err)
                goto fail_put;
 
@@ -268,8 +270,11 @@ int xenbus_dev_remove(struct device *_dev)
 
        free_otherend_watch(dev);
 
-       if (drv->remove)
+       if (drv->remove) {
+               spin_lock(&dev->reclaim_lock);
                drv->remove(dev);
+               spin_unlock(&dev->reclaim_lock);
+       }
 
        module_put(drv->driver.owner);
 
@@ -468,6 +473,7 @@ int xenbus_probe_node(struct xen_bus_type *bus,
                goto fail;
 
        dev_set_name(&xendev->dev, "%s", devname);
+       spin_lock_init(&xendev->reclaim_lock);
 
        /* Register with generic device framework. */
        err = device_register(&xendev->dev);
index 14876fa..791f6fe 100644 (file)
@@ -247,6 +247,41 @@ static int backend_probe_and_watch(struct notifier_block *notifier,
        return NOTIFY_DONE;
 }
 
+static int backend_reclaim_memory(struct device *dev, void *data)
+{
+       const struct xenbus_driver *drv;
+       struct xenbus_device *xdev;
+
+       if (!dev->driver)
+               return 0;
+       drv = to_xenbus_driver(dev->driver);
+       if (drv && drv->reclaim_memory) {
+               xdev = to_xenbus_device(dev);
+               if (!spin_trylock(&xdev->reclaim_lock))
+                       return 0;
+               drv->reclaim_memory(xdev);
+               spin_unlock(&xdev->reclaim_lock);
+       }
+       return 0;
+}
+
+/*
+ * Returns 0 always because we are using shrinker to only detect memory
+ * pressure.
+ */
+static unsigned long backend_shrink_memory_count(struct shrinker *shrinker,
+                               struct shrink_control *sc)
+{
+       bus_for_each_dev(&xenbus_backend.bus, NULL, NULL,
+                       backend_reclaim_memory);
+       return 0;
+}
+
+static struct shrinker backend_memory_shrinker = {
+       .count_objects = backend_shrink_memory_count,
+       .seeks = DEFAULT_SEEKS,
+};
+
 static int __init xenbus_probe_backend_init(void)
 {
        static struct notifier_block xenstore_notifier = {
@@ -263,6 +298,9 @@ static int __init xenbus_probe_backend_init(void)
 
        register_xenstore_notifier(&xenstore_notifier);
 
+       if (register_shrinker(&backend_memory_shrinker))
+               pr_warn("shrinker registration failed\n");
+
        return 0;
 }
 subsys_initcall(xenbus_probe_backend_init);
index 2e4ca4d..1c9ae08 100644 (file)
@@ -56,10 +56,9 @@ proc_bus_zorro_read(struct file *file, char __user *buf, size_t nbytes, loff_t *
        return nbytes;
 }
 
-static const struct file_operations proc_bus_zorro_operations = {
-       .owner          = THIS_MODULE,
-       .llseek         = proc_bus_zorro_lseek,
-       .read           = proc_bus_zorro_read,
+static const struct proc_ops bus_zorro_proc_ops = {
+       .proc_lseek     = proc_bus_zorro_lseek,
+       .proc_read      = proc_bus_zorro_read,
 };
 
 static void * zorro_seq_start(struct seq_file *m, loff_t *pos)
@@ -105,7 +104,7 @@ static int __init zorro_proc_attach_device(unsigned int slot)
 
        sprintf(name, "%02x", slot);
        entry = proc_create_data(name, 0, proc_bus_zorro_dir,
-                                &proc_bus_zorro_operations,
+                                &bus_zorro_proc_ops,
                                 &zorro_autocon[slot]);
        if (!entry)
                return -ENOMEM;
index 7b623e9..8493a3f 100644 (file)
@@ -264,6 +264,7 @@ source "fs/pstore/Kconfig"
 source "fs/sysv/Kconfig"
 source "fs/ufs/Kconfig"
 source "fs/erofs/Kconfig"
+source "fs/vboxsf/Kconfig"
 
 endif # MISC_FILESYSTEMS
 
index 98be354..96520ba 100644 (file)
@@ -133,3 +133,4 @@ obj-$(CONFIG_CEPH_FS)               += ceph/
 obj-$(CONFIG_PSTORE)           += pstore/
 obj-$(CONFIG_EFIVAR_FS)                += efivarfs/
 obj-$(CONFIG_EROFS_FS)         += erofs/
+obj-$(CONFIG_VBOXSF_FS)                += vboxsf/
index 7f8a9b3..dda7a9a 100644 (file)
@@ -38,13 +38,13 @@ static int afs_statfs(struct dentry *dentry, struct kstatfs *buf);
 static int afs_show_devname(struct seq_file *m, struct dentry *root);
 static int afs_show_options(struct seq_file *m, struct dentry *root);
 static int afs_init_fs_context(struct fs_context *fc);
-static const struct fs_parameter_description afs_fs_parameters;
+static const struct fs_parameter_spec afs_fs_parameters[];
 
 struct file_system_type afs_fs_type = {
        .owner                  = THIS_MODULE,
        .name                   = "afs",
        .init_fs_context        = afs_init_fs_context,
-       .parameters             = &afs_fs_parameters,
+       .parameters             = afs_fs_parameters,
        .kill_sb                = afs_kill_super,
        .fs_flags               = FS_RENAME_DOES_D_MOVE,
 };
@@ -73,28 +73,22 @@ enum afs_param {
        Opt_source,
 };
 
-static const struct fs_parameter_spec afs_param_specs[] = {
-       fsparam_flag  ("autocell",      Opt_autocell),
-       fsparam_flag  ("dyn",           Opt_dyn),
-       fsparam_enum  ("flock",         Opt_flock),
-       fsparam_string("source",        Opt_source),
+static const struct constant_table afs_param_flock[] = {
+       {"local",       afs_flock_mode_local },
+       {"openafs",     afs_flock_mode_openafs },
+       {"strict",      afs_flock_mode_strict },
+       {"write",       afs_flock_mode_write },
        {}
 };
 
-static const struct fs_parameter_enum afs_param_enums[] = {
-       { Opt_flock,    "local",        afs_flock_mode_local },
-       { Opt_flock,    "openafs",      afs_flock_mode_openafs },
-       { Opt_flock,    "strict",       afs_flock_mode_strict },
-       { Opt_flock,    "write",        afs_flock_mode_write },
+static const struct fs_parameter_spec afs_fs_parameters[] = {
+       fsparam_flag  ("autocell",      Opt_autocell),
+       fsparam_flag  ("dyn",           Opt_dyn),
+       fsparam_enum  ("flock",         Opt_flock, afs_param_flock),
+       fsparam_string("source",        Opt_source),
        {}
 };
 
-static const struct fs_parameter_description afs_fs_parameters = {
-       .name           = "kAFS",
-       .specs          = afs_param_specs,
-       .enums          = afs_param_enums,
-};
-
 /*
  * initialise the filesystem
  */
@@ -323,7 +317,7 @@ static int afs_parse_param(struct fs_context *fc, struct fs_parameter *param)
        struct afs_fs_context *ctx = fc->fs_private;
        int opt;
 
-       opt = fs_parse(fc, &afs_fs_parameters, param, &result);
+       opt = fs_parse(fc, afs_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
index a9fbad2..5f3d3d8 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -1610,6 +1610,14 @@ static int aio_fsync(struct fsync_iocb *req, const struct iocb *iocb,
        return 0;
 }
 
+static void aio_poll_put_work(struct work_struct *work)
+{
+       struct poll_iocb *req = container_of(work, struct poll_iocb, work);
+       struct aio_kiocb *iocb = container_of(req, struct aio_kiocb, poll);
+
+       iocb_put(iocb);
+}
+
 static void aio_poll_complete_work(struct work_struct *work)
 {
        struct poll_iocb *req = container_of(work, struct poll_iocb, work);
@@ -1674,6 +1682,8 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
        list_del_init(&req->wait.entry);
 
        if (mask && spin_trylock_irqsave(&iocb->ki_ctx->ctx_lock, flags)) {
+               struct kioctx *ctx = iocb->ki_ctx;
+
                /*
                 * Try to complete the iocb inline if we can. Use
                 * irqsave/irqrestore because not all filesystems (e.g. fuse)
@@ -1683,8 +1693,14 @@ static int aio_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
                list_del(&iocb->ki_list);
                iocb->ki_res.res = mangle_poll(mask);
                req->done = true;
-               spin_unlock_irqrestore(&iocb->ki_ctx->ctx_lock, flags);
-               iocb_put(iocb);
+               if (iocb->ki_eventfd && eventfd_signal_count()) {
+                       iocb = NULL;
+                       INIT_WORK(&req->work, aio_poll_put_work);
+                       schedule_work(&req->work);
+               }
+               spin_unlock_irqrestore(&ctx->ctx_lock, flags);
+               if (iocb)
+                       iocb_put(iocb);
        } else {
                schedule_work(&req->work);
        }
index df28035..b4bbdbd 100644 (file)
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -183,18 +183,12 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
                inode->i_uid = attr->ia_uid;
        if (ia_valid & ATTR_GID)
                inode->i_gid = attr->ia_gid;
-       if (ia_valid & ATTR_ATIME) {
-               inode->i_atime = timestamp_truncate(attr->ia_atime,
-                                                 inode);
-       }
-       if (ia_valid & ATTR_MTIME) {
-               inode->i_mtime = timestamp_truncate(attr->ia_mtime,
-                                                 inode);
-       }
-       if (ia_valid & ATTR_CTIME) {
-               inode->i_ctime = timestamp_truncate(attr->ia_ctime,
-                                                 inode);
-       }
+       if (ia_valid & ATTR_ATIME)
+               inode->i_atime = attr->ia_atime;
+       if (ia_valid & ATTR_MTIME)
+               inode->i_mtime = attr->ia_mtime;
+       if (ia_valid & ATTR_CTIME)
+               inode->i_ctime = attr->ia_ctime;
        if (ia_valid & ATTR_MODE) {
                umode_t mode = attr->ia_mode;
 
@@ -268,8 +262,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
        attr->ia_ctime = now;
        if (!(ia_valid & ATTR_ATIME_SET))
                attr->ia_atime = now;
+       else
+               attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
        if (!(ia_valid & ATTR_MTIME_SET))
                attr->ia_mtime = now;
+       else
+               attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
+
        if (ia_valid & ATTR_KILL_PRIV) {
                error = security_inode_need_killpriv(dentry);
                if (error < 0)
index 1485158..404e050 100644 (file)
@@ -1191,7 +1191,6 @@ static int inc_block_group_ro(struct btrfs_block_group *cache, int force)
 {
        struct btrfs_space_info *sinfo = cache->space_info;
        u64 num_bytes;
-       u64 sinfo_used;
        int ret = -ENOSPC;
 
        spin_lock(&sinfo->lock);
@@ -1205,19 +1204,38 @@ static int inc_block_group_ro(struct btrfs_block_group *cache, int force)
 
        num_bytes = cache->length - cache->reserved - cache->pinned -
                    cache->bytes_super - cache->used;
-       sinfo_used = btrfs_space_info_used(sinfo, true);
 
        /*
-        * sinfo_used + num_bytes should always <= sinfo->total_bytes.
-        *
-        * Here we make sure if we mark this bg RO, we still have enough
-        * free space as buffer.
+        * Data never overcommits, even in mixed mode, so do just the straight
+        * check of left over space in how much we have allocated.
         */
-       if (sinfo_used + num_bytes <= sinfo->total_bytes) {
+       if (force) {
+               ret = 0;
+       } else if (sinfo->flags & BTRFS_BLOCK_GROUP_DATA) {
+               u64 sinfo_used = btrfs_space_info_used(sinfo, true);
+
+               /*
+                * Here we make sure if we mark this bg RO, we still have enough
+                * free space as buffer.
+                */
+               if (sinfo_used + num_bytes <= sinfo->total_bytes)
+                       ret = 0;
+       } else {
+               /*
+                * We overcommit metadata, so we need to do the
+                * btrfs_can_overcommit check here, and we need to pass in
+                * BTRFS_RESERVE_NO_FLUSH to give ourselves the most amount of
+                * leeway to allow us to mark this block group as read only.
+                */
+               if (btrfs_can_overcommit(cache->fs_info, sinfo, num_bytes,
+                                        BTRFS_RESERVE_NO_FLUSH))
+                       ret = 0;
+       }
+
+       if (!ret) {
                sinfo->bytes_readonly += num_bytes;
                cache->ro++;
                list_add_tail(&cache->ro_list, &sinfo->ro_bgs);
-               ret = 0;
        }
 out:
        spin_unlock(&cache->lock);
@@ -1225,9 +1243,6 @@ out:
        if (ret == -ENOSPC && btrfs_test_opt(cache->fs_info, ENOSPC_DEBUG)) {
                btrfs_info(cache->fs_info,
                        "unable to make block group %llu ro", cache->start);
-               btrfs_info(cache->fs_info,
-                       "sinfo_used=%llu bg_num_bytes=%llu",
-                       sinfo_used, num_bytes);
                btrfs_dump_space_info(cache->fs_info, cache->space_info, 0, 0);
        }
        return ret;
@@ -2225,7 +2240,7 @@ again:
                }
        }
 
-       ret = inc_block_group_ro(cache, !do_chunk_alloc);
+       ret = inc_block_group_ro(cache, 0);
        if (!do_chunk_alloc)
                goto unlock_out;
        if (!ret)
index 24658b5..f2ec1a9 100644 (file)
@@ -326,12 +326,10 @@ u64 btrfs_get_tree_mod_seq(struct btrfs_fs_info *fs_info,
                           struct seq_list *elem)
 {
        write_lock(&fs_info->tree_mod_log_lock);
-       spin_lock(&fs_info->tree_mod_seq_lock);
        if (!elem->seq) {
                elem->seq = btrfs_inc_tree_mod_seq(fs_info);
                list_add_tail(&elem->list, &fs_info->tree_mod_seq_list);
        }
-       spin_unlock(&fs_info->tree_mod_seq_lock);
        write_unlock(&fs_info->tree_mod_log_lock);
 
        return elem->seq;
@@ -351,7 +349,7 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
        if (!seq_putting)
                return;
 
-       spin_lock(&fs_info->tree_mod_seq_lock);
+       write_lock(&fs_info->tree_mod_log_lock);
        list_del(&elem->list);
        elem->seq = 0;
 
@@ -362,19 +360,17 @@ void btrfs_put_tree_mod_seq(struct btrfs_fs_info *fs_info,
                                 * blocker with lower sequence number exists, we
                                 * cannot remove anything from the log
                                 */
-                               spin_unlock(&fs_info->tree_mod_seq_lock);
+                               write_unlock(&fs_info->tree_mod_log_lock);
                                return;
                        }
                        min_seq = cur_elem->seq;
                }
        }
-       spin_unlock(&fs_info->tree_mod_seq_lock);
 
        /*
         * anything that's lower than the lowest existing (read: blocked)
         * sequence number can be removed from the tree.
         */
-       write_lock(&fs_info->tree_mod_log_lock);
        tm_root = &fs_info->tree_mod_log;
        for (node = rb_first(tm_root); node; node = next) {
                next = rb_next(node);
index f90b820..36df977 100644 (file)
@@ -714,14 +714,12 @@ struct btrfs_fs_info {
        atomic_t nr_delayed_iputs;
        wait_queue_head_t delayed_iputs_wait;
 
-       /* this protects tree_mod_seq_list */
-       spinlock_t tree_mod_seq_lock;
        atomic64_t tree_mod_seq;
-       struct list_head tree_mod_seq_list;
 
-       /* this protects tree_mod_log */
+       /* this protects tree_mod_log and tree_mod_seq_list */
        rwlock_t tree_mod_log_lock;
        struct rb_root tree_mod_log;
+       struct list_head tree_mod_seq_list;
 
        atomic_t async_delalloc_pages;
 
index df3bd88..dfdb7d4 100644 (file)
@@ -492,7 +492,7 @@ void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
        if (head->is_data)
                return;
 
-       spin_lock(&fs_info->tree_mod_seq_lock);
+       read_lock(&fs_info->tree_mod_log_lock);
        if (!list_empty(&fs_info->tree_mod_seq_list)) {
                struct seq_list *elem;
 
@@ -500,7 +500,7 @@ void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
                                        struct seq_list, list);
                seq = elem->seq;
        }
-       spin_unlock(&fs_info->tree_mod_seq_lock);
+       read_unlock(&fs_info->tree_mod_log_lock);
 
 again:
        for (node = rb_first_cached(&head->ref_tree); node;
@@ -518,7 +518,7 @@ int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, u64 seq)
        struct seq_list *elem;
        int ret = 0;
 
-       spin_lock(&fs_info->tree_mod_seq_lock);
+       read_lock(&fs_info->tree_mod_log_lock);
        if (!list_empty(&fs_info->tree_mod_seq_list)) {
                elem = list_first_entry(&fs_info->tree_mod_seq_list,
                                        struct seq_list, list);
@@ -531,7 +531,7 @@ int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, u64 seq)
                }
        }
 
-       spin_unlock(&fs_info->tree_mod_seq_lock);
+       read_unlock(&fs_info->tree_mod_log_lock);
        return ret;
 }
 
index aea48d6..7fa9bb7 100644 (file)
@@ -2697,7 +2697,6 @@ int __cold open_ctree(struct super_block *sb,
        spin_lock_init(&fs_info->fs_roots_radix_lock);
        spin_lock_init(&fs_info->delayed_iput_lock);
        spin_lock_init(&fs_info->defrag_inodes_lock);
-       spin_lock_init(&fs_info->tree_mod_seq_lock);
        spin_lock_init(&fs_info->super_lock);
        spin_lock_init(&fs_info->buffer_lock);
        spin_lock_init(&fs_info->unused_bgs_lock);
index e2d3028..c0f2027 100644 (file)
@@ -1593,21 +1593,25 @@ void find_first_clear_extent_bit(struct extent_io_tree *tree, u64 start,
        /* Find first extent with bits cleared */
        while (1) {
                node = __etree_search(tree, start, &next, &prev, NULL, NULL);
-               if (!node) {
+               if (!node && !next && !prev) {
+                       /*
+                        * Tree is completely empty, send full range and let
+                        * caller deal with it
+                        */
+                       *start_ret = 0;
+                       *end_ret = -1;
+                       goto out;
+               } else if (!node && !next) {
+                       /*
+                        * We are past the last allocated chunk, set start at
+                        * the end of the last extent.
+                        */
+                       state = rb_entry(prev, struct extent_state, rb_node);
+                       *start_ret = state->end + 1;
+                       *end_ret = -1;
+                       goto out;
+               } else if (!node) {
                        node = next;
-                       if (!node) {
-                               /*
-                                * We are past the last allocated chunk,
-                                * set start at the end of the last extent. The
-                                * device alloc tree should never be empty so
-                                * prev is always set.
-                                */
-                               ASSERT(prev);
-                               state = rb_entry(prev, struct extent_state, rb_node);
-                               *start_ret = state->end + 1;
-                               *end_ret = -1;
-                               goto out;
-                       }
                }
                /*
                 * At this point 'node' either contains 'start' or start is
@@ -3438,11 +3442,7 @@ static noinline_for_stack int __extent_writepage_io(struct inode *inode,
        ret = btrfs_writepage_cow_fixup(page, start, page_end);
        if (ret) {
                /* Fixup worker will requeue */
-               if (ret == -EBUSY)
-                       wbc->pages_skipped++;
-               else
-                       redirty_page_for_writepage(wbc, page);
-
+               redirty_page_for_writepage(wbc, page);
                update_nr_written(wbc, nr_written);
                unlock_page(page);
                return 1;
@@ -4166,7 +4166,16 @@ retry:
                 */
                scanned = 1;
                index = 0;
-               goto retry;
+
+               /*
+                * If we're looping we could run into a page that is locked by a
+                * writer and that writer could be waiting on writeback for a
+                * page in our current bio, and thus deadlock, so flush the
+                * write bio here.
+                */
+               ret = flush_write_bio(epd);
+               if (!ret)
+                       goto retry;
        }
 
        if (wbc->range_cyclic || (wbc->nr_to_write > 0 && range_whole))
index 6d2bb58..5b3ec93 100644 (file)
@@ -2189,6 +2189,7 @@ int btrfs_set_extent_delalloc(struct inode *inode, u64 start, u64 end,
 /* see btrfs_writepage_start_hook for details on why this is required */
 struct btrfs_writepage_fixup {
        struct page *page;
+       struct inode *inode;
        struct btrfs_work work;
 };
 
@@ -2202,27 +2203,71 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work)
        struct inode *inode;
        u64 page_start;
        u64 page_end;
-       int ret;
+       int ret = 0;
+       bool free_delalloc_space = true;
 
        fixup = container_of(work, struct btrfs_writepage_fixup, work);
        page = fixup->page;
+       inode = fixup->inode;
+       page_start = page_offset(page);
+       page_end = page_offset(page) + PAGE_SIZE - 1;
+
+       /*
+        * This is similar to page_mkwrite, we need to reserve the space before
+        * we take the page lock.
+        */
+       ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start,
+                                          PAGE_SIZE);
 again:
        lock_page(page);
+
+       /*
+        * Before we queued this fixup, we took a reference on the page.
+        * page->mapping may go NULL, but it shouldn't be moved to a different
+        * address space.
+        */
        if (!page->mapping || !PageDirty(page) || !PageChecked(page)) {
-               ClearPageChecked(page);
+               /*
+                * Unfortunately this is a little tricky, either
+                *
+                * 1) We got here and our page had already been dealt with and
+                *    we reserved our space, thus ret == 0, so we need to just
+                *    drop our space reservation and bail.  This can happen the
+                *    first time we come into the fixup worker, or could happen
+                *    while waiting for the ordered extent.
+                * 2) Our page was already dealt with, but we happened to get an
+                *    ENOSPC above from the btrfs_delalloc_reserve_space.  In
+                *    this case we obviously don't have anything to release, but
+                *    because the page was already dealt with we don't want to
+                *    mark the page with an error, so make sure we're resetting
+                *    ret to 0.  This is why we have this check _before_ the ret
+                *    check, because we do not want to have a surprise ENOSPC
+                *    when the page was already properly dealt with.
+                */
+               if (!ret) {
+                       btrfs_delalloc_release_extents(BTRFS_I(inode),
+                                                      PAGE_SIZE);
+                       btrfs_delalloc_release_space(inode, data_reserved,
+                                                    page_start, PAGE_SIZE,
+                                                    true);
+               }
+               ret = 0;
                goto out_page;
        }
 
-       inode = page->mapping->host;
-       page_start = page_offset(page);
-       page_end = page_offset(page) + PAGE_SIZE - 1;
+       /*
+        * We can't mess with the page state unless it is locked, so now that
+        * it is locked bail if we failed to make our space reservation.
+        */
+       if (ret)
+               goto out_page;
 
        lock_extent_bits(&BTRFS_I(inode)->io_tree, page_start, page_end,
                         &cached_state);
 
        /* already ordered? We're done */
        if (PagePrivate2(page))
-               goto out;
+               goto out_reserved;
 
        ordered = btrfs_lookup_ordered_range(BTRFS_I(inode), page_start,
                                        PAGE_SIZE);
@@ -2235,39 +2280,49 @@ again:
                goto again;
        }
 
-       ret = btrfs_delalloc_reserve_space(inode, &data_reserved, page_start,
-                                          PAGE_SIZE);
-       if (ret) {
-               mapping_set_error(page->mapping, ret);
-               end_extent_writepage(page, ret, page_start, page_end);
-               ClearPageChecked(page);
-               goto out;
-        }
-
        ret = btrfs_set_extent_delalloc(inode, page_start, page_end, 0,
                                        &cached_state);
-       if (ret) {
-               mapping_set_error(page->mapping, ret);
-               end_extent_writepage(page, ret, page_start, page_end);
-               ClearPageChecked(page);
+       if (ret)
                goto out_reserved;
-       }
 
-       ClearPageChecked(page);
-       set_page_dirty(page);
+       /*
+        * Everything went as planned, we're now the owner of a dirty page with
+        * delayed allocation bits set and space reserved for our COW
+        * destination.
+        *
+        * The page was dirty when we started, nothing should have cleaned it.
+        */
+       BUG_ON(!PageDirty(page));
+       free_delalloc_space = false;
 out_reserved:
        btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
-       if (ret)
+       if (free_delalloc_space)
                btrfs_delalloc_release_space(inode, data_reserved, page_start,
                                             PAGE_SIZE, true);
-out:
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
                             &cached_state);
 out_page:
+       if (ret) {
+               /*
+                * We hit ENOSPC or other errors.  Update the mapping and page
+                * to reflect the errors and clean the page.
+                */
+               mapping_set_error(page->mapping, ret);
+               end_extent_writepage(page, ret, page_start, page_end);
+               clear_page_dirty_for_io(page);
+               SetPageError(page);
+       }
+       ClearPageChecked(page);
        unlock_page(page);
        put_page(page);
        kfree(fixup);
        extent_changeset_free(data_reserved);
+       /*
+        * As a precaution, do a delayed iput in case it would be the last iput
+        * that could need flushing space. Recursing back to fixup worker would
+        * deadlock.
+        */
+       btrfs_add_delayed_iput(inode);
 }
 
 /*
@@ -2291,6 +2346,13 @@ int btrfs_writepage_cow_fixup(struct page *page, u64 start, u64 end)
        if (TestClearPagePrivate2(page))
                return 0;
 
+       /*
+        * PageChecked is set below when we create a fixup worker for this page,
+        * don't try to create another one if we're already PageChecked()
+        *
+        * The extent_io writepage code will redirty the page if we send back
+        * EAGAIN.
+        */
        if (PageChecked(page))
                return -EAGAIN;
 
@@ -2298,12 +2360,21 @@ int btrfs_writepage_cow_fixup(struct page *page, u64 start, u64 end)
        if (!fixup)
                return -EAGAIN;
 
+       /*
+        * We are already holding a reference to this inode from
+        * write_cache_pages.  We need to hold it because the space reservation
+        * takes place outside of the page lock, and we can't trust
+        * page->mapping outside of the page lock.
+        */
+       ihold(inode);
        SetPageChecked(page);
        get_page(page);
        btrfs_init_work(&fixup->work, btrfs_writepage_fixup_worker, NULL, NULL);
        fixup->page = page;
+       fixup->inode = inode;
        btrfs_queue_work(fs_info->fixup_workers, &fixup->work);
-       return -EBUSY;
+
+       return -EAGAIN;
 }
 
 static int insert_reserved_file_extent(struct btrfs_trans_handle *trans,
index 091e5bc..a055b65 100644 (file)
@@ -1269,7 +1269,8 @@ static int __iterate_backrefs(u64 ino, u64 offset, u64 root, void *ctx_)
                 * destination of the stream.
                 */
                if (ino == bctx->cur_objectid &&
-                   offset >= bctx->sctx->cur_inode_next_write_offset)
+                   offset + bctx->extent_len >
+                   bctx->sctx->cur_inode_next_write_offset)
                        return 0;
        }
 
index 537bc31..01297c5 100644 (file)
@@ -159,9 +159,9 @@ static inline u64 calc_global_rsv_need_space(struct btrfs_block_rsv *global)
        return (global->size << 1);
 }
 
-static int can_overcommit(struct btrfs_fs_info *fs_info,
-                         struct btrfs_space_info *space_info, u64 bytes,
-                         enum btrfs_reserve_flush_enum flush)
+int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
+                        struct btrfs_space_info *space_info, u64 bytes,
+                        enum btrfs_reserve_flush_enum flush)
 {
        u64 profile;
        u64 avail;
@@ -226,7 +226,8 @@ again:
 
                /* Check and see if our ticket can be satisified now. */
                if ((used + ticket->bytes <= space_info->total_bytes) ||
-                   can_overcommit(fs_info, space_info, ticket->bytes, flush)) {
+                   btrfs_can_overcommit(fs_info, space_info, ticket->bytes,
+                                        flush)) {
                        btrfs_space_info_update_bytes_may_use(fs_info,
                                                              space_info,
                                                              ticket->bytes);
@@ -639,13 +640,14 @@ btrfs_calc_reclaim_metadata_size(struct btrfs_fs_info *fs_info,
                return to_reclaim;
 
        to_reclaim = min_t(u64, num_online_cpus() * SZ_1M, SZ_16M);
-       if (can_overcommit(fs_info, space_info, to_reclaim,
-                          BTRFS_RESERVE_FLUSH_ALL))
+       if (btrfs_can_overcommit(fs_info, space_info, to_reclaim,
+                                BTRFS_RESERVE_FLUSH_ALL))
                return 0;
 
        used = btrfs_space_info_used(space_info, true);
 
-       if (can_overcommit(fs_info, space_info, SZ_1M, BTRFS_RESERVE_FLUSH_ALL))
+       if (btrfs_can_overcommit(fs_info, space_info, SZ_1M,
+                                BTRFS_RESERVE_FLUSH_ALL))
                expected = div_factor_fine(space_info->total_bytes, 95);
        else
                expected = div_factor_fine(space_info->total_bytes, 90);
@@ -1004,7 +1006,7 @@ static int __reserve_metadata_bytes(struct btrfs_fs_info *fs_info,
         */
        if (!pending_tickets &&
            ((used + orig_bytes <= space_info->total_bytes) ||
-            can_overcommit(fs_info, space_info, orig_bytes, flush))) {
+            btrfs_can_overcommit(fs_info, space_info, orig_bytes, flush))) {
                btrfs_space_info_update_bytes_may_use(fs_info, space_info,
                                                      orig_bytes);
                ret = 0;
index 1a349e3..24514cd 100644 (file)
@@ -127,6 +127,9 @@ int btrfs_reserve_metadata_bytes(struct btrfs_root *root,
                                 enum btrfs_reserve_flush_enum flush);
 void btrfs_try_granting_tickets(struct btrfs_fs_info *fs_info,
                                struct btrfs_space_info *space_info);
+int btrfs_can_overcommit(struct btrfs_fs_info *fs_info,
+                        struct btrfs_space_info *space_info, u64 bytes,
+                        enum btrfs_reserve_flush_enum flush);
 
 static inline void btrfs_space_info_free_bytes_may_use(
                                struct btrfs_fs_info *fs_info,
index a906315..0616a54 100644 (file)
@@ -2135,7 +2135,15 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
         */
        thresh = SZ_4M;
 
-       if (!mixed && total_free_meta - thresh < block_rsv->size)
+       /*
+        * We only want to claim there's no available space if we can no longer
+        * allocate chunks for our metadata profile and our global reserve will
+        * not fit in the free metadata space.  If we aren't ->full then we
+        * still can allocate chunks and thus are fine using the currently
+        * calculated f_bavail.
+        */
+       if (!mixed && block_rsv->space_info->full &&
+           total_free_meta - thresh < block_rsv->size)
                buf->f_bavail = 0;
 
        buf->f_type = BTRFS_SUPER_MAGIC;
index c12b91f..84fb3fa 100644 (file)
@@ -142,7 +142,6 @@ struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(u32 nodesize, u32 sectorsize)
        spin_lock_init(&fs_info->qgroup_lock);
        spin_lock_init(&fs_info->super_lock);
        spin_lock_init(&fs_info->fs_roots_radix_lock);
-       spin_lock_init(&fs_info->tree_mod_seq_lock);
        mutex_init(&fs_info->qgroup_ioctl_lock);
        mutex_init(&fs_info->qgroup_rescan_lock);
        rwlock_init(&fs_info->tree_mod_log_lock);
index 123d9a6..df7ce87 100644 (file)
@@ -441,8 +441,17 @@ static int test_find_first_clear_extent_bit(void)
        int ret = -EINVAL;
 
        test_msg("running find_first_clear_extent_bit test");
+
        extent_io_tree_init(NULL, &tree, IO_TREE_SELFTEST, NULL);
 
+       /* Test correct handling of empty tree */
+       find_first_clear_extent_bit(&tree, 0, &start, &end, CHUNK_TRIMMED);
+       if (start != 0 || end != -1) {
+               test_err(
+       "error getting a range from completely empty tree: start %llu end %llu",
+                        start, end);
+               goto out;
+       }
        /*
         * Set 1M-4M alloc/discard and 32M-64M thus leaving a hole between
         * 4M-32M
index 44a3ce1..1dc97f2 100644 (file)
@@ -396,7 +396,7 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
        struct cachefiles_object *object;
        struct cachefiles_cache *cache;
        struct inode *inode;
-       sector_t block0, block;
+       sector_t block;
        unsigned shift;
        int ret;
 
@@ -412,7 +412,6 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
 
        inode = d_backing_inode(object->backer);
        ASSERT(S_ISREG(inode->i_mode));
-       ASSERT(inode->i_mapping->a_ops->bmap);
        ASSERT(inode->i_mapping->a_ops->readpages);
 
        /* calculate the shift required to use bmap */
@@ -428,12 +427,14 @@ int cachefiles_read_or_alloc_page(struct fscache_retrieval *op,
         *   enough for this as it doesn't indicate errors, but it's all we've
         *   got for the moment
         */
-       block0 = page->index;
-       block0 <<= shift;
+       block = page->index;
+       block <<= shift;
+
+       ret = bmap(inode, &block);
+       ASSERT(ret < 0);
 
-       block = inode->i_mapping->a_ops->bmap(inode->i_mapping, block0);
        _debug("%llx -> %llx",
-              (unsigned long long) block0,
+              (unsigned long long) (page->index << shift),
               (unsigned long long) block);
 
        if (block) {
@@ -711,7 +712,6 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
 
        inode = d_backing_inode(object->backer);
        ASSERT(S_ISREG(inode->i_mode));
-       ASSERT(inode->i_mapping->a_ops->bmap);
        ASSERT(inode->i_mapping->a_ops->readpages);
 
        /* calculate the shift required to use bmap */
@@ -728,7 +728,7 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
 
        ret = space ? -ENODATA : -ENOBUFS;
        list_for_each_entry_safe(page, _n, pages, lru) {
-               sector_t block0, block;
+               sector_t block;
 
                /* we assume the absence or presence of the first block is a
                 * good enough indication for the page as a whole
@@ -736,13 +736,14 @@ int cachefiles_read_or_alloc_pages(struct fscache_retrieval *op,
                 *   good enough for this as it doesn't indicate errors, but
                 *   it's all we've got for the moment
                 */
-               block0 = page->index;
-               block0 <<= shift;
+               block = page->index;
+               block <<= shift;
+
+               ret = bmap(inode, &block);
+               ASSERT(!ret);
 
-               block = inode->i_mapping->a_ops->bmap(inode->i_mapping,
-                                                     block0);
                _debug("%llx -> %llx",
-                      (unsigned long long) block0,
+                      (unsigned long long) (page->index << shift),
                       (unsigned long long) block);
 
                if (block) {
index c1da294..0a0823d 100644 (file)
@@ -8,7 +8,7 @@ obj-$(CONFIG_CEPH_FS) += ceph.o
 ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \
        export.o caps.o snap.o xattr.o quota.o io.o \
        mds_client.o mdsmap.o strings.o ceph_frag.o \
-       debugfs.o
+       debugfs.o util.o
 
 ceph-$(CONFIG_CEPH_FSCACHE) += cache.o
 ceph-$(CONFIG_CEPH_FS_POSIX_ACL) += acl.o
index aa55f41..26be652 100644 (file)
@@ -222,8 +222,8 @@ int ceph_pre_init_acls(struct inode *dir, umode_t *mode,
                err = ceph_pagelist_reserve(pagelist, len + val_size2 + 8);
                if (err)
                        goto out_err;
-               err = ceph_pagelist_encode_string(pagelist,
-                                                 XATTR_NAME_POSIX_ACL_DEFAULT, len);
+               ceph_pagelist_encode_string(pagelist,
+                                         XATTR_NAME_POSIX_ACL_DEFAULT, len);
                err = posix_acl_to_xattr(&init_user_ns, default_acl,
                                         tmp_buf, val_size2);
                if (err < 0)
index 73f24f3..270b769 100644 (file)
@@ -67,7 +67,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc)
                if (uniq_len && memcmp(ent->uniquifier, fscache_uniq, uniq_len))
                        continue;
 
-               errorf(fc, "ceph: fscache cookie already registered for fsid %pU, use fsc=<uniquifier> option",
+               errorfc(fc, "fscache cookie already registered for fsid %pU, use fsc=<uniquifier> option",
                       fsid);
                err = -EBUSY;
                goto out_unlock;
@@ -96,7 +96,7 @@ int ceph_fscache_register_fs(struct ceph_fs_client* fsc, struct fs_context *fc)
                list_add_tail(&ent->list, &ceph_fscache_list);
        } else {
                kfree(ent);
-               errorf(fc, "ceph: unable to register fscache cookie for fsid %pU",
+               errorfc(fc, "unable to register fscache cookie for fsid %pU",
                       fsid);
                /* all other fs ignore this error */
        }
index 9d09bb5..28ae0c1 100644 (file)
@@ -908,7 +908,8 @@ int __ceph_caps_issued_mask(struct ceph_inode_info *ci, int mask, int touch)
                                                       ci_node);
                                        if (!__cap_is_valid(cap))
                                                continue;
-                                       __touch_cap(cap);
+                                       if (cap->issued & mask)
+                                               __touch_cap(cap);
                                }
                        }
                        return 1;
index c281f32..fb7cabd 100644 (file)
@@ -33,7 +33,7 @@ static int mdsmap_show(struct seq_file *s, void *p)
        seq_printf(s, "max_mds %d\n", mdsmap->m_max_mds);
        seq_printf(s, "session_timeout %d\n", mdsmap->m_session_timeout);
        seq_printf(s, "session_autoclose %d\n", mdsmap->m_session_autoclose);
-       for (i = 0; i < mdsmap->m_num_mds; i++) {
+       for (i = 0; i < mdsmap->possible_max_rank; i++) {
                struct ceph_entity_addr *addr = &mdsmap->m_info[i].addr;
                int state = mdsmap->m_info[i].state;
                seq_printf(s, "\tmds%d\t%s\t(%s)\n", i,
index 2e4764f..d0cd0ab 100644 (file)
@@ -1186,7 +1186,7 @@ void __ceph_dentry_dir_lease_touch(struct ceph_dentry_info *di)
        struct dentry *dn = di->dentry;
        struct ceph_mds_client *mdsc;
 
-       dout("dentry_dir_lease_touch %p %p '%pd' (offset %lld)\n",
+       dout("dentry_dir_lease_touch %p %p '%pd' (offset 0x%llx)\n",
             di, dn, dn, di->offset);
 
        if (!list_empty(&di->lease_list)) {
@@ -1567,7 +1567,7 @@ static int ceph_d_revalidate(struct dentry *dentry, unsigned int flags)
                inode = d_inode(dentry);
        }
 
-       dout("d_revalidate %p '%pd' inode %p offset %lld\n", dentry,
+       dout("d_revalidate %p '%pd' inode %p offset 0x%llx\n", dentry,
             dentry, inode, ceph_dentry(dentry)->offset);
 
        /* always trust cached snapped dentries, snapdir dentry */
index 11929d2..c3b8e8e 100644 (file)
@@ -1974,6 +1974,9 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
        if (ceph_test_mount_opt(src_fsc, NOCOPYFROM))
                return -EOPNOTSUPP;
 
+       if (!src_fsc->have_copy_from2)
+               return -EOPNOTSUPP;
+
        /*
         * Striped file layouts require that we copy partial objects, but the
         * OSD copy-from operation only supports full-object copies.  Limit
@@ -2101,8 +2104,14 @@ static ssize_t __ceph_copy_file_range(struct file *src_file, loff_t src_off,
                        CEPH_OSD_OP_FLAG_FADVISE_NOCACHE,
                        &dst_oid, &dst_oloc,
                        CEPH_OSD_OP_FLAG_FADVISE_SEQUENTIAL |
-                       CEPH_OSD_OP_FLAG_FADVISE_DONTNEED, 0);
+                       CEPH_OSD_OP_FLAG_FADVISE_DONTNEED,
+                       dst_ci->i_truncate_seq, dst_ci->i_truncate_size,
+                       CEPH_OSD_COPY_FROM_FLAG_TRUNCATE_SEQ);
                if (err) {
+                       if (err == -EOPNOTSUPP) {
+                               src_fsc->have_copy_from2 = false;
+                               pr_notice("OSDs don't support copy-from2; disabling copy offload\n");
+                       }
                        dout("ceph_osdc_copy_from returned %d\n", err);
                        if (!ret)
                                ret = err;
index c074075..d01710a 100644 (file)
@@ -55,11 +55,9 @@ struct inode *ceph_get_inode(struct super_block *sb, struct ceph_vino vino)
        inode = iget5_locked(sb, t, ceph_ino_compare, ceph_set_ino_cb, &vino);
        if (!inode)
                return ERR_PTR(-ENOMEM);
-       if (inode->i_state & I_NEW) {
+       if (inode->i_state & I_NEW)
                dout("get_inode created new inode %p %llx.%llx ino %llx\n",
                     inode, ceph_vinop(inode), (u64)inode->i_ino);
-               unlock_new_inode(inode);
-       }
 
        dout("get_inode on %lu=%llx.%llx got %p\n", inode->i_ino, vino.ino,
             vino.snap, inode);
@@ -88,6 +86,10 @@ struct inode *ceph_get_snapdir(struct inode *parent)
        inode->i_fop = &ceph_snapdir_fops;
        ci->i_snap_caps = CEPH_CAP_PIN; /* so we can open */
        ci->i_rbytes = 0;
+
+       if (inode->i_state & I_NEW)
+               unlock_new_inode(inode);
+
        return inode;
 }
 
@@ -728,8 +730,7 @@ void ceph_fill_file_time(struct inode *inode, int issued,
 static int fill_inode(struct inode *inode, struct page *locked_page,
                      struct ceph_mds_reply_info_in *iinfo,
                      struct ceph_mds_reply_dirfrag *dirinfo,
-                     struct ceph_mds_session *session,
-                     unsigned long ttl_from, int cap_fmode,
+                     struct ceph_mds_session *session, int cap_fmode,
                      struct ceph_cap_reservation *caps_reservation)
 {
        struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
@@ -754,8 +755,11 @@ static int fill_inode(struct inode *inode, struct page *locked_page,
        info_caps = le32_to_cpu(info->cap.caps);
 
        /* prealloc new cap struct */
-       if (info_caps && ceph_snap(inode) == CEPH_NOSNAP)
+       if (info_caps && ceph_snap(inode) == CEPH_NOSNAP) {
                new_cap = ceph_get_cap(mdsc, caps_reservation);
+               if (!new_cap)
+                       return -ENOMEM;
+       }
 
        /*
         * prealloc xattr data, if it looks like we'll need it.  only
@@ -1237,7 +1241,7 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req)
                if (dir) {
                        err = fill_inode(dir, NULL,
                                         &rinfo->diri, rinfo->dirfrag,
-                                        session, req->r_request_started, -1,
+                                        session, -1,
                                         &req->r_caps_reservation);
                        if (err < 0)
                                goto done;
@@ -1302,18 +1306,22 @@ retry_lookup:
                        err = PTR_ERR(in);
                        goto done;
                }
-               req->r_target_inode = in;
 
                err = fill_inode(in, req->r_locked_page, &rinfo->targeti, NULL,
-                               session, req->r_request_started,
+                               session,
                                (!test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags) &&
-                               rinfo->head->result == 0) ?  req->r_fmode : -1,
+                                rinfo->head->result == 0) ?  req->r_fmode : -1,
                                &req->r_caps_reservation);
                if (err < 0) {
                        pr_err("fill_inode badness %p %llx.%llx\n",
                                in, ceph_vinop(in));
+                       if (in->i_state & I_NEW)
+                               discard_new_inode(in);
                        goto done;
                }
+               req->r_target_inode = in;
+               if (in->i_state & I_NEW)
+                       unlock_new_inode(in);
        }
 
        /*
@@ -1493,12 +1501,18 @@ static int readdir_prepopulate_inodes_only(struct ceph_mds_request *req,
                        continue;
                }
                rc = fill_inode(in, NULL, &rde->inode, NULL, session,
-                               req->r_request_started, -1,
-                               &req->r_caps_reservation);
+                               -1, &req->r_caps_reservation);
                if (rc < 0) {
                        pr_err("fill_inode badness on %p got %d\n", in, rc);
                        err = rc;
+                       if (in->i_state & I_NEW) {
+                               ihold(in);
+                               discard_new_inode(in);
+                       }
+               } else if (in->i_state & I_NEW) {
+                       unlock_new_inode(in);
                }
+
                /* avoid calling iput_final() in mds dispatch threads */
                ceph_async_iput(in);
        }
@@ -1694,19 +1708,24 @@ retry_lookup:
                }
 
                ret = fill_inode(in, NULL, &rde->inode, NULL, session,
-                                req->r_request_started, -1,
-                                &req->r_caps_reservation);
+                                -1, &req->r_caps_reservation);
                if (ret < 0) {
                        pr_err("fill_inode badness on %p\n", in);
                        if (d_really_is_negative(dn)) {
                                /* avoid calling iput_final() in mds
                                 * dispatch threads */
+                               if (in->i_state & I_NEW) {
+                                       ihold(in);
+                                       discard_new_inode(in);
+                               }
                                ceph_async_iput(in);
                        }
                        d_drop(dn);
                        err = ret;
                        goto next_item;
                }
+               if (in->i_state & I_NEW)
+                       unlock_new_inode(in);
 
                if (d_really_is_negative(dn)) {
                        if (ceph_security_xattr_deadlock(in)) {
index 145d46b..bbbbddf 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/ratelimit.h>
+#include <linux/bits.h>
 
 #include "super.h"
 #include "mds_client.h"
@@ -530,6 +531,7 @@ const char *ceph_session_state_name(int s)
        case CEPH_MDS_SESSION_OPEN: return "open";
        case CEPH_MDS_SESSION_HUNG: return "hung";
        case CEPH_MDS_SESSION_CLOSING: return "closing";
+       case CEPH_MDS_SESSION_CLOSED: return "closed";
        case CEPH_MDS_SESSION_RESTARTING: return "restarting";
        case CEPH_MDS_SESSION_RECONNECTING: return "reconnecting";
        case CEPH_MDS_SESSION_REJECTED: return "rejected";
@@ -537,7 +539,7 @@ const char *ceph_session_state_name(int s)
        }
 }
 
-static struct ceph_mds_session *get_session(struct ceph_mds_session *s)
+struct ceph_mds_session *ceph_get_mds_session(struct ceph_mds_session *s)
 {
        if (refcount_inc_not_zero(&s->s_ref)) {
                dout("mdsc get_session %p %d -> %d\n", s,
@@ -568,7 +570,7 @@ struct ceph_mds_session *__ceph_lookup_mds_session(struct ceph_mds_client *mdsc,
 {
        if (mds >= mdsc->max_sessions || !mdsc->sessions[mds])
                return NULL;
-       return get_session(mdsc->sessions[mds]);
+       return ceph_get_mds_session(mdsc->sessions[mds]);
 }
 
 static bool __have_session(struct ceph_mds_client *mdsc, int mds)
@@ -597,7 +599,7 @@ static struct ceph_mds_session *register_session(struct ceph_mds_client *mdsc,
 {
        struct ceph_mds_session *s;
 
-       if (mds >= mdsc->mdsmap->m_num_mds)
+       if (mds >= mdsc->mdsmap->possible_max_rank)
                return ERR_PTR(-EINVAL);
 
        s = kzalloc(sizeof(*s), GFP_NOFS);
@@ -674,7 +676,6 @@ static void __unregister_session(struct ceph_mds_client *mdsc,
        dout("__unregister_session mds%d %p\n", s->s_mds, s);
        BUG_ON(mdsc->sessions[s->s_mds] != s);
        mdsc->sessions[s->s_mds] = NULL;
-       s->s_state = 0;
        ceph_con_close(&s->s_con);
        ceph_put_mds_session(s);
        atomic_dec(&mdsc->num_sessions);
@@ -878,7 +879,8 @@ static struct inode *get_nonsnap_parent(struct dentry *dentry)
  * Called under mdsc->mutex.
  */
 static int __choose_mds(struct ceph_mds_client *mdsc,
-                       struct ceph_mds_request *req)
+                       struct ceph_mds_request *req,
+                       bool *random)
 {
        struct inode *inode;
        struct ceph_inode_info *ci;
@@ -888,6 +890,9 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
        u32 hash = req->r_direct_hash;
        bool is_hash = test_bit(CEPH_MDS_R_DIRECT_IS_HASH, &req->r_req_flags);
 
+       if (random)
+               *random = false;
+
        /*
         * is there a specific mds we should try?  ignore hint if we have
         * no session and the mds is not up (active or recovering).
@@ -895,7 +900,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
        if (req->r_resend_mds >= 0 &&
            (__have_session(mdsc, req->r_resend_mds) ||
             ceph_mdsmap_get_state(mdsc->mdsmap, req->r_resend_mds) > 0)) {
-               dout("choose_mds using resend_mds mds%d\n",
+               dout("%s using resend_mds mds%d\n", __func__,
                     req->r_resend_mds);
                return req->r_resend_mds;
        }
@@ -913,7 +918,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
                        rcu_read_lock();
                        inode = get_nonsnap_parent(req->r_dentry);
                        rcu_read_unlock();
-                       dout("__choose_mds using snapdir's parent %p\n", inode);
+                       dout("%s using snapdir's parent %p\n", __func__, inode);
                }
        } else if (req->r_dentry) {
                /* ignore race with rename; old or new d_parent is okay */
@@ -933,7 +938,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
                        /* direct snapped/virtual snapdir requests
                         * based on parent dir inode */
                        inode = get_nonsnap_parent(parent);
-                       dout("__choose_mds using nonsnap parent %p\n", inode);
+                       dout("%s using nonsnap parent %p\n", __func__, inode);
                } else {
                        /* dentry target */
                        inode = d_inode(req->r_dentry);
@@ -949,8 +954,8 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
                rcu_read_unlock();
        }
 
-       dout("__choose_mds %p is_hash=%d (%d) mode %d\n", inode, (int)is_hash,
-            (int)hash, mode);
+       dout("%s %p is_hash=%d (0x%x) mode %d\n", __func__, inode, (int)is_hash,
+            hash, mode);
        if (!inode)
                goto random;
        ci = ceph_inode(inode);
@@ -968,30 +973,33 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
                                get_random_bytes(&r, 1);
                                r %= frag.ndist;
                                mds = frag.dist[r];
-                               dout("choose_mds %p %llx.%llx "
-                                    "frag %u mds%d (%d/%d)\n",
-                                    inode, ceph_vinop(inode),
-                                    frag.frag, mds,
-                                    (int)r, frag.ndist);
+                               dout("%s %p %llx.%llx frag %u mds%d (%d/%d)\n",
+                                    __func__, inode, ceph_vinop(inode),
+                                    frag.frag, mds, (int)r, frag.ndist);
                                if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >=
-                                   CEPH_MDS_STATE_ACTIVE)
+                                   CEPH_MDS_STATE_ACTIVE &&
+                                   !ceph_mdsmap_is_laggy(mdsc->mdsmap, mds))
                                        goto out;
                        }
 
                        /* since this file/dir wasn't known to be
                         * replicated, then we want to look for the
                         * authoritative mds. */
-                       mode = USE_AUTH_MDS;
                        if (frag.mds >= 0) {
                                /* choose auth mds */
                                mds = frag.mds;
-                               dout("choose_mds %p %llx.%llx "
-                                    "frag %u mds%d (auth)\n",
-                                    inode, ceph_vinop(inode), frag.frag, mds);
+                               dout("%s %p %llx.%llx frag %u mds%d (auth)\n",
+                                    __func__, inode, ceph_vinop(inode),
+                                    frag.frag, mds);
                                if (ceph_mdsmap_get_state(mdsc->mdsmap, mds) >=
-                                   CEPH_MDS_STATE_ACTIVE)
-                                       goto out;
+                                   CEPH_MDS_STATE_ACTIVE) {
+                                       if (mode == USE_ANY_MDS &&
+                                           !ceph_mdsmap_is_laggy(mdsc->mdsmap,
+                                                                 mds))
+                                               goto out;
+                               }
                        }
+                       mode = USE_AUTH_MDS;
                }
        }
 
@@ -1007,7 +1015,7 @@ static int __choose_mds(struct ceph_mds_client *mdsc,
                goto random;
        }
        mds = cap->session->s_mds;
-       dout("choose_mds %p %llx.%llx mds%d (%scap %p)\n",
+       dout("%s %p %llx.%llx mds%d (%scap %p)\n", __func__,
             inode, ceph_vinop(inode), mds,
             cap == ci->i_auth_cap ? "auth " : "", cap);
        spin_unlock(&ci->i_ceph_lock);
@@ -1018,8 +1026,11 @@ out:
        return mds;
 
 random:
+       if (random)
+               *random = true;
+
        mds = ceph_mdsmap_get_random_mds(mdsc->mdsmap);
-       dout("choose_mds chose random mds%d\n", mds);
+       dout("%s chose random mds%d\n", __func__, mds);
        return mds;
 }
 
@@ -1045,20 +1056,21 @@ static struct ceph_msg *create_session_msg(u32 op, u64 seq)
        return msg;
 }
 
+static const unsigned char feature_bits[] = CEPHFS_FEATURES_CLIENT_SUPPORTED;
+#define FEATURE_BYTES(c) (DIV_ROUND_UP((size_t)feature_bits[c - 1] + 1, 64) * 8)
 static void encode_supported_features(void **p, void *end)
 {
-       static const unsigned char bits[] = CEPHFS_FEATURES_CLIENT_SUPPORTED;
-       static const size_t count = ARRAY_SIZE(bits);
+       static const size_t count = ARRAY_SIZE(feature_bits);
 
        if (count > 0) {
                size_t i;
-               size_t size = ((size_t)bits[count - 1] + 64) / 64 * 8;
+               size_t size = FEATURE_BYTES(count);
 
                BUG_ON(*p + 4 + size > end);
                ceph_encode_32(p, size);
                memset(*p, 0, size);
                for (i = 0; i < count; i++)
-                       ((unsigned char*)(*p))[i / 8] |= 1 << (bits[i] % 8);
+                       ((unsigned char*)(*p))[i / 8] |= BIT(feature_bits[i] % 8);
                *p += size;
        } else {
                BUG_ON(*p + 4 > end);
@@ -1079,6 +1091,7 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
        int metadata_key_count = 0;
        struct ceph_options *opt = mdsc->fsc->client->options;
        struct ceph_mount_options *fsopt = mdsc->fsc->mount_options;
+       size_t size, count;
        void *p, *end;
 
        const char* metadata[][2] = {
@@ -1096,8 +1109,13 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
                        strlen(metadata[i][1]);
                metadata_key_count++;
        }
+
        /* supported feature */
-       extra_bytes += 4 + 8;
+       size = 0;
+       count = ARRAY_SIZE(feature_bits);
+       if (count > 0)
+               size = FEATURE_BYTES(count);
+       extra_bytes += 4 + size;
 
        /* Allocate the message */
        msg = ceph_msg_new(CEPH_MSG_CLIENT_SESSION, sizeof(*h) + extra_bytes,
@@ -1117,7 +1135,7 @@ static struct ceph_msg *create_session_open_msg(struct ceph_mds_client *mdsc, u6
         * Serialize client metadata into waiting buffer space, using
         * the format that userspace expects for map<string, string>
         *
-        * ClientSession messages with metadata are v2
+        * ClientSession messages with metadata are v3
         */
        msg->hdr.version = cpu_to_le16(3);
        msg->hdr.compat_version = cpu_to_le16(1);
@@ -1219,7 +1237,7 @@ static void __open_export_target_sessions(struct ceph_mds_client *mdsc,
        struct ceph_mds_session *ts;
        int i, mds = session->s_mds;
 
-       if (mds >= mdsc->mdsmap->m_num_mds)
+       if (mds >= mdsc->mdsmap->possible_max_rank)
                return;
 
        mi = &mdsc->mdsmap->m_info[mds];
@@ -1967,7 +1985,7 @@ void ceph_flush_cap_releases(struct ceph_mds_client *mdsc,
        if (mdsc->stopping)
                return;
 
-       get_session(session);
+       ceph_get_mds_session(session);
        if (queue_work(mdsc->fsc->cap_wq,
                       &session->s_cap_release_work)) {
                dout("cap release work queued\n");
@@ -2072,7 +2090,6 @@ struct ceph_mds_request *
 ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
 {
        struct ceph_mds_request *req = kzalloc(sizeof(*req), GFP_NOFS);
-       struct timespec64 ts;
 
        if (!req)
                return ERR_PTR(-ENOMEM);
@@ -2091,8 +2108,7 @@ ceph_mdsc_create_request(struct ceph_mds_client *mdsc, int op, int mode)
        init_completion(&req->r_safe_completion);
        INIT_LIST_HEAD(&req->r_unsafe_item);
 
-       ktime_get_coarse_real_ts64(&ts);
-       req->r_stamp = timespec64_trunc(ts, mdsc->fsc->sb->s_time_gran);
+       ktime_get_coarse_real_ts64(&req->r_stamp);
 
        req->r_op = op;
        req->r_direct_mode = mode;
@@ -2518,6 +2534,26 @@ static int __prepare_send_request(struct ceph_mds_client *mdsc,
 }
 
 /*
+ * called under mdsc->mutex
+ */
+static int __send_request(struct ceph_mds_client *mdsc,
+                         struct ceph_mds_session *session,
+                         struct ceph_mds_request *req,
+                         bool drop_cap_releases)
+{
+       int err;
+
+       err = __prepare_send_request(mdsc, req, session->s_mds,
+                                    drop_cap_releases);
+       if (!err) {
+               ceph_msg_get(req->r_request);
+               ceph_con_send(&session->s_con, req->r_request);
+       }
+
+       return err;
+}
+
+/*
  * send request, or put it on the appropriate wait list.
  */
 static void __do_request(struct ceph_mds_client *mdsc,
@@ -2526,6 +2562,7 @@ static void __do_request(struct ceph_mds_client *mdsc,
        struct ceph_mds_session *session = NULL;
        int mds = -1;
        int err = 0;
+       bool random;
 
        if (req->r_err || test_bit(CEPH_MDS_R_GOT_RESULT, &req->r_req_flags)) {
                if (test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags))
@@ -2558,15 +2595,14 @@ static void __do_request(struct ceph_mds_client *mdsc,
                if (!(mdsc->fsc->mount_options->flags &
                      CEPH_MOUNT_OPT_MOUNTWAIT) &&
                    !ceph_mdsmap_is_cluster_available(mdsc->mdsmap)) {
-                       err = -ENOENT;
-                       pr_info("probably no mds server is up\n");
+                       err = -EHOSTUNREACH;
                        goto finish;
                }
        }
 
        put_request_session(req);
 
-       mds = __choose_mds(mdsc, req);
+       mds = __choose_mds(mdsc, req, &random);
        if (mds < 0 ||
            ceph_mdsmap_get_state(mdsc->mdsmap, mds) < CEPH_MDS_STATE_ACTIVE) {
                dout("do_request no mds or not active, waiting for map\n");
@@ -2583,7 +2619,7 @@ static void __do_request(struct ceph_mds_client *mdsc,
                        goto finish;
                }
        }
-       req->r_session = get_session(session);
+       req->r_session = ceph_get_mds_session(session);
 
        dout("do_request mds%d session %p state %s\n", mds, session,
             ceph_session_state_name(session->s_state));
@@ -2594,8 +2630,12 @@ static void __do_request(struct ceph_mds_client *mdsc,
                        goto out_session;
                }
                if (session->s_state == CEPH_MDS_SESSION_NEW ||
-                   session->s_state == CEPH_MDS_SESSION_CLOSING)
+                   session->s_state == CEPH_MDS_SESSION_CLOSING) {
                        __open_session(mdsc, session);
+                       /* retry the same mds later */
+                       if (random)
+                               req->r_resend_mds = mds;
+               }
                list_add(&req->r_wait, &session->s_waiting);
                goto out_session;
        }
@@ -2606,11 +2646,7 @@ static void __do_request(struct ceph_mds_client *mdsc,
        if (req->r_request_started == 0)   /* note request start time */
                req->r_request_started = jiffies;
 
-       err = __prepare_send_request(mdsc, req, mds, false);
-       if (!err) {
-               ceph_msg_get(req->r_request);
-               ceph_con_send(&session->s_con, req->r_request);
-       }
+       err = __send_request(mdsc, session, req, false);
 
 out_session:
        ceph_put_mds_session(session);
@@ -2863,7 +2899,7 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
                        mutex_unlock(&mdsc->mutex);
                        goto out;
                } else  {
-                       int mds = __choose_mds(mdsc, req);
+                       int mds = __choose_mds(mdsc, req, NULL);
                        if (mds >= 0 && mds != req->r_session->s_mds) {
                                dout("but auth changed, so resending\n");
                                __do_request(mdsc, req);
@@ -2879,6 +2915,10 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
                set_bit(CEPH_MDS_R_GOT_SAFE, &req->r_req_flags);
                __unregister_request(mdsc, req);
 
+               /* last request during umount? */
+               if (mdsc->stopping && !__get_oldest_req(mdsc))
+                       complete_all(&mdsc->safe_umount_waiters);
+
                if (test_bit(CEPH_MDS_R_GOT_UNSAFE, &req->r_req_flags)) {
                        /*
                         * We already handled the unsafe response, now do the
@@ -2889,9 +2929,6 @@ static void handle_reply(struct ceph_mds_session *session, struct ceph_msg *msg)
                         */
                        dout("got safe reply %llu, mds%d\n", tid, mds);
 
-                       /* last unsafe request during umount? */
-                       if (mdsc->stopping && !__get_oldest_req(mdsc))
-                               complete_all(&mdsc->safe_umount_waiters);
                        mutex_unlock(&mdsc->mutex);
                        goto out;
                }
@@ -3106,7 +3143,7 @@ static void handle_session(struct ceph_mds_session *session,
 
        mutex_lock(&mdsc->mutex);
        if (op == CEPH_SESSION_CLOSE) {
-               get_session(session);
+               ceph_get_mds_session(session);
                __unregister_session(mdsc, session);
        }
        /* FIXME: this ttl calculation is generous */
@@ -3144,6 +3181,7 @@ static void handle_session(struct ceph_mds_session *session,
        case CEPH_SESSION_CLOSE:
                if (session->s_state == CEPH_MDS_SESSION_RECONNECTING)
                        pr_info("mds%d reconnect denied\n", session->s_mds);
+               session->s_state = CEPH_MDS_SESSION_CLOSED;
                cleanup_session_requests(mdsc, session);
                remove_session_caps(session);
                wake = 2; /* for good measure */
@@ -3211,7 +3249,6 @@ bad:
        return;
 }
 
-
 /*
  * called under session->mutex.
  */
@@ -3220,18 +3257,12 @@ static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
 {
        struct ceph_mds_request *req, *nreq;
        struct rb_node *p;
-       int err;
 
        dout("replay_unsafe_requests mds%d\n", session->s_mds);
 
        mutex_lock(&mdsc->mutex);
-       list_for_each_entry_safe(req, nreq, &session->s_unsafe, r_unsafe_item) {
-               err = __prepare_send_request(mdsc, req, session->s_mds, true);
-               if (!err) {
-                       ceph_msg_get(req->r_request);
-                       ceph_con_send(&session->s_con, req->r_request);
-               }
-       }
+       list_for_each_entry_safe(req, nreq, &session->s_unsafe, r_unsafe_item)
+               __send_request(mdsc, session, req, true);
 
        /*
         * also re-send old requests when MDS enters reconnect stage. So that MDS
@@ -3246,14 +3277,8 @@ static void replay_unsafe_requests(struct ceph_mds_client *mdsc,
                if (req->r_attempts == 0)
                        continue; /* only old requests */
                if (req->r_session &&
-                   req->r_session->s_mds == session->s_mds) {
-                       err = __prepare_send_request(mdsc, req,
-                                                    session->s_mds, true);
-                       if (!err) {
-                               ceph_msg_get(req->r_request);
-                               ceph_con_send(&session->s_con, req->r_request);
-                       }
-               }
+                   req->r_session->s_mds == session->s_mds)
+                       __send_request(mdsc, session, req, true);
        }
        mutex_unlock(&mdsc->mutex);
 }
@@ -3764,7 +3789,7 @@ static void check_new_map(struct ceph_mds_client *mdsc,
        dout("check_new_map new %u old %u\n",
             newmap->m_epoch, oldmap->m_epoch);
 
-       for (i = 0; i < oldmap->m_num_mds && i < mdsc->max_sessions; i++) {
+       for (i = 0; i < oldmap->possible_max_rank && i < mdsc->max_sessions; i++) {
                if (!mdsc->sessions[i])
                        continue;
                s = mdsc->sessions[i];
@@ -3778,9 +3803,9 @@ static void check_new_map(struct ceph_mds_client *mdsc,
                     ceph_mdsmap_is_laggy(newmap, i) ? " (laggy)" : "",
                     ceph_session_state_name(s->s_state));
 
-               if (i >= newmap->m_num_mds) {
+               if (i >= newmap->possible_max_rank) {
                        /* force close session for stopped mds */
-                       get_session(s);
+                       ceph_get_mds_session(s);
                        __unregister_session(mdsc, s);
                        __wake_requests(mdsc, &s->s_waiting);
                        mutex_unlock(&mdsc->mutex);
@@ -3835,7 +3860,7 @@ static void check_new_map(struct ceph_mds_client *mdsc,
                }
        }
 
-       for (i = 0; i < newmap->m_num_mds && i < mdsc->max_sessions; i++) {
+       for (i = 0; i < newmap->possible_max_rank && i < mdsc->max_sessions; i++) {
                s = mdsc->sessions[i];
                if (!s)
                        continue;
@@ -4381,7 +4406,7 @@ void ceph_mdsc_close_sessions(struct ceph_mds_client *mdsc)
        mutex_lock(&mdsc->mutex);
        for (i = 0; i < mdsc->max_sessions; i++) {
                if (mdsc->sessions[i]) {
-                       session = get_session(mdsc->sessions[i]);
+                       session = ceph_get_mds_session(mdsc->sessions[i]);
                        __unregister_session(mdsc, session);
                        mutex_unlock(&mdsc->mutex);
                        mutex_lock(&session->s_mutex);
@@ -4609,11 +4634,8 @@ static struct ceph_connection *con_get(struct ceph_connection *con)
 {
        struct ceph_mds_session *s = con->private;
 
-       if (get_session(s)) {
-               dout("mdsc con_get %p ok (%d)\n", s, refcount_read(&s->s_ref));
+       if (ceph_get_mds_session(s))
                return con;
-       }
-       dout("mdsc con_get %p FAIL\n", s);
        return NULL;
 }
 
@@ -4621,7 +4643,6 @@ static void con_put(struct ceph_connection *con)
 {
        struct ceph_mds_session *s = con->private;
 
-       dout("mdsc con_put %p (%d)\n", s, refcount_read(&s->s_ref) - 1);
        ceph_put_mds_session(s);
 }
 
index 14c7e8c..27a7446 100644 (file)
 #include <linux/ceph/auth.h>
 
 /* The first 8 bits are reserved for old ceph releases */
-#define CEPHFS_FEATURE_MIMIC           8
-#define CEPHFS_FEATURE_REPLY_ENCODING  9
-#define CEPHFS_FEATURE_RECLAIM_CLIENT  10
-#define CEPHFS_FEATURE_LAZY_CAP_WANTED 11
-#define CEPHFS_FEATURE_MULTI_RECONNECT  12
+enum ceph_feature_type {
+       CEPHFS_FEATURE_MIMIC = 8,
+       CEPHFS_FEATURE_REPLY_ENCODING,
+       CEPHFS_FEATURE_RECLAIM_CLIENT,
+       CEPHFS_FEATURE_LAZY_CAP_WANTED,
+       CEPHFS_FEATURE_MULTI_RECONNECT,
+
+       CEPHFS_FEATURE_MAX = CEPHFS_FEATURE_MULTI_RECONNECT,
+};
 
-#define CEPHFS_FEATURES_CLIENT_SUPPORTED {     \
+/*
+ * This will always have the highest feature bit value
+ * as the last element of the array.
+ */
+#define CEPHFS_FEATURES_CLIENT_SUPPORTED {     \
        0, 1, 2, 3, 4, 5, 6, 7,                 \
        CEPHFS_FEATURE_MIMIC,                   \
        CEPHFS_FEATURE_REPLY_ENCODING,          \
        CEPHFS_FEATURE_LAZY_CAP_WANTED,         \
        CEPHFS_FEATURE_MULTI_RECONNECT,         \
+                                               \
+       CEPHFS_FEATURE_MAX,                     \
 }
 #define CEPHFS_FEATURES_CLIENT_REQUIRED {}
 
-
 /*
  * Some lock dependencies:
  *
@@ -151,7 +160,8 @@ enum {
        CEPH_MDS_SESSION_RESTARTING = 5,
        CEPH_MDS_SESSION_RECONNECTING = 6,
        CEPH_MDS_SESSION_CLOSING = 7,
-       CEPH_MDS_SESSION_REJECTED = 8,
+       CEPH_MDS_SESSION_CLOSED = 8,
+       CEPH_MDS_SESSION_REJECTED = 9,
 };
 
 struct ceph_mds_session {
@@ -174,6 +184,7 @@ struct ceph_mds_session {
 
        /* protected by s_cap_lock */
        spinlock_t        s_cap_lock;
+       refcount_t        s_ref;
        struct list_head  s_caps;     /* all caps issued by this session */
        struct ceph_cap  *s_cap_iterator;
        int               s_nr_caps;
@@ -188,7 +199,6 @@ struct ceph_mds_session {
        unsigned long     s_renew_requested; /* last time we sent a renew req */
        u64               s_renew_seq;
 
-       refcount_t        s_ref;
        struct list_head  s_waiting;  /* waiting requests */
        struct list_head  s_unsafe;   /* unsafe requests */
 };
@@ -224,6 +234,7 @@ struct ceph_mds_request {
        struct rb_node r_node;
        struct ceph_mds_client *r_mdsc;
 
+       struct kref       r_kref;
        int r_op;                    /* mds op code */
 
        /* operation on what? */
@@ -294,7 +305,6 @@ struct ceph_mds_request {
        int               r_resend_mds; /* mds to resend to next, if any*/
        u32               r_sent_on_mseq; /* cap mseq request was sent at*/
 
-       struct kref       r_kref;
        struct list_head  r_wait;
        struct completion r_completion;
        struct completion r_safe_completion;
@@ -451,15 +461,10 @@ extern const char *ceph_mds_op_name(int op);
 extern struct ceph_mds_session *
 __ceph_lookup_mds_session(struct ceph_mds_client *, int mds);
 
-static inline struct ceph_mds_session *
-ceph_get_mds_session(struct ceph_mds_session *s)
-{
-       refcount_inc(&s->s_ref);
-       return s;
-}
-
 extern const char *ceph_session_state_name(int s);
 
+extern struct ceph_mds_session *
+ceph_get_mds_session(struct ceph_mds_session *s);
 extern void ceph_put_mds_session(struct ceph_mds_session *s);
 
 extern int ceph_send_msg_mds(struct ceph_mds_client *mdsc,
index 471bac3..8896278 100644 (file)
 
 #include "super.h"
 
+#define CEPH_MDS_IS_READY(i, ignore_laggy) \
+       (m->m_info[i].state > 0 && ignore_laggy ? true : !m->m_info[i].laggy)
 
-/*
- * choose a random mds that is "up" (i.e. has a state > 0), or -1.
- */
-int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
+static int __mdsmap_get_random_mds(struct ceph_mdsmap *m, bool ignore_laggy)
 {
        int n = 0;
        int i, j;
 
-       /* special case for one mds */
-       if (1 == m->m_num_mds && m->m_info[0].state > 0)
-               return 0;
-
        /* count */
-       for (i = 0; i < m->m_num_mds; i++)
-               if (m->m_info[i].state > 0)
+       for (i = 0; i < m->possible_max_rank; i++)
+               if (CEPH_MDS_IS_READY(i, ignore_laggy))
                        n++;
        if (n == 0)
                return -1;
 
        /* pick */
        n = prandom_u32() % n;
-       for (j = 0, i = 0; i < m->m_num_mds; i++) {
-               if (m->m_info[i].state > 0)
+       for (j = 0, i = 0; i < m->possible_max_rank; i++) {
+               if (CEPH_MDS_IS_READY(i, ignore_laggy))
                        j++;
                if (j > n)
                        break;
@@ -45,6 +40,20 @@ int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
        return i;
 }
 
+/*
+ * choose a random mds that is "up" (i.e. has a state > 0), or -1.
+ */
+int ceph_mdsmap_get_random_mds(struct ceph_mdsmap *m)
+{
+       int mds;
+
+       mds = __mdsmap_get_random_mds(m, false);
+       if (mds == m->possible_max_rank || mds == -1)
+               mds = __mdsmap_get_random_mds(m, true);
+
+       return mds == m->possible_max_rank ? -1 : mds;
+}
+
 #define __decode_and_drop_type(p, end, type, bad)              \
        do {                                                    \
                if (*p + sizeof(type) > end)                    \
@@ -138,14 +147,29 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
        m->m_session_autoclose = ceph_decode_32(p);
        m->m_max_file_size = ceph_decode_64(p);
        m->m_max_mds = ceph_decode_32(p);
-       m->m_num_mds = m->m_max_mds;
 
-       m->m_info = kcalloc(m->m_num_mds, sizeof(*m->m_info), GFP_NOFS);
+       /*
+        * pick out the active nodes as the m_num_active_mds, the
+        * m_num_active_mds maybe larger than m_max_mds when decreasing
+        * the max_mds in cluster side, in other case it should less
+        * than or equal to m_max_mds.
+        */
+       m->m_num_active_mds = n = ceph_decode_32(p);
+
+       /*
+        * the possible max rank, it maybe larger than the m_num_active_mds,
+        * for example if the mds_max == 2 in the cluster, when the MDS(0)
+        * was laggy and being replaced by a new MDS, we will temporarily
+        * receive a new mds map with n_num_mds == 1 and the active MDS(1),
+        * and the mds rank >= m_num_active_mds.
+        */
+       m->possible_max_rank = max(m->m_num_active_mds, m->m_max_mds);
+
+       m->m_info = kcalloc(m->possible_max_rank, sizeof(*m->m_info), GFP_NOFS);
        if (!m->m_info)
                goto nomem;
 
        /* pick out active nodes from mds_info (state > 0) */
-       n = ceph_decode_32(p);
        for (i = 0; i < n; i++) {
                u64 global_id;
                u32 namelen;
@@ -215,18 +239,15 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                     ceph_mds_state_name(state),
                     laggy ? "(laggy)" : "");
 
-               if (mds < 0 || state <= 0)
+               if (mds < 0 || mds >= m->possible_max_rank) {
+                       pr_warn("mdsmap_decode got incorrect mds(%d)\n", mds);
                        continue;
+               }
 
-               if (mds >= m->m_num_mds) {
-                       int new_num = max(mds + 1, m->m_num_mds * 2);
-                       void *new_m_info = krealloc(m->m_info,
-                                               new_num * sizeof(*m->m_info),
-                                               GFP_NOFS | __GFP_ZERO);
-                       if (!new_m_info)
-                               goto nomem;
-                       m->m_info = new_m_info;
-                       m->m_num_mds = new_num;
+               if (state <= 0) {
+                       pr_warn("mdsmap_decode got incorrect state(%s)\n",
+                               ceph_mds_state_name(state));
+                       continue;
                }
 
                info = &m->m_info[mds];
@@ -247,14 +268,6 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                        info->export_targets = NULL;
                }
        }
-       if (m->m_num_mds > m->m_max_mds) {
-               /* find max up mds */
-               for (i = m->m_num_mds; i >= m->m_max_mds; i--) {
-                       if (i == 0 || m->m_info[i-1].state > 0)
-                               break;
-               }
-               m->m_num_mds = i;
-       }
 
        /* pg_pools */
        ceph_decode_32_safe(p, end, n, bad);
@@ -296,14 +309,14 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
 
                for (i = 0; i < n; i++) {
                        s32 mds = ceph_decode_32(p);
-                       if (mds >= 0 && mds < m->m_num_mds) {
+                       if (mds >= 0 && mds < m->possible_max_rank) {
                                if (m->m_info[mds].laggy)
                                        num_laggy++;
                        }
                }
                m->m_num_laggy = num_laggy;
 
-               if (n > m->m_num_mds) {
+               if (n > m->possible_max_rank) {
                        void *new_m_info = krealloc(m->m_info,
                                                    n * sizeof(*m->m_info),
                                                    GFP_NOFS | __GFP_ZERO);
@@ -311,7 +324,7 @@ struct ceph_mdsmap *ceph_mdsmap_decode(void **p, void *end)
                                goto nomem;
                        m->m_info = new_m_info;
                }
-               m->m_num_mds = n;
+               m->possible_max_rank = n;
        }
 
        /* inc */
@@ -382,7 +395,7 @@ void ceph_mdsmap_destroy(struct ceph_mdsmap *m)
 {
        int i;
 
-       for (i = 0; i < m->m_num_mds; i++)
+       for (i = 0; i < m->possible_max_rank; i++)
                kfree(m->m_info[i].export_targets);
        kfree(m->m_info);
        kfree(m->m_data_pg_pools);
@@ -396,9 +409,9 @@ bool ceph_mdsmap_is_cluster_available(struct ceph_mdsmap *m)
                return false;
        if (m->m_damaged)
                return false;
-       if (m->m_num_laggy > 0)
+       if (m->m_num_laggy == m->m_num_active_mds)
                return false;
-       for (i = 0; i < m->m_num_mds; i++) {
+       for (i = 0; i < m->possible_max_rank; i++) {
                if (m->m_info[i].state == CEPH_MDS_STATE_ACTIVE)
                        nr_active++;
        }
index 29a795f..1d9f083 100644 (file)
@@ -107,7 +107,6 @@ static int ceph_statfs(struct dentry *dentry, struct kstatfs *buf)
        return 0;
 }
 
-
 static int ceph_sync_fs(struct super_block *sb, int wait)
 {
        struct ceph_fs_client *fsc = ceph_sb_to_client(sb);
@@ -163,13 +162,13 @@ enum ceph_recover_session_mode {
        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 constant_table ceph_param_recover[] = {
+       { "no",         ceph_recover_session_no },
+       { "clean",      ceph_recover_session_clean },
        {}
 };
 
-static const struct fs_parameter_spec ceph_mount_param_specs[] = {
+static const struct fs_parameter_spec ceph_mount_parameters[] = {
        fsparam_flag_no ("acl",                         Opt_acl),
        fsparam_flag_no ("asyncreaddir",                Opt_asyncreaddir),
        fsparam_s32     ("caps_max",                    Opt_caps_max),
@@ -179,8 +178,8 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = {
        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 ("fsc",                         Opt_fscache), // fsc|nofsc
+       fsparam_string  ("fsc",                         Opt_fscache), // fsc=...
        fsparam_flag_no ("ino32",                       Opt_ino32),
        fsparam_string  ("mds_namespace",               Opt_mds_namespace),
        fsparam_flag_no ("poolperm",                    Opt_poolperm),
@@ -189,7 +188,7 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = {
        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_enum    ("recover_session",             Opt_recover_session, ceph_param_recover),
        fsparam_flag_no ("require_active_mds",          Opt_require_active_mds),
        fsparam_u32     ("rsize",                       Opt_rsize),
        fsparam_string  ("snapdirname",                 Opt_snapdirname),
@@ -198,12 +197,6 @@ static const struct fs_parameter_spec ceph_mount_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description ceph_mount_parameters = {
-       .name           = "ceph",
-       .specs          = ceph_mount_param_specs,
-       .enums          = ceph_mount_param_enums,
-};
-
 struct ceph_parse_opts_ctx {
        struct ceph_options             *copts;
        struct ceph_mount_options       *opts;
@@ -211,7 +204,6 @@ struct ceph_parse_opts_ctx {
 
 /*
  * 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>]
@@ -228,30 +220,33 @@ static int ceph_parse_source(struct fs_parameter *param, struct fs_context *fc)
 
        dout("%s '%s'\n", __func__, dev_name);
        if (!dev_name || !*dev_name)
-               return invalf(fc, "ceph: Empty source");
+               return invalfc(fc, "Empty source");
 
        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;
-               }
+               kfree(fsopt->server_path);
+
+               /*
+                * The server_path will include the whole chars from userland
+                * including the leading '/'.
+                */
+               fsopt->server_path = kstrdup(dev_name_end, GFP_KERNEL);
+               if (!fsopt->server_path)
+                       return -ENOMEM;
        } else {
                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");
+               return invalfc(fc, "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);
+                                pctx->copts, fc->log.log);
        if (ret)
                return ret;
 
@@ -269,11 +264,11 @@ static int ceph_parse_mount_param(struct fs_context *fc,
        unsigned int mode;
        int token, ret;
 
-       ret = ceph_parse_param(param, pctx->copts, fc);
+       ret = ceph_parse_param(param, pctx->copts, fc->log.log);
        if (ret != -ENOPARAM)
                return ret;
 
-       token = fs_parse(fc, &ceph_mount_parameters, param, &result);
+       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;
@@ -300,7 +295,7 @@ static int ceph_parse_mount_param(struct fs_context *fc,
                break;
        case Opt_source:
                if (fc->source)
-                       return invalf(fc, "ceph: Multiple sources specified");
+                       return invalfc(fc, "Multiple sources specified");
                return ceph_parse_source(param, fc);
        case Opt_wsize:
                if (result.uint_32 < PAGE_SIZE ||
@@ -391,7 +386,7 @@ static int ceph_parse_mount_param(struct fs_context *fc,
                }
                break;
 #else
-               return invalf(fc, "ceph: fscache support is disabled");
+               return invalfc(fc, "fscache support is disabled");
 #endif
        case Opt_poolperm:
                if (!result.negated)
@@ -422,7 +417,7 @@ static int ceph_parse_mount_param(struct fs_context *fc,
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
                        fc->sb_flags |= SB_POSIXACL;
 #else
-                       return invalf(fc, "ceph: POSIX ACL support is disabled");
+                       return invalfc(fc, "POSIX ACL support is disabled");
 #endif
                } else {
                        fc->sb_flags &= ~SB_POSIXACL;
@@ -434,7 +429,7 @@ static int ceph_parse_mount_param(struct fs_context *fc,
        return 0;
 
 out_of_range:
-       return invalf(fc, "ceph: %s out of range", param->key);
+       return invalfc(fc, "%s out of range", param->key);
 }
 
 static void destroy_mount_options(struct ceph_mount_options *args)
@@ -461,6 +456,73 @@ static int strcmp_null(const char *s1, const char *s2)
        return strcmp(s1, s2);
 }
 
+/**
+ * path_remove_extra_slash - Remove the extra slashes in the server path
+ * @server_path: the server path and could be NULL
+ *
+ * Return NULL if the path is NULL or only consists of "/", or a string
+ * without any extra slashes including the leading slash(es) and the
+ * slash(es) at the end of the server path, such as:
+ * "//dir1////dir2///" --> "dir1/dir2"
+ */
+static char *path_remove_extra_slash(const char *server_path)
+{
+       const char *path = server_path;
+       const char *cur, *end;
+       char *buf, *p;
+       int len;
+
+       /* if the server path is omitted */
+       if (!path)
+               return NULL;
+
+       /* remove all the leading slashes */
+       while (*path == '/')
+               path++;
+
+       /* if the server path only consists of slashes */
+       if (*path == '\0')
+               return NULL;
+
+       len = strlen(path);
+
+       buf = kmalloc(len + 1, GFP_KERNEL);
+       if (!buf)
+               return ERR_PTR(-ENOMEM);
+
+       end = path + len;
+       p = buf;
+       do {
+               cur = strchr(path, '/');
+               if (!cur)
+                       cur = end;
+
+               len = cur - path;
+
+               /* including one '/' */
+               if (cur != end)
+                       len += 1;
+
+               memcpy(p, path, len);
+               p += len;
+
+               while (cur <= end && *cur == '/')
+                       cur++;
+               path = cur;
+       } while (path < end);
+
+       *p = '\0';
+
+       /*
+        * remove the last slash if there has and just to make sure that
+        * we will get something like "dir1/dir2"
+        */
+       if (*(--p) == '/')
+               *p = '\0';
+
+       return buf;
+}
+
 static int compare_mount_options(struct ceph_mount_options *new_fsopt,
                                 struct ceph_options *new_opt,
                                 struct ceph_fs_client *fsc)
@@ -468,6 +530,7 @@ static int compare_mount_options(struct ceph_mount_options *new_fsopt,
        struct ceph_mount_options *fsopt1 = new_fsopt;
        struct ceph_mount_options *fsopt2 = fsc->mount_options;
        int ofs = offsetof(struct ceph_mount_options, snapdir_name);
+       char *p1, *p2;
        int ret;
 
        ret = memcmp(fsopt1, fsopt2, ofs);
@@ -480,9 +543,21 @@ static int compare_mount_options(struct ceph_mount_options *new_fsopt,
        ret = strcmp_null(fsopt1->mds_namespace, fsopt2->mds_namespace);
        if (ret)
                return ret;
-       ret = strcmp_null(fsopt1->server_path, fsopt2->server_path);
+
+       p1 = path_remove_extra_slash(fsopt1->server_path);
+       if (IS_ERR(p1))
+               return PTR_ERR(p1);
+       p2 = path_remove_extra_slash(fsopt2->server_path);
+       if (IS_ERR(p2)) {
+               kfree(p1);
+               return PTR_ERR(p2);
+       }
+       ret = strcmp_null(p1, p2);
+       kfree(p1);
+       kfree(p2);
        if (ret)
                return ret;
+
        ret = strcmp_null(fsopt1->fscache_uniq, fsopt2->fscache_uniq);
        if (ret)
                return ret;
@@ -637,6 +712,7 @@ static struct ceph_fs_client *create_fs_client(struct ceph_mount_options *fsopt,
        fsc->sb = NULL;
        fsc->mount_state = CEPH_MOUNT_MOUNTING;
        fsc->filp_gen = 1;
+       fsc->have_copy_from2 = true;
 
        atomic_long_set(&fsc->writeback_count, 0);
 
@@ -788,7 +864,6 @@ static void destroy_caches(void)
        ceph_fscache_unregister();
 }
 
-
 /*
  * ceph_umount_begin - initiate forced umount.  Tear down down the
  * mount, skipping steps that may hang while waiting for server(s).
@@ -868,9 +943,6 @@ out:
        return root;
 }
 
-
-
-
 /*
  * mount: join the ceph cluster, and open root directory.
  */
@@ -885,7 +957,7 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
        mutex_lock(&fsc->client->mount_mutex);
 
        if (!fsc->sb->s_root) {
-               const char *path;
+               const char *path, *p;
                err = __ceph_open_session(fsc->client, started);
                if (err < 0)
                        goto out;
@@ -897,17 +969,22 @@ static struct dentry *ceph_real_mount(struct ceph_fs_client *fsc,
                                goto out;
                }
 
-               if (!fsc->mount_options->server_path) {
-                       path = "";
-                       dout("mount opening path \\t\n");
-               } else {
-                       path = fsc->mount_options->server_path + 1;
-                       dout("mount opening path %s\n", path);
+               p = path_remove_extra_slash(fsc->mount_options->server_path);
+               if (IS_ERR(p)) {
+                       err = PTR_ERR(p);
+                       goto out;
                }
+               /* if the server path is omitted or just consists of '/' */
+               if (!p)
+                       path = "";
+               else
+                       path = p;
+               dout("mount opening path '%s'\n", path);
 
                ceph_fs_debugfs_init(fsc);
 
                root = open_root_dentry(fsc, path, started);
+               kfree(p);
                if (IS_ERR(root)) {
                        err = PTR_ERR(root);
                        goto out;
@@ -1018,7 +1095,7 @@ static int ceph_get_tree(struct fs_context *fc)
        dout("ceph_get_tree\n");
 
        if (!fc->source)
-               return invalf(fc, "ceph: No source");
+               return invalfc(fc, "No source");
 
 #ifdef CONFIG_CEPH_FS_POSIX_ACL
        fc->sb_flags |= SB_POSIXACL;
@@ -1070,6 +1147,11 @@ static int ceph_get_tree(struct fs_context *fc)
        return 0;
 
 out_splat:
+       if (!ceph_mdsmap_is_cluster_available(fsc->mdsc->mdsmap)) {
+               pr_info("No mds server is up or the cluster is laggy\n");
+               err = -EHOSTUNREACH;
+       }
+
        ceph_mdsc_close_sessions(fsc->mdsc);
        deactivate_locked_super(sb);
        goto out_final;
index 3bf1a01..1e456a9 100644 (file)
@@ -106,6 +106,8 @@ struct ceph_fs_client {
        unsigned long last_auto_reconnect;
        bool blacklisted;
 
+       bool have_copy_from2;
+
        u32 filp_gen;
        loff_t max_file_size;
 
similarity index 94%
rename from net/ceph/ceph_fs.c
rename to fs/ceph/util.c
index 756a2dc..2c34875 100644 (file)
@@ -39,7 +39,6 @@ void ceph_file_layout_from_legacy(struct ceph_file_layout *fl,
            fl->stripe_count == 0 && fl->object_size == 0)
                fl->pool_id = -1;
 }
-EXPORT_SYMBOL(ceph_file_layout_from_legacy);
 
 void ceph_file_layout_to_legacy(struct ceph_file_layout *fl,
                                struct ceph_file_layout_legacy *legacy)
@@ -52,7 +51,6 @@ void ceph_file_layout_to_legacy(struct ceph_file_layout *fl,
        else
                legacy->fl_pg_pool = 0;
 }
-EXPORT_SYMBOL(ceph_file_layout_to_legacy);
 
 int ceph_flags_to_mode(int flags)
 {
@@ -82,7 +80,6 @@ int ceph_flags_to_mode(int flags)
 
        return mode;
 }
-EXPORT_SYMBOL(ceph_flags_to_mode);
 
 int ceph_caps_for_mode(int mode)
 {
@@ -101,4 +98,3 @@ int ceph_caps_for_mode(int mode)
 
        return caps;
 }
-EXPORT_SYMBOL(ceph_caps_for_mode);
index cb18ee6..7b8a070 100644 (file)
@@ -655,7 +655,7 @@ static int __build_xattrs(struct inode *inode)
        u32 len;
        const char *name, *val;
        struct ceph_inode_info *ci = ceph_inode(inode);
-       int xattr_version;
+       u64 xattr_version;
        struct ceph_inode_xattr **xattrs = NULL;
        int err = 0;
        int i;
@@ -851,7 +851,7 @@ ssize_t __ceph_getxattr(struct inode *inode, const char *name, void *value,
        req_mask = __get_request_mask(inode);
 
        spin_lock(&ci->i_ceph_lock);
-       dout("getxattr %p ver=%lld index_ver=%lld\n", inode,
+       dout("getxattr %p name '%s' ver=%lld index_ver=%lld\n", inode, name,
             ci->i_xattrs.version, ci->i_xattrs.index_version);
 
        if (ci->i_xattrs.version == 0 ||
@@ -1078,7 +1078,8 @@ retry:
                }
        }
 
-       dout("setxattr %p issued %s\n", inode, ceph_cap_string(issued));
+       dout("setxattr %p name '%s' issued %s\n", inode, name,
+            ceph_cap_string(issued));
        __build_xattrs(inode);
 
        required_blob_size = __get_required_blob_size(ci, name_len, val_len);
index 19f6e59..276e4b5 100644 (file)
@@ -611,12 +611,12 @@ static int cifs_stats_proc_open(struct inode *inode, struct file *file)
        return single_open(file, cifs_stats_proc_show, NULL);
 }
 
-static const struct file_operations cifs_stats_proc_fops = {
-       .open           = cifs_stats_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = cifs_stats_proc_write,
+static const struct proc_ops cifs_stats_proc_ops = {
+       .proc_open      = cifs_stats_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = cifs_stats_proc_write,
 };
 
 #ifdef CONFIG_CIFS_SMB_DIRECT
@@ -640,12 +640,12 @@ static int name##_open(struct inode *inode, struct file *file) \
        return single_open(file, name##_proc_show, NULL); \
 } \
 \
-static const struct file_operations cifs_##name##_proc_fops = { \
-       .open           = name##_open, \
-       .read           = seq_read, \
-       .llseek         = seq_lseek, \
-       .release        = single_release, \
-       .write          = name##_write, \
+static const struct proc_ops cifs_##name##_proc_fops = { \
+       .proc_open      = name##_open, \
+       .proc_read      = seq_read, \
+       .proc_lseek     = seq_lseek, \
+       .proc_release   = single_release, \
+       .proc_write     = name##_write, \
 }
 
 PROC_FILE_DEFINE(rdma_readwrite_threshold);
@@ -659,11 +659,11 @@ PROC_FILE_DEFINE(smbd_receive_credit_max);
 #endif
 
 static struct proc_dir_entry *proc_fs_cifs;
-static const struct file_operations cifsFYI_proc_fops;
-static const struct file_operations cifs_lookup_cache_proc_fops;
-static const struct file_operations traceSMB_proc_fops;
-static const struct file_operations cifs_security_flags_proc_fops;
-static const struct file_operations cifs_linux_ext_proc_fops;
+static const struct proc_ops cifsFYI_proc_ops;
+static const struct proc_ops cifs_lookup_cache_proc_ops;
+static const struct proc_ops traceSMB_proc_ops;
+static const struct proc_ops cifs_security_flags_proc_ops;
+static const struct proc_ops cifs_linux_ext_proc_ops;
 
 void
 cifs_proc_init(void)
@@ -678,18 +678,18 @@ cifs_proc_init(void)
        proc_create_single("open_files", 0400, proc_fs_cifs,
                        cifs_debug_files_proc_show);
 
-       proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_fops);
-       proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_fops);
-       proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_fops);
+       proc_create("Stats", 0644, proc_fs_cifs, &cifs_stats_proc_ops);
+       proc_create("cifsFYI", 0644, proc_fs_cifs, &cifsFYI_proc_ops);
+       proc_create("traceSMB", 0644, proc_fs_cifs, &traceSMB_proc_ops);
        proc_create("LinuxExtensionsEnabled", 0644, proc_fs_cifs,
-                   &cifs_linux_ext_proc_fops);
+                   &cifs_linux_ext_proc_ops);
        proc_create("SecurityFlags", 0644, proc_fs_cifs,
-                   &cifs_security_flags_proc_fops);
+                   &cifs_security_flags_proc_ops);
        proc_create("LookupCacheEnabled", 0644, proc_fs_cifs,
-                   &cifs_lookup_cache_proc_fops);
+                   &cifs_lookup_cache_proc_ops);
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
-       proc_create("dfscache", 0644, proc_fs_cifs, &dfscache_proc_fops);
+       proc_create("dfscache", 0644, proc_fs_cifs, &dfscache_proc_ops);
 #endif
 
 #ifdef CONFIG_CIFS_SMB_DIRECT
@@ -774,12 +774,12 @@ static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
        return count;
 }
 
-static const struct file_operations cifsFYI_proc_fops = {
-       .open           = cifsFYI_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = cifsFYI_proc_write,
+static const struct proc_ops cifsFYI_proc_ops = {
+       .proc_open      = cifsFYI_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = cifsFYI_proc_write,
 };
 
 static int cifs_linux_ext_proc_show(struct seq_file *m, void *v)
@@ -805,12 +805,12 @@ static ssize_t cifs_linux_ext_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations cifs_linux_ext_proc_fops = {
-       .open           = cifs_linux_ext_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = cifs_linux_ext_proc_write,
+static const struct proc_ops cifs_linux_ext_proc_ops = {
+       .proc_open      = cifs_linux_ext_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = cifs_linux_ext_proc_write,
 };
 
 static int cifs_lookup_cache_proc_show(struct seq_file *m, void *v)
@@ -836,12 +836,12 @@ static ssize_t cifs_lookup_cache_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations cifs_lookup_cache_proc_fops = {
-       .open           = cifs_lookup_cache_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = cifs_lookup_cache_proc_write,
+static const struct proc_ops cifs_lookup_cache_proc_ops = {
+       .proc_open      = cifs_lookup_cache_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = cifs_lookup_cache_proc_write,
 };
 
 static int traceSMB_proc_show(struct seq_file *m, void *v)
@@ -867,12 +867,12 @@ static ssize_t traceSMB_proc_write(struct file *file, const char __user *buffer,
        return count;
 }
 
-static const struct file_operations traceSMB_proc_fops = {
-       .open           = traceSMB_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = traceSMB_proc_write,
+static const struct proc_ops traceSMB_proc_ops = {
+       .proc_open      = traceSMB_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = traceSMB_proc_write,
 };
 
 static int cifs_security_flags_proc_show(struct seq_file *m, void *v)
@@ -978,12 +978,12 @@ static ssize_t cifs_security_flags_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations cifs_security_flags_proc_fops = {
-       .open           = cifs_security_flags_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = cifs_security_flags_proc_write,
+static const struct proc_ops cifs_security_flags_proc_ops = {
+       .proc_open      = cifs_security_flags_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = cifs_security_flags_proc_write,
 };
 #else
 inline void cifs_proc_init(void)
index 9a384d1..43c1b43 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/jhash.h>
 #include <linux/ktime.h>
 #include <linux/slab.h>
+#include <linux/proc_fs.h>
 #include <linux/nls.h>
 #include <linux/workqueue.h>
 #include "cifsglob.h"
@@ -211,12 +212,12 @@ static int dfscache_proc_open(struct inode *inode, struct file *file)
        return single_open(file, dfscache_proc_show, NULL);
 }
 
-const struct file_operations dfscache_proc_fops = {
-       .open           = dfscache_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = dfscache_proc_write,
+const struct proc_ops dfscache_proc_ops = {
+       .proc_open      = dfscache_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = dfscache_proc_write,
 };
 
 #ifdef CONFIG_CIFS_DEBUG2
index 76c7329..99ee44f 100644 (file)
@@ -24,7 +24,7 @@ struct dfs_cache_tgt_iterator {
 
 extern int dfs_cache_init(void);
 extern void dfs_cache_destroy(void);
-extern const struct file_operations dfscache_proc_fops;
+extern const struct proc_ops dfscache_proc_ops;
 
 extern int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses,
                          const struct nls_table *nls_codepage, int remap,
index b1383c5..9ba623b 100644 (file)
@@ -113,6 +113,7 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr)
        }
 
         /* revalidate if mtime or size have changed */
+       fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode);
        if (timespec64_equal(&inode->i_mtime, &fattr->cf_mtime) &&
            cifs_i->server_eof == fattr->cf_eof) {
                cifs_dbg(FYI, "%s: inode %llu is unchanged\n",
@@ -162,6 +163,9 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr)
        cifs_revalidate_cache(inode, fattr);
 
        spin_lock(&inode->i_lock);
+       fattr->cf_mtime = timestamp_truncate(fattr->cf_mtime, inode);
+       fattr->cf_atime = timestamp_truncate(fattr->cf_atime, inode);
+       fattr->cf_ctime = timestamp_truncate(fattr->cf_ctime, inode);
        /* we do not want atime to be less than mtime, it broke some apps */
        if (timespec64_compare(&fattr->cf_atime, &fattr->cf_mtime) < 0)
                inode->i_atime = fattr->cf_mtime;
@@ -329,8 +333,7 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
        fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
        fattr->cf_uid = cifs_sb->mnt_uid;
        fattr->cf_gid = cifs_sb->mnt_gid;
-       ktime_get_real_ts64(&fattr->cf_mtime);
-       fattr->cf_mtime = timespec64_trunc(fattr->cf_mtime, sb->s_time_gran);
+       ktime_get_coarse_real_ts64(&fattr->cf_mtime);
        fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
        fattr->cf_nlink = 2;
        fattr->cf_flags = CIFS_FATTR_DFS_REFERRAL;
@@ -607,10 +610,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 
        if (info->LastAccessTime)
                fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime);
-       else {
-               ktime_get_real_ts64(&fattr->cf_atime);
-               fattr->cf_atime = timespec64_trunc(fattr->cf_atime, sb->s_time_gran);
-       }
+       else
+               ktime_get_coarse_real_ts64(&fattr->cf_atime);
 
        fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime);
        fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime);
index 680aba9..fd0b5dd 100644 (file)
@@ -76,14 +76,11 @@ int configfs_setattr(struct dentry * dentry, struct iattr * iattr)
        if (ia_valid & ATTR_GID)
                sd_iattr->ia_gid = iattr->ia_gid;
        if (ia_valid & ATTR_ATIME)
-               sd_iattr->ia_atime = timestamp_truncate(iattr->ia_atime,
-                                                     inode);
+               sd_iattr->ia_atime = iattr->ia_atime;
        if (ia_valid & ATTR_MTIME)
-               sd_iattr->ia_mtime = timestamp_truncate(iattr->ia_mtime,
-                                                     inode);
+               sd_iattr->ia_mtime = iattr->ia_mtime;
        if (ia_valid & ATTR_CTIME)
-               sd_iattr->ia_ctime = timestamp_truncate(iattr->ia_ctime,
-                                                     inode);
+               sd_iattr->ia_ctime = iattr->ia_ctime;
        if (ia_valid & ATTR_MODE) {
                umode_t mode = iattr->ia_mode;
 
index b1ea7df..f8296a8 100644 (file)
@@ -517,7 +517,7 @@ static void wait_for_dump_helpers(struct file *file)
        pipe_lock(pipe);
        pipe->readers++;
        pipe->writers--;
-       wake_up_interruptible_sync(&pipe->wait);
+       wake_up_interruptible_sync(&pipe->rd_wait);
        kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
        pipe_unlock(pipe);
 
@@ -525,7 +525,7 @@ static void wait_for_dump_helpers(struct file *file)
         * We actually want wait_event_freezable() but then we need
         * to clear TIF_SIGPENDING and improve dump_interrupted().
         */
-       wait_event_interruptible(pipe->wait, pipe->readers == 1);
+       wait_event_interruptible(pipe->rd_wait, pipe->readers == 1);
 
        pipe_lock(pipe);
        pipe->readers--;
index 2f04024..9123086 100644 (file)
@@ -534,7 +534,7 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
                /* check for wrong endianness */
                if (super->magic == CRAMFS_MAGIC_WEND) {
                        if (!silent)
-                               errorf(fc, "cramfs: wrong endianness");
+                               errorfc(fc, "wrong endianness");
                        return -EINVAL;
                }
 
@@ -546,22 +546,22 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
                mutex_unlock(&read_mutex);
                if (super->magic != CRAMFS_MAGIC) {
                        if (super->magic == CRAMFS_MAGIC_WEND && !silent)
-                               errorf(fc, "cramfs: wrong endianness");
+                               errorfc(fc, "wrong endianness");
                        else if (!silent)
-                               errorf(fc, "cramfs: wrong magic");
+                               errorfc(fc, "wrong magic");
                        return -EINVAL;
                }
        }
 
        /* get feature flags first */
        if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) {
-               errorf(fc, "cramfs: unsupported filesystem features");
+               errorfc(fc, "unsupported filesystem features");
                return -EINVAL;
        }
 
        /* Check that the root inode is in a sane state */
        if (!S_ISDIR(super->root.mode)) {
-               errorf(fc, "cramfs: root is not a directory");
+               errorfc(fc, "root is not a directory");
                return -EINVAL;
        }
        /* correct strange, hard-coded permissions of mkcramfs */
@@ -580,12 +580,12 @@ static int cramfs_read_super(struct super_block *sb, struct fs_context *fc,
        sbi->magic = super->magic;
        sbi->flags = super->flags;
        if (root_offset == 0)
-               infof(fc, "cramfs: empty filesystem");
+               infofc(fc, "empty filesystem");
        else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) &&
                 ((root_offset != sizeof(struct cramfs_super)) &&
                  (root_offset != 512 + sizeof(struct cramfs_super))))
        {
-               errorf(fc, "cramfs: bad root offset %lu", root_offset);
+               errorfc(fc, "bad root offset %lu", root_offset);
                return -EINVAL;
        }
 
index dc6cffc..e742dfc 100644 (file)
@@ -332,7 +332,10 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
                parent = debugfs_mount->mnt_root;
 
        inode_lock(d_inode(parent));
-       dentry = lookup_one_len(name, parent, strlen(name));
+       if (unlikely(IS_DEADDIR(d_inode(parent))))
+               dentry = ERR_PTR(-ENOENT);
+       else
+               dentry = lookup_one_len(name, parent, strlen(name));
        if (!IS_ERR(dentry) && d_really_is_positive(dentry)) {
                if (d_is_dir(dentry))
                        pr_err("Directory '%s' with parent '%s' already present!\n",
@@ -681,62 +684,15 @@ static void __debugfs_file_removed(struct dentry *dentry)
                wait_for_completion(&fsd->active_users_drained);
 }
 
-static int __debugfs_remove(struct dentry *dentry, struct dentry *parent)
-{
-       int ret = 0;
-
-       if (simple_positive(dentry)) {
-               dget(dentry);
-               if (d_is_dir(dentry)) {
-                       ret = simple_rmdir(d_inode(parent), dentry);
-                       if (!ret)
-                               fsnotify_rmdir(d_inode(parent), dentry);
-               } else {
-                       simple_unlink(d_inode(parent), dentry);
-                       fsnotify_unlink(d_inode(parent), dentry);
-               }
-               if (!ret)
-                       d_delete(dentry);
-               if (d_is_reg(dentry))
-                       __debugfs_file_removed(dentry);
-               dput(dentry);
-       }
-       return ret;
-}
-
-/**
- * debugfs_remove - removes a file or directory from the debugfs filesystem
- * @dentry: a pointer to a the dentry of the file or directory to be
- *          removed.  If this parameter is NULL or an error value, nothing
- *          will be done.
- *
- * This function removes a file or directory in debugfs that was previously
- * created with a call to another debugfs function (like
- * debugfs_create_file() or variants thereof.)
- *
- * This function is required to be called in order for the file to be
- * removed, no automatic cleanup of files will happen when a module is
- * removed, you are responsible here.
- */
-void debugfs_remove(struct dentry *dentry)
+static void remove_one(struct dentry *victim)
 {
-       struct dentry *parent;
-       int ret;
-
-       if (IS_ERR_OR_NULL(dentry))
-               return;
-
-       parent = dentry->d_parent;
-       inode_lock(d_inode(parent));
-       ret = __debugfs_remove(dentry, parent);
-       inode_unlock(d_inode(parent));
-       if (!ret)
-               simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+        if (d_is_reg(victim))
+               __debugfs_file_removed(victim);
+       simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 }
-EXPORT_SYMBOL_GPL(debugfs_remove);
 
 /**
- * debugfs_remove_recursive - recursively removes a directory
+ * debugfs_remove - recursively removes a directory
  * @dentry: a pointer to a the dentry of the directory to be removed.  If this
  *          parameter is NULL or an error value, nothing will be done.
  *
@@ -748,65 +704,16 @@ EXPORT_SYMBOL_GPL(debugfs_remove);
  * removed, no automatic cleanup of files will happen when a module is
  * removed, you are responsible here.
  */
-void debugfs_remove_recursive(struct dentry *dentry)
+void debugfs_remove(struct dentry *dentry)
 {
-       struct dentry *child, *parent;
-
        if (IS_ERR_OR_NULL(dentry))
                return;
 
-       parent = dentry;
- down:
-       inode_lock(d_inode(parent));
- loop:
-       /*
-        * The parent->d_subdirs is protected by the d_lock. Outside that
-        * lock, the child can be unlinked and set to be freed which can
-        * use the d_u.d_child as the rcu head and corrupt this list.
-        */
-       spin_lock(&parent->d_lock);
-       list_for_each_entry(child, &parent->d_subdirs, d_child) {
-               if (!simple_positive(child))
-                       continue;
-
-               /* perhaps simple_empty(child) makes more sense */
-               if (!list_empty(&child->d_subdirs)) {
-                       spin_unlock(&parent->d_lock);
-                       inode_unlock(d_inode(parent));
-                       parent = child;
-                       goto down;
-               }
-
-               spin_unlock(&parent->d_lock);
-
-               if (!__debugfs_remove(child, parent))
-                       simple_release_fs(&debugfs_mount, &debugfs_mount_count);
-
-               /*
-                * The parent->d_lock protects agaist child from unlinking
-                * from d_subdirs. When releasing the parent->d_lock we can
-                * no longer trust that the next pointer is valid.
-                * Restart the loop. We'll skip this one with the
-                * simple_positive() check.
-                */
-               goto loop;
-       }
-       spin_unlock(&parent->d_lock);
-
-       inode_unlock(d_inode(parent));
-       child = parent;
-       parent = parent->d_parent;
-       inode_lock(d_inode(parent));
-
-       if (child != dentry)
-               /* go up */
-               goto loop;
-
-       if (!__debugfs_remove(child, parent))
-               simple_release_fs(&debugfs_mount, &debugfs_mount_count);
-       inode_unlock(d_inode(parent));
+       simple_pin_fs(&debug_fs_type, &debugfs_mount, &debugfs_mount_count);
+       simple_recursive_removal(dentry, remove_one);
+       simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 }
-EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
+EXPORT_SYMBOL_GPL(debugfs_remove);
 
 /**
  * debugfs_rename - rename a file/directory in the debugfs filesystem
index cffa0c1..019572c 100644 (file)
@@ -524,16 +524,12 @@ out:
 
 static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
 {
-       int rc = 0;
-       struct inode *inode;
-       struct inode *lower_inode;
-
-       inode = (struct inode *)mapping->host;
-       lower_inode = ecryptfs_inode_to_lower(inode);
-       if (lower_inode->i_mapping->a_ops->bmap)
-               rc = lower_inode->i_mapping->a_ops->bmap(lower_inode->i_mapping,
-                                                        block);
-       return rc;
+       struct inode *lower_inode = ecryptfs_inode_to_lower(mapping->host);
+       int ret = bmap(lower_inode, &block);
+
+       if (ret)
+               return 0;
+       return block;
 }
 
 const struct address_space_operations ecryptfs_aops = {
index 8aa0ea8..78e41c7 100644 (file)
@@ -24,6 +24,8 @@
 #include <linux/seq_file.h>
 #include <linux/idr.h>
 
+DEFINE_PER_CPU(int, eventfd_wake_count);
+
 static DEFINE_IDA(eventfd_ida);
 
 struct eventfd_ctx {
@@ -60,12 +62,25 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n)
 {
        unsigned long flags;
 
+       /*
+        * Deadlock or stack overflow issues can happen if we recurse here
+        * through waitqueue wakeup handlers. If the caller users potentially
+        * nested waitqueues with custom wakeup handlers, then it should
+        * check eventfd_signal_count() before calling this function. If
+        * it returns true, the eventfd_signal() call should be deferred to a
+        * safe context.
+        */
+       if (WARN_ON_ONCE(this_cpu_read(eventfd_wake_count)))
+               return 0;
+
        spin_lock_irqsave(&ctx->wqh.lock, flags);
+       this_cpu_inc(eventfd_wake_count);
        if (ULLONG_MAX - ctx->count < n)
                n = ULLONG_MAX - ctx->count;
        ctx->count += n;
        if (waitqueue_active(&ctx->wqh))
                wake_up_locked_poll(&ctx->wqh, EPOLLIN);
+       this_cpu_dec(eventfd_wake_count);
        spin_unlock_irqrestore(&ctx->wqh.lock, flags);
 
        return n;
index 88b213b..8434217 100644 (file)
@@ -6043,7 +6043,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type,
                bh = ext4_bread(handle, inode, blk,
                                EXT4_GET_BLOCKS_CREATE |
                                EXT4_GET_BLOCKS_METADATA_NOFAIL);
-       } while (IS_ERR(bh) && (PTR_ERR(bh) == -ENOSPC) &&
+       } while (PTR_ERR(bh) == -ENOSPC &&
                 ext4_should_retry_alloc(inode->i_sb, &retries));
        if (IS_ERR(bh))
                return PTR_ERR(bh);
index 8bd9afa..b27b721 100644 (file)
@@ -3666,12 +3666,16 @@ static int check_swap_activate(struct swap_info_struct *sis,
                        page_no < sis->max) {
                unsigned block_in_page;
                sector_t first_block;
+               sector_t block = 0;
+               int      err = 0;
 
                cond_resched();
 
-               first_block = bmap(inode, probe_block);
-               if (first_block == 0)
+               block = probe_block;
+               err = bmap(inode, &block);
+               if (err || !block)
                        goto bad_bmap;
+               first_block = block;
 
                /*
                 * It must be PAGE_SIZE aligned on-disk
@@ -3683,11 +3687,13 @@ static int check_swap_activate(struct swap_info_struct *sis,
 
                for (block_in_page = 1; block_in_page < blocks_per_page;
                                        block_in_page++) {
-                       sector_t block;
 
-                       block = bmap(inode, probe_block + block_in_page);
-                       if (block == 0)
+                       block = probe_block + block_in_page;
+                       err = bmap(inode, &block);
+
+                       if (err || !block)
                                goto bad_bmap;
+
                        if (block != first_block + block_in_page) {
                                /* Discontiguity */
                                probe_block++;
index 86ddbb5..0d4da64 100644 (file)
@@ -829,18 +829,12 @@ static void __setattr_copy(struct inode *inode, const struct iattr *attr)
                inode->i_uid = attr->ia_uid;
        if (ia_valid & ATTR_GID)
                inode->i_gid = attr->ia_gid;
-       if (ia_valid & ATTR_ATIME) {
-               inode->i_atime = timestamp_truncate(attr->ia_atime,
-                                                 inode);
-       }
-       if (ia_valid & ATTR_MTIME) {
-               inode->i_mtime = timestamp_truncate(attr->ia_mtime,
-                                                 inode);
-       }
-       if (ia_valid & ATTR_CTIME) {
-               inode->i_ctime = timestamp_truncate(attr->ia_ctime,
-                                                 inode);
-       }
+       if (ia_valid & ATTR_ATIME)
+               inode->i_atime = attr->ia_atime;
+       if (ia_valid & ATTR_MTIME)
+               inode->i_mtime = attr->ia_mtime;
+       if (ia_valid & ATTR_CTIME)
+               inode->i_ctime = attr->ia_ctime;
        if (ia_valid & ATTR_MODE) {
                umode_t mode = attr->ia_mode;
 
index 3314a0f..9d02cdc 100644 (file)
@@ -875,7 +875,7 @@ static int truncate_dnode(struct dnode_of_data *dn)
 
        /* get direct node */
        page = f2fs_get_node_page(F2FS_I_SB(dn->inode), dn->nid);
-       if (IS_ERR(page) && PTR_ERR(page) == -ENOENT)
+       if (PTR_ERR(page) == -ENOENT)
                return 1;
        else if (IS_ERR(page))
                return PTR_ERR(page);
index 1e08bd5..f1b2a1f 100644 (file)
@@ -271,6 +271,14 @@ static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts)
 {
        return (struct timespec64){ ts.tv_sec & ~1ULL, 0 };
 }
+
+static inline struct timespec64 fat_timespec64_trunc_10ms(struct timespec64 ts)
+{
+       if (ts.tv_nsec)
+               ts.tv_nsec -= ts.tv_nsec % 10000000UL;
+       return ts;
+}
+
 /*
  * truncate the various times with appropriate granularity:
  *   root inode:
@@ -308,7 +316,7 @@ int fat_truncate_time(struct inode *inode, struct timespec64 *now, int flags)
        }
        if (flags & S_CTIME) {
                if (sbi->options.isvfat)
-                       inode->i_ctime = timespec64_trunc(*now, 10000000);
+                       inode->i_ctime = fat_timespec64_trunc_10ms(*now);
                else
                        inode->i_ctime = fat_timespec64_trunc_2secs(*now);
        }
index 9135646..77bf5f9 100644 (file)
@@ -74,7 +74,8 @@ int register_filesystem(struct file_system_type * fs)
        int res = 0;
        struct file_system_type ** p;
 
-       if (fs->parameters && !fs_validate_description(fs->parameters))
+       if (fs->parameters &&
+           !fs_validate_description(fs->name, fs->parameters))
                return -EINVAL;
 
        BUG_ON(strchr(fs->name, '.'));
index 138b5b4..fc9f6ef 100644 (file)
@@ -45,6 +45,7 @@ static const struct constant_table common_set_sb_flag[] = {
        { "posixacl",   SB_POSIXACL },
        { "ro",         SB_RDONLY },
        { "sync",       SB_SYNCHRONOUS },
+       { },
 };
 
 static const struct constant_table common_clear_sb_flag[] = {
@@ -53,6 +54,7 @@ static const struct constant_table common_clear_sb_flag[] = {
        { "nomand",     SB_MANDLOCK },
        { "rw",         SB_RDONLY },
        { "silent",     SB_SILENT },
+       { },
 };
 
 static const char *const forbidden_sb_flag[] = {
@@ -175,14 +177,15 @@ int vfs_parse_fs_string(struct fs_context *fc, const char *key,
 
        struct fs_parameter param = {
                .key    = key,
-               .type   = fs_value_is_string,
+               .type   = fs_value_is_flag,
                .size   = v_size,
        };
 
-       if (v_size > 0) {
+       if (value) {
                param.string = kmemdup_nul(value, v_size, GFP_KERNEL);
                if (!param.string)
                        return -ENOMEM;
+               param.type = fs_value_is_string;
        }
 
        ret = vfs_parse_fs_param(fc, &param);
@@ -268,6 +271,7 @@ static struct fs_context *alloc_fs_context(struct file_system_type *fs_type,
        fc->fs_type     = get_filesystem(fs_type);
        fc->cred        = get_current_cred();
        fc->net_ns      = get_net(current->nsproxy->net_ns);
+       fc->log.prefix  = fs_type->name;
 
        mutex_init(&fc->uapi_mutex);
 
@@ -361,8 +365,8 @@ struct fs_context *vfs_dup_fs_context(struct fs_context *src_fc)
        get_net(fc->net_ns);
        get_user_ns(fc->user_ns);
        get_cred(fc->cred);
-       if (fc->log)
-               refcount_inc(&fc->log->usage);
+       if (fc->log.log)
+               refcount_inc(&fc->log.log->usage);
 
        /* Can't call put until we've called ->dup */
        ret = fc->ops->dup(fc, src_fc);
@@ -385,64 +389,33 @@ EXPORT_SYMBOL(vfs_dup_fs_context);
  * @fc: The filesystem context to log to.
  * @fmt: The format of the buffer.
  */
-void logfc(struct fs_context *fc, const char *fmt, ...)
+void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...)
 {
-       static const char store_failure[] = "OOM: Can't store error string";
-       struct fc_log *log = fc ? fc->log : NULL;
-       const char *p;
        va_list va;
-       char *q;
-       u8 freeable;
+       struct va_format vaf = {.fmt = fmt, .va = &va};
 
        va_start(va, fmt);
-       if (!strchr(fmt, '%')) {
-               p = fmt;
-               goto unformatted_string;
-       }
-       if (strcmp(fmt, "%s") == 0) {
-               p = va_arg(va, const char *);
-               goto unformatted_string;
-       }
-
-       q = kvasprintf(GFP_KERNEL, fmt, va);
-copied_string:
-       if (!q)
-               goto store_failure;
-       freeable = 1;
-       goto store_string;
-
-unformatted_string:
-       if ((unsigned long)p >= (unsigned long)__start_rodata &&
-           (unsigned long)p <  (unsigned long)__end_rodata)
-               goto const_string;
-       if (log && within_module_core((unsigned long)p, log->owner))
-               goto const_string;
-       q = kstrdup(p, GFP_KERNEL);
-       goto copied_string;
-
-store_failure:
-       p = store_failure;
-const_string:
-       q = (char *)p;
-       freeable = 0;
-store_string:
        if (!log) {
-               switch (fmt[0]) {
+               switch (level) {
                case 'w':
-                       printk(KERN_WARNING "%s\n", q + 2);
+                       printk(KERN_WARNING "%s%s%pV\n", prefix ? prefix : "",
+                                               prefix ? ": " : "", &vaf);
                        break;
                case 'e':
-                       printk(KERN_ERR "%s\n", q + 2);
+                       printk(KERN_ERR "%s%s%pV\n", prefix ? prefix : "",
+                                               prefix ? ": " : "", &vaf);
                        break;
                default:
-                       printk(KERN_NOTICE "%s\n", q + 2);
+                       printk(KERN_NOTICE "%s%s%pV\n", prefix ? prefix : "",
+                                               prefix ? ": " : "", &vaf);
                        break;
                }
-               if (freeable)
-                       kfree(q);
        } else {
                unsigned int logsize = ARRAY_SIZE(log->buffer);
                u8 index;
+               char *q = kasprintf(GFP_KERNEL, "%c %s%s%pV\n", level,
+                                               prefix ? prefix : "",
+                                               prefix ? ": " : "", &vaf);
 
                index = log->head & (logsize - 1);
                BUILD_BUG_ON(sizeof(log->head) != sizeof(u8) ||
@@ -454,9 +427,11 @@ store_string:
                        log->tail++;
                }
 
-               log->buffer[index] = q;
-               log->need_free &= ~(1 << index);
-               log->need_free |= freeable << index;
+               log->buffer[index] = q ? q : "OOM: Can't store error string";
+               if (q)
+                       log->need_free |= 1 << index;
+               else
+                       log->need_free &= ~(1 << index);
                log->head++;
        }
        va_end(va);
@@ -468,12 +443,12 @@ EXPORT_SYMBOL(logfc);
  */
 static void put_fc_log(struct fs_context *fc)
 {
-       struct fc_log *log = fc->log;
+       struct fc_log *log = fc->log.log;
        int i;
 
        if (log) {
                if (refcount_dec_and_test(&log->usage)) {
-                       fc->log = NULL;
+                       fc->log.log = NULL;
                        for (i = 0; i <= 7; i++)
                                if (log->need_free & (1 << i))
                                        kfree(log->buffer[i]);
index d1930ad..7e6fb43 100644 (file)
@@ -20,42 +20,66 @@ static const struct constant_table bool_names[] = {
        { "no",         false },
        { "true",       true },
        { "yes",        true },
+       { },
 };
 
+static const struct constant_table *
+__lookup_constant(const struct constant_table *tbl, const char *name)
+{
+       for ( ; tbl->name; tbl++)
+               if (strcmp(name, tbl->name) == 0)
+                       return tbl;
+       return NULL;
+}
+
 /**
  * lookup_constant - Look up a constant by name in an ordered table
  * @tbl: The table of constants to search.
- * @tbl_size: The size of the table.
  * @name: The name to look up.
  * @not_found: The value to return if the name is not found.
  */
-int __lookup_constant(const struct constant_table *tbl, size_t tbl_size,
-                     const char *name, int not_found)
+int lookup_constant(const struct constant_table *tbl, const char *name, int not_found)
 {
-       unsigned int i;
+       const struct constant_table *p = __lookup_constant(tbl, name);
 
-       for (i = 0; i < tbl_size; i++)
-               if (strcmp(name, tbl[i].name) == 0)
-                       return tbl[i].value;
+       return p ? p->value : not_found;
+}
+EXPORT_SYMBOL(lookup_constant);
 
-       return not_found;
+static inline bool is_flag(const struct fs_parameter_spec *p)
+{
+       return p->type == NULL;
 }
-EXPORT_SYMBOL(__lookup_constant);
 
 static const struct fs_parameter_spec *fs_lookup_key(
-       const struct fs_parameter_description *desc,
-       const char *name)
+       const struct fs_parameter_spec *desc,
+       struct fs_parameter *param, bool *negated)
 {
-       const struct fs_parameter_spec *p;
-
-       if (!desc->specs)
-               return NULL;
-
-       for (p = desc->specs; p->name; p++)
-               if (strcmp(p->name, name) == 0)
+       const struct fs_parameter_spec *p, *other = NULL;
+       const char *name = param->key;
+       bool want_flag = param->type == fs_value_is_flag;
+
+       *negated = false;
+       for (p = desc; p->name; p++) {
+               if (strcmp(p->name, name) != 0)
+                       continue;
+               if (likely(is_flag(p) == want_flag))
                        return p;
-
-       return NULL;
+               other = p;
+       }
+       if (want_flag) {
+               if (name[0] == 'n' && name[1] == 'o' && name[2]) {
+                       for (p = desc; p->name; p++) {
+                               if (strcmp(p->name, name + 2) != 0)
+                                       continue;
+                               if (!(p->flags & fs_param_neg_with_no))
+                                       continue;
+                               *negated = true;
+                               return p;
+                       }
+               }
+       }
+       return other;
 }
 
 /*
@@ -76,172 +100,38 @@ static const struct fs_parameter_spec *fs_lookup_key(
  * unknown parameters are okay and -EINVAL if there was a conversion issue or
  * the parameter wasn't recognised and unknowns aren't okay.
  */
-int fs_parse(struct fs_context *fc,
-            const struct fs_parameter_description *desc,
+int __fs_parse(struct p_log *log,
+            const struct fs_parameter_spec *desc,
             struct fs_parameter *param,
             struct fs_parse_result *result)
 {
        const struct fs_parameter_spec *p;
-       const struct fs_parameter_enum *e;
-       int ret = -ENOPARAM, b;
 
-       result->has_value = !!param->string;
-       result->negated = false;
        result->uint_64 = 0;
 
-       p = fs_lookup_key(desc, param->key);
-       if (!p) {
-               /* If we didn't find something that looks like "noxxx", see if
-                * "xxx" takes the "no"-form negative - but only if there
-                * wasn't an value.
-                */
-               if (result->has_value)
-                       goto unknown_parameter;
-               if (param->key[0] != 'n' || param->key[1] != 'o' || !param->key[2])
-                       goto unknown_parameter;
-
-               p = fs_lookup_key(desc, param->key + 2);
-               if (!p)
-                       goto unknown_parameter;
-               if (!(p->flags & fs_param_neg_with_no))
-                       goto unknown_parameter;
-               result->boolean = false;
-               result->negated = true;
-       }
+       p = fs_lookup_key(desc, param, &result->negated);
+       if (!p)
+               return -ENOPARAM;
 
        if (p->flags & fs_param_deprecated)
-               warnf(fc, "%s: Deprecated parameter '%s'",
-                     desc->name, param->key);
-
-       if (result->negated)
-               goto okay;
-
-       /* Certain parameter types only take a string and convert it. */
-       switch (p->type) {
-       case __fs_param_wasnt_defined:
-               return -EINVAL;
-       case fs_param_is_u32:
-       case fs_param_is_u32_octal:
-       case fs_param_is_u32_hex:
-       case fs_param_is_s32:
-       case fs_param_is_u64:
-       case fs_param_is_enum:
-       case fs_param_is_string:
-               if (param->type != fs_value_is_string)
-                       goto bad_value;
-               if (!result->has_value) {
-                       if (p->flags & fs_param_v_optional)
-                               goto okay;
-                       goto bad_value;
-               }
-               /* Fall through */
-       default:
-               break;
-       }
+               warn_plog(log, "Deprecated parameter '%s'", param->key);
 
        /* Try to turn the type we were given into the type desired by the
         * parameter and give an error if we can't.
         */
-       switch (p->type) {
-       case fs_param_is_flag:
-               if (param->type != fs_value_is_flag &&
-                   (param->type != fs_value_is_string || result->has_value))
-                       return invalf(fc, "%s: Unexpected value for '%s'",
-                                     desc->name, param->key);
-               result->boolean = true;
-               goto okay;
-
-       case fs_param_is_bool:
-               switch (param->type) {
-               case fs_value_is_flag:
-                       result->boolean = true;
-                       goto okay;
-               case fs_value_is_string:
-                       if (param->size == 0) {
-                               result->boolean = true;
-                               goto okay;
-                       }
-                       b = lookup_constant(bool_names, param->string, -1);
-                       if (b == -1)
-                               goto bad_value;
-                       result->boolean = b;
-                       goto okay;
-               default:
-                       goto bad_value;
-               }
-
-       case fs_param_is_u32:
-               ret = kstrtouint(param->string, 0, &result->uint_32);
-               goto maybe_okay;
-       case fs_param_is_u32_octal:
-               ret = kstrtouint(param->string, 8, &result->uint_32);
-               goto maybe_okay;
-       case fs_param_is_u32_hex:
-               ret = kstrtouint(param->string, 16, &result->uint_32);
-               goto maybe_okay;
-       case fs_param_is_s32:
-               ret = kstrtoint(param->string, 0, &result->int_32);
-               goto maybe_okay;
-       case fs_param_is_u64:
-               ret = kstrtoull(param->string, 0, &result->uint_64);
-               goto maybe_okay;
-
-       case fs_param_is_enum:
-               for (e = desc->enums; e->name[0]; e++) {
-                       if (e->opt == p->opt &&
-                           strcmp(e->name, param->string) == 0) {
-                               result->uint_32 = e->value;
-                               goto okay;
-                       }
-               }
-               goto bad_value;
-
-       case fs_param_is_string:
-               goto okay;
-       case fs_param_is_blob:
-               if (param->type != fs_value_is_blob)
-                       goto bad_value;
-               goto okay;
-
-       case fs_param_is_fd: {
-               switch (param->type) {
-               case fs_value_is_string:
-                       if (!result->has_value)
-                               goto bad_value;
-
-                       ret = kstrtouint(param->string, 0, &result->uint_32);
-                       break;
-               case fs_value_is_file:
-                       result->uint_32 = param->dirfd;
-                       ret = 0;
-               default:
-                       goto bad_value;
-               }
-
-               if (result->uint_32 > INT_MAX)
-                       goto bad_value;
-               goto maybe_okay;
-       }
-
-       case fs_param_is_blockdev:
-       case fs_param_is_path:
-               goto okay;
-       default:
-               BUG();
+       if (is_flag(p)) {
+               if (param->type != fs_value_is_flag)
+                       return inval_plog(log, "Unexpected value for '%s'",
+                                     param->key);
+               result->boolean = !result->negated;
+       } else  {
+               int ret = p->type(log, p, param, result);
+               if (ret)
+                       return ret;
        }
-
-maybe_okay:
-       if (ret < 0)
-               goto bad_value;
-okay:
        return p->opt;
-
-bad_value:
-       return invalf(fc, "%s: Bad value for '%s'", desc->name, param->key);
-unknown_parameter:
-       return -ENOPARAM;
 }
-EXPORT_SYMBOL(fs_parse);
+EXPORT_SYMBOL(__fs_parse);
 
 /**
  * fs_lookup_param - Look up a path referred to by a parameter
@@ -267,9 +157,6 @@ int fs_lookup_param(struct fs_context *fc,
                        return PTR_ERR(f);
                put_f = true;
                break;
-       case fs_value_is_filename_empty:
-               flags = LOOKUP_EMPTY;
-               /* Fall through */
        case fs_value_is_filename:
                f = param->name;
                put_f = false;
@@ -302,6 +189,124 @@ out:
 }
 EXPORT_SYMBOL(fs_lookup_param);
 
+int fs_param_bad_value(struct p_log *log, struct fs_parameter *param)
+{
+       return inval_plog(log, "Bad value for '%s'", param->key);
+}
+
+int fs_param_is_bool(struct p_log *log, const struct fs_parameter_spec *p,
+                    struct fs_parameter *param, struct fs_parse_result *result)
+{
+       int b;
+       if (param->type != fs_value_is_string)
+               return fs_param_bad_value(log, param);
+       b = lookup_constant(bool_names, param->string, -1);
+       if (b == -1)
+               return fs_param_bad_value(log, param);
+       result->boolean = b;
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_bool);
+
+int fs_param_is_u32(struct p_log *log, const struct fs_parameter_spec *p,
+                   struct fs_parameter *param, struct fs_parse_result *result)
+{
+       int base = (unsigned long)p->data;
+       if (param->type != fs_value_is_string ||
+           kstrtouint(param->string, base, &result->uint_32) < 0)
+               return fs_param_bad_value(log, param);
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_u32);
+
+int fs_param_is_s32(struct p_log *log, const struct fs_parameter_spec *p,
+                   struct fs_parameter *param, struct fs_parse_result *result)
+{
+       if (param->type != fs_value_is_string ||
+           kstrtoint(param->string, 0, &result->int_32) < 0)
+               return fs_param_bad_value(log, param);
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_s32);
+
+int fs_param_is_u64(struct p_log *log, const struct fs_parameter_spec *p,
+                   struct fs_parameter *param, struct fs_parse_result *result)
+{
+       if (param->type != fs_value_is_string ||
+           kstrtoull(param->string, 0, &result->uint_64) < 0)
+               return fs_param_bad_value(log, param);
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_u64);
+
+int fs_param_is_enum(struct p_log *log, const struct fs_parameter_spec *p,
+                    struct fs_parameter *param, struct fs_parse_result *result)
+{
+       const struct constant_table *c;
+       if (param->type != fs_value_is_string)
+               return fs_param_bad_value(log, param);
+       c = __lookup_constant(p->data, param->string);
+       if (!c)
+               return fs_param_bad_value(log, param);
+       result->uint_32 = c->value;
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_enum);
+
+int fs_param_is_string(struct p_log *log, const struct fs_parameter_spec *p,
+                      struct fs_parameter *param, struct fs_parse_result *result)
+{
+       if (param->type != fs_value_is_string || !*param->string)
+               return fs_param_bad_value(log, param);
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_string);
+
+int fs_param_is_blob(struct p_log *log, const struct fs_parameter_spec *p,
+                    struct fs_parameter *param, struct fs_parse_result *result)
+{
+       if (param->type != fs_value_is_blob)
+               return fs_param_bad_value(log, param);
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_blob);
+
+int fs_param_is_fd(struct p_log *log, const struct fs_parameter_spec *p,
+                 struct fs_parameter *param, struct fs_parse_result *result)
+{
+       switch (param->type) {
+       case fs_value_is_string:
+               if (kstrtouint(param->string, 0, &result->uint_32) < 0)
+                       break;
+               if (result->uint_32 <= INT_MAX)
+                       return 0;
+               break;
+       case fs_value_is_file:
+               result->uint_32 = param->dirfd;
+               if (result->uint_32 <= INT_MAX)
+                       return 0;
+               break;
+       default:
+               break;
+       }
+       return fs_param_bad_value(log, param);
+}
+EXPORT_SYMBOL(fs_param_is_fd);
+
+int fs_param_is_blockdev(struct p_log *log, const struct fs_parameter_spec *p,
+                 struct fs_parameter *param, struct fs_parse_result *result)
+{
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_blockdev);
+
+int fs_param_is_path(struct p_log *log, const struct fs_parameter_spec *p,
+                    struct fs_parameter *param, struct fs_parse_result *result)
+{
+       return 0;
+}
+EXPORT_SYMBOL(fs_param_is_path);
+
 #ifdef CONFIG_VALIDATE_FS_PARSER
 /**
  * validate_constant_table - Validate a constant table
@@ -357,102 +362,26 @@ bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
  * fs_validate_description - Validate a parameter description
  * @desc: The parameter description to validate.
  */
-bool fs_validate_description(const struct fs_parameter_description *desc)
+bool fs_validate_description(const char *name,
+       const struct fs_parameter_spec *desc)
 {
        const struct fs_parameter_spec *param, *p2;
-       const struct fs_parameter_enum *e;
-       const char *name = desc->name;
-       unsigned int nr_params = 0;
-       bool good = true, enums = false;
+       bool good = true;
 
        pr_notice("*** VALIDATE %s ***\n", name);
 
-       if (!name[0]) {
-               pr_err("VALIDATE Parser: No name\n");
-               name = "Unknown";
-               good = false;
-       }
-
-       if (desc->specs) {
-               for (param = desc->specs; param->name; param++) {
-                       enum fs_parameter_type t = param->type;
-
-                       /* Check that the type is in range */
-                       if (t == __fs_param_wasnt_defined ||
-                           t >= nr__fs_parameter_type) {
-                               pr_err("VALIDATE %s: PARAM[%s] Bad type %u\n",
-                                      name, param->name, t);
-                               good = false;
-                       } else if (t == fs_param_is_enum) {
-                               enums = true;
-                       }
-
-                       /* Check for duplicate parameter names */
-                       for (p2 = desc->specs; p2 < param; p2++) {
-                               if (strcmp(param->name, p2->name) == 0) {
-                                       pr_err("VALIDATE %s: PARAM[%s]: Duplicate\n",
-                                              name, param->name);
-                                       good = false;
-                               }
-                       }
-               }
-
-               nr_params = param - desc->specs;
-       }
-
-       if (desc->enums) {
-               if (!nr_params) {
-                       pr_err("VALIDATE %s: Enum table but no parameters\n",
-                              name);
-                       good = false;
-                       goto no_enums;
-               }
-               if (!enums) {
-                       pr_err("VALIDATE %s: Enum table but no enum-type values\n",
-                              name);
-                       good = false;
-                       goto no_enums;
-               }
-
-               for (e = desc->enums; e->name[0]; e++) {
-                       /* Check that all entries in the enum table have at
-                        * least one parameter that uses them.
-                        */
-                       for (param = desc->specs; param->name; param++) {
-                               if (param->opt == e->opt &&
-                                   param->type != fs_param_is_enum) {
-                                       pr_err("VALIDATE %s: e[%tu] enum val for %s\n",
-                                              name, e - desc->enums, param->name);
-                                       good = false;
-                               }
-                       }
-               }
-
-               /* Check that all enum-type parameters have at least one enum
-                * value in the enum table.
-                */
-               for (param = desc->specs; param->name; param++) {
-                       if (param->type != fs_param_is_enum)
-                               continue;
-                       for (e = desc->enums; e->name[0]; e++)
-                               if (e->opt == param->opt)
-                                       break;
-                       if (!e->name[0]) {
-                               pr_err("VALIDATE %s: PARAM[%s] enum with no values\n",
+       for (param = desc; param->name; param++) {
+               /* Check for duplicate parameter names */
+               for (p2 = desc; p2 < param; p2++) {
+                       if (strcmp(param->name, p2->name) == 0) {
+                               if (is_flag(param) != is_flag(p2))
+                                       continue;
+                               pr_err("VALIDATE %s: PARAM[%s]: Duplicate\n",
                                       name, param->name);
                                good = false;
                        }
                }
-       } else {
-               if (enums) {
-                       pr_err("VALIDATE %s: enum-type values, but no enum table\n",
-                              name);
-                       good = false;
-                       goto no_enums;
-               }
        }
-
-no_enums:
        return good;
 }
 #endif /* CONFIG_VALIDATE_FS_PARSER */
index 9616af3..08e91ef 100644 (file)
@@ -111,7 +111,7 @@ extern void fscache_enqueue_object(struct fscache_object *);
  * object-list.c
  */
 #ifdef CONFIG_FSCACHE_OBJECT_LIST
-extern const struct file_operations fscache_objlist_fops;
+extern const struct proc_ops fscache_objlist_proc_ops;
 
 extern void fscache_objlist_add(struct fscache_object *);
 extern void fscache_objlist_remove(struct fscache_object *);
index 72ebfe5..e106a1a 100644 (file)
@@ -7,6 +7,7 @@
 
 #define FSCACHE_DEBUG_LEVEL COOKIE
 #include <linux/module.h>
+#include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/key.h>
@@ -405,9 +406,9 @@ static int fscache_objlist_release(struct inode *inode, struct file *file)
        return seq_release(inode, file);
 }
 
-const struct file_operations fscache_objlist_fops = {
-       .open           = fscache_objlist_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = fscache_objlist_release,
+const struct proc_ops fscache_objlist_proc_ops = {
+       .proc_open      = fscache_objlist_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = fscache_objlist_release,
 };
index 5523446..90a7bc2 100644 (file)
@@ -35,7 +35,7 @@ int __init fscache_proc_init(void)
 
 #ifdef CONFIG_FSCACHE_OBJECT_LIST
        if (!proc_create("fs/fscache/objects", S_IFREG | 0444, NULL,
-                        &fscache_objlist_fops))
+                        &fscache_objlist_proc_ops))
                goto error_objects;
 #endif
 
index 043ffa8..2fa3f24 100644 (file)
@@ -25,7 +25,7 @@ static ssize_t fscontext_read(struct file *file,
                              char __user *_buf, size_t len, loff_t *pos)
 {
        struct fs_context *fc = file->private_data;
-       struct fc_log *log = fc->log;
+       struct fc_log *log = fc->log.log;
        unsigned int logsize = ARRAY_SIZE(log->buffer);
        ssize_t ret;
        char *p;
@@ -97,11 +97,11 @@ static int fscontext_create_fd(struct fs_context *fc, unsigned int o_flags)
 
 static int fscontext_alloc_log(struct fs_context *fc)
 {
-       fc->log = kzalloc(sizeof(*fc->log), GFP_KERNEL);
-       if (!fc->log)
+       fc->log.log = kzalloc(sizeof(*fc->log.log), GFP_KERNEL);
+       if (!fc->log.log)
                return -ENOMEM;
-       refcount_set(&fc->log->usage, 1);
-       fc->log->owner = fc->fs_type->owner;
+       refcount_set(&fc->log.log->usage, 1);
+       fc->log.log->owner = fc->fs_type->owner;
        return 0;
 }
 
@@ -321,6 +321,7 @@ SYSCALL_DEFINE5(fsconfig,
        struct fs_context *fc;
        struct fd f;
        int ret;
+       int lookup_flags = 0;
 
        struct fs_parameter param = {
                .type   = fs_value_is_undefined,
@@ -409,19 +410,12 @@ SYSCALL_DEFINE5(fsconfig,
                        goto out_key;
                }
                break;
+       case FSCONFIG_SET_PATH_EMPTY:
+               lookup_flags = LOOKUP_EMPTY;
+               /* fallthru */
        case FSCONFIG_SET_PATH:
                param.type = fs_value_is_filename;
-               param.name = getname_flags(_value, 0, NULL);
-               if (IS_ERR(param.name)) {
-                       ret = PTR_ERR(param.name);
-                       goto out_key;
-               }
-               param.dirfd = aux;
-               param.size = strlen(param.name->name);
-               break;
-       case FSCONFIG_SET_PATH_EMPTY:
-               param.type = fs_value_is_filename_empty;
-               param.name = getname_flags(_value, LOOKUP_EMPTY, NULL);
+               param.name = getname_flags(_value, lookup_flags, NULL);
                if (IS_ERR(param.name)) {
                        ret = PTR_ERR(param.name);
                        goto out_key;
index 00015d8..030f094 100644 (file)
@@ -451,8 +451,8 @@ static int cuse_send_init(struct cuse_conn *cc)
        ap->args.out_args[0].size = sizeof(ia->out);
        ap->args.out_args[0].value = &ia->out;
        ap->args.out_args[1].size = CUSE_INIT_INFO_MAX;
-       ap->args.out_argvar = 1;
-       ap->args.out_pages = 1;
+       ap->args.out_argvar = true;
+       ap->args.out_pages = true;
        ap->num_pages = 1;
        ap->pages = &ia->page;
        ap->descs = &ia->desc;
index ee19011..de1e2fd 100644 (file)
@@ -818,7 +818,7 @@ static int fuse_rename2(struct inode *olddir, struct dentry *oldent,
        struct fuse_conn *fc = get_fuse_conn(olddir);
        int err;
 
-       if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE))
+       if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
                return -EINVAL;
 
        if (flags) {
index ce71538..9d67b83 100644 (file)
@@ -803,6 +803,10 @@ static int fuse_do_readpage(struct file *file, struct page *page)
 
        attr_ver = fuse_get_attr_version(fc);
 
+       /* Don't overflow end offset */
+       if (pos + (desc.length - 1) == LLONG_MAX)
+               desc.length--;
+
        fuse_read_args_fill(&ia, file, pos, desc.length, FUSE_READ);
        res = fuse_simple_request(fc, &ia.ap.args);
        if (res < 0)
@@ -888,6 +892,14 @@ static void fuse_send_readpages(struct fuse_io_args *ia, struct file *file)
        ap->args.out_pages = true;
        ap->args.page_zeroing = true;
        ap->args.page_replace = true;
+
+       /* Don't overflow end offset */
+       if (pos + (count - 1) == LLONG_MAX) {
+               count--;
+               ap->descs[ap->num_pages - 1].length--;
+       }
+       WARN_ON((loff_t) (pos + count) < 0);
+
        fuse_read_args_fill(ia, file, pos, count, FUSE_READ);
        ia->read.attr_ver = fuse_get_attr_version(fc);
        if (fc->async_read) {
@@ -1397,9 +1409,9 @@ static int fuse_get_user_pages(struct fuse_args_pages *ap, struct iov_iter *ii,
        }
 
        if (write)
-               ap->args.in_pages = 1;
+               ap->args.in_pages = true;
        else
-               ap->args.out_pages = 1;
+               ap->args.out_pages = true;
 
        *nbytesp = nbytes;
 
@@ -1465,6 +1477,7 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
                }
                ia = NULL;
                if (nres < 0) {
+                       iov_iter_revert(iter, nbytes);
                        err = nres;
                        break;
                }
@@ -1473,8 +1486,10 @@ ssize_t fuse_direct_io(struct fuse_io_priv *io, struct iov_iter *iter,
                count -= nres;
                res += nres;
                pos += nres;
-               if (nres != nbytes)
+               if (nres != nbytes) {
+                       iov_iter_revert(iter, nbytes - nres);
                        break;
+               }
                if (count) {
                        max_pages = iov_iter_npages(iter, fc->max_pages);
                        ia = fuse_io_alloc(io, max_pages);
index 16aec32..95d712d 100644 (file)
@@ -448,7 +448,7 @@ enum {
        OPT_ERR
 };
 
-static const struct fs_parameter_spec fuse_param_specs[] = {
+static const struct fs_parameter_spec fuse_fs_parameters[] = {
        fsparam_string  ("source",              OPT_SOURCE),
        fsparam_u32     ("fd",                  OPT_FD),
        fsparam_u32oct  ("rootmode",            OPT_ROOTMODE),
@@ -462,68 +462,63 @@ static const struct fs_parameter_spec fuse_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description fuse_fs_parameters = {
-       .name           = "fuse",
-       .specs          = fuse_param_specs,
-};
-
 static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct fs_parse_result result;
        struct fuse_fs_context *ctx = fc->fs_private;
        int opt;
 
-       opt = fs_parse(fc, &fuse_fs_parameters, param, &result);
+       opt = fs_parse(fc, fuse_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
        switch (opt) {
        case OPT_SOURCE:
                if (fc->source)
-                       return invalf(fc, "fuse: Multiple sources specified");
+                       return invalfc(fc, "Multiple sources specified");
                fc->source = param->string;
                param->string = NULL;
                break;
 
        case OPT_SUBTYPE:
                if (ctx->subtype)
-                       return invalf(fc, "fuse: Multiple subtypes specified");
+                       return invalfc(fc, "Multiple subtypes specified");
                ctx->subtype = param->string;
                param->string = NULL;
                return 0;
 
        case OPT_FD:
                ctx->fd = result.uint_32;
-               ctx->fd_present = 1;
+               ctx->fd_present = true;
                break;
 
        case OPT_ROOTMODE:
                if (!fuse_valid_type(result.uint_32))
-                       return invalf(fc, "fuse: Invalid rootmode");
+                       return invalfc(fc, "Invalid rootmode");
                ctx->rootmode = result.uint_32;
-               ctx->rootmode_present = 1;
+               ctx->rootmode_present = true;
                break;
 
        case OPT_USER_ID:
                ctx->user_id = make_kuid(fc->user_ns, result.uint_32);
                if (!uid_valid(ctx->user_id))
-                       return invalf(fc, "fuse: Invalid user_id");
-               ctx->user_id_present = 1;
+                       return invalfc(fc, "Invalid user_id");
+               ctx->user_id_present = true;
                break;
 
        case OPT_GROUP_ID:
                ctx->group_id = make_kgid(fc->user_ns, result.uint_32);
                if (!gid_valid(ctx->group_id))
-                       return invalf(fc, "fuse: Invalid group_id");
-               ctx->group_id_present = 1;
+                       return invalfc(fc, "Invalid group_id");
+               ctx->group_id_present = true;
                break;
 
        case OPT_DEFAULT_PERMISSIONS:
-               ctx->default_permissions = 1;
+               ctx->default_permissions = true;
                break;
 
        case OPT_ALLOW_OTHER:
-               ctx->allow_other = 1;
+               ctx->allow_other = true;
                break;
 
        case OPT_MAX_READ:
@@ -532,7 +527,7 @@ static int fuse_parse_param(struct fs_context *fc, struct fs_parameter *param)
 
        case OPT_BLKSIZE:
                if (!ctx->is_bdev)
-                       return invalf(fc, "fuse: blksize only supported for fuseblk");
+                       return invalfc(fc, "blksize only supported for fuseblk");
                ctx->blksize = result.uint_32;
                break;
 
@@ -997,7 +992,7 @@ void fuse_send_init(struct fuse_conn *fc)
        /* Variable length argument used for backward compatibility
           with interface version < 7.5.  Rest of init_out is zeroed
           by do_get_request(), so a short reply is not a problem */
-       ia->args.out_argvar = 1;
+       ia->args.out_argvar = true;
        ia->args.out_args[0].size = sizeof(ia->out);
        ia->args.out_args[0].value = &ia->out;
        ia->args.force = true;
@@ -1347,7 +1342,7 @@ static struct file_system_type fuse_fs_type = {
        .name           = "fuse",
        .fs_flags       = FS_HAS_SUBTYPE | FS_USERNS_MOUNT,
        .init_fs_context = fuse_init_fs_context,
-       .parameters     = &fuse_fs_parameters,
+       .parameters     = fuse_fs_parameters,
        .kill_sb        = fuse_kill_sb_anon,
 };
 MODULE_ALIAS_FS("fuse");
@@ -1363,7 +1358,7 @@ static struct file_system_type fuseblk_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "fuseblk",
        .init_fs_context = fuse_init_fs_context,
-       .parameters     = &fuse_fs_parameters,
+       .parameters     = fuse_fs_parameters,
        .kill_sb        = fuse_kill_sb_blk,
        .fs_flags       = FS_REQUIRES_DEV | FS_HAS_SUBTYPE,
 };
index 6a40f75..90e3f01 100644 (file)
@@ -332,7 +332,7 @@ static int fuse_readdir_uncached(struct file *file, struct dir_context *ctx)
                return -ENOMEM;
 
        plus = fuse_use_readdirplus(inode, ctx);
-       ap->args.out_pages = 1;
+       ap->args.out_pages = true;
        ap->num_pages = 1;
        ap->pages = &page;
        ap->descs = &desc;
index 9d58295..cb26be6 100644 (file)
@@ -847,7 +847,7 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        struct file *file = iocb->ki_filp;
        struct inode *inode = file_inode(file);
        struct gfs2_inode *ip = GFS2_I(inode);
-       ssize_t written = 0, ret;
+       ssize_t ret;
 
        ret = gfs2_rsqa_alloc(ip);
        if (ret)
@@ -867,68 +867,58 @@ static ssize_t gfs2_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
        inode_lock(inode);
        ret = generic_write_checks(iocb, from);
        if (ret <= 0)
-               goto out;
-
-       /* We can write back this queue in page reclaim */
-       current->backing_dev_info = inode_to_bdi(inode);
+               goto out_unlock;
 
        ret = file_remove_privs(file);
        if (ret)
-               goto out2;
+               goto out_unlock;
 
        ret = file_update_time(file);
        if (ret)
-               goto out2;
+               goto out_unlock;
 
        if (iocb->ki_flags & IOCB_DIRECT) {
                struct address_space *mapping = file->f_mapping;
-               loff_t pos, endbyte;
-               ssize_t buffered;
+               ssize_t buffered, ret2;
 
-               written = gfs2_file_direct_write(iocb, from);
-               if (written < 0 || !iov_iter_count(from))
-                       goto out2;
+               ret = gfs2_file_direct_write(iocb, from);
+               if (ret < 0 || !iov_iter_count(from))
+                       goto out_unlock;
 
-               ret = iomap_file_buffered_write(iocb, from, &gfs2_iomap_ops);
-               if (unlikely(ret < 0))
-                       goto out2;
-               buffered = ret;
+               iocb->ki_flags |= IOCB_DSYNC;
+               current->backing_dev_info = inode_to_bdi(inode);
+               buffered = iomap_file_buffered_write(iocb, from, &gfs2_iomap_ops);
+               current->backing_dev_info = NULL;
+               if (unlikely(buffered <= 0))
+                       goto out_unlock;
 
                /*
                 * We need to ensure that the page cache pages are written to
                 * disk and invalidated to preserve the expected O_DIRECT
-                * semantics.
+                * semantics.  If the writeback or invalidate fails, only report
+                * the direct I/O range as we don't know if the buffered pages
+                * made it to disk.
                 */
-               pos = iocb->ki_pos;
-               endbyte = pos + buffered - 1;
-               ret = filemap_write_and_wait_range(mapping, pos, endbyte);
-               if (!ret) {
-                       iocb->ki_pos += buffered;
-                       written += buffered;
-                       invalidate_mapping_pages(mapping,
-                                                pos >> PAGE_SHIFT,
-                                                endbyte >> PAGE_SHIFT);
-               } else {
-                       /*
-                        * We don't know how much we wrote, so just return
-                        * the number of bytes which were direct-written
-                        */
-               }
+               iocb->ki_pos += buffered;
+               ret2 = generic_write_sync(iocb, buffered);
+               invalidate_mapping_pages(mapping,
+                               (iocb->ki_pos - buffered) >> PAGE_SHIFT,
+                               (iocb->ki_pos - 1) >> PAGE_SHIFT);
+               if (!ret || ret2 > 0)
+                       ret += ret2;
        } else {
+               current->backing_dev_info = inode_to_bdi(inode);
                ret = iomap_file_buffered_write(iocb, from, &gfs2_iomap_ops);
-               if (likely(ret > 0))
+               current->backing_dev_info = NULL;
+               if (likely(ret > 0)) {
                        iocb->ki_pos += ret;
+                       ret = generic_write_sync(iocb, ret);
+               }
        }
 
-out2:
-       current->backing_dev_info = NULL;
-out:
+out_unlock:
        inode_unlock(inode);
-       if (likely(ret > 0)) {
-               /* Handle various SYNC-type writes */
-               ret = generic_write_sync(iocb, ret);
-       }
-       return written ? written : ret;
+       return ret;
 }
 
 static int fallocate_chunk(struct inode *inode, loff_t offset, loff_t len,
index d943172..c090d5a 100644 (file)
@@ -422,7 +422,7 @@ static bool gfs2_jhead_pg_srch(struct gfs2_jdesc *jd,
 
        for (offset = 0; offset < PAGE_SIZE; offset += sdp->sd_sb.sb_bsize) {
                if (!__get_log_header(sdp, kaddr + offset, 0, &lh)) {
-                       if (lh.lh_sequence > head->lh_sequence)
+                       if (lh.lh_sequence >= head->lh_sequence)
                                *head = lh;
                        else {
                                ret = true;
index b3e904b..a1a8ef7 100644 (file)
@@ -1252,6 +1252,7 @@ enum gfs2_param {
        Opt_upgrade,
        Opt_acl,
        Opt_quota,
+       Opt_quota_flag,
        Opt_suiddir,
        Opt_data,
        Opt_meta,
@@ -1266,17 +1267,11 @@ enum gfs2_param {
        Opt_loccookie,
 };
 
-enum opt_quota {
-       Opt_quota_unset = 0,
-       Opt_quota_off,
-       Opt_quota_account,
-       Opt_quota_on,
-};
-
-static const unsigned int opt_quota_values[] = {
-       [Opt_quota_off]     = GFS2_QUOTA_OFF,
-       [Opt_quota_account] = GFS2_QUOTA_ACCOUNT,
-       [Opt_quota_on]      = GFS2_QUOTA_ON,
+static const struct constant_table gfs2_param_quota[] = {
+       {"off",        GFS2_QUOTA_OFF},
+       {"account",    GFS2_QUOTA_ACCOUNT},
+       {"on",         GFS2_QUOTA_ON},
+       {}
 };
 
 enum opt_data {
@@ -1284,12 +1279,24 @@ enum opt_data {
        Opt_data_ordered   = GFS2_DATA_ORDERED,
 };
 
+static const struct constant_table gfs2_param_data[] = {
+       {"writeback",  Opt_data_writeback },
+       {"ordered",    Opt_data_ordered },
+       {}
+};
+
 enum opt_errors {
        Opt_errors_withdraw = GFS2_ERRORS_WITHDRAW,
        Opt_errors_panic    = GFS2_ERRORS_PANIC,
 };
 
-static const struct fs_parameter_spec gfs2_param_specs[] = {
+static const struct constant_table gfs2_param_errors[] = {
+       {"withdraw",   Opt_errors_withdraw },
+       {"panic",      Opt_errors_panic },
+       {}
+};
+
+static const struct fs_parameter_spec gfs2_fs_parameters[] = {
        fsparam_string ("lockproto",          Opt_lockproto),
        fsparam_string ("locktable",          Opt_locktable),
        fsparam_string ("hostdata",           Opt_hostdata),
@@ -1302,11 +1309,11 @@ static const struct fs_parameter_spec gfs2_param_specs[] = {
        fsparam_flag   ("upgrade",            Opt_upgrade),
        fsparam_flag_no("acl",                Opt_acl),
        fsparam_flag_no("suiddir",            Opt_suiddir),
-       fsparam_enum   ("data",               Opt_data),
+       fsparam_enum   ("data",               Opt_data, gfs2_param_data),
        fsparam_flag   ("meta",               Opt_meta),
        fsparam_flag_no("discard",            Opt_discard),
        fsparam_s32    ("commit",             Opt_commit),
-       fsparam_enum   ("errors",             Opt_errors),
+       fsparam_enum   ("errors",             Opt_errors, gfs2_param_errors),
        fsparam_s32    ("statfs_quantum",     Opt_statfs_quantum),
        fsparam_s32    ("statfs_percent",     Opt_statfs_percent),
        fsparam_s32    ("quota_quantum",      Opt_quota_quantum),
@@ -1314,27 +1321,11 @@ static const struct fs_parameter_spec gfs2_param_specs[] = {
        fsparam_flag_no("rgrplvb",            Opt_rgrplvb),
        fsparam_flag_no("loccookie",          Opt_loccookie),
        /* quota can be a flag or an enum so it gets special treatment */
-       __fsparam(fs_param_is_enum, "quota", Opt_quota, fs_param_neg_with_no|fs_param_v_optional),
-       {}
-};
-
-static const struct fs_parameter_enum gfs2_param_enums[] = {
-       { Opt_quota,    "off",        Opt_quota_off },
-       { Opt_quota,    "account",    Opt_quota_account },
-       { Opt_quota,    "on",         Opt_quota_on },
-       { Opt_data,     "writeback",  Opt_data_writeback },
-       { Opt_data,     "ordered",    Opt_data_ordered },
-       { Opt_errors,   "withdraw",   Opt_errors_withdraw },
-       { Opt_errors,   "panic",      Opt_errors_panic },
+       fsparam_flag_no("quota",              Opt_quota_flag),
+       fsparam_enum("quota",                 Opt_quota, gfs2_param_quota),
        {}
 };
 
-static const struct fs_parameter_description gfs2_fs_parameters = {
-       .name = "gfs2",
-       .specs = gfs2_param_specs,
-       .enums = gfs2_param_enums,
-};
-
 /* Parse a single mount parameter */
 static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
@@ -1342,7 +1333,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
        struct fs_parse_result result;
        int o;
 
-       o = fs_parse(fc, &gfs2_fs_parameters, param, &result);
+       o = fs_parse(fc, gfs2_fs_parameters, param, &result);
        if (o < 0)
                return o;
 
@@ -1370,7 +1361,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
                break;
        case Opt_debug:
                if (result.boolean && args->ar_errors == GFS2_ERRORS_PANIC)
-                       return invalf(fc, "gfs2: -o debug and -o errors=panic are mutually exclusive");
+                       return invalfc(fc, "-o debug and -o errors=panic are mutually exclusive");
                args->ar_debug = result.boolean;
                break;
        case Opt_upgrade:
@@ -1379,17 +1370,11 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
        case Opt_acl:
                args->ar_posix_acl = result.boolean;
                break;
+       case Opt_quota_flag:
+               args->ar_quota = result.negated ? GFS2_QUOTA_OFF : GFS2_QUOTA_ON;
+               break;
        case Opt_quota:
-               /* The quota option can be a flag or an enum. A non-zero int_32
-                  result means that we have an enum index. Otherwise we have
-                  to rely on the 'negated' flag to tell us whether 'quota' or
-                  'noquota' was specified. */
-               if (result.negated)
-                       args->ar_quota = GFS2_QUOTA_OFF;
-               else if (result.int_32 > 0)
-                       args->ar_quota = opt_quota_values[result.int_32];
-               else
-                       args->ar_quota = GFS2_QUOTA_ON;
+               args->ar_quota = result.int_32;
                break;
        case Opt_suiddir:
                args->ar_suiddir = result.boolean;
@@ -1406,27 +1391,27 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
                break;
        case Opt_commit:
                if (result.int_32 <= 0)
-                       return invalf(fc, "gfs2: commit mount option requires a positive numeric argument");
+                       return invalfc(fc, "commit mount option requires a positive numeric argument");
                args->ar_commit = result.int_32;
                break;
        case Opt_statfs_quantum:
                if (result.int_32 < 0)
-                       return invalf(fc, "gfs2: statfs_quantum mount option requires a non-negative numeric argument");
+                       return invalfc(fc, "statfs_quantum mount option requires a non-negative numeric argument");
                args->ar_statfs_quantum = result.int_32;
                break;
        case Opt_quota_quantum:
                if (result.int_32 <= 0)
-                       return invalf(fc, "gfs2: quota_quantum mount option requires a positive numeric argument");
+                       return invalfc(fc, "quota_quantum mount option requires a positive numeric argument");
                args->ar_quota_quantum = result.int_32;
                break;
        case Opt_statfs_percent:
                if (result.int_32 < 0 || result.int_32 > 100)
-                       return invalf(fc, "gfs2: statfs_percent mount option requires a numeric argument between 0 and 100");
+                       return invalfc(fc, "statfs_percent mount option requires a numeric argument between 0 and 100");
                args->ar_statfs_percent = result.int_32;
                break;
        case Opt_errors:
                if (args->ar_debug && result.uint_32 == GFS2_ERRORS_PANIC)
-                       return invalf(fc, "gfs2: -o debug and -o errors=panic are mutually exclusive");
+                       return invalfc(fc, "-o debug and -o errors=panic are mutually exclusive");
                args->ar_errors = result.uint_32;
                break;
        case Opt_barrier:
@@ -1439,7 +1424,7 @@ static int gfs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
                args->ar_loccookie = result.boolean;
                break;
        default:
-               return invalf(fc, "gfs2: invalid mount option: %s", param->key);
+               return invalfc(fc, "invalid mount option: %s", param->key);
        }
        return 0;
 }
@@ -1465,27 +1450,27 @@ static int gfs2_reconfigure(struct fs_context *fc)
        spin_unlock(&gt->gt_spin);
 
        if (strcmp(newargs->ar_lockproto, oldargs->ar_lockproto)) {
-               errorf(fc, "gfs2: reconfiguration of locking protocol not allowed");
+               errorfc(fc, "reconfiguration of locking protocol not allowed");
                return -EINVAL;
        }
        if (strcmp(newargs->ar_locktable, oldargs->ar_locktable)) {
-               errorf(fc, "gfs2: reconfiguration of lock table not allowed");
+               errorfc(fc, "reconfiguration of lock table not allowed");
                return -EINVAL;
        }
        if (strcmp(newargs->ar_hostdata, oldargs->ar_hostdata)) {
-               errorf(fc, "gfs2: reconfiguration of host data not allowed");
+               errorfc(fc, "reconfiguration of host data not allowed");
                return -EINVAL;
        }
        if (newargs->ar_spectator != oldargs->ar_spectator) {
-               errorf(fc, "gfs2: reconfiguration of spectator mode not allowed");
+               errorfc(fc, "reconfiguration of spectator mode not allowed");
                return -EINVAL;
        }
        if (newargs->ar_localflocks != oldargs->ar_localflocks) {
-               errorf(fc, "gfs2: reconfiguration of localflocks not allowed");
+               errorfc(fc, "reconfiguration of localflocks not allowed");
                return -EINVAL;
        }
        if (newargs->ar_meta != oldargs->ar_meta) {
-               errorf(fc, "gfs2: switching between gfs2 and gfs2meta not allowed");
+               errorfc(fc, "switching between gfs2 and gfs2meta not allowed");
                return -EINVAL;
        }
        if (oldargs->ar_spectator)
@@ -1495,11 +1480,11 @@ static int gfs2_reconfigure(struct fs_context *fc)
                if (fc->sb_flags & SB_RDONLY) {
                        error = gfs2_make_fs_ro(sdp);
                        if (error)
-                               errorf(fc, "gfs2: unable to remount read-only");
+                               errorfc(fc, "unable to remount read-only");
                } else {
                        error = gfs2_make_fs_rw(sdp);
                        if (error)
-                               errorf(fc, "gfs2: unable to remount read-write");
+                               errorfc(fc, "unable to remount read-write");
                }
        }
        sdp->sd_args = *newargs;
@@ -1644,7 +1629,7 @@ struct file_system_type gfs2_fs_type = {
        .name = "gfs2",
        .fs_flags = FS_REQUIRES_DEV,
        .init_fs_context = gfs2_init_fs_context,
-       .parameters = &gfs2_fs_parameters,
+       .parameters = gfs2_fs_parameters,
        .kill_sb = gfs2_kill_sb,
        .owner = THIS_MODULE,
 };
index a66e425..aff8642 100644 (file)
@@ -73,7 +73,7 @@ enum hugetlb_param {
        Opt_uid,
 };
 
-static const struct fs_parameter_spec hugetlb_param_specs[] = {
+static const struct fs_parameter_spec hugetlb_fs_parameters[] = {
        fsparam_u32   ("gid",           Opt_gid),
        fsparam_string("min_size",      Opt_min_size),
        fsparam_u32   ("mode",          Opt_mode),
@@ -84,11 +84,6 @@ static const struct fs_parameter_spec hugetlb_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description hugetlb_fs_parameters = {
-       .name           = "hugetlbfs",
-       .specs          = hugetlb_param_specs,
-};
-
 #ifdef CONFIG_NUMA
 static inline void hugetlb_set_vma_policy(struct vm_area_struct *vma,
                                        struct inode *inode, pgoff_t index)
@@ -1171,7 +1166,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
        unsigned long ps;
        int opt;
 
-       opt = fs_parse(fc, &hugetlb_fs_parameters, param, &result);
+       opt = fs_parse(fc, hugetlb_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -1233,7 +1228,7 @@ static int hugetlbfs_parse_param(struct fs_context *fc, struct fs_parameter *par
        }
 
 bad_val:
-       return invalf(fc, "hugetlbfs: Bad value '%s' for mount option '%s'\n",
+       return invalfc(fc, "Bad value '%s' for mount option '%s'\n",
                      param->string, param->key);
 }
 
@@ -1358,7 +1353,7 @@ static int hugetlbfs_init_fs_context(struct fs_context *fc)
 static struct file_system_type hugetlbfs_fs_type = {
        .name                   = "hugetlbfs",
        .init_fs_context        = hugetlbfs_init_fs_context,
-       .parameters             = &hugetlb_fs_parameters,
+       .parameters             = hugetlb_fs_parameters,
        .kill_sb                = kill_litter_super,
 };
 
index ea15c6d..7d57068 100644 (file)
@@ -1599,25 +1599,31 @@ retry:
 }
 EXPORT_SYMBOL(iput);
 
+#ifdef CONFIG_BLOCK
 /**
  *     bmap    - find a block number in a file
- *     @inode: inode of file
- *     @block: block to find
- *
- *     Returns the block number on the device holding the inode that
- *     is the disk block number for the block of the file requested.
- *     That is, asked for block 4 of inode 1 the function will return the
- *     disk block relative to the disk start that holds that block of the
- *     file.
+ *     @inode:  inode owning the block number being requested
+ *     @block: pointer containing the block to find
+ *
+ *     Replaces the value in *block with the block number on the device holding
+ *     corresponding to the requested block number in the file.
+ *     That is, asked for block 4 of inode 1 the function will replace the
+ *     4 in *block, with disk block relative to the disk start that holds that
+ *     block of the file.
+ *
+ *     Returns -EINVAL in case of error, 0 otherwise. If mapping falls into a
+ *     hole, returns 0 and *block is also set to 0.
  */
-sector_t bmap(struct inode *inode, sector_t block)
+int bmap(struct inode *inode, sector_t *block)
 {
-       sector_t res = 0;
-       if (inode->i_mapping->a_ops->bmap)
-               res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block);
-       return res;
+       if (!inode->i_mapping->a_ops->bmap)
+               return -EINVAL;
+
+       *block = inode->i_mapping->a_ops->bmap(inode->i_mapping, *block);
+       return 0;
 }
 EXPORT_SYMBOL(bmap);
+#endif
 
 /*
  * With relative atime, only update atime if the previous atime is
@@ -1683,12 +1689,9 @@ EXPORT_SYMBOL(generic_update_time);
  */
 static int update_time(struct inode *inode, struct timespec64 *time, int flags)
 {
-       int (*update_time)(struct inode *, struct timespec64 *, int);
-
-       update_time = inode->i_op->update_time ? inode->i_op->update_time :
-               generic_update_time;
-
-       return update_time(inode, time, flags);
+       if (inode->i_op->update_time)
+               return inode->i_op->update_time(inode, time, flags);
+       return generic_update_time(inode, time, flags);
 }
 
 /**
@@ -2154,30 +2157,6 @@ void inode_nohighmem(struct inode *inode)
 EXPORT_SYMBOL(inode_nohighmem);
 
 /**
- * timespec64_trunc - Truncate timespec64 to a granularity
- * @t: Timespec64
- * @gran: Granularity in ns.
- *
- * Truncate a timespec64 to a granularity. Always rounds down. gran must
- * not be 0 nor greater than a second (NSEC_PER_SEC, or 10^9 ns).
- */
-struct timespec64 timespec64_trunc(struct timespec64 t, unsigned gran)
-{
-       /* Avoid division in the common cases 1 ns and 1 s. */
-       if (gran == 1) {
-               /* nothing */
-       } else if (gran == NSEC_PER_SEC) {
-               t.tv_nsec = 0;
-       } else if (gran > 1 && gran < NSEC_PER_SEC) {
-               t.tv_nsec -= t.tv_nsec % gran;
-       } else {
-               WARN(1, "illegal file time granularity: %u", gran);
-       }
-       return t;
-}
-EXPORT_SYMBOL(timespec64_trunc);
-
-/**
  * timestamp_truncate - Truncate timespec to a granularity
  * @t: Timespec
  * @inode: inode being updated
index 1806afd..77f22c3 100644 (file)
@@ -585,8 +585,7 @@ struct io_submit_state {
         * io_kiocb alloc cache
         */
        void                    *reqs[IO_IOPOLL_BATCH];
-       unsigned                int free_reqs;
-       unsigned                int cur_req;
+       unsigned int            free_reqs;
 
        /*
         * File reference cache
@@ -754,6 +753,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
                                 struct io_uring_files_update *ip,
                                 unsigned nr_args);
 static int io_grab_files(struct io_kiocb *req);
+static void io_ring_file_ref_flush(struct fixed_file_data *data);
 
 static struct kmem_cache *req_cachep;
 
@@ -1020,21 +1020,28 @@ static struct io_uring_cqe *io_get_cqring(struct io_ring_ctx *ctx)
 
 static inline bool io_should_trigger_evfd(struct io_ring_ctx *ctx)
 {
+       if (!ctx->cq_ev_fd)
+               return false;
        if (!ctx->eventfd_async)
                return true;
        return io_wq_current_is_worker() || in_interrupt();
 }
 
-static void io_cqring_ev_posted(struct io_ring_ctx *ctx)
+static void __io_cqring_ev_posted(struct io_ring_ctx *ctx, bool trigger_ev)
 {
        if (waitqueue_active(&ctx->wait))
                wake_up(&ctx->wait);
        if (waitqueue_active(&ctx->sqo_wait))
                wake_up(&ctx->sqo_wait);
-       if (ctx->cq_ev_fd && io_should_trigger_evfd(ctx))
+       if (trigger_ev)
                eventfd_signal(ctx->cq_ev_fd, 1);
 }
 
+static void io_cqring_ev_posted(struct io_ring_ctx *ctx)
+{
+       __io_cqring_ev_posted(ctx, io_should_trigger_evfd(ctx));
+}
+
 /* Returns true if there are no backlogged entries after the flush */
 static bool io_cqring_overflow_flush(struct io_ring_ctx *ctx, bool force)
 {
@@ -1183,12 +1190,10 @@ static struct io_kiocb *io_get_req(struct io_ring_ctx *ctx,
                        ret = 1;
                }
                state->free_reqs = ret - 1;
-               state->cur_req = 1;
-               req = state->reqs[0];
+               req = state->reqs[ret - 1];
        } else {
-               req = state->reqs[state->cur_req];
                state->free_reqs--;
-               state->cur_req++;
+               req = state->reqs[state->free_reqs];
        }
 
 got_it:
@@ -1855,9 +1860,6 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        unsigned ioprio;
        int ret;
 
-       if (!req->file)
-               return -EBADF;
-
        if (S_ISREG(file_inode(req->file)->i_mode))
                req->flags |= REQ_F_ISREG;
 
@@ -1866,8 +1868,11 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
                req->flags |= REQ_F_CUR_POS;
                kiocb->ki_pos = req->file->f_pos;
        }
-       kiocb->ki_flags = iocb_flags(kiocb->ki_filp);
        kiocb->ki_hint = ki_hint_validate(file_write_hint(kiocb->ki_filp));
+       kiocb->ki_flags = iocb_flags(kiocb->ki_filp);
+       ret = kiocb_set_rw_flags(kiocb, READ_ONCE(sqe->rw_flags));
+       if (unlikely(ret))
+               return ret;
 
        ioprio = READ_ONCE(sqe->ioprio);
        if (ioprio) {
@@ -1879,10 +1884,6 @@ static int io_prep_rw(struct io_kiocb *req, const struct io_uring_sqe *sqe,
        } else
                kiocb->ki_ioprio = get_current_ioprio();
 
-       ret = kiocb_set_rw_flags(kiocb, READ_ONCE(sqe->rw_flags));
-       if (unlikely(ret))
-               return ret;
-
        /* don't allow async punt if RWF_NOWAIT was requested */
        if ((kiocb->ki_flags & IOCB_NOWAIT) ||
            (req->file->f_flags & O_NONBLOCK))
@@ -2164,10 +2165,12 @@ static int io_setup_async_rw(struct io_kiocb *req, ssize_t io_size,
 {
        if (!io_op_defs[req->opcode].async_ctx)
                return 0;
-       if (!req->io && io_alloc_async_ctx(req))
-               return -ENOMEM;
+       if (!req->io) {
+               if (io_alloc_async_ctx(req))
+                       return -ENOMEM;
 
-       io_req_map_rw(req, io_size, iovec, fast_iov, iter);
+               io_req_map_rw(req, io_size, iovec, fast_iov, iter);
+       }
        req->work.func = io_rw_async;
        return 0;
 }
@@ -2724,9 +2727,16 @@ static int io_fadvise(struct io_kiocb *req, struct io_kiocb **nxt,
        struct io_fadvise *fa = &req->fadvise;
        int ret;
 
-       /* DONTNEED may block, others _should_ not */
-       if (fa->advice == POSIX_FADV_DONTNEED && force_nonblock)
-               return -EAGAIN;
+       if (force_nonblock) {
+               switch (fa->advice) {
+               case POSIX_FADV_NORMAL:
+               case POSIX_FADV_RANDOM:
+               case POSIX_FADV_SEQUENTIAL:
+                       break;
+               default:
+                       return -EAGAIN;
+               }
+       }
 
        ret = vfs_fadvise(req->file, fa->offset, fa->len, fa->advice);
        if (ret < 0)
@@ -2837,16 +2847,13 @@ static void io_close_finish(struct io_wq_work **workptr)
                int ret;
 
                ret = filp_close(req->close.put_file, req->work.files);
-               if (ret < 0) {
+               if (ret < 0)
                        req_set_fail_links(req);
-               }
                io_cqring_add_event(req, ret);
        }
 
        fput(req->close.put_file);
 
-       /* we bypassed the re-issue, drop the submission reference */
-       io_put_req(req);
        io_put_req_find_next(req, &nxt);
        if (nxt)
                io_wq_assign_next(workptr, nxt);
@@ -2888,7 +2895,13 @@ static int io_close(struct io_kiocb *req, struct io_kiocb **nxt,
 
 eagain:
        req->work.func = io_close_finish;
-       return -EAGAIN;
+       /*
+        * Do manual async queue here to avoid grabbing files - we don't
+        * need the files, and it'll cause io_close_finish() to close
+        * the file again and cause a double CQE entry for this request
+        */
+       io_queue_async_work(req);
+       return 0;
 }
 
 static int io_prep_sfr(struct io_kiocb *req, const struct io_uring_sqe *sqe)
@@ -3083,7 +3096,8 @@ static int io_send(struct io_kiocb *req, struct io_kiocb **nxt,
                else if (force_nonblock)
                        flags |= MSG_DONTWAIT;
 
-               ret = __sys_sendmsg_sock(sock, &msg, flags);
+               msg.msg_flags = flags;
+               ret = sock_sendmsg(sock, &msg);
                if (force_nonblock && ret == -EAGAIN)
                        return -EAGAIN;
                if (ret == -ERESTARTSYS)
@@ -3109,6 +3123,7 @@ static int io_recvmsg_prep(struct io_kiocb *req,
 
        sr->msg_flags = READ_ONCE(sqe->msg_flags);
        sr->msg = u64_to_user_ptr(READ_ONCE(sqe->addr));
+       sr->len = READ_ONCE(sqe->len);
 
        if (!io || req->opcode == IORING_OP_RECV)
                return 0;
@@ -3227,7 +3242,7 @@ static int io_recv(struct io_kiocb *req, struct io_kiocb **nxt,
                else if (force_nonblock)
                        flags |= MSG_DONTWAIT;
 
-               ret = __sys_recvmsg_sock(sock, &msg, NULL, NULL, flags);
+               ret = sock_recvmsg(sock, &msg, flags);
                if (force_nonblock && ret == -EAGAIN)
                        return -EAGAIN;
                if (ret == -ERESTARTSYS)
@@ -3561,6 +3576,14 @@ static void io_poll_flush(struct io_wq_work **workptr)
                __io_poll_flush(req->ctx, nodes);
 }
 
+static void io_poll_trigger_evfd(struct io_wq_work **workptr)
+{
+       struct io_kiocb *req = container_of(*workptr, struct io_kiocb, work);
+
+       eventfd_signal(req->ctx->cq_ev_fd, 1);
+       io_put_req(req);
+}
+
 static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
                        void *key)
 {
@@ -3586,14 +3609,22 @@ static int io_poll_wake(struct wait_queue_entry *wait, unsigned mode, int sync,
 
                if (llist_empty(&ctx->poll_llist) &&
                    spin_trylock_irqsave(&ctx->completion_lock, flags)) {
+                       bool trigger_ev;
+
                        hash_del(&req->hash_node);
                        io_poll_complete(req, mask, 0);
-                       req->flags |= REQ_F_COMP_LOCKED;
-                       io_put_req(req);
-                       spin_unlock_irqrestore(&ctx->completion_lock, flags);
 
-                       io_cqring_ev_posted(ctx);
-                       req = NULL;
+                       trigger_ev = io_should_trigger_evfd(ctx);
+                       if (trigger_ev && eventfd_signal_count()) {
+                               trigger_ev = false;
+                               req->work.func = io_poll_trigger_evfd;
+                       } else {
+                               req->flags |= REQ_F_COMP_LOCKED;
+                               io_put_req(req);
+                               req = NULL;
+                       }
+                       spin_unlock_irqrestore(&ctx->completion_lock, flags);
+                       __io_cqring_ev_posted(ctx, trigger_ev);
                } else {
                        req->result = mask;
                        req->llist_node.next = NULL;
@@ -4815,8 +4846,7 @@ static void io_submit_state_end(struct io_submit_state *state)
        blk_finish_plug(&state->plug);
        io_file_put(state);
        if (state->free_reqs)
-               kmem_cache_free_bulk(req_cachep, state->free_reqs,
-                                       &state->reqs[state->cur_req]);
+               kmem_cache_free_bulk(req_cachep, state->free_reqs, state->reqs);
 }
 
 /*
@@ -5041,7 +5071,8 @@ static int io_sq_thread(void *data)
                         * reap events and wake us up.
                         */
                        if (inflight ||
-                           (!time_after(jiffies, timeout) && ret != -EBUSY)) {
+                           (!time_after(jiffies, timeout) && ret != -EBUSY &&
+                           !percpu_ref_is_dying(&ctx->refs))) {
                                cond_resched();
                                continue;
                        }
@@ -5231,15 +5262,10 @@ static int io_sqe_files_unregister(struct io_ring_ctx *ctx)
        if (!data)
                return -ENXIO;
 
-       /* protect against inflight atomic switch, which drops the ref */
-       percpu_ref_get(&data->refs);
-       /* wait for existing switches */
-       flush_work(&data->ref_work);
        percpu_ref_kill_and_confirm(&data->refs, io_file_ref_kill);
-       wait_for_completion(&data->done);
-       percpu_ref_put(&data->refs);
-       /* flush potential new switch */
        flush_work(&data->ref_work);
+       wait_for_completion(&data->done);
+       io_ring_file_ref_flush(data);
        percpu_ref_exit(&data->refs);
 
        __io_sqe_files_unregister(ctx);
@@ -5477,14 +5503,11 @@ struct io_file_put {
        struct completion *done;
 };
 
-static void io_ring_file_ref_switch(struct work_struct *work)
+static void io_ring_file_ref_flush(struct fixed_file_data *data)
 {
        struct io_file_put *pfile, *tmp;
-       struct fixed_file_data *data;
        struct llist_node *node;
 
-       data = container_of(work, struct fixed_file_data, ref_work);
-
        while ((node = llist_del_all(&data->put_llist)) != NULL) {
                llist_for_each_entry_safe(pfile, tmp, node, llist) {
                        io_ring_file_put(data->ctx, pfile->file);
@@ -5494,7 +5517,14 @@ static void io_ring_file_ref_switch(struct work_struct *work)
                                kfree(pfile);
                }
        }
+}
 
+static void io_ring_file_ref_switch(struct work_struct *work)
+{
+       struct fixed_file_data *data;
+
+       data = container_of(work, struct fixed_file_data, ref_work);
+       io_ring_file_ref_flush(data);
        percpu_ref_get(&data->refs);
        percpu_ref_switch_to_percpu(&data->refs);
 }
@@ -5505,8 +5535,14 @@ static void io_file_data_ref_zero(struct percpu_ref *ref)
 
        data = container_of(ref, struct fixed_file_data, refs);
 
-       /* we can't safely switch from inside this context, punt to wq */
-       queue_work(system_wq, &data->ref_work);
+       /*
+        * We can't safely switch from inside this context, punt to wq. If
+        * the table ref is going away, the table is being unregistered.
+        * Don't queue up the async work for that case, the caller will
+        * handle it.
+        */
+       if (!percpu_ref_is_dying(&data->refs))
+               queue_work(system_wq, &data->ref_work);
 }
 
 static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
@@ -6295,6 +6331,16 @@ static void io_ring_ctx_wait_and_kill(struct io_ring_ctx *ctx)
        percpu_ref_kill(&ctx->refs);
        mutex_unlock(&ctx->uring_lock);
 
+       /*
+        * Wait for sq thread to idle, if we have one. It won't spin on new
+        * work after we've killed the ctx ref above. This is important to do
+        * before we cancel existing commands, as the thread could otherwise
+        * be queueing new work post that. If that's work we need to cancel,
+        * it could cause shutdown to hang.
+        */
+       while (ctx->sqo_thread && !wq_has_sleeper(&ctx->sqo_wait))
+               cpu_relax();
+
        io_kill_timeouts(ctx);
        io_poll_remove_all(ctx);
 
@@ -6501,6 +6547,80 @@ out_fput:
        return submitted ? submitted : ret;
 }
 
+static int io_uring_show_cred(int id, void *p, void *data)
+{
+       const struct cred *cred = p;
+       struct seq_file *m = data;
+       struct user_namespace *uns = seq_user_ns(m);
+       struct group_info *gi;
+       kernel_cap_t cap;
+       unsigned __capi;
+       int g;
+
+       seq_printf(m, "%5d\n", id);
+       seq_put_decimal_ull(m, "\tUid:\t", from_kuid_munged(uns, cred->uid));
+       seq_put_decimal_ull(m, "\t\t", from_kuid_munged(uns, cred->euid));
+       seq_put_decimal_ull(m, "\t\t", from_kuid_munged(uns, cred->suid));
+       seq_put_decimal_ull(m, "\t\t", from_kuid_munged(uns, cred->fsuid));
+       seq_put_decimal_ull(m, "\n\tGid:\t", from_kgid_munged(uns, cred->gid));
+       seq_put_decimal_ull(m, "\t\t", from_kgid_munged(uns, cred->egid));
+       seq_put_decimal_ull(m, "\t\t", from_kgid_munged(uns, cred->sgid));
+       seq_put_decimal_ull(m, "\t\t", from_kgid_munged(uns, cred->fsgid));
+       seq_puts(m, "\n\tGroups:\t");
+       gi = cred->group_info;
+       for (g = 0; g < gi->ngroups; g++) {
+               seq_put_decimal_ull(m, g ? " " : "",
+                                       from_kgid_munged(uns, gi->gid[g]));
+       }
+       seq_puts(m, "\n\tCapEff:\t");
+       cap = cred->cap_effective;
+       CAP_FOR_EACH_U32(__capi)
+               seq_put_hex_ll(m, NULL, cap.cap[CAP_LAST_U32 - __capi], 8);
+       seq_putc(m, '\n');
+       return 0;
+}
+
+static void __io_uring_show_fdinfo(struct io_ring_ctx *ctx, struct seq_file *m)
+{
+       int i;
+
+       mutex_lock(&ctx->uring_lock);
+       seq_printf(m, "UserFiles:\t%u\n", ctx->nr_user_files);
+       for (i = 0; i < ctx->nr_user_files; i++) {
+               struct fixed_file_table *table;
+               struct file *f;
+
+               table = &ctx->file_data->table[i >> IORING_FILE_TABLE_SHIFT];
+               f = table->files[i & IORING_FILE_TABLE_MASK];
+               if (f)
+                       seq_printf(m, "%5u: %s\n", i, file_dentry(f)->d_iname);
+               else
+                       seq_printf(m, "%5u: <none>\n", i);
+       }
+       seq_printf(m, "UserBufs:\t%u\n", ctx->nr_user_bufs);
+       for (i = 0; i < ctx->nr_user_bufs; i++) {
+               struct io_mapped_ubuf *buf = &ctx->user_bufs[i];
+
+               seq_printf(m, "%5u: 0x%llx/%u\n", i, buf->ubuf,
+                                               (unsigned int) buf->len);
+       }
+       if (!idr_is_empty(&ctx->personality_idr)) {
+               seq_printf(m, "Personalities:\n");
+               idr_for_each(&ctx->personality_idr, io_uring_show_cred, m);
+       }
+       mutex_unlock(&ctx->uring_lock);
+}
+
+static void io_uring_show_fdinfo(struct seq_file *m, struct file *f)
+{
+       struct io_ring_ctx *ctx = f->private_data;
+
+       if (percpu_ref_tryget(&ctx->refs)) {
+               __io_uring_show_fdinfo(ctx, m);
+               percpu_ref_put(&ctx->refs);
+       }
+}
+
 static const struct file_operations io_uring_fops = {
        .release        = io_uring_release,
        .flush          = io_uring_flush,
@@ -6511,6 +6631,7 @@ static const struct file_operations io_uring_fops = {
 #endif
        .poll           = io_uring_poll,
        .fasync         = io_uring_fasync,
+       .show_fdinfo    = io_uring_show_fdinfo,
 };
 
 static int io_allocate_scq_urings(struct io_ring_ctx *ctx,
@@ -6963,6 +7084,39 @@ out_fput:
 
 static int __init io_uring_init(void)
 {
+#define __BUILD_BUG_VERIFY_ELEMENT(stype, eoffset, etype, ename) do { \
+       BUILD_BUG_ON(offsetof(stype, ename) != eoffset); \
+       BUILD_BUG_ON(sizeof(etype) != sizeof_field(stype, ename)); \
+} while (0)
+
+#define BUILD_BUG_SQE_ELEM(eoffset, etype, ename) \
+       __BUILD_BUG_VERIFY_ELEMENT(struct io_uring_sqe, eoffset, etype, ename)
+       BUILD_BUG_ON(sizeof(struct io_uring_sqe) != 64);
+       BUILD_BUG_SQE_ELEM(0,  __u8,   opcode);
+       BUILD_BUG_SQE_ELEM(1,  __u8,   flags);
+       BUILD_BUG_SQE_ELEM(2,  __u16,  ioprio);
+       BUILD_BUG_SQE_ELEM(4,  __s32,  fd);
+       BUILD_BUG_SQE_ELEM(8,  __u64,  off);
+       BUILD_BUG_SQE_ELEM(8,  __u64,  addr2);
+       BUILD_BUG_SQE_ELEM(16, __u64,  addr);
+       BUILD_BUG_SQE_ELEM(24, __u32,  len);
+       BUILD_BUG_SQE_ELEM(28,     __kernel_rwf_t, rw_flags);
+       BUILD_BUG_SQE_ELEM(28, /* compat */   int, rw_flags);
+       BUILD_BUG_SQE_ELEM(28, /* compat */ __u32, rw_flags);
+       BUILD_BUG_SQE_ELEM(28, __u32,  fsync_flags);
+       BUILD_BUG_SQE_ELEM(28, __u16,  poll_events);
+       BUILD_BUG_SQE_ELEM(28, __u32,  sync_range_flags);
+       BUILD_BUG_SQE_ELEM(28, __u32,  msg_flags);
+       BUILD_BUG_SQE_ELEM(28, __u32,  timeout_flags);
+       BUILD_BUG_SQE_ELEM(28, __u32,  accept_flags);
+       BUILD_BUG_SQE_ELEM(28, __u32,  cancel_flags);
+       BUILD_BUG_SQE_ELEM(28, __u32,  open_flags);
+       BUILD_BUG_SQE_ELEM(28, __u32,  statx_flags);
+       BUILD_BUG_SQE_ELEM(28, __u32,  fadvise_advice);
+       BUILD_BUG_SQE_ELEM(32, __u64,  user_data);
+       BUILD_BUG_SQE_ELEM(40, __u16,  buf_index);
+       BUILD_BUG_SQE_ELEM(42, __u16,  personality);
+
        BUILD_BUG_ON(ARRAY_SIZE(io_op_defs) != IORING_OP_LAST);
        req_cachep = KMEM_CACHE(io_kiocb, SLAB_HWCACHE_ALIGN | SLAB_PANIC);
        return 0;
index 7c9a5df..282d45b 100644 (file)
@@ -54,19 +54,32 @@ EXPORT_SYMBOL(vfs_ioctl);
 
 static int ioctl_fibmap(struct file *filp, int __user *p)
 {
-       struct address_space *mapping = filp->f_mapping;
-       int res, block;
+       struct inode *inode = file_inode(filp);
+       int error, ur_block;
+       sector_t block;
 
-       /* do we support this mess? */
-       if (!mapping->a_ops->bmap)
-               return -EINVAL;
        if (!capable(CAP_SYS_RAWIO))
                return -EPERM;
-       res = get_user(block, p);
-       if (res)
-               return res;
-       res = mapping->a_ops->bmap(mapping, block);
-       return put_user(res, p);
+
+       error = get_user(ur_block, p);
+       if (error)
+               return error;
+
+       if (ur_block < 0)
+               return -EINVAL;
+
+       block = ur_block;
+       error = bmap(inode, &block);
+
+       if (error)
+               ur_block = 0;
+       else
+               ur_block = block;
+
+       if (put_user(ur_block, p))
+               error = -EFAULT;
+
+       return error;
 }
 
 /**
@@ -523,13 +536,9 @@ static int compat_ioctl_preallocate(struct file *file, int mode,
 
 static int file_ioctl(struct file *filp, unsigned int cmd, int __user *p)
 {
-       struct inode *inode = file_inode(filp);
-
        switch (cmd) {
        case FIBMAP:
                return ioctl_fibmap(filp, p);
-       case FIONREAD:
-               return put_user(i_size_read(inode) - filp->f_pos, p);
        case FS_IOC_RESVSP:
        case FS_IOC_RESVSP64:
                return ioctl_preallocate(filp, 0, p);
@@ -721,6 +730,13 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd,
        case FIDEDUPERANGE:
                return ioctl_file_dedupe_range(filp, argp);
 
+       case FIONREAD:
+               if (!S_ISREG(inode->i_mode))
+                       return vfs_ioctl(filp, cmd, arg);
+
+               return put_user(i_size_read(inode) - filp->f_pos,
+                               (int __user *)argp);
+
        default:
                if (S_ISREG(inode->i_mode))
                        return file_ioctl(filp, cmd, argp);
index 60bf8ff..a49d0e6 100644 (file)
@@ -794,18 +794,22 @@ int jbd2_journal_bmap(journal_t *journal, unsigned long blocknr,
 {
        int err = 0;
        unsigned long long ret;
+       sector_t block = 0;
 
        if (journal->j_inode) {
-               ret = bmap(journal->j_inode, blocknr);
-               if (ret)
-                       *retp = ret;
-               else {
+               block = blocknr;
+               ret = bmap(journal->j_inode, &block);
+
+               if (ret || !block) {
                        printk(KERN_ALERT "%s: journal block not found "
                                        "at offset %lu on %s\n",
                               __func__, blocknr, journal->j_devname);
                        err = -EIO;
                        jbd2_journal_abort(journal, err);
+               } else {
+                       *retp = block;
                }
+
        } else {
                *retp = blocknr; /* +journal->j_blk_offset */
        }
@@ -1074,12 +1078,11 @@ static int jbd2_seq_info_release(struct inode *inode, struct file *file)
        return seq_release(inode, file);
 }
 
-static const struct file_operations jbd2_seq_info_fops = {
-       .owner          = THIS_MODULE,
-       .open           = jbd2_seq_info_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = jbd2_seq_info_release,
+static const struct proc_ops jbd2_info_proc_ops = {
+       .proc_open      = jbd2_seq_info_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = jbd2_seq_info_release,
 };
 
 static struct proc_dir_entry *proc_jbd2_stats;
@@ -1089,7 +1092,7 @@ static void jbd2_stats_proc_init(journal_t *journal)
        journal->j_proc_entry = proc_mkdir(journal->j_devname, proc_jbd2_stats);
        if (journal->j_proc_entry) {
                proc_create_data("info", S_IRUGO, journal->j_proc_entry,
-                                &jbd2_seq_info_fops, journal);
+                                &jbd2_info_proc_ops, journal);
        }
 }
 
@@ -1244,11 +1247,14 @@ journal_t *jbd2_journal_init_dev(struct block_device *bdev,
 journal_t *jbd2_journal_init_inode(struct inode *inode)
 {
        journal_t *journal;
+       sector_t blocknr;
        char *p;
-       unsigned long long blocknr;
+       int err = 0;
+
+       blocknr = 0;
+       err = bmap(inode, &blocknr);
 
-       blocknr = bmap(inode, 0);
-       if (!blocknr) {
+       if (err || !blocknr) {
                pr_err("%s: Cannot locate journal superblock\n",
                        __func__);
                return NULL;
index 0e6406c..05d7878 100644 (file)
@@ -167,27 +167,21 @@ enum {
        Opt_rp_size,
 };
 
-static const struct fs_parameter_spec jffs2_param_specs[] = {
-       fsparam_enum    ("compr",       Opt_override_compr),
-       fsparam_u32     ("rp_size",     Opt_rp_size),
-       {}
-};
-
-static const struct fs_parameter_enum jffs2_param_enums[] = {
-       { Opt_override_compr,   "none", JFFS2_COMPR_MODE_NONE },
+static const struct constant_table jffs2_param_compr[] = {
+       {"none",        JFFS2_COMPR_MODE_NONE },
 #ifdef CONFIG_JFFS2_LZO
-       { Opt_override_compr,   "lzo",  JFFS2_COMPR_MODE_FORCELZO },
+       {"lzo",         JFFS2_COMPR_MODE_FORCELZO },
 #endif
 #ifdef CONFIG_JFFS2_ZLIB
-       { Opt_override_compr,   "zlib", JFFS2_COMPR_MODE_FORCEZLIB },
+       {"zlib",        JFFS2_COMPR_MODE_FORCEZLIB },
 #endif
        {}
 };
 
-const struct fs_parameter_description jffs2_fs_parameters = {
-       .name           = "jffs2",
-       .specs          = jffs2_param_specs,
-       .enums          = jffs2_param_enums,
+static const struct fs_parameter_spec jffs2_fs_parameters[] = {
+       fsparam_enum    ("compr",       Opt_override_compr, jffs2_param_compr),
+       fsparam_u32     ("rp_size",     Opt_rp_size),
+       {}
 };
 
 static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
@@ -196,7 +190,7 @@ static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param)
        struct jffs2_sb_info *c = fc->s_fs_info;
        int opt;
 
-       opt = fs_parse(fc, &jffs2_fs_parameters, param, &result);
+       opt = fs_parse(fc, jffs2_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -339,7 +333,7 @@ static struct file_system_type jffs2_fs_type = {
        .owner =        THIS_MODULE,
        .name =         "jffs2",
        .init_fs_context = jffs2_init_fs_context,
-       .parameters =   &jffs2_fs_parameters,
+       .parameters =   jffs2_fs_parameters,
        .kill_sb =      jffs2_kill_sb,
 };
 MODULE_ALIAS_FS("jffs2");
index 888cdd6..44b62b3 100644 (file)
@@ -43,12 +43,12 @@ static ssize_t jfs_loglevel_proc_write(struct file *file,
        return count;
 }
 
-static const struct file_operations jfs_loglevel_proc_fops = {
-       .open           = jfs_loglevel_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = jfs_loglevel_proc_write,
+static const struct proc_ops jfs_loglevel_proc_ops = {
+       .proc_open      = jfs_loglevel_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = jfs_loglevel_proc_write,
 };
 #endif
 
@@ -68,7 +68,7 @@ void jfs_proc_init(void)
 #endif
 #ifdef CONFIG_JFS_DEBUG
        proc_create_single("TxAnchor", 0, base, jfs_txanchor_proc_show);
-       proc_create("loglevel", 0, base, &jfs_loglevel_proc_fops);
+       proc_create("loglevel", 0, base, &jfs_loglevel_proc_ops);
 #endif
 }
 
index caade18..7dfcab2 100644 (file)
@@ -4027,7 +4027,6 @@ static int dbGetL2AGSize(s64 nblocks)
  */
 #define MAXL0PAGES     (1 + LPERCTL)
 #define MAXL1PAGES     (1 + LPERCTL * MAXL0PAGES)
-#define MAXL2PAGES     (1 + LPERCTL * MAXL1PAGES)
 
 /*
  * convert number of map pages to the zero origin top dmapctl level
index eac277c..d0f7a5a 100644 (file)
@@ -160,9 +160,9 @@ static inline void set_inode_attr(struct inode *inode,
 {
        inode->i_uid = attrs->ia_uid;
        inode->i_gid = attrs->ia_gid;
-       inode->i_atime = timestamp_truncate(attrs->ia_atime, inode);
-       inode->i_mtime = timestamp_truncate(attrs->ia_mtime, inode);
-       inode->i_ctime = timestamp_truncate(attrs->ia_ctime, inode);
+       inode->i_atime = attrs->ia_atime;
+       inode->i_mtime = attrs->ia_mtime;
+       inode->i_ctime = attrs->ia_ctime;
 }
 
 static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
index 1463b03..c686bd9 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/buffer_head.h> /* sync_mapping_buffers */
 #include <linux/fs_context.h>
 #include <linux/pseudo_fs.h>
+#include <linux/fsnotify.h>
 
 #include <linux/uaccess.h>
 
@@ -239,6 +240,75 @@ const struct inode_operations simple_dir_inode_operations = {
 };
 EXPORT_SYMBOL(simple_dir_inode_operations);
 
+static struct dentry *find_next_child(struct dentry *parent, struct dentry *prev)
+{
+       struct dentry *child = NULL;
+       struct list_head *p = prev ? &prev->d_child : &parent->d_subdirs;
+
+       spin_lock(&parent->d_lock);
+       while ((p = p->next) != &parent->d_subdirs) {
+               struct dentry *d = container_of(p, struct dentry, d_child);
+               if (simple_positive(d)) {
+                       spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED);
+                       if (simple_positive(d))
+                               child = dget_dlock(d);
+                       spin_unlock(&d->d_lock);
+                       if (likely(child))
+                               break;
+               }
+       }
+       spin_unlock(&parent->d_lock);
+       dput(prev);
+       return child;
+}
+
+void simple_recursive_removal(struct dentry *dentry,
+                              void (*callback)(struct dentry *))
+{
+       struct dentry *this = dget(dentry);
+       while (true) {
+               struct dentry *victim = NULL, *child;
+               struct inode *inode = this->d_inode;
+
+               inode_lock(inode);
+               if (d_is_dir(this))
+                       inode->i_flags |= S_DEAD;
+               while ((child = find_next_child(this, victim)) == NULL) {
+                       // kill and ascend
+                       // update metadata while it's still locked
+                       inode->i_ctime = current_time(inode);
+                       clear_nlink(inode);
+                       inode_unlock(inode);
+                       victim = this;
+                       this = this->d_parent;
+                       inode = this->d_inode;
+                       inode_lock(inode);
+                       if (simple_positive(victim)) {
+                               d_invalidate(victim);   // avoid lost mounts
+                               if (d_is_dir(victim))
+                                       fsnotify_rmdir(inode, victim);
+                               else
+                                       fsnotify_unlink(inode, victim);
+                               if (callback)
+                                       callback(victim);
+                               dput(victim);           // unpin it
+                       }
+                       if (victim == dentry) {
+                               inode->i_ctime = inode->i_mtime =
+                                       current_time(inode);
+                               if (d_is_dir(dentry))
+                                       drop_nlink(inode);
+                               inode_unlock(inode);
+                               dput(dentry);
+                               return;
+                       }
+               }
+               inode_unlock(inode);
+               this = child;
+       }
+}
+EXPORT_SYMBOL(simple_recursive_removal);
+
 static const struct super_operations simple_super_operations = {
        .statfs         = simple_statfs,
 };
index ca9228a..a01f08c 100644 (file)
@@ -60,11 +60,11 @@ nlm_end_grace_read(struct file *file, char __user *buf, size_t size,
        return simple_read_from_buffer(buf, size, pos, resp, sizeof(resp));
 }
 
-static const struct file_operations lockd_end_grace_operations = {
-       .write          = nlm_end_grace_write,
-       .read           = nlm_end_grace_read,
-       .llseek         = default_llseek,
-       .release        = simple_transaction_release,
+static const struct proc_ops lockd_end_grace_proc_ops = {
+       .proc_write     = nlm_end_grace_write,
+       .proc_read      = nlm_end_grace_read,
+       .proc_lseek     = default_llseek,
+       .proc_release   = simple_transaction_release,
 };
 
 int __init
@@ -76,7 +76,7 @@ lockd_create_procfs(void)
        if (!entry)
                return -ENOMEM;
        entry = proc_create("nlm_end_grace", S_IRUGO|S_IWUSR, entry,
-                                &lockd_end_grace_operations);
+                           &lockd_end_grace_proc_ops);
        if (!entry) {
                remove_proc_entry("fs/lockd", NULL);
                return -ENOMEM;
index 5e1bf61..85b5f7b 100644 (file)
@@ -2979,39 +2979,10 @@ static void shrink_submounts(struct mount *mnt)
        }
 }
 
-/*
- * Some copy_from_user() implementations do not return the exact number of
- * bytes remaining to copy on a fault.  But copy_mount_options() requires that.
- * Note that this function differs from copy_from_user() in that it will oops
- * on bad values of `to', rather than returning a short copy.
- */
-static long exact_copy_from_user(void *to, const void __user * from,
-                                unsigned long n)
-{
-       char *t = to;
-       const char __user *f = from;
-       char c;
-
-       if (!access_ok(from, n))
-               return n;
-
-       while (n) {
-               if (__get_user(c, f)) {
-                       memset(t, 0, n);
-                       break;
-               }
-               *t++ = c;
-               f++;
-               n--;
-       }
-       return n;
-}
-
 void *copy_mount_options(const void __user * data)
 {
-       int i;
-       unsigned long size;
        char *copy;
+       unsigned size;
 
        if (!data)
                return NULL;
@@ -3020,22 +2991,16 @@ void *copy_mount_options(const void __user * data)
        if (!copy)
                return ERR_PTR(-ENOMEM);
 
-       /* We only care that *some* data at the address the user
-        * gave us is valid.  Just in case, we'll zero
-        * the remainder of the page.
-        */
-       /* copy_from_user cannot cross TASK_SIZE ! */
-       size = TASK_SIZE - (unsigned long)untagged_addr(data);
-       if (size > PAGE_SIZE)
-               size = PAGE_SIZE;
+       size = PAGE_SIZE - offset_in_page(data);
 
-       i = size - exact_copy_from_user(copy, data, size);
-       if (!i) {
+       if (copy_from_user(copy, data, size)) {
                kfree(copy);
                return ERR_PTR(-EFAULT);
        }
-       if (i != PAGE_SIZE)
-               memset(copy + i, 0, PAGE_SIZE - i);
+       if (size != PAGE_SIZE) {
+               if (copy_from_user(copy + size, data + size, PAGE_SIZE - size))
+                       memset(copy + size, 0, PAGE_SIZE - size);
+       }
        return copy;
 }
 
index 295a7a2..40b6c5a 100644 (file)
@@ -90,7 +90,7 @@ config NFS_V4
 config NFS_SWAP
        bool "Provide swap over NFS support"
        default n
-       depends on NFS_FS
+       depends on NFS_FS && SWAP
        select SUNRPC_SWAP
        help
          This option enables swapon to work on files located on NFS mounts.
@@ -196,3 +196,12 @@ config NFS_DEBUG
        depends on NFS_FS && SUNRPC_DEBUG
        select CRC32
        default y
+
+config NFS_DISABLE_UDP_SUPPORT
+       bool "NFS: Disable NFS UDP protocol support"
+       depends on NFS_FS
+       default y
+       help
+        Choose Y here to disable the use of NFS over UDP. NFS over UDP
+        on modern networks (1Gb+) can lead to data corruption caused by
+        fragmentation during high loads.
index 34cdeae..2433c3e 100644 (file)
@@ -9,7 +9,7 @@ CFLAGS_nfstrace.o += -I$(src)
 nfs-y                  := client.o dir.o file.o getroot.o inode.o super.o \
                           io.o direct.o pagelist.o read.o symlink.o unlink.o \
                           write.o namespace.o mount_clnt.o nfstrace.o \
-                          export.o sysfs.o
+                          export.o sysfs.o fs_context.o
 nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
 nfs-$(CONFIG_SYSCTL)   += sysctl.o
 nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
index 03a20f5..79ff172 100644 (file)
@@ -18,6 +18,7 @@
 #include "callback.h"
 #include "internal.h"
 #include "nfs4session.h"
+#include "nfs4trace.h"
 
 #define CB_OP_TAGLEN_MAXSZ             (512)
 #define CB_OP_HDR_RES_MAXSZ            (2 * 4) // opcode, status
@@ -946,9 +947,13 @@ static __be32 nfs4_callback_compound(struct svc_rqst *rqstp)
 
        if (hdr_arg.minorversion == 0) {
                cps.clp = nfs4_find_client_ident(SVC_NET(rqstp), hdr_arg.cb_ident);
-               if (!cps.clp || !check_gss_callback_principal(cps.clp, rqstp)) {
-                       if (cps.clp)
-                               nfs_put_client(cps.clp);
+               if (!cps.clp) {
+                       trace_nfs_cb_no_clp(rqstp->rq_xid, hdr_arg.cb_ident);
+                       goto out_invalidcred;
+               }
+               if (!check_gss_callback_principal(cps.clp, rqstp)) {
+                       trace_nfs_cb_badprinc(rqstp->rq_xid, hdr_arg.cb_ident);
+                       nfs_put_client(cps.clp);
                        goto out_invalidcred;
                }
        }
index 02110a3..989c30c 100644 (file)
@@ -474,6 +474,7 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
                        to->to_maxval = to->to_initval;
                to->to_exponential = 0;
                break;
+#ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT
        case XPRT_TRANSPORT_UDP:
                if (retrans == NFS_UNSPEC_RETRANS)
                        to->to_retries = NFS_DEF_UDP_RETRANS;
@@ -484,6 +485,7 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
                to->to_maxval = NFS_MAX_UDP_TIMEOUT;
                to->to_exponential = 1;
                break;
+#endif
        default:
                BUG();
        }
@@ -580,8 +582,10 @@ static int nfs_start_lockd(struct nfs_server *server)
                default:
                        nlm_init.protocol = IPPROTO_TCP;
                        break;
+#ifndef CONFIG_NFS_DISABLE_UDP_SUPPORT
                case XPRT_TRANSPORT_UDP:
                        nlm_init.protocol = IPPROTO_UDP;
+#endif
        }
 
        host = nlmclnt_init(&nlm_init);
@@ -658,28 +662,28 @@ EXPORT_SYMBOL_GPL(nfs_init_client);
  * Create a version 2 or 3 client
  */
 static int nfs_init_server(struct nfs_server *server,
-                          const struct nfs_parsed_mount_data *data,
-                          struct nfs_subversion *nfs_mod)
+                          const struct fs_context *fc)
 {
+       const struct nfs_fs_context *ctx = nfs_fc2context(fc);
        struct rpc_timeout timeparms;
        struct nfs_client_initdata cl_init = {
-               .hostname = data->nfs_server.hostname,
-               .addr = (const struct sockaddr *)&data->nfs_server.address,
-               .addrlen = data->nfs_server.addrlen,
-               .nfs_mod = nfs_mod,
-               .proto = data->nfs_server.protocol,
-               .net = data->net,
+               .hostname = ctx->nfs_server.hostname,
+               .addr = (const struct sockaddr *)&ctx->nfs_server.address,
+               .addrlen = ctx->nfs_server.addrlen,
+               .nfs_mod = ctx->nfs_mod,
+               .proto = ctx->nfs_server.protocol,
+               .net = fc->net_ns,
                .timeparms = &timeparms,
                .cred = server->cred,
-               .nconnect = data->nfs_server.nconnect,
+               .nconnect = ctx->nfs_server.nconnect,
                .init_flags = (1UL << NFS_CS_REUSEPORT),
        };
        struct nfs_client *clp;
        int error;
 
-       nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
-                       data->timeo, data->retrans);
-       if (data->flags & NFS_MOUNT_NORESVPORT)
+       nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol,
+                               ctx->timeo, ctx->retrans);
+       if (ctx->flags & NFS_MOUNT_NORESVPORT)
                set_bit(NFS_CS_NORESVPORT, &cl_init.init_flags);
 
        /* Allocate or find a client reference we can use */
@@ -690,46 +694,46 @@ static int nfs_init_server(struct nfs_server *server,
        server->nfs_client = clp;
 
        /* Initialise the client representation from the mount data */
-       server->flags = data->flags;
-       server->options = data->options;
+       server->flags = ctx->flags;
+       server->options = ctx->options;
        server->caps |= NFS_CAP_HARDLINKS|NFS_CAP_SYMLINKS|NFS_CAP_FILEID|
                NFS_CAP_MODE|NFS_CAP_NLINK|NFS_CAP_OWNER|NFS_CAP_OWNER_GROUP|
                NFS_CAP_ATIME|NFS_CAP_CTIME|NFS_CAP_MTIME;
 
-       if (data->rsize)
-               server->rsize = nfs_block_size(data->rsize, NULL);
-       if (data->wsize)
-               server->wsize = nfs_block_size(data->wsize, NULL);
+       if (ctx->rsize)
+               server->rsize = nfs_block_size(ctx->rsize, NULL);
+       if (ctx->wsize)
+               server->wsize = nfs_block_size(ctx->wsize, NULL);
 
-       server->acregmin = data->acregmin * HZ;
-       server->acregmax = data->acregmax * HZ;
-       server->acdirmin = data->acdirmin * HZ;
-       server->acdirmax = data->acdirmax * HZ;
+       server->acregmin = ctx->acregmin * HZ;
+       server->acregmax = ctx->acregmax * HZ;
+       server->acdirmin = ctx->acdirmin * HZ;
+       server->acdirmax = ctx->acdirmax * HZ;
 
        /* Start lockd here, before we might error out */
        error = nfs_start_lockd(server);
        if (error < 0)
                goto error;
 
-       server->port = data->nfs_server.port;
-       server->auth_info = data->auth_info;
+       server->port = ctx->nfs_server.port;
+       server->auth_info = ctx->auth_info;
 
        error = nfs_init_server_rpcclient(server, &timeparms,
-                                         data->selected_flavor);
+                                         ctx->selected_flavor);
        if (error < 0)
                goto error;
 
        /* Preserve the values of mount_server-related mount options */
-       if (data->mount_server.addrlen) {
-               memcpy(&server->mountd_address, &data->mount_server.address,
-                       data->mount_server.addrlen);
-               server->mountd_addrlen = data->mount_server.addrlen;
+       if (ctx->mount_server.addrlen) {
+               memcpy(&server->mountd_address, &ctx->mount_server.address,
+                       ctx->mount_server.addrlen);
+               server->mountd_addrlen = ctx->mount_server.addrlen;
        }
-       server->mountd_version = data->mount_server.version;
-       server->mountd_port = data->mount_server.port;
-       server->mountd_protocol = data->mount_server.protocol;
+       server->mountd_version = ctx->mount_server.version;
+       server->mountd_port = ctx->mount_server.port;
+       server->mountd_protocol = ctx->mount_server.protocol;
 
-       server->namelen  = data->namlen;
+       server->namelen  = ctx->namlen;
        return 0;
 
 error:
@@ -951,9 +955,9 @@ EXPORT_SYMBOL_GPL(nfs_free_server);
  * Create a version 2 or 3 volume record
  * - keyed on server and FSID
  */
-struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
-                                    struct nfs_subversion *nfs_mod)
+struct nfs_server *nfs_create_server(struct fs_context *fc)
 {
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
        struct nfs_server *server;
        struct nfs_fattr *fattr;
        int error;
@@ -970,18 +974,18 @@ struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
                goto error;
 
        /* Get a client representation */
-       error = nfs_init_server(server, mount_info->parsed, nfs_mod);
+       error = nfs_init_server(server, fc);
        if (error < 0)
                goto error;
 
        /* Probe the root fh to retrieve its FSID */
-       error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr);
+       error = nfs_probe_fsinfo(server, ctx->mntfh, fattr);
        if (error < 0)
                goto error;
        if (server->nfs_client->rpc_ops->version == 3) {
                if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
                        server->namelen = NFS3_MAXNAMLEN;
-               if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS))
+               if (!(ctx->flags & NFS_MOUNT_NORDIRPLUS))
                        server->caps |= NFS_CAP_READDIRPLUS;
        } else {
                if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
@@ -989,8 +993,8 @@ struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
        }
 
        if (!(fattr->valid & NFS_ATTR_FATTR)) {
-               error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh,
-                               fattr, NULL, NULL);
+               error = ctx->nfs_mod->rpc_ops->getattr(server, ctx->mntfh,
+                                                      fattr, NULL, NULL);
                if (error < 0) {
                        dprintk("nfs_create_server: getattr error = %d\n", -error);
                        goto error;
index fe57b2b..4a84107 100644 (file)
 #include "internal.h"
 #include "nfs4trace.h"
 
-static void nfs_free_delegation(struct nfs_delegation *delegation)
+#define NFS_DEFAULT_DELEGATION_WATERMARK (5000U)
+
+static atomic_long_t nfs_active_delegations;
+static unsigned nfs_delegation_watermark = NFS_DEFAULT_DELEGATION_WATERMARK;
+
+static void __nfs_free_delegation(struct nfs_delegation *delegation)
 {
        put_cred(delegation->cred);
        delegation->cred = NULL;
        kfree_rcu(delegation, rcu);
 }
 
+static void nfs_mark_delegation_revoked(struct nfs_delegation *delegation)
+{
+       if (!test_and_set_bit(NFS_DELEGATION_REVOKED, &delegation->flags)) {
+               delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
+               atomic_long_dec(&nfs_active_delegations);
+       }
+}
+
+static void nfs_free_delegation(struct nfs_delegation *delegation)
+{
+       nfs_mark_delegation_revoked(delegation);
+       __nfs_free_delegation(delegation);
+}
+
 /**
  * nfs_mark_delegation_referenced - set delegation's REFERENCED flag
  * @delegation: delegation to process
@@ -343,7 +362,8 @@ 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);
+               if (test_and_clear_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
+                       atomic_long_inc(&nfs_active_delegations);
        }
 }
 
@@ -423,6 +443,8 @@ add_new:
        rcu_assign_pointer(nfsi->delegation, delegation);
        delegation = NULL;
 
+       atomic_long_inc(&nfs_active_delegations);
+
        trace_nfs4_set_delegation(inode, type);
 
        spin_lock(&inode->i_lock);
@@ -432,7 +454,7 @@ add_new:
 out:
        spin_unlock(&clp->cl_lock);
        if (delegation != NULL)
-               nfs_free_delegation(delegation);
+               __nfs_free_delegation(delegation);
        if (freeme != NULL) {
                nfs_do_return_delegation(inode, freeme, 0);
                nfs_free_delegation(freeme);
@@ -479,7 +501,7 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
 
        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) {
+       else if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags)) {
                struct inode *inode;
 
                spin_lock(&delegation->lock);
@@ -488,6 +510,8 @@ static bool nfs_delegation_need_return(struct nfs_delegation *delegation)
                        ret = true;
                spin_unlock(&delegation->lock);
        }
+       if (ret)
+               clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
        if (test_bit(NFS_DELEGATION_RETURNING, &delegation->flags) ||
            test_bit(NFS_DELEGATION_REVOKED, &delegation->flags))
                ret = false;
@@ -607,6 +631,7 @@ void nfs_inode_evict_delegation(struct inode *inode)
 
        delegation = nfs_inode_detach_delegation(inode);
        if (delegation != NULL) {
+               set_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
                set_bit(NFS_DELEGATION_INODE_FREEING, &delegation->flags);
                nfs_do_return_delegation(inode, delegation, 1);
                nfs_free_delegation(delegation);
@@ -637,6 +662,40 @@ int nfs4_inode_return_delegation(struct inode *inode)
 }
 
 /**
+ * nfs_inode_return_delegation_on_close - asynchronously return a delegation
+ * @inode: inode to process
+ *
+ * This routine is called on file close in order to determine if the
+ * inode delegation needs to be returned immediately.
+ */
+void nfs4_inode_return_delegation_on_close(struct inode *inode)
+{
+       struct nfs_delegation *delegation;
+       struct nfs_delegation *ret = NULL;
+
+       if (!inode)
+               return;
+       rcu_read_lock();
+       delegation = nfs4_get_valid_delegation(inode);
+       if (!delegation)
+               goto out;
+       if (test_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags) ||
+           atomic_long_read(&nfs_active_delegations) >= nfs_delegation_watermark) {
+               spin_lock(&delegation->lock);
+               if (delegation->inode &&
+                   list_empty(&NFS_I(inode)->open_files) &&
+                   !test_and_set_bit(NFS_DELEGATION_RETURNING, &delegation->flags)) {
+                       clear_bit(NFS_DELEGATION_RETURN_IF_CLOSED, &delegation->flags);
+                       ret = delegation;
+               }
+               spin_unlock(&delegation->lock);
+       }
+out:
+       rcu_read_unlock();
+       nfs_end_delegation_return(inode, ret, 0);
+}
+
+/**
  * nfs4_inode_make_writeable
  * @inode: pointer to inode
  *
@@ -760,13 +819,6 @@ static void nfs_client_mark_return_unused_delegation_types(struct nfs_client *cl
        rcu_read_unlock();
 }
 
-static void nfs_mark_delegation_revoked(struct nfs_server *server,
-               struct nfs_delegation *delegation)
-{
-       set_bit(NFS_DELEGATION_REVOKED, &delegation->flags);
-       delegation->stateid.type = NFS4_INVALID_STATEID_TYPE;
-}
-
 static void nfs_revoke_delegation(struct inode *inode,
                const nfs4_stateid *stateid)
 {
@@ -794,7 +846,7 @@ static void nfs_revoke_delegation(struct inode *inode,
                }
                spin_unlock(&delegation->lock);
        }
-       nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
+       nfs_mark_delegation_revoked(delegation);
        ret = true;
 out:
        rcu_read_unlock();
@@ -833,7 +885,7 @@ void nfs_delegation_mark_returned(struct inode *inode,
                        delegation->stateid.seqid = stateid->seqid;
        }
 
-       nfs_mark_delegation_revoked(NFS_SERVER(inode), delegation);
+       nfs_mark_delegation_revoked(delegation);
 
 out_clear_returning:
        clear_bit(NFS_DELEGATION_RETURNING, &delegation->flags);
@@ -1317,3 +1369,5 @@ out:
        rcu_read_unlock();
        return ret;
 }
+
+module_param_named(delegation_watermark, nfs_delegation_watermark, uint, 0644);
index 15d3484..31b8460 100644 (file)
@@ -42,6 +42,7 @@ int nfs_inode_set_delegation(struct inode *inode, const struct cred *cred,
 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);
+void nfs4_inode_return_delegation_on_close(struct inode *inode);
 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
 void nfs_inode_evict_delegation(struct inode *inode);
 
index e180033..1320288 100644 (file)
@@ -58,7 +58,7 @@ static void nfs_readdir_clear_array(struct page*);
 const struct file_operations nfs_dir_operations = {
        .llseek         = nfs_llseek_dir,
        .read           = generic_read_dir,
-       .iterate        = nfs_readdir,
+       .iterate_shared = nfs_readdir,
        .open           = nfs_opendir,
        .release        = nfs_closedir,
        .fsync          = nfs_fsync_dir,
@@ -162,6 +162,17 @@ typedef struct {
        bool eof;
 } nfs_readdir_descriptor_t;
 
+static
+void nfs_readdir_init_array(struct page *page)
+{
+       struct nfs_cache_array *array;
+
+       array = kmap_atomic(page);
+       memset(array, 0, sizeof(struct nfs_cache_array));
+       array->eof_index = -1;
+       kunmap_atomic(array);
+}
+
 /*
  * we are freeing strings created by nfs_add_to_readdir_array()
  */
@@ -174,6 +185,7 @@ void nfs_readdir_clear_array(struct page *page)
        array = kmap_atomic(page);
        for (i = 0; i < array->size; i++)
                kfree(array->array[i].string.name);
+       array->size = 0;
        kunmap_atomic(array);
 }
 
@@ -186,7 +198,7 @@ static
 int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int len)
 {
        string->len = len;
-       string->name = kmemdup(name, len, GFP_KERNEL);
+       string->name = kmemdup_nul(name, len, GFP_KERNEL);
        if (string->name == NULL)
                return -ENOMEM;
        /*
@@ -437,7 +449,8 @@ void nfs_force_use_readdirplus(struct inode *dir)
        if (nfs_server_capable(dir, NFS_CAP_READDIRPLUS) &&
            !list_empty(&nfsi->open_files)) {
                set_bit(NFS_INO_ADVISE_RDPLUS, &nfsi->flags);
-               invalidate_mapping_pages(dir->i_mapping, 0, -1);
+               invalidate_mapping_pages(dir->i_mapping,
+                       nfsi->page_index + 1, -1);
        }
 }
 
@@ -610,6 +623,8 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        int status = -ENOMEM;
        unsigned int array_size = ARRAY_SIZE(pages);
 
+       nfs_readdir_init_array(page);
+
        entry.prev_cookie = 0;
        entry.cookie = desc->last_cookie;
        entry.eof = 0;
@@ -626,8 +641,6 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
        }
 
        array = kmap(page);
-       memset(array, 0, sizeof(struct nfs_cache_array));
-       array->eof_index = -1;
 
        status = nfs_readdir_alloc_pages(pages, array_size);
        if (status < 0)
@@ -682,6 +695,7 @@ int nfs_readdir_filler(void *data, struct page* page)
        unlock_page(page);
        return 0;
  error:
+       nfs_readdir_clear_array(page);
        unlock_page(page);
        return ret;
 }
@@ -689,8 +703,6 @@ int nfs_readdir_filler(void *data, struct page* page)
 static
 void cache_page_release(nfs_readdir_descriptor_t *desc)
 {
-       if (!desc->page->mapping)
-               nfs_readdir_clear_array(desc->page);
        put_page(desc->page);
        desc->page = NULL;
 }
@@ -704,19 +716,32 @@ struct page *get_cache_page(nfs_readdir_descriptor_t *desc)
 
 /*
  * Returns 0 if desc->dir_cookie was found on page desc->page_index
+ * and locks the page to prevent removal from the page cache.
  */
 static
-int find_cache_page(nfs_readdir_descriptor_t *desc)
+int find_and_lock_cache_page(nfs_readdir_descriptor_t *desc)
 {
+       struct inode *inode = file_inode(desc->file);
+       struct nfs_inode *nfsi = NFS_I(inode);
        int res;
 
        desc->page = get_cache_page(desc);
        if (IS_ERR(desc->page))
                return PTR_ERR(desc->page);
-
-       res = nfs_readdir_search_array(desc);
+       res = lock_page_killable(desc->page);
        if (res != 0)
-               cache_page_release(desc);
+               goto error;
+       res = -EAGAIN;
+       if (desc->page->mapping != NULL) {
+               res = nfs_readdir_search_array(desc);
+               if (res == 0) {
+                       nfsi->page_index = desc->page_index;
+                       return 0;
+               }
+       }
+       unlock_page(desc->page);
+error:
+       cache_page_release(desc);
        return res;
 }
 
@@ -731,7 +756,7 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
                desc->last_cookie = 0;
        }
        do {
-               res = find_cache_page(desc);
+               res = find_and_lock_cache_page(desc);
        } while (res == -EAGAIN);
        return res;
 }
@@ -770,7 +795,6 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc)
                desc->eof = true;
 
        kunmap(desc->page);
-       cache_page_release(desc);
        dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n",
                        (unsigned long long)*desc->dir_cookie, res);
        return res;
@@ -816,13 +840,13 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc)
 
        status = nfs_do_filldir(desc);
 
+ out_release:
+       nfs_readdir_clear_array(desc->page);
+       cache_page_release(desc);
  out:
        dfprintk(DIRCACHE, "NFS: %s: returns %d\n",
                        __func__, status);
        return status;
- out_release:
-       cache_page_release(desc);
-       goto out;
 }
 
 /* The file offset position represents the dirent entry number.  A
@@ -887,6 +911,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
                        break;
 
                res = nfs_do_filldir(desc);
+               unlock_page(desc->page);
+               cache_page_release(desc);
                if (res < 0)
                        break;
        } while (!desc->eof);
@@ -1142,10 +1168,17 @@ nfs_lookup_revalidate_dentry(struct inode *dir, struct dentry *dentry,
        if (fhandle == NULL || fattr == NULL || IS_ERR(label))
                goto out;
 
-       ret = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
+       ret = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label);
        if (ret < 0) {
-               if (ret == -ESTALE || ret == -ENOENT)
+               switch (ret) {
+               case -ESTALE:
+               case -ENOENT:
                        ret = 0;
+                       break;
+               case -ETIMEDOUT:
+                       if (NFS_SERVER(inode)->flags & NFS_MOUNT_SOFTREVAL)
+                               ret = 1;
+               }
                goto out;
        }
        ret = 0;
@@ -1408,7 +1441,7 @@ struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned in
                goto out;
 
        trace_nfs_lookup_enter(dir, dentry, flags);
-       error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, label);
+       error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, label);
        if (error == -ENOENT)
                goto no_entry;
        if (error < 0) {
@@ -1683,7 +1716,7 @@ nfs_add_or_obtain(struct dentry *dentry, struct nfs_fh *fhandle,
        d_drop(dentry);
 
        if (fhandle->size == 0) {
-               error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, fhandle, fattr, NULL);
+               error = NFS_PROTO(dir)->lookup(dir, dentry, fhandle, fattr, NULL);
                if (error)
                        goto out_error;
        }
@@ -2312,11 +2345,11 @@ static int nfs_access_get_cached(struct inode *inode, const struct cred *cred, s
                /* Found an entry, is our attribute cache valid? */
                if (!nfs_check_cache_invalid(inode, NFS_INO_INVALID_ACCESS))
                        break;
+               if (!retry)
+                       break;
                err = -ECHILD;
                if (!may_block)
                        goto out;
-               if (!retry)
-                       goto out_zap;
                spin_unlock(&inode->i_lock);
                err = __nfs_revalidate_inode(NFS_SERVER(inode), inode);
                if (err)
@@ -2353,7 +2386,7 @@ static int nfs_access_get_cached_rcu(struct inode *inode, const struct cred *cre
        lh = rcu_dereference(nfsi->access_cache_entry_lru.prev);
        cache = list_entry(lh, struct nfs_access_entry, lru);
        if (lh == &nfsi->access_cache_entry_lru ||
-           cred != cache->cred)
+           cred_fscmp(cred, cache->cred) != 0)
                cache = NULL;
        if (cache == NULL)
                goto out;
@@ -2476,7 +2509,7 @@ static int nfs_do_access(struct inode *inode, const struct cred *cred, int mask)
 {
        struct nfs_access_entry cache;
        bool may_block = (mask & MAY_NOT_BLOCK) == 0;
-       int cache_mask;
+       int cache_mask = -1;
        int status;
 
        trace_nfs_access_enter(inode);
@@ -2515,7 +2548,7 @@ out_cached:
        if ((mask & ~cache_mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) != 0)
                status = -EACCES;
 out:
-       trace_nfs_access_exit(inode, status);
+       trace_nfs_access_exit(inode, mask, cache_mask, status);
        return status;
 }
 
index 040a50f..b768a0b 100644 (file)
@@ -245,10 +245,10 @@ static int nfs_direct_cmp_commit_data_verf(struct nfs_direct_req *dreq,
                                         data->ds_commit_index);
 
        /* verifier not set so always fail */
-       if (verfp->committed < 0)
+       if (verfp->committed < 0 || data->res.verf->committed <= NFS_UNSTABLE)
                return 1;
 
-       return nfs_direct_cmp_verf(verfp, &data->verf);
+       return nfs_direct_cmp_verf(verfp, data->res.verf);
 }
 
 /**
@@ -824,7 +824,8 @@ static void nfs_direct_write_reschedule_io(struct nfs_pgio_header *hdr)
                dreq->flags = NFS_ODIRECT_RESCHED_WRITES;
                /* fake unstable write to let common nfs resend pages */
                hdr->verf.committed = NFS_UNSTABLE;
-               hdr->good_bytes = hdr->args.count;
+               hdr->good_bytes = hdr->args.offset + hdr->args.count -
+                       hdr->io_start;
        }
        spin_unlock(&dreq->lock);
 }
index aec769a..89bd558 100644 (file)
@@ -93,7 +93,7 @@ static void nfs_dns_ent_init(struct cache_head *cnew,
        key = container_of(ckey, struct nfs_dns_ent, h);
 
        kfree(new->hostname);
-       new->hostname = kstrndup(key->hostname, key->namelen, GFP_KERNEL);
+       new->hostname = kmemdup_nul(key->hostname, key->namelen, GFP_KERNEL);
        if (new->hostname) {
                new->namelen = key->namelen;
                nfs_dns_ent_update(cnew, ckey);
index 8eb731d..f96367a 100644 (file)
@@ -204,44 +204,39 @@ EXPORT_SYMBOL_GPL(nfs_file_mmap);
 static int
 nfs_file_fsync_commit(struct file *file, int datasync)
 {
-       struct nfs_open_context *ctx = nfs_file_open_context(file);
        struct inode *inode = file_inode(file);
-       int do_resend, status;
-       int ret = 0;
+       int ret;
 
        dprintk("NFS: fsync file(%pD2) datasync %d\n", file, datasync);
 
        nfs_inc_stats(inode, NFSIOS_VFSFSYNC);
-       do_resend = test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
-       status = nfs_commit_inode(inode, FLUSH_SYNC);
-       if (status == 0)
-               status = file_check_and_advance_wb_err(file);
-       if (status < 0) {
-               ret = status;
-               goto out;
-       }
-       do_resend |= test_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags);
-       if (do_resend)
-               ret = -EAGAIN;
-out:
-       return ret;
+       ret = nfs_commit_inode(inode, FLUSH_SYNC);
+       if (ret < 0)
+               return ret;
+       return file_check_and_advance_wb_err(file);
 }
 
 int
 nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
-       int ret;
+       struct nfs_open_context *ctx = nfs_file_open_context(file);
        struct inode *inode = file_inode(file);
+       int ret;
 
        trace_nfs_fsync_enter(inode);
 
-       do {
+       for (;;) {
                ret = file_write_and_wait_range(file, start, end);
                if (ret != 0)
                        break;
                ret = nfs_file_fsync_commit(file, datasync);
-               if (!ret)
-                       ret = pnfs_sync_inode(inode, !!datasync);
+               if (ret != 0)
+                       break;
+               ret = pnfs_sync_inode(inode, !!datasync);
+               if (ret != 0)
+                       break;
+               if (!test_and_clear_bit(NFS_CONTEXT_RESEND_WRITES, &ctx->flags))
+                       break;
                /*
                 * If nfs_file_fsync_commit detected a server reboot, then
                 * resend all dirty pages that might have been covered by
@@ -249,7 +244,7 @@ nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
                 */
                start = 0;
                end = LLONG_MAX;
-       } while (ret == -EAGAIN);
+       }
 
        trace_nfs_fsync_exit(inode, ret);
        return ret;
@@ -489,7 +484,19 @@ static int nfs_launder_page(struct page *page)
 static int nfs_swap_activate(struct swap_info_struct *sis, struct file *file,
                                                sector_t *span)
 {
+       unsigned long blocks;
+       long long isize;
        struct rpc_clnt *clnt = NFS_CLIENT(file->f_mapping->host);
+       struct inode *inode = file->f_mapping->host;
+
+       spin_lock(&inode->i_lock);
+       blocks = inode->i_blocks;
+       isize = inode->i_size;
+       spin_unlock(&inode->i_lock);
+       if (blocks*512 < isize) {
+               pr_warn("swap activate: swapfile has holes\n");
+               return -EINVAL;
+       }
 
        *span = sis->pages;
 
index 5657b7f..bb9148b 100644 (file)
@@ -1266,9 +1266,10 @@ static int ff_layout_async_handle_error(struct rpc_task *task,
 
 static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
                                        int idx, u64 offset, u64 length,
-                                       u32 status, int opnum, int error)
+                                       u32 *op_status, int opnum, int error)
 {
        struct nfs4_ff_layout_mirror *mirror;
+       u32 status = *op_status;
        int err;
 
        if (status == 0) {
@@ -1286,10 +1287,10 @@ static void ff_layout_io_track_ds_error(struct pnfs_layout_segment *lseg,
                case -ENOBUFS:
                case -EPIPE:
                case -EPERM:
-                       status = NFS4ERR_NXIO;
+                       *op_status = status = NFS4ERR_NXIO;
                        break;
                case -EACCES:
-                       status = NFS4ERR_ACCESS;
+                       *op_status = status = NFS4ERR_ACCESS;
                        break;
                default:
                        return;
@@ -1321,16 +1322,19 @@ static int ff_layout_read_done_cb(struct rpc_task *task,
        int new_idx = hdr->pgio_mirror_idx;
        int err;
 
-       trace_nfs4_pnfs_read(hdr, task->tk_status);
-       if (task->tk_status < 0)
+       if (task->tk_status < 0) {
                ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx,
                                            hdr->args.offset, hdr->args.count,
-                                           hdr->res.op_status, OP_READ,
+                                           &hdr->res.op_status, OP_READ,
                                            task->tk_status);
+               trace_ff_layout_read_error(hdr);
+       }
+
        err = ff_layout_async_handle_error(task, hdr->args.context->state,
                                           hdr->ds_clp, hdr->lseg,
                                           hdr->pgio_mirror_idx);
 
+       trace_nfs4_pnfs_read(hdr, err);
        clear_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags);
        clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags);
        switch (err) {
@@ -1494,16 +1498,19 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
        loff_t end_offs = 0;
        int err;
 
-       trace_nfs4_pnfs_write(hdr, task->tk_status);
-       if (task->tk_status < 0)
+       if (task->tk_status < 0) {
                ff_layout_io_track_ds_error(hdr->lseg, hdr->pgio_mirror_idx,
                                            hdr->args.offset, hdr->args.count,
-                                           hdr->res.op_status, OP_WRITE,
+                                           &hdr->res.op_status, OP_WRITE,
                                            task->tk_status);
+               trace_ff_layout_write_error(hdr);
+       }
+
        err = ff_layout_async_handle_error(task, hdr->args.context->state,
                                           hdr->ds_clp, hdr->lseg,
                                           hdr->pgio_mirror_idx);
 
+       trace_nfs4_pnfs_write(hdr, err);
        clear_bit(NFS_IOHDR_RESEND_PNFS, &hdr->flags);
        clear_bit(NFS_IOHDR_RESEND_MDS, &hdr->flags);
        switch (err) {
@@ -1537,15 +1544,18 @@ static int ff_layout_commit_done_cb(struct rpc_task *task,
 {
        int err;
 
-       trace_nfs4_pnfs_commit_ds(data, task->tk_status);
-       if (task->tk_status < 0)
+       if (task->tk_status < 0) {
                ff_layout_io_track_ds_error(data->lseg, data->ds_commit_index,
                                            data->args.offset, data->args.count,
-                                           data->res.op_status, OP_COMMIT,
+                                           &data->res.op_status, OP_COMMIT,
                                            task->tk_status);
+               trace_ff_layout_commit_error(data);
+       }
+
        err = ff_layout_async_handle_error(task, NULL, data->ds_clp,
                                           data->lseg, data->ds_commit_index);
 
+       trace_nfs4_pnfs_commit_ds(data, err);
        switch (err) {
        case -NFS4ERR_RESET_TO_PNFS:
                pnfs_generic_prepare_to_resend_writes(data);
diff --git a/fs/nfs/fs_context.c b/fs/nfs/fs_context.c
new file mode 100644 (file)
index 0000000..e1b9384
--- /dev/null
@@ -0,0 +1,1440 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * linux/fs/nfs/fs_context.c
+ *
+ * Copyright (C) 1992 Rick Sladkey
+ * Conversion to new mount api Copyright (C) David Howells
+ *
+ * NFS mount handling.
+ *
+ * Split from fs/nfs/super.c by David Howells <dhowells@redhat.com>
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
+#include <linux/nfs_fs.h>
+#include <linux/nfs_mount.h>
+#include <linux/nfs4_mount.h>
+#include "nfs.h"
+#include "internal.h"
+
+#define NFSDBG_FACILITY                NFSDBG_MOUNT
+
+#if IS_ENABLED(CONFIG_NFS_V3)
+#define NFS_DEFAULT_VERSION 3
+#else
+#define NFS_DEFAULT_VERSION 2
+#endif
+
+#define NFS_MAX_CONNECTIONS 16
+
+enum nfs_param {
+       Opt_ac,
+       Opt_acdirmax,
+       Opt_acdirmin,
+       Opt_acl,
+       Opt_acregmax,
+       Opt_acregmin,
+       Opt_actimeo,
+       Opt_addr,
+       Opt_bg,
+       Opt_bsize,
+       Opt_clientaddr,
+       Opt_cto,
+       Opt_fg,
+       Opt_fscache,
+       Opt_fscache_flag,
+       Opt_hard,
+       Opt_intr,
+       Opt_local_lock,
+       Opt_lock,
+       Opt_lookupcache,
+       Opt_migration,
+       Opt_minorversion,
+       Opt_mountaddr,
+       Opt_mounthost,
+       Opt_mountport,
+       Opt_mountproto,
+       Opt_mountvers,
+       Opt_namelen,
+       Opt_nconnect,
+       Opt_port,
+       Opt_posix,
+       Opt_proto,
+       Opt_rdirplus,
+       Opt_rdma,
+       Opt_resvport,
+       Opt_retrans,
+       Opt_retry,
+       Opt_rsize,
+       Opt_sec,
+       Opt_sharecache,
+       Opt_sloppy,
+       Opt_soft,
+       Opt_softerr,
+       Opt_softreval,
+       Opt_source,
+       Opt_tcp,
+       Opt_timeo,
+       Opt_udp,
+       Opt_v,
+       Opt_vers,
+       Opt_wsize,
+};
+
+enum {
+       Opt_local_lock_all,
+       Opt_local_lock_flock,
+       Opt_local_lock_none,
+       Opt_local_lock_posix,
+};
+
+static const struct constant_table nfs_param_enums_local_lock[] = {
+       { "all",                Opt_local_lock_all },
+       { "flock",      Opt_local_lock_flock },
+       { "none",               Opt_local_lock_none },
+       {}
+};
+
+enum {
+       Opt_lookupcache_all,
+       Opt_lookupcache_none,
+       Opt_lookupcache_positive,
+};
+
+static const struct constant_table nfs_param_enums_lookupcache[] = {
+       { "all",                Opt_lookupcache_all },
+       { "none",               Opt_lookupcache_none },
+       { "pos",                Opt_lookupcache_positive },
+       { "positive",           Opt_lookupcache_positive },
+       {}
+};
+
+static const struct fs_parameter_spec nfs_fs_parameters[] = {
+       fsparam_flag_no("ac",           Opt_ac),
+       fsparam_u32   ("acdirmax",      Opt_acdirmax),
+       fsparam_u32   ("acdirmin",      Opt_acdirmin),
+       fsparam_flag_no("acl",          Opt_acl),
+       fsparam_u32   ("acregmax",      Opt_acregmax),
+       fsparam_u32   ("acregmin",      Opt_acregmin),
+       fsparam_u32   ("actimeo",       Opt_actimeo),
+       fsparam_string("addr",          Opt_addr),
+       fsparam_flag  ("bg",            Opt_bg),
+       fsparam_u32   ("bsize",         Opt_bsize),
+       fsparam_string("clientaddr",    Opt_clientaddr),
+       fsparam_flag_no("cto",          Opt_cto),
+       fsparam_flag  ("fg",            Opt_fg),
+       fsparam_flag_no("fsc",          Opt_fscache_flag),
+       fsparam_string("fsc",           Opt_fscache),
+       fsparam_flag  ("hard",          Opt_hard),
+       __fsparam(NULL, "intr",         Opt_intr,
+                 fs_param_neg_with_no|fs_param_deprecated, NULL),
+       fsparam_enum  ("local_lock",    Opt_local_lock, nfs_param_enums_local_lock),
+       fsparam_flag_no("lock",         Opt_lock),
+       fsparam_enum  ("lookupcache",   Opt_lookupcache, nfs_param_enums_lookupcache),
+       fsparam_flag_no("migration",    Opt_migration),
+       fsparam_u32   ("minorversion",  Opt_minorversion),
+       fsparam_string("mountaddr",     Opt_mountaddr),
+       fsparam_string("mounthost",     Opt_mounthost),
+       fsparam_u32   ("mountport",     Opt_mountport),
+       fsparam_string("mountproto",    Opt_mountproto),
+       fsparam_u32   ("mountvers",     Opt_mountvers),
+       fsparam_u32   ("namlen",        Opt_namelen),
+       fsparam_u32   ("nconnect",      Opt_nconnect),
+       fsparam_string("nfsvers",       Opt_vers),
+       fsparam_u32   ("port",          Opt_port),
+       fsparam_flag_no("posix",        Opt_posix),
+       fsparam_string("proto",         Opt_proto),
+       fsparam_flag_no("rdirplus",     Opt_rdirplus),
+       fsparam_flag  ("rdma",          Opt_rdma),
+       fsparam_flag_no("resvport",     Opt_resvport),
+       fsparam_u32   ("retrans",       Opt_retrans),
+       fsparam_string("retry",         Opt_retry),
+       fsparam_u32   ("rsize",         Opt_rsize),
+       fsparam_string("sec",           Opt_sec),
+       fsparam_flag_no("sharecache",   Opt_sharecache),
+       fsparam_flag  ("sloppy",        Opt_sloppy),
+       fsparam_flag  ("soft",          Opt_soft),
+       fsparam_flag  ("softerr",       Opt_softerr),
+       fsparam_flag  ("softreval",     Opt_softreval),
+       fsparam_string("source",        Opt_source),
+       fsparam_flag  ("tcp",           Opt_tcp),
+       fsparam_u32   ("timeo",         Opt_timeo),
+       fsparam_flag  ("udp",           Opt_udp),
+       fsparam_flag  ("v2",            Opt_v),
+       fsparam_flag  ("v3",            Opt_v),
+       fsparam_flag  ("v4",            Opt_v),
+       fsparam_flag  ("v4.0",          Opt_v),
+       fsparam_flag  ("v4.1",          Opt_v),
+       fsparam_flag  ("v4.2",          Opt_v),
+       fsparam_string("vers",          Opt_vers),
+       fsparam_u32   ("wsize",         Opt_wsize),
+       {}
+};
+
+enum {
+       Opt_vers_2,
+       Opt_vers_3,
+       Opt_vers_4,
+       Opt_vers_4_0,
+       Opt_vers_4_1,
+       Opt_vers_4_2,
+};
+
+static const struct constant_table nfs_vers_tokens[] = {
+       { "2",          Opt_vers_2 },
+       { "3",          Opt_vers_3 },
+       { "4",          Opt_vers_4 },
+       { "4.0",        Opt_vers_4_0 },
+       { "4.1",        Opt_vers_4_1 },
+       { "4.2",        Opt_vers_4_2 },
+};
+
+enum {
+       Opt_xprt_rdma,
+       Opt_xprt_rdma6,
+       Opt_xprt_tcp,
+       Opt_xprt_tcp6,
+       Opt_xprt_udp,
+       Opt_xprt_udp6,
+       nr__Opt_xprt
+};
+
+static const struct constant_table nfs_xprt_protocol_tokens[nr__Opt_xprt] = {
+       { "rdma",       Opt_xprt_rdma },
+       { "rdma6",      Opt_xprt_rdma6 },
+       { "tcp",        Opt_xprt_tcp },
+       { "tcp6",       Opt_xprt_tcp6 },
+       { "udp",        Opt_xprt_udp },
+       { "udp6",       Opt_xprt_udp6 },
+};
+
+enum {
+       Opt_sec_krb5,
+       Opt_sec_krb5i,
+       Opt_sec_krb5p,
+       Opt_sec_lkey,
+       Opt_sec_lkeyi,
+       Opt_sec_lkeyp,
+       Opt_sec_none,
+       Opt_sec_spkm,
+       Opt_sec_spkmi,
+       Opt_sec_spkmp,
+       Opt_sec_sys,
+       nr__Opt_sec
+};
+
+static const struct constant_table nfs_secflavor_tokens[] = {
+       { "krb5",       Opt_sec_krb5 },
+       { "krb5i",      Opt_sec_krb5i },
+       { "krb5p",      Opt_sec_krb5p },
+       { "lkey",       Opt_sec_lkey },
+       { "lkeyi",      Opt_sec_lkeyi },
+       { "lkeyp",      Opt_sec_lkeyp },
+       { "none",       Opt_sec_none },
+       { "null",       Opt_sec_none },
+       { "spkm3",      Opt_sec_spkm },
+       { "spkm3i",     Opt_sec_spkmi },
+       { "spkm3p",     Opt_sec_spkmp },
+       { "sys",        Opt_sec_sys },
+};
+
+/*
+ * Sanity-check a server address provided by the mount command.
+ *
+ * Address family must be initialized, and address must not be
+ * the ANY address for that family.
+ */
+static int nfs_verify_server_address(struct sockaddr *addr)
+{
+       switch (addr->sa_family) {
+       case AF_INET: {
+               struct sockaddr_in *sa = (struct sockaddr_in *)addr;
+               return sa->sin_addr.s_addr != htonl(INADDR_ANY);
+       }
+       case AF_INET6: {
+               struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr;
+               return !ipv6_addr_any(sa);
+       }
+       }
+
+       dfprintk(MOUNT, "NFS: Invalid IP address specified\n");
+       return 0;
+}
+
+/*
+ * Sanity check the NFS transport protocol.
+ *
+ */
+static void nfs_validate_transport_protocol(struct nfs_fs_context *ctx)
+{
+       switch (ctx->nfs_server.protocol) {
+       case XPRT_TRANSPORT_UDP:
+       case XPRT_TRANSPORT_TCP:
+       case XPRT_TRANSPORT_RDMA:
+               break;
+       default:
+               ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+       }
+}
+
+/*
+ * For text based NFSv2/v3 mounts, the mount protocol transport default
+ * settings should depend upon the specified NFS transport.
+ */
+static void nfs_set_mount_transport_protocol(struct nfs_fs_context *ctx)
+{
+       nfs_validate_transport_protocol(ctx);
+
+       if (ctx->mount_server.protocol == XPRT_TRANSPORT_UDP ||
+           ctx->mount_server.protocol == XPRT_TRANSPORT_TCP)
+                       return;
+       switch (ctx->nfs_server.protocol) {
+       case XPRT_TRANSPORT_UDP:
+               ctx->mount_server.protocol = XPRT_TRANSPORT_UDP;
+               break;
+       case XPRT_TRANSPORT_TCP:
+       case XPRT_TRANSPORT_RDMA:
+               ctx->mount_server.protocol = XPRT_TRANSPORT_TCP;
+       }
+}
+
+/*
+ * Add 'flavor' to 'auth_info' if not already present.
+ * Returns true if 'flavor' ends up in the list, false otherwise
+ */
+static int nfs_auth_info_add(struct fs_context *fc,
+                            struct nfs_auth_info *auth_info,
+                            rpc_authflavor_t flavor)
+{
+       unsigned int i;
+       unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors);
+
+       /* make sure this flavor isn't already in the list */
+       for (i = 0; i < auth_info->flavor_len; i++) {
+               if (flavor == auth_info->flavors[i])
+                       return 0;
+       }
+
+       if (auth_info->flavor_len + 1 >= max_flavor_len)
+               return nfs_invalf(fc, "NFS: too many sec= flavors");
+
+       auth_info->flavors[auth_info->flavor_len++] = flavor;
+       return 0;
+}
+
+/*
+ * Parse the value of the 'sec=' option.
+ */
+static int nfs_parse_security_flavors(struct fs_context *fc,
+                                     struct fs_parameter *param)
+{
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       rpc_authflavor_t pseudoflavor;
+       char *string = param->string, *p;
+       int ret;
+
+       dfprintk(MOUNT, "NFS: parsing %s=%s option\n", param->key, param->string);
+
+       while ((p = strsep(&string, ":")) != NULL) {
+               if (!*p)
+                       continue;
+               switch (lookup_constant(nfs_secflavor_tokens, p, -1)) {
+               case Opt_sec_none:
+                       pseudoflavor = RPC_AUTH_NULL;
+                       break;
+               case Opt_sec_sys:
+                       pseudoflavor = RPC_AUTH_UNIX;
+                       break;
+               case Opt_sec_krb5:
+                       pseudoflavor = RPC_AUTH_GSS_KRB5;
+                       break;
+               case Opt_sec_krb5i:
+                       pseudoflavor = RPC_AUTH_GSS_KRB5I;
+                       break;
+               case Opt_sec_krb5p:
+                       pseudoflavor = RPC_AUTH_GSS_KRB5P;
+                       break;
+               case Opt_sec_lkey:
+                       pseudoflavor = RPC_AUTH_GSS_LKEY;
+                       break;
+               case Opt_sec_lkeyi:
+                       pseudoflavor = RPC_AUTH_GSS_LKEYI;
+                       break;
+               case Opt_sec_lkeyp:
+                       pseudoflavor = RPC_AUTH_GSS_LKEYP;
+                       break;
+               case Opt_sec_spkm:
+                       pseudoflavor = RPC_AUTH_GSS_SPKM;
+                       break;
+               case Opt_sec_spkmi:
+                       pseudoflavor = RPC_AUTH_GSS_SPKMI;
+                       break;
+               case Opt_sec_spkmp:
+                       pseudoflavor = RPC_AUTH_GSS_SPKMP;
+                       break;
+               default:
+                       return nfs_invalf(fc, "NFS: sec=%s option not recognized", p);
+               }
+
+               ret = nfs_auth_info_add(fc, &ctx->auth_info, pseudoflavor);
+               if (ret < 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static int nfs_parse_version_string(struct fs_context *fc,
+                                   const char *string)
+{
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+
+       ctx->flags &= ~NFS_MOUNT_VER3;
+       switch (lookup_constant(nfs_vers_tokens, string, -1)) {
+       case Opt_vers_2:
+               ctx->version = 2;
+               break;
+       case Opt_vers_3:
+               ctx->flags |= NFS_MOUNT_VER3;
+               ctx->version = 3;
+               break;
+       case Opt_vers_4:
+               /* Backward compatibility option. In future,
+                * the mount program should always supply
+                * a NFSv4 minor version number.
+                */
+               ctx->version = 4;
+               break;
+       case Opt_vers_4_0:
+               ctx->version = 4;
+               ctx->minorversion = 0;
+               break;
+       case Opt_vers_4_1:
+               ctx->version = 4;
+               ctx->minorversion = 1;
+               break;
+       case Opt_vers_4_2:
+               ctx->version = 4;
+               ctx->minorversion = 2;
+               break;
+       default:
+               return nfs_invalf(fc, "NFS: Unsupported NFS version");
+       }
+       return 0;
+}
+
+/*
+ * Parse a single mount parameter.
+ */
+static int nfs_fs_context_parse_param(struct fs_context *fc,
+                                     struct fs_parameter *param)
+{
+       struct fs_parse_result result;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       unsigned short protofamily, mountfamily;
+       unsigned int len;
+       int ret, opt;
+
+       dfprintk(MOUNT, "NFS:   parsing nfs mount option '%s'\n", param->key);
+
+       opt = fs_parse(fc, nfs_fs_parameters, param, &result);
+       if (opt < 0)
+               return ctx->sloppy ? 1 : opt;
+
+       switch (opt) {
+       case Opt_source:
+               if (fc->source)
+                       return nfs_invalf(fc, "NFS: Multiple sources not supported");
+               fc->source = param->string;
+               param->string = NULL;
+               break;
+
+               /*
+                * boolean options:  foo/nofoo
+                */
+       case Opt_soft:
+               ctx->flags |= NFS_MOUNT_SOFT;
+               ctx->flags &= ~NFS_MOUNT_SOFTERR;
+               break;
+       case Opt_softerr:
+               ctx->flags |= NFS_MOUNT_SOFTERR | NFS_MOUNT_SOFTREVAL;
+               ctx->flags &= ~NFS_MOUNT_SOFT;
+               break;
+       case Opt_hard:
+               ctx->flags &= ~(NFS_MOUNT_SOFT |
+                               NFS_MOUNT_SOFTERR |
+                               NFS_MOUNT_SOFTREVAL);
+               break;
+       case Opt_softreval:
+               if (result.negated)
+                       ctx->flags &= ~NFS_MOUNT_SOFTREVAL;
+               else
+                       ctx->flags &= NFS_MOUNT_SOFTREVAL;
+               break;
+       case Opt_posix:
+               if (result.negated)
+                       ctx->flags &= ~NFS_MOUNT_POSIX;
+               else
+                       ctx->flags |= NFS_MOUNT_POSIX;
+               break;
+       case Opt_cto:
+               if (result.negated)
+                       ctx->flags |= NFS_MOUNT_NOCTO;
+               else
+                       ctx->flags &= ~NFS_MOUNT_NOCTO;
+               break;
+       case Opt_ac:
+               if (result.negated)
+                       ctx->flags |= NFS_MOUNT_NOAC;
+               else
+                       ctx->flags &= ~NFS_MOUNT_NOAC;
+               break;
+       case Opt_lock:
+               if (result.negated) {
+                       ctx->flags |= NFS_MOUNT_NONLM;
+                       ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
+               } else {
+                       ctx->flags &= ~NFS_MOUNT_NONLM;
+                       ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK | NFS_MOUNT_LOCAL_FCNTL);
+               }
+               break;
+       case Opt_udp:
+               ctx->flags &= ~NFS_MOUNT_TCP;
+               ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
+               break;
+       case Opt_tcp:
+               ctx->flags |= NFS_MOUNT_TCP;
+               ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+               break;
+       case Opt_rdma:
+               ctx->flags |= NFS_MOUNT_TCP; /* for side protocols */
+               ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
+               xprt_load_transport(param->key);
+               break;
+       case Opt_acl:
+               if (result.negated)
+                       ctx->flags |= NFS_MOUNT_NOACL;
+               else
+                       ctx->flags &= ~NFS_MOUNT_NOACL;
+               break;
+       case Opt_rdirplus:
+               if (result.negated)
+                       ctx->flags |= NFS_MOUNT_NORDIRPLUS;
+               else
+                       ctx->flags &= ~NFS_MOUNT_NORDIRPLUS;
+               break;
+       case Opt_sharecache:
+               if (result.negated)
+                       ctx->flags |= NFS_MOUNT_UNSHARED;
+               else
+                       ctx->flags &= ~NFS_MOUNT_UNSHARED;
+               break;
+       case Opt_resvport:
+               if (result.negated)
+                       ctx->flags |= NFS_MOUNT_NORESVPORT;
+               else
+                       ctx->flags &= ~NFS_MOUNT_NORESVPORT;
+               break;
+       case Opt_fscache_flag:
+               if (result.negated)
+                       ctx->options &= ~NFS_OPTION_FSCACHE;
+               else
+                       ctx->options |= NFS_OPTION_FSCACHE;
+               kfree(ctx->fscache_uniq);
+               ctx->fscache_uniq = NULL;
+               break;
+       case Opt_fscache:
+               ctx->options |= NFS_OPTION_FSCACHE;
+               kfree(ctx->fscache_uniq);
+               ctx->fscache_uniq = param->string;
+               param->string = NULL;
+               break;
+       case Opt_migration:
+               if (result.negated)
+                       ctx->options &= ~NFS_OPTION_MIGRATION;
+               else
+                       ctx->options |= NFS_OPTION_MIGRATION;
+               break;
+
+               /*
+                * options that take numeric values
+                */
+       case Opt_port:
+               if (result.uint_32 > USHRT_MAX)
+                       goto out_of_bounds;
+               ctx->nfs_server.port = result.uint_32;
+               break;
+       case Opt_rsize:
+               ctx->rsize = result.uint_32;
+               break;
+       case Opt_wsize:
+               ctx->wsize = result.uint_32;
+               break;
+       case Opt_bsize:
+               ctx->bsize = result.uint_32;
+               break;
+       case Opt_timeo:
+               if (result.uint_32 < 1 || result.uint_32 > INT_MAX)
+                       goto out_of_bounds;
+               ctx->timeo = result.uint_32;
+               break;
+       case Opt_retrans:
+               if (result.uint_32 > INT_MAX)
+                       goto out_of_bounds;
+               ctx->retrans = result.uint_32;
+               break;
+       case Opt_acregmin:
+               ctx->acregmin = result.uint_32;
+               break;
+       case Opt_acregmax:
+               ctx->acregmax = result.uint_32;
+               break;
+       case Opt_acdirmin:
+               ctx->acdirmin = result.uint_32;
+               break;
+       case Opt_acdirmax:
+               ctx->acdirmax = result.uint_32;
+               break;
+       case Opt_actimeo:
+               ctx->acregmin = result.uint_32;
+               ctx->acregmax = result.uint_32;
+               ctx->acdirmin = result.uint_32;
+               ctx->acdirmax = result.uint_32;
+               break;
+       case Opt_namelen:
+               ctx->namlen = result.uint_32;
+               break;
+       case Opt_mountport:
+               if (result.uint_32 > USHRT_MAX)
+                       goto out_of_bounds;
+               ctx->mount_server.port = result.uint_32;
+               break;
+       case Opt_mountvers:
+               if (result.uint_32 < NFS_MNT_VERSION ||
+                   result.uint_32 > NFS_MNT3_VERSION)
+                       goto out_of_bounds;
+               ctx->mount_server.version = result.uint_32;
+               break;
+       case Opt_minorversion:
+               if (result.uint_32 > NFS4_MAX_MINOR_VERSION)
+                       goto out_of_bounds;
+               ctx->minorversion = result.uint_32;
+               break;
+
+               /*
+                * options that take text values
+                */
+       case Opt_v:
+               ret = nfs_parse_version_string(fc, param->key + 1);
+               if (ret < 0)
+                       return ret;
+               break;
+       case Opt_vers:
+               ret = nfs_parse_version_string(fc, param->string);
+               if (ret < 0)
+                       return ret;
+               break;
+       case Opt_sec:
+               ret = nfs_parse_security_flavors(fc, param);
+               if (ret < 0)
+                       return ret;
+               break;
+
+       case Opt_proto:
+               protofamily = AF_INET;
+               switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
+               case Opt_xprt_udp6:
+                       protofamily = AF_INET6;
+                       /* fall through */
+               case Opt_xprt_udp:
+                       ctx->flags &= ~NFS_MOUNT_TCP;
+                       ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
+                       break;
+               case Opt_xprt_tcp6:
+                       protofamily = AF_INET6;
+                       /* fall through */
+               case Opt_xprt_tcp:
+                       ctx->flags |= NFS_MOUNT_TCP;
+                       ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+                       break;
+               case Opt_xprt_rdma6:
+                       protofamily = AF_INET6;
+                       /* fall through */
+               case Opt_xprt_rdma:
+                       /* vector side protocols to TCP */
+                       ctx->flags |= NFS_MOUNT_TCP;
+                       ctx->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
+                       xprt_load_transport(param->string);
+                       break;
+               default:
+                       return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
+               }
+
+               ctx->protofamily = protofamily;
+               break;
+
+       case Opt_mountproto:
+               mountfamily = AF_INET;
+               switch (lookup_constant(nfs_xprt_protocol_tokens, param->string, -1)) {
+               case Opt_xprt_udp6:
+                       mountfamily = AF_INET6;
+                       /* fall through */
+               case Opt_xprt_udp:
+                       ctx->mount_server.protocol = XPRT_TRANSPORT_UDP;
+                       break;
+               case Opt_xprt_tcp6:
+                       mountfamily = AF_INET6;
+                       /* fall through */
+               case Opt_xprt_tcp:
+                       ctx->mount_server.protocol = XPRT_TRANSPORT_TCP;
+                       break;
+               case Opt_xprt_rdma: /* not used for side protocols */
+               default:
+                       return nfs_invalf(fc, "NFS: Unrecognized transport protocol");
+               }
+               ctx->mountfamily = mountfamily;
+               break;
+
+       case Opt_addr:
+               len = rpc_pton(fc->net_ns, param->string, param->size,
+                              &ctx->nfs_server.address,
+                              sizeof(ctx->nfs_server._address));
+               if (len == 0)
+                       goto out_invalid_address;
+               ctx->nfs_server.addrlen = len;
+               break;
+       case Opt_clientaddr:
+               kfree(ctx->client_address);
+               ctx->client_address = param->string;
+               param->string = NULL;
+               break;
+       case Opt_mounthost:
+               kfree(ctx->mount_server.hostname);
+               ctx->mount_server.hostname = param->string;
+               param->string = NULL;
+               break;
+       case Opt_mountaddr:
+               len = rpc_pton(fc->net_ns, param->string, param->size,
+                              &ctx->mount_server.address,
+                              sizeof(ctx->mount_server._address));
+               if (len == 0)
+                       goto out_invalid_address;
+               ctx->mount_server.addrlen = len;
+               break;
+       case Opt_nconnect:
+               if (result.uint_32 < 1 || result.uint_32 > NFS_MAX_CONNECTIONS)
+                       goto out_of_bounds;
+               ctx->nfs_server.nconnect = result.uint_32;
+               break;
+       case Opt_lookupcache:
+               switch (result.uint_32) {
+               case Opt_lookupcache_all:
+                       ctx->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE);
+                       break;
+               case Opt_lookupcache_positive:
+                       ctx->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE;
+                       ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG;
+                       break;
+               case Opt_lookupcache_none:
+                       ctx->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
+                       break;
+               default:
+                       goto out_invalid_value;
+               }
+               break;
+       case Opt_local_lock:
+               switch (result.uint_32) {
+               case Opt_local_lock_all:
+                       ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK |
+                                      NFS_MOUNT_LOCAL_FCNTL);
+                       break;
+               case Opt_local_lock_flock:
+                       ctx->flags |= NFS_MOUNT_LOCAL_FLOCK;
+                       break;
+               case Opt_local_lock_posix:
+                       ctx->flags |= NFS_MOUNT_LOCAL_FCNTL;
+                       break;
+               case Opt_local_lock_none:
+                       ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK |
+                                       NFS_MOUNT_LOCAL_FCNTL);
+                       break;
+               default:
+                       goto out_invalid_value;
+               }
+               break;
+
+               /*
+                * Special options
+                */
+       case Opt_sloppy:
+               ctx->sloppy = true;
+               dfprintk(MOUNT, "NFS:   relaxing parsing rules\n");
+               break;
+       }
+
+       return 0;
+
+out_invalid_value:
+       return nfs_invalf(fc, "NFS: Bad mount option value specified");
+out_invalid_address:
+       return nfs_invalf(fc, "NFS: Bad IP address specified");
+out_of_bounds:
+       return nfs_invalf(fc, "NFS: Value for '%s' out of range", param->key);
+}
+
+/*
+ * Split fc->source into "hostname:export_path".
+ *
+ * The leftmost colon demarks the split between the server's hostname
+ * and the export path.  If the hostname starts with a left square
+ * bracket, then it may contain colons.
+ *
+ * Note: caller frees hostname and export path, even on error.
+ */
+static int nfs_parse_source(struct fs_context *fc,
+                           size_t maxnamlen, size_t maxpathlen)
+{
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       const char *dev_name = fc->source;
+       size_t len;
+       const char *end;
+
+       if (unlikely(!dev_name || !*dev_name)) {
+               dfprintk(MOUNT, "NFS: device name not specified\n");
+               return -EINVAL;
+       }
+
+       /* Is the host name protected with square brakcets? */
+       if (*dev_name == '[') {
+               end = strchr(++dev_name, ']');
+               if (end == NULL || end[1] != ':')
+                       goto out_bad_devname;
+
+               len = end - dev_name;
+               end++;
+       } else {
+               const char *comma;
+
+               end = strchr(dev_name, ':');
+               if (end == NULL)
+                       goto out_bad_devname;
+               len = end - dev_name;
+
+               /* kill possible hostname list: not supported */
+               comma = memchr(dev_name, ',', len);
+               if (comma)
+                       len = comma - dev_name;
+       }
+
+       if (len > maxnamlen)
+               goto out_hostname;
+
+       /* N.B. caller will free nfs_server.hostname in all cases */
+       ctx->nfs_server.hostname = kmemdup_nul(dev_name, len, GFP_KERNEL);
+       if (!ctx->nfs_server.hostname)
+               goto out_nomem;
+       len = strlen(++end);
+       if (len > maxpathlen)
+               goto out_path;
+       ctx->nfs_server.export_path = kmemdup_nul(end, len, GFP_KERNEL);
+       if (!ctx->nfs_server.export_path)
+               goto out_nomem;
+
+       dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", ctx->nfs_server.export_path);
+       return 0;
+
+out_bad_devname:
+       return nfs_invalf(fc, "NFS: device name not in host:path format");
+out_nomem:
+       nfs_errorf(fc, "NFS: not enough memory to parse device name");
+       return -ENOMEM;
+out_hostname:
+       nfs_errorf(fc, "NFS: server hostname too long");
+       return -ENAMETOOLONG;
+out_path:
+       nfs_errorf(fc, "NFS: export pathname too long");
+       return -ENAMETOOLONG;
+}
+
+static inline bool is_remount_fc(struct fs_context *fc)
+{
+       return fc->root != NULL;
+}
+
+/*
+ * Parse monolithic NFS2/NFS3 mount data
+ * - fills in the mount root filehandle
+ *
+ * For option strings, user space handles the following behaviors:
+ *
+ * + DNS: mapping server host name to IP address ("addr=" option)
+ *
+ * + failure mode: how to behave if a mount request can't be handled
+ *   immediately ("fg/bg" option)
+ *
+ * + retry: how often to retry a mount request ("retry=" option)
+ *
+ * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
+ *   mountproto=tcp after mountproto=udp, and so on
+ */
+static int nfs23_parse_monolithic(struct fs_context *fc,
+                                 struct nfs_mount_data *data)
+{
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct nfs_fh *mntfh = ctx->mntfh;
+       struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
+       int extra_flags = NFS_MOUNT_LEGACY_INTERFACE;
+
+       if (data == NULL)
+               goto out_no_data;
+
+       ctx->version = NFS_DEFAULT_VERSION;
+       switch (data->version) {
+       case 1:
+               data->namlen = 0; /* fall through */
+       case 2:
+               data->bsize = 0; /* fall through */
+       case 3:
+               if (data->flags & NFS_MOUNT_VER3)
+                       goto out_no_v3;
+               data->root.size = NFS2_FHSIZE;
+               memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
+               /* Turn off security negotiation */
+               extra_flags |= NFS_MOUNT_SECFLAVOUR;
+               /* fall through */
+       case 4:
+               if (data->flags & NFS_MOUNT_SECFLAVOUR)
+                       goto out_no_sec;
+               /* fall through */
+       case 5:
+               memset(data->context, 0, sizeof(data->context));
+               /* fall through */
+       case 6:
+               if (data->flags & NFS_MOUNT_VER3) {
+                       if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
+                               goto out_invalid_fh;
+                       mntfh->size = data->root.size;
+                       ctx->version = 3;
+               } else {
+                       mntfh->size = NFS2_FHSIZE;
+                       ctx->version = 2;
+               }
+
+
+               memcpy(mntfh->data, data->root.data, mntfh->size);
+               if (mntfh->size < sizeof(mntfh->data))
+                       memset(mntfh->data + mntfh->size, 0,
+                              sizeof(mntfh->data) - mntfh->size);
+
+               /*
+                * Translate to nfs_fs_context, which nfs_fill_super
+                * can deal with.
+                */
+               ctx->flags      = data->flags & NFS_MOUNT_FLAGMASK;
+               ctx->flags      |= extra_flags;
+               ctx->rsize      = data->rsize;
+               ctx->wsize      = data->wsize;
+               ctx->timeo      = data->timeo;
+               ctx->retrans    = data->retrans;
+               ctx->acregmin   = data->acregmin;
+               ctx->acregmax   = data->acregmax;
+               ctx->acdirmin   = data->acdirmin;
+               ctx->acdirmax   = data->acdirmax;
+               ctx->need_mount = false;
+
+               memcpy(sap, &data->addr, sizeof(data->addr));
+               ctx->nfs_server.addrlen = sizeof(data->addr);
+               ctx->nfs_server.port = ntohs(data->addr.sin_port);
+               if (sap->sa_family != AF_INET ||
+                   !nfs_verify_server_address(sap))
+                       goto out_no_address;
+
+               if (!(data->flags & NFS_MOUNT_TCP))
+                       ctx->nfs_server.protocol = XPRT_TRANSPORT_UDP;
+               /* N.B. caller will free nfs_server.hostname in all cases */
+               ctx->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
+               if (!ctx->nfs_server.hostname)
+                       goto out_nomem;
+
+               ctx->namlen             = data->namlen;
+               ctx->bsize              = data->bsize;
+
+               if (data->flags & NFS_MOUNT_SECFLAVOUR)
+                       ctx->selected_flavor = data->pseudoflavor;
+               else
+                       ctx->selected_flavor = RPC_AUTH_UNIX;
+
+               if (!(data->flags & NFS_MOUNT_NONLM))
+                       ctx->flags &= ~(NFS_MOUNT_LOCAL_FLOCK|
+                                        NFS_MOUNT_LOCAL_FCNTL);
+               else
+                       ctx->flags |= (NFS_MOUNT_LOCAL_FLOCK|
+                                       NFS_MOUNT_LOCAL_FCNTL);
+
+               /*
+                * The legacy version 6 binary mount data from userspace has a
+                * field used only to transport selinux information into the
+                * the kernel.  To continue to support that functionality we
+                * have a touch of selinux knowledge here in the NFS code. The
+                * userspace code converted context=blah to just blah so we are
+                * converting back to the full string selinux understands.
+                */
+               if (data->context[0]){
+#ifdef CONFIG_SECURITY_SELINUX
+                       int ret;
+
+                       data->context[NFS_MAX_CONTEXT_LEN] = '\0';
+                       ret = vfs_parse_fs_string(fc, "context",
+                                                 data->context, strlen(data->context));
+                       if (ret < 0)
+                               return ret;
+#else
+                       return -EINVAL;
+#endif
+               }
+
+               break;
+       default:
+               goto generic;
+       }
+
+       ctx->skip_reconfig_option_check = true;
+       return 0;
+
+generic:
+       return generic_parse_monolithic(fc, data);
+
+out_no_data:
+       if (is_remount_fc(fc)) {
+               ctx->skip_reconfig_option_check = true;
+               return 0;
+       }
+       return nfs_invalf(fc, "NFS: mount program didn't pass any mount data");
+
+out_no_v3:
+       return nfs_invalf(fc, "NFS: nfs_mount_data version does not support v3");
+
+out_no_sec:
+       return nfs_invalf(fc, "NFS: nfs_mount_data version supports only AUTH_SYS");
+
+out_nomem:
+       dfprintk(MOUNT, "NFS: not enough memory to handle mount options");
+       return -ENOMEM;
+
+out_no_address:
+       return nfs_invalf(fc, "NFS: mount program didn't pass remote address");
+
+out_invalid_fh:
+       return nfs_invalf(fc, "NFS: invalid root filehandle");
+}
+
+#if IS_ENABLED(CONFIG_NFS_V4)
+/*
+ * Validate NFSv4 mount options
+ */
+static int nfs4_parse_monolithic(struct fs_context *fc,
+                                struct nfs4_mount_data *data)
+{
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
+       char *c;
+
+       if (data == NULL)
+               goto out_no_data;
+
+       ctx->version = 4;
+
+       switch (data->version) {
+       case 1:
+               if (data->host_addrlen > sizeof(ctx->nfs_server.address))
+                       goto out_no_address;
+               if (data->host_addrlen == 0)
+                       goto out_no_address;
+               ctx->nfs_server.addrlen = data->host_addrlen;
+               if (copy_from_user(sap, data->host_addr, data->host_addrlen))
+                       return -EFAULT;
+               if (!nfs_verify_server_address(sap))
+                       goto out_no_address;
+               ctx->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
+
+               if (data->auth_flavourlen) {
+                       rpc_authflavor_t pseudoflavor;
+                       if (data->auth_flavourlen > 1)
+                               goto out_inval_auth;
+                       if (copy_from_user(&pseudoflavor,
+                                          data->auth_flavours,
+                                          sizeof(pseudoflavor)))
+                               return -EFAULT;
+                       ctx->selected_flavor = pseudoflavor;
+               } else
+                       ctx->selected_flavor = RPC_AUTH_UNIX;
+
+               c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
+               if (IS_ERR(c))
+                       return PTR_ERR(c);
+               ctx->nfs_server.hostname = c;
+
+               c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
+               if (IS_ERR(c))
+                       return PTR_ERR(c);
+               ctx->nfs_server.export_path = c;
+               dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
+
+               c = strndup_user(data->client_addr.data, 16);
+               if (IS_ERR(c))
+                       return PTR_ERR(c);
+               ctx->client_address = c;
+
+               /*
+                * Translate to nfs_fs_context, which nfs_fill_super
+                * can deal with.
+                */
+
+               ctx->flags      = data->flags & NFS4_MOUNT_FLAGMASK;
+               ctx->rsize      = data->rsize;
+               ctx->wsize      = data->wsize;
+               ctx->timeo      = data->timeo;
+               ctx->retrans    = data->retrans;
+               ctx->acregmin   = data->acregmin;
+               ctx->acregmax   = data->acregmax;
+               ctx->acdirmin   = data->acdirmin;
+               ctx->acdirmax   = data->acdirmax;
+               ctx->nfs_server.protocol = data->proto;
+               nfs_validate_transport_protocol(ctx);
+               if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP)
+                       goto out_invalid_transport_udp;
+
+               break;
+       default:
+               goto generic;
+       }
+
+       ctx->skip_reconfig_option_check = true;
+       return 0;
+
+generic:
+       return generic_parse_monolithic(fc, data);
+
+out_no_data:
+       if (is_remount_fc(fc)) {
+               ctx->skip_reconfig_option_check = true;
+               return 0;
+       }
+       return nfs_invalf(fc, "NFS4: mount program didn't pass any mount data");
+
+out_inval_auth:
+       return nfs_invalf(fc, "NFS4: Invalid number of RPC auth flavours %d",
+                     data->auth_flavourlen);
+
+out_no_address:
+       return nfs_invalf(fc, "NFS4: mount program didn't pass remote address");
+
+out_invalid_transport_udp:
+       return nfs_invalf(fc, "NFSv4: Unsupported transport protocol udp");
+}
+#endif
+
+/*
+ * Parse a monolithic block of data from sys_mount().
+ */
+static int nfs_fs_context_parse_monolithic(struct fs_context *fc,
+                                          void *data)
+{
+       if (fc->fs_type == &nfs_fs_type)
+               return nfs23_parse_monolithic(fc, data);
+
+#if IS_ENABLED(CONFIG_NFS_V4)
+       if (fc->fs_type == &nfs4_fs_type)
+               return nfs4_parse_monolithic(fc, data);
+#endif
+
+       return nfs_invalf(fc, "NFS: Unsupported monolithic data version");
+}
+
+/*
+ * Validate the preparsed information in the config.
+ */
+static int nfs_fs_context_validate(struct fs_context *fc)
+{
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct nfs_subversion *nfs_mod;
+       struct sockaddr *sap = (struct sockaddr *)&ctx->nfs_server.address;
+       int max_namelen = PAGE_SIZE;
+       int max_pathlen = NFS_MAXPATHLEN;
+       int port = 0;
+       int ret;
+
+       if (!fc->source)
+               goto out_no_device_name;
+
+       /* Check for sanity first. */
+       if (ctx->minorversion && ctx->version != 4)
+               goto out_minorversion_mismatch;
+
+       if (ctx->options & NFS_OPTION_MIGRATION &&
+           (ctx->version != 4 || ctx->minorversion != 0))
+               goto out_migration_misuse;
+
+       /* Verify that any proto=/mountproto= options match the address
+        * families in the addr=/mountaddr= options.
+        */
+       if (ctx->protofamily != AF_UNSPEC &&
+           ctx->protofamily != ctx->nfs_server.address.sa_family)
+               goto out_proto_mismatch;
+
+       if (ctx->mountfamily != AF_UNSPEC) {
+               if (ctx->mount_server.addrlen) {
+                       if (ctx->mountfamily != ctx->mount_server.address.sa_family)
+                               goto out_mountproto_mismatch;
+               } else {
+                       if (ctx->mountfamily != ctx->nfs_server.address.sa_family)
+                               goto out_mountproto_mismatch;
+               }
+       }
+
+       if (!nfs_verify_server_address(sap))
+               goto out_no_address;
+
+       if (ctx->version == 4) {
+               if (IS_ENABLED(CONFIG_NFS_V4)) {
+                       if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
+                               port = NFS_RDMA_PORT;
+                       else
+                               port = NFS_PORT;
+                       max_namelen = NFS4_MAXNAMLEN;
+                       max_pathlen = NFS4_MAXPATHLEN;
+                       nfs_validate_transport_protocol(ctx);
+                       if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP)
+                               goto out_invalid_transport_udp;
+                       ctx->flags &= ~(NFS_MOUNT_NONLM | NFS_MOUNT_NOACL |
+                                       NFS_MOUNT_VER3 | NFS_MOUNT_LOCAL_FLOCK |
+                                       NFS_MOUNT_LOCAL_FCNTL);
+               } else {
+                       goto out_v4_not_compiled;
+               }
+       } else {
+               nfs_set_mount_transport_protocol(ctx);
+#ifdef CONFIG_NFS_DISABLE_UDP_SUPPORT
+              if (ctx->nfs_server.protocol == XPRT_TRANSPORT_UDP)
+                      goto out_invalid_transport_udp;
+#endif
+               if (ctx->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
+                       port = NFS_RDMA_PORT;
+       }
+
+       nfs_set_port(sap, &ctx->nfs_server.port, port);
+
+       ret = nfs_parse_source(fc, max_namelen, max_pathlen);
+       if (ret < 0)
+               return ret;
+
+       /* Load the NFS protocol module if we haven't done so yet */
+       if (!ctx->nfs_mod) {
+               nfs_mod = get_nfs_version(ctx->version);
+               if (IS_ERR(nfs_mod)) {
+                       ret = PTR_ERR(nfs_mod);
+                       goto out_version_unavailable;
+               }
+               ctx->nfs_mod = nfs_mod;
+       }
+       return 0;
+
+out_no_device_name:
+       return nfs_invalf(fc, "NFS: Device name not specified");
+out_v4_not_compiled:
+       nfs_errorf(fc, "NFS: NFSv4 is not compiled into kernel");
+       return -EPROTONOSUPPORT;
+out_invalid_transport_udp:
+       return nfs_invalf(fc, "NFSv4: Unsupported transport protocol udp");
+out_no_address:
+       return nfs_invalf(fc, "NFS: mount program didn't pass remote address");
+out_mountproto_mismatch:
+       return nfs_invalf(fc, "NFS: Mount server address does not match mountproto= option");
+out_proto_mismatch:
+       return nfs_invalf(fc, "NFS: Server address does not match proto= option");
+out_minorversion_mismatch:
+       return nfs_invalf(fc, "NFS: Mount option vers=%u does not support minorversion=%u",
+                         ctx->version, ctx->minorversion);
+out_migration_misuse:
+       return nfs_invalf(fc, "NFS: 'Migration' not supported for this NFS version");
+out_version_unavailable:
+       nfs_errorf(fc, "NFS: Version unavailable");
+       return ret;
+}
+
+/*
+ * Create an NFS superblock by the appropriate method.
+ */
+static int nfs_get_tree(struct fs_context *fc)
+{
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       int err = nfs_fs_context_validate(fc);
+
+       if (err)
+               return err;
+       if (!ctx->internal)
+               return ctx->nfs_mod->rpc_ops->try_get_tree(fc);
+       else
+               return nfs_get_tree_common(fc);
+}
+
+/*
+ * Handle duplication of a configuration.  The caller copied *src into *sc, but
+ * it can't deal with resource pointers in the filesystem context, so we have
+ * to do that.  We need to clear pointers, copy data or get extra refs as
+ * appropriate.
+ */
+static int nfs_fs_context_dup(struct fs_context *fc, struct fs_context *src_fc)
+{
+       struct nfs_fs_context *src = nfs_fc2context(src_fc), *ctx;
+
+       ctx = kmemdup(src, sizeof(struct nfs_fs_context), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+
+       ctx->mntfh = nfs_alloc_fhandle();
+       if (!ctx->mntfh) {
+               kfree(ctx);
+               return -ENOMEM;
+       }
+       nfs_copy_fh(ctx->mntfh, src->mntfh);
+
+       __module_get(ctx->nfs_mod->owner);
+       ctx->client_address             = NULL;
+       ctx->mount_server.hostname      = NULL;
+       ctx->nfs_server.export_path     = NULL;
+       ctx->nfs_server.hostname        = NULL;
+       ctx->fscache_uniq               = NULL;
+       ctx->clone_data.fattr           = NULL;
+       fc->fs_private = ctx;
+       return 0;
+}
+
+static void nfs_fs_context_free(struct fs_context *fc)
+{
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+
+       if (ctx) {
+               if (ctx->server)
+                       nfs_free_server(ctx->server);
+               if (ctx->nfs_mod)
+                       put_nfs_version(ctx->nfs_mod);
+               kfree(ctx->client_address);
+               kfree(ctx->mount_server.hostname);
+               kfree(ctx->nfs_server.export_path);
+               kfree(ctx->nfs_server.hostname);
+               kfree(ctx->fscache_uniq);
+               nfs_free_fhandle(ctx->mntfh);
+               nfs_free_fattr(ctx->clone_data.fattr);
+               kfree(ctx);
+       }
+}
+
+static const struct fs_context_operations nfs_fs_context_ops = {
+       .free                   = nfs_fs_context_free,
+       .dup                    = nfs_fs_context_dup,
+       .parse_param            = nfs_fs_context_parse_param,
+       .parse_monolithic       = nfs_fs_context_parse_monolithic,
+       .get_tree               = nfs_get_tree,
+       .reconfigure            = nfs_reconfigure,
+};
+
+/*
+ * Prepare superblock configuration.  We use the namespaces attached to the
+ * context.  This may be the current process's namespaces, or it may be a
+ * container's namespaces.
+ */
+static int nfs_init_fs_context(struct fs_context *fc)
+{
+       struct nfs_fs_context *ctx;
+
+       ctx = kzalloc(sizeof(struct nfs_fs_context), GFP_KERNEL);
+       if (unlikely(!ctx))
+               return -ENOMEM;
+
+       ctx->mntfh = nfs_alloc_fhandle();
+       if (unlikely(!ctx->mntfh)) {
+               kfree(ctx);
+               return -ENOMEM;
+       }
+
+       ctx->protofamily        = AF_UNSPEC;
+       ctx->mountfamily        = AF_UNSPEC;
+       ctx->mount_server.port  = NFS_UNSPEC_PORT;
+
+       if (fc->root) {
+               /* reconfigure, start with the current config */
+               struct nfs_server *nfss = fc->root->d_sb->s_fs_info;
+               struct net *net = nfss->nfs_client->cl_net;
+
+               ctx->flags              = nfss->flags;
+               ctx->rsize              = nfss->rsize;
+               ctx->wsize              = nfss->wsize;
+               ctx->retrans            = nfss->client->cl_timeout->to_retries;
+               ctx->selected_flavor    = nfss->client->cl_auth->au_flavor;
+               ctx->acregmin           = nfss->acregmin / HZ;
+               ctx->acregmax           = nfss->acregmax / HZ;
+               ctx->acdirmin           = nfss->acdirmin / HZ;
+               ctx->acdirmax           = nfss->acdirmax / HZ;
+               ctx->timeo              = 10U * nfss->client->cl_timeout->to_initval / HZ;
+               ctx->nfs_server.port    = nfss->port;
+               ctx->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
+               ctx->version            = nfss->nfs_client->rpc_ops->version;
+               ctx->minorversion       = nfss->nfs_client->cl_minorversion;
+
+               memcpy(&ctx->nfs_server.address, &nfss->nfs_client->cl_addr,
+                       ctx->nfs_server.addrlen);
+
+               if (fc->net_ns != net) {
+                       put_net(fc->net_ns);
+                       fc->net_ns = get_net(net);
+               }
+
+               ctx->nfs_mod = nfss->nfs_client->cl_nfs_mod;
+               __module_get(ctx->nfs_mod->owner);
+       } else {
+               /* defaults */
+               ctx->timeo              = NFS_UNSPEC_TIMEO;
+               ctx->retrans            = NFS_UNSPEC_RETRANS;
+               ctx->acregmin           = NFS_DEF_ACREGMIN;
+               ctx->acregmax           = NFS_DEF_ACREGMAX;
+               ctx->acdirmin           = NFS_DEF_ACDIRMIN;
+               ctx->acdirmax           = NFS_DEF_ACDIRMAX;
+               ctx->nfs_server.port    = NFS_UNSPEC_PORT;
+               ctx->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+               ctx->selected_flavor    = RPC_AUTH_MAXFLAVOR;
+               ctx->minorversion       = 0;
+               ctx->need_mount         = true;
+       }
+       fc->fs_private = ctx;
+       fc->ops = &nfs_fs_context_ops;
+       return 0;
+}
+
+struct file_system_type nfs_fs_type = {
+       .owner                  = THIS_MODULE,
+       .name                   = "nfs",
+       .init_fs_context        = nfs_init_fs_context,
+       .parameters             = nfs_fs_parameters,
+       .kill_sb                = nfs_kill_super,
+       .fs_flags               = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
+};
+MODULE_ALIAS_FS("nfs");
+EXPORT_SYMBOL_GPL(nfs_fs_type);
+
+#if IS_ENABLED(CONFIG_NFS_V4)
+struct file_system_type nfs4_fs_type = {
+       .owner                  = THIS_MODULE,
+       .name                   = "nfs4",
+       .init_fs_context        = nfs_init_fs_context,
+       .parameters             = nfs_fs_parameters,
+       .kill_sb                = nfs_kill_super,
+       .fs_flags               = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
+};
+MODULE_ALIAS_FS("nfs4");
+MODULE_ALIAS("nfs4");
+EXPORT_SYMBOL_GPL(nfs4_fs_type);
+#endif /* CONFIG_NFS_V4 */
index 7def925..52270bf 100644 (file)
@@ -128,7 +128,7 @@ void nfs_fscache_get_super_cookie(struct super_block *sb, const char *uniq, int
                return;
 
        key->nfs_client = nfss->nfs_client;
-       key->key.super.s_flags = sb->s_flags & NFS_MS_MASK;
+       key->key.super.s_flags = sb->s_flags & NFS_SB_MASK;
        key->key.nfs_server.flags = nfss->flags;
        key->key.nfs_server.rsize = nfss->rsize;
        key->key.nfs_server.wsize = nfss->wsize;
index 878c4c5..b012c26 100644 (file)
@@ -64,66 +64,71 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
 /*
  * get an NFS2/NFS3 root dentry from the root filehandle
  */
-struct dentry *nfs_get_root(struct super_block *sb, struct nfs_fh *mntfh,
-                           const char *devname)
+int nfs_get_root(struct super_block *s, struct fs_context *fc)
 {
-       struct nfs_server *server = NFS_SB(sb);
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct nfs_server *server = NFS_SB(s);
        struct nfs_fsinfo fsinfo;
-       struct dentry *ret;
+       struct dentry *root;
        struct inode *inode;
-       void *name = kstrdup(devname, GFP_KERNEL);
-       int error;
+       char *name;
+       int error = -ENOMEM;
 
+       name = kstrdup(fc->source, GFP_KERNEL);
        if (!name)
-               return ERR_PTR(-ENOMEM);
+               goto out;
 
        /* get the actual root for this mount */
        fsinfo.fattr = nfs_alloc_fattr();
-       if (fsinfo.fattr == NULL) {
-               kfree(name);
-               return ERR_PTR(-ENOMEM);
-       }
+       if (fsinfo.fattr == NULL)
+               goto out_name;
 
-       error = server->nfs_client->rpc_ops->getroot(server, mntfh, &fsinfo);
+       error = server->nfs_client->rpc_ops->getroot(server, ctx->mntfh, &fsinfo);
        if (error < 0) {
                dprintk("nfs_get_root: getattr error = %d\n", -error);
-               ret = ERR_PTR(error);
-               goto out;
+               nfs_errorf(fc, "NFS: Couldn't getattr on root");
+               goto out_fattr;
        }
 
-       inode = nfs_fhget(sb, mntfh, fsinfo.fattr, NULL);
+       inode = nfs_fhget(s, ctx->mntfh, fsinfo.fattr, NULL);
        if (IS_ERR(inode)) {
                dprintk("nfs_get_root: get root inode failed\n");
-               ret = ERR_CAST(inode);
-               goto out;
+               error = PTR_ERR(inode);
+               nfs_errorf(fc, "NFS: Couldn't get root inode");
+               goto out_fattr;
        }
 
-       error = nfs_superblock_set_dummy_root(sb, inode);
-       if (error != 0) {
-               ret = ERR_PTR(error);
-               goto out;
-       }
+       error = nfs_superblock_set_dummy_root(s, inode);
+       if (error != 0)
+               goto out_fattr;
 
        /* root dentries normally start off anonymous and get spliced in later
         * if the dentry tree reaches them; however if the dentry already
         * exists, we'll pick it up at this point and use it as the root
         */
-       ret = d_obtain_root(inode);
-       if (IS_ERR(ret)) {
+       root = d_obtain_root(inode);
+       if (IS_ERR(root)) {
                dprintk("nfs_get_root: get root dentry failed\n");
-               goto out;
+               error = PTR_ERR(root);
+               nfs_errorf(fc, "NFS: Couldn't get root dentry");
+               goto out_fattr;
        }
 
-       security_d_instantiate(ret, inode);
-       spin_lock(&ret->d_lock);
-       if (IS_ROOT(ret) && !ret->d_fsdata &&
-           !(ret->d_flags & DCACHE_NFSFS_RENAMED)) {
-               ret->d_fsdata = name;
+       security_d_instantiate(root, inode);
+       spin_lock(&root->d_lock);
+       if (IS_ROOT(root) && !root->d_fsdata &&
+           !(root->d_flags & DCACHE_NFSFS_RENAMED)) {
+               root->d_fsdata = name;
                name = NULL;
        }
-       spin_unlock(&ret->d_lock);
-out:
-       kfree(name);
+       spin_unlock(&root->d_lock);
+       fc->root = root;
+       error = 0;
+
+out_fattr:
        nfs_free_fattr(fsinfo.fattr);
-       return ret;
+out_name:
+       kfree(name);
+out:
+       return error;
 }
index b0b4b9f..1309e6f 100644 (file)
@@ -1061,7 +1061,7 @@ struct nfs_open_context *nfs_find_open_context(struct inode *inode, const struct
 
        rcu_read_lock();
        list_for_each_entry_rcu(pos, &nfsi->open_files, list) {
-               if (cred != NULL && pos->cred != cred)
+               if (cred != NULL && cred_fscmp(pos->cred, cred) != 0)
                        continue;
                if ((pos->mode & (FMODE_READ|FMODE_WRITE)) != mode)
                        continue;
@@ -1156,7 +1156,13 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
                dfprintk(PAGECACHE, "nfs_revalidate_inode: (%s/%Lu) getattr failed, error=%d\n",
                         inode->i_sb->s_id,
                         (unsigned long long)NFS_FILEID(inode), status);
-               if (status == -ESTALE) {
+               switch (status) {
+               case -ETIMEDOUT:
+                       /* A soft timeout occurred. Use cached information? */
+                       if (server->flags & NFS_MOUNT_SOFTREVAL)
+                               status = 0;
+                       break;
+               case -ESTALE:
                        nfs_zap_caches(inode);
                        if (!S_ISDIR(inode->i_mode))
                                set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
index 24a65da..f80c47d 100644 (file)
@@ -4,17 +4,19 @@
  */
 
 #include "nfs4_fs.h"
-#include <linux/mount.h>
+#include <linux/fs_context.h>
 #include <linux/security.h>
 #include <linux/crc32.h>
+#include <linux/sunrpc/addr.h>
 #include <linux/nfs_page.h>
 #include <linux/wait_bit.h>
 
-#define NFS_MS_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)
+#define NFS_SB_MASK (SB_RDONLY|SB_NOSUID|SB_NODEV|SB_NOEXEC|SB_SYNCHRONOUS)
 
 extern const struct export_operations nfs_export_ops;
 
 struct nfs_string;
+struct nfs_pageio_descriptor;
 
 static inline void nfs_attr_check_mountpoint(struct super_block *parent, struct nfs_fattr *fattr)
 {
@@ -31,17 +33,14 @@ static inline int nfs_attr_use_mounted_on_fileid(struct nfs_fattr *fattr)
        return 1;
 }
 
-struct nfs_clone_mount {
-       const struct super_block *sb;
-       const struct dentry *dentry;
-       struct nfs_fh *fh;
-       struct nfs_fattr *fattr;
-       char *hostname;
-       char *mnt_path;
-       struct sockaddr *addr;
-       size_t addrlen;
-       rpc_authflavor_t authflavor;
-};
+static inline bool nfs_lookup_is_soft_revalidate(const struct dentry *dentry)
+{
+       if (!(NFS_SB(dentry->d_sb)->flags & NFS_MOUNT_SOFTREVAL))
+               return false;
+       if (!d_is_positive(dentry) || !NFS_FH(d_inode(dentry))->size)
+               return false;
+       return true;
+}
 
 /*
  * Note: RFC 1813 doesn't limit the number of auth flavors that
@@ -82,12 +81,16 @@ struct nfs_client_initdata {
 /*
  * In-kernel mount arguments
  */
-struct nfs_parsed_mount_data {
-       int                     flags;
+struct nfs_fs_context {
+       bool                    internal;
+       bool                    skip_reconfig_option_check;
+       bool                    need_mount;
+       bool                    sloppy;
+       unsigned int            flags;          /* NFS{,4}_MOUNT_* flags */
        unsigned int            rsize, wsize;
        unsigned int            timeo, retrans;
-       unsigned int            acregmin, acregmax,
-                               acdirmin, acdirmax;
+       unsigned int            acregmin, acregmax;
+       unsigned int            acdirmin, acdirmax;
        unsigned int            namlen;
        unsigned int            options;
        unsigned int            bsize;
@@ -97,10 +100,14 @@ struct nfs_parsed_mount_data {
        unsigned int            version;
        unsigned int            minorversion;
        char                    *fscache_uniq;
-       bool                    need_mount;
+       unsigned short          protofamily;
+       unsigned short          mountfamily;
 
        struct {
-               struct sockaddr_storage address;
+               union {
+                       struct sockaddr address;
+                       struct sockaddr_storage _address;
+               };
                size_t                  addrlen;
                char                    *hostname;
                u32                     version;
@@ -109,19 +116,41 @@ struct nfs_parsed_mount_data {
        } mount_server;
 
        struct {
-               struct sockaddr_storage address;
+               union {
+                       struct sockaddr address;
+                       struct sockaddr_storage _address;
+               };
                size_t                  addrlen;
                char                    *hostname;
                char                    *export_path;
                int                     port;
                unsigned short          protocol;
                unsigned short          nconnect;
+               unsigned short          export_path_len;
        } nfs_server;
 
-       void                    *lsm_opts;
-       struct net              *net;
+       struct nfs_fh           *mntfh;
+       struct nfs_server       *server;
+       struct nfs_subversion   *nfs_mod;
+
+       /* Information for a cloned mount. */
+       struct nfs_clone_mount {
+               struct super_block      *sb;
+               struct dentry           *dentry;
+               struct nfs_fattr        *fattr;
+               unsigned int            inherited_bsize;
+       } clone_data;
 };
 
+#define nfs_errorf(fc, fmt, ...) errorf(fc, fmt, ## __VA_ARGS__)
+#define nfs_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__)
+#define nfs_warnf(fc, fmt, ...) warnf(fc, fmt, ## __VA_ARGS__)
+
+static inline struct nfs_fs_context *nfs_fc2context(const struct fs_context *fc)
+{
+       return fc->fs_private;
+}
+
 /* mount_clnt.c */
 struct nfs_mount_request {
        struct sockaddr         *sap;
@@ -137,14 +166,6 @@ struct nfs_mount_request {
        struct net              *net;
 };
 
-struct nfs_mount_info {
-       void (*fill_super)(struct super_block *, struct nfs_mount_info *);
-       int (*set_security)(struct super_block *, struct dentry *, struct nfs_mount_info *);
-       struct nfs_parsed_mount_data *parsed;
-       struct nfs_clone_mount *cloned;
-       struct nfs_fh *mntfh;
-};
-
 extern int nfs_mount(struct nfs_mount_request *info);
 extern void nfs_umount(const struct nfs_mount_request *info);
 
@@ -170,13 +191,9 @@ extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
 extern struct nfs_client *
 nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
                                struct nfs4_sessionid *, u32);
-extern struct nfs_server *nfs_create_server(struct nfs_mount_info *,
-                                       struct nfs_subversion *);
-extern struct nfs_server *nfs4_create_server(
-                                       struct nfs_mount_info *,
-                                       struct nfs_subversion *);
-extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
-                                                     struct nfs_fh *);
+extern struct nfs_server *nfs_create_server(struct fs_context *);
+extern struct nfs_server *nfs4_create_server(struct fs_context *);
+extern struct nfs_server *nfs4_create_referral_server(struct fs_context *);
 extern int nfs4_update_server(struct nfs_server *server, const char *hostname,
                                        struct sockaddr *sap, size_t salen,
                                        struct net *net);
@@ -227,7 +244,9 @@ static inline void nfs_fs_proc_exit(void)
 extern const struct svc_version nfs4_callback_version1;
 extern const struct svc_version nfs4_callback_version4;
 
-struct nfs_pageio_descriptor;
+/* fs_context.c */
+extern struct file_system_type nfs_fs_type;
+
 /* pagelist.c */
 extern int __init nfs_init_nfspagecache(void);
 extern void nfs_destroy_nfspagecache(void);
@@ -387,23 +406,10 @@ extern int nfs_wait_atomic_killable(atomic_t *p, unsigned int mode);
 
 /* super.c */
 extern const struct super_operations nfs_sops;
-extern struct file_system_type nfs_fs_type;
-extern struct file_system_type nfs_xdev_fs_type;
-#if IS_ENABLED(CONFIG_NFS_V4)
-extern struct file_system_type nfs4_referral_fs_type;
-#endif
 bool nfs_auth_info_match(const struct nfs_auth_info *, rpc_authflavor_t);
-struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *,
-                       struct nfs_subversion *);
-int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
-int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
-struct dentry *nfs_fs_mount_common(struct nfs_server *, int, const char *,
-                                  struct nfs_mount_info *, struct nfs_subversion *);
-struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *);
-struct dentry * nfs_xdev_mount_common(struct file_system_type *, int,
-               const char *, struct nfs_mount_info *);
+int nfs_try_get_tree(struct fs_context *);
+int nfs_get_tree_common(struct fs_context *);
 void nfs_kill_super(struct super_block *);
-void nfs_fill_super(struct super_block *, struct nfs_mount_info *);
 
 extern struct rpc_stat nfs_rpcstat;
 
@@ -430,18 +436,12 @@ static inline bool nfs_file_io_is_buffered(struct nfs_inode *nfsi)
 extern char *nfs_path(char **p, struct dentry *dentry,
                      char *buffer, ssize_t buflen, unsigned flags);
 extern struct vfsmount *nfs_d_automount(struct path *path);
-struct vfsmount *nfs_submount(struct nfs_server *, struct dentry *,
-                             struct nfs_fh *, struct nfs_fattr *);
-struct vfsmount *nfs_do_submount(struct dentry *, struct nfs_fh *,
-                                struct nfs_fattr *, rpc_authflavor_t);
+int nfs_submount(struct fs_context *, struct nfs_server *);
+int nfs_do_submount(struct fs_context *);
 
 /* getroot.c */
-extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
-                                  const char *);
+extern int nfs_get_root(struct super_block *s, struct fs_context *fc);
 #if IS_ENABLED(CONFIG_NFS_V4)
-extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
-                                   const char *);
-
 extern int nfs4_get_rootfh(struct nfs_server *server, struct nfs_fh *mntfh, bool);
 #endif
 
@@ -460,7 +460,7 @@ int  nfs_show_options(struct seq_file *, struct dentry *);
 int  nfs_show_devname(struct seq_file *, struct dentry *);
 int  nfs_show_path(struct seq_file *, struct dentry *);
 int  nfs_show_stats(struct seq_file *, struct dentry *);
-int nfs_remount(struct super_block *sb, int *flags, char *raw_data);
+int  nfs_reconfigure(struct fs_context *);
 
 /* write.c */
 extern void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
@@ -706,9 +706,9 @@ unsigned int nfs_page_array_len(unsigned int base, size_t len)
 }
 
 /*
- * Convert a struct timespec into a 64-bit change attribute
+ * Convert a struct timespec64 into a 64-bit change attribute
  *
- * This does approximately the same thing as timespec_to_ns(),
+ * This does approximately the same thing as timespec64_to_ns(),
  * but for calculation efficiency, we multiply the seconds by
  * 1024*1024*1024.
  */
@@ -777,3 +777,16 @@ static inline bool nfs_error_is_fatal_on_server(int err)
        }
        return nfs_error_is_fatal(err);
 }
+
+/*
+ * Select between a default port value and a user-specified port value.
+ * If a zero value is set, then autobind will be used.
+ */
+static inline void nfs_set_port(struct sockaddr *sap, int *port,
+                               const unsigned short default_port)
+{
+       if (*port == NFS_UNSPEC_PORT)
+               *port = default_port;
+
+       rpc_set_port(sap, *port);
+}
index cb7c10e..35c8cb2 100644 (file)
@@ -29,9 +29,7 @@
  */
 #define encode_dirpath_sz      (1 + XDR_QUADLEN(MNTPATHLEN))
 #define MNT_status_sz          (1)
-#define MNT_fhs_status_sz      (1)
 #define MNT_fhandle_sz         XDR_QUADLEN(NFS2_FHSIZE)
-#define MNT_fhandle3_sz                (1 + XDR_QUADLEN(NFS3_FHSIZE))
 #define MNT_authflav3_sz       (1 + NFS_MAX_SECFLAVORS)
 
 /*
index 5e0e9d2..ad60774 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/vfs.h>
 #include <linux/sunrpc/gss_api.h>
 #include "internal.h"
+#include "nfs.h"
 
 #define NFSDBG_FACILITY                NFSDBG_VFS
 
@@ -139,34 +140,65 @@ EXPORT_SYMBOL_GPL(nfs_path);
  */
 struct vfsmount *nfs_d_automount(struct path *path)
 {
-       struct vfsmount *mnt;
+       struct nfs_fs_context *ctx;
+       struct fs_context *fc;
+       struct vfsmount *mnt = ERR_PTR(-ENOMEM);
        struct nfs_server *server = NFS_SERVER(d_inode(path->dentry));
-       struct nfs_fh *fh = NULL;
-       struct nfs_fattr *fattr = NULL;
+       struct nfs_client *client = server->nfs_client;
+       int ret;
 
        if (IS_ROOT(path->dentry))
                return ERR_PTR(-ESTALE);
 
-       mnt = ERR_PTR(-ENOMEM);
-       fh = nfs_alloc_fhandle();
-       fattr = nfs_alloc_fattr();
-       if (fh == NULL || fattr == NULL)
-               goto out;
+       /* Open a new filesystem context, transferring parameters from the
+        * parent superblock, including the network namespace.
+        */
+       fc = fs_context_for_submount(&nfs_fs_type, path->dentry);
+       if (IS_ERR(fc))
+               return ERR_CAST(fc);
 
-       mnt = server->nfs_client->rpc_ops->submount(server, path->dentry, fh, fattr);
+       ctx = nfs_fc2context(fc);
+       ctx->clone_data.dentry  = path->dentry;
+       ctx->clone_data.sb      = path->dentry->d_sb;
+       ctx->clone_data.fattr   = nfs_alloc_fattr();
+       if (!ctx->clone_data.fattr)
+               goto out_fc;
+
+       if (fc->net_ns != client->cl_net) {
+               put_net(fc->net_ns);
+               fc->net_ns = get_net(client->cl_net);
+       }
+
+       /* for submounts we want the same server; referrals will reassign */
+       memcpy(&ctx->nfs_server.address, &client->cl_addr, client->cl_addrlen);
+       ctx->nfs_server.addrlen = client->cl_addrlen;
+       ctx->nfs_server.port    = server->port;
+
+       ctx->version            = client->rpc_ops->version;
+       ctx->minorversion       = client->cl_minorversion;
+       ctx->nfs_mod            = client->cl_nfs_mod;
+       __module_get(ctx->nfs_mod->owner);
+
+       ret = client->rpc_ops->submount(fc, server);
+       if (ret < 0) {
+               mnt = ERR_PTR(ret);
+               goto out_fc;
+       }
+
+       up_write(&fc->root->d_sb->s_umount);
+       mnt = vfs_create_mount(fc);
        if (IS_ERR(mnt))
-               goto out;
+               goto out_fc;
 
        if (nfs_mountpoint_expiry_timeout < 0)
-               goto out;
+               goto out_fc;
 
        mntget(mnt); /* prevent immediate expiration */
        mnt_set_expiry(mnt, &nfs_automount_list);
        schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout);
 
-out:
-       nfs_free_fattr(fattr);
-       nfs_free_fhandle(fh);
+out_fc:
+       put_fs_context(fc);
        return mnt;
 }
 
@@ -213,16 +245,6 @@ void nfs_release_automount_timer(void)
                cancel_delayed_work(&nfs_automount_task);
 }
 
-/*
- * Clone a mountpoint of the appropriate type
- */
-static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
-                                          const char *devname,
-                                          struct nfs_clone_mount *mountdata)
-{
-       return vfs_submount(mountdata->dentry, &nfs_xdev_fs_type, devname, mountdata);
-}
-
 /**
  * nfs_do_submount - set up mountpoint when crossing a filesystem boundary
  * @dentry: parent directory
@@ -231,46 +253,62 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
  * @authflavor: security flavor to use when performing the mount
  *
  */
-struct vfsmount *nfs_do_submount(struct dentry *dentry, struct nfs_fh *fh,
-                                struct nfs_fattr *fattr, rpc_authflavor_t authflavor)
+int nfs_do_submount(struct fs_context *fc)
 {
-       struct nfs_clone_mount mountdata = {
-               .sb = dentry->d_sb,
-               .dentry = dentry,
-               .fh = fh,
-               .fattr = fattr,
-               .authflavor = authflavor,
-       };
-       struct vfsmount *mnt;
-       char *page = (char *) __get_free_page(GFP_USER);
-       char *devname;
-
-       if (page == NULL)
-               return ERR_PTR(-ENOMEM);
-
-       devname = nfs_devname(dentry, page, PAGE_SIZE);
-       if (IS_ERR(devname))
-               mnt = ERR_CAST(devname);
-       else
-               mnt = nfs_do_clone_mount(NFS_SB(dentry->d_sb), devname, &mountdata);
-
-       free_page((unsigned long)page);
-       return mnt;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct dentry *dentry = ctx->clone_data.dentry;
+       struct nfs_server *server;
+       char *buffer, *p;
+       int ret;
+
+       /* create a new volume representation */
+       server = ctx->nfs_mod->rpc_ops->clone_server(NFS_SB(ctx->clone_data.sb),
+                                                    ctx->mntfh,
+                                                    ctx->clone_data.fattr,
+                                                    ctx->selected_flavor);
+
+       if (IS_ERR(server))
+               return PTR_ERR(server);
+
+       ctx->server = server;
+
+       buffer = kmalloc(4096, GFP_USER);
+       if (!buffer)
+               return -ENOMEM;
+
+       ctx->internal           = true;
+       ctx->clone_data.inherited_bsize = ctx->clone_data.sb->s_blocksize_bits;
+
+       p = nfs_devname(dentry, buffer, 4096);
+       if (IS_ERR(p)) {
+               nfs_errorf(fc, "NFS: Couldn't determine submount pathname");
+               ret = PTR_ERR(p);
+       } else {
+               ret = vfs_parse_fs_string(fc, "source", p, buffer + 4096 - p);
+               if (!ret)
+                       ret = vfs_get_tree(fc);
+       }
+       kfree(buffer);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(nfs_do_submount);
 
-struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry,
-                             struct nfs_fh *fh, struct nfs_fattr *fattr)
+int nfs_submount(struct fs_context *fc, struct nfs_server *server)
 {
-       int err;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct dentry *dentry = ctx->clone_data.dentry;
        struct dentry *parent = dget_parent(dentry);
+       int err;
 
        /* Look it up again to get its attributes */
-       err = server->nfs_client->rpc_ops->lookup(d_inode(parent), &dentry->d_name, fh, fattr, NULL);
+       err = server->nfs_client->rpc_ops->lookup(d_inode(parent), dentry,
+                                                 ctx->mntfh, ctx->clone_data.fattr,
+                                                 NULL);
        dput(parent);
        if (err != 0)
-               return ERR_PTR(err);
+               return err;
 
-       return nfs_do_submount(dentry, fh, fattr, server->client->cl_auth->au_flavor);
+       ctx->selected_flavor = server->client->cl_auth->au_flavor;
+       return nfs_do_submount(fc);
 }
 EXPORT_SYMBOL_GPL(nfs_submount);
index d94c7ab..f6676af 100644 (file)
@@ -360,17 +360,17 @@ static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr,
        else
                *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET);
 
-       if (attr->ia_valid & ATTR_ATIME_SET) {
+       if (attr->ia_valid & ATTR_ATIME_SET)
                p = xdr_encode_time(p, &attr->ia_atime);
-       } else if (attr->ia_valid & ATTR_ATIME) {
+       else if (attr->ia_valid & ATTR_ATIME)
                p = xdr_encode_current_server_time(p, &attr->ia_atime);
-       else
+       else
                p = xdr_time_not_set(p);
-       if (attr->ia_valid & ATTR_MTIME_SET) {
+       if (attr->ia_valid & ATTR_MTIME_SET)
                xdr_encode_time(p, &attr->ia_mtime);
-       } else if (attr->ia_valid & ATTR_MTIME) {
+       else if (attr->ia_valid & ATTR_MTIME)
                xdr_encode_current_server_time(p, &attr->ia_mtime);
-       else
+       else
                xdr_time_not_set(p);
 }
 
index f82e11c..1b950b6 100644 (file)
@@ -27,7 +27,7 @@ static inline int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl,
 #endif /* CONFIG_NFS_V3_ACL */
 
 /* nfs3client.c */
-struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *);
+struct nfs_server *nfs3_create_server(struct fs_context *);
 struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *,
                                     struct nfs_fattr *, rpc_authflavor_t);
 
index 223904b..5601e47 100644 (file)
@@ -46,10 +46,10 @@ static inline void nfs_init_server_aclclient(struct nfs_server *server)
 }
 #endif
 
-struct nfs_server *nfs3_create_server(struct nfs_mount_info *mount_info,
-                                     struct nfs_subversion *nfs_mod)
+struct nfs_server *nfs3_create_server(struct fs_context *fc)
 {
-       struct nfs_server *server = nfs_create_server(mount_info, nfs_mod);
+       struct nfs_server *server = nfs_create_server(fc);
+
        /* Create a client RPC handle for the NFS v3 ACL management interface */
        if (!IS_ERR(server))
                nfs_init_server_aclclient(server);
index 9eb2f1a..a46d1d5 100644 (file)
@@ -110,10 +110,15 @@ nfs3_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
                .rpc_resp       = fattr,
        };
        int     status;
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        dprintk("NFS call  getattr\n");
        nfs_fattr_init(fattr);
-       status = rpc_call_sync(server->client, &msg, 0);
+       status = rpc_call_sync(server->client, &msg, task_flags);
        dprintk("NFS reply getattr: %d\n", status);
        return status;
 }
@@ -140,23 +145,23 @@ nfs3_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
        nfs_fattr_init(fattr);
        status = rpc_call_sync(NFS_CLIENT(inode), &msg, 0);
        if (status == 0) {
+               nfs_setattr_update_inode(inode, sattr, fattr);
                if (NFS_I(inode)->cache_validity & NFS_INO_INVALID_ACL)
                        nfs_zap_acl_cache(inode);
-               nfs_setattr_update_inode(inode, sattr, fattr);
        }
        dprintk("NFS reply setattr: %d\n", status);
        return status;
 }
 
 static int
-nfs3_proc_lookup(struct inode *dir, const struct qstr *name,
+nfs3_proc_lookup(struct inode *dir, struct dentry *dentry,
                 struct nfs_fh *fhandle, struct nfs_fattr *fattr,
                 struct nfs4_label *label)
 {
        struct nfs3_diropargs   arg = {
                .fh             = NFS_FH(dir),
-               .name           = name->name,
-               .len            = name->len
+               .name           = dentry->d_name.name,
+               .len            = dentry->d_name.len
        };
        struct nfs3_diropres    res = {
                .fh             = fhandle,
@@ -168,20 +173,25 @@ nfs3_proc_lookup(struct inode *dir, const struct qstr *name,
                .rpc_resp       = &res,
        };
        int                     status;
+       unsigned short task_flags = 0;
 
-       dprintk("NFS call  lookup %s\n", name->name);
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (nfs_lookup_is_soft_revalidate(dentry))
+               task_flags |= RPC_TASK_TIMEOUT;
+
+       dprintk("NFS call  lookup %pd2\n", dentry);
        res.dir_attr = nfs_alloc_fattr();
        if (res.dir_attr == NULL)
                return -ENOMEM;
 
        nfs_fattr_init(fattr);
-       status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+       status = rpc_call_sync(NFS_CLIENT(dir), &msg, task_flags);
        nfs_refresh_inode(dir, res.dir_attr);
        if (status >= 0 && !(fattr->valid & NFS_ATTR_FATTR)) {
                msg.rpc_proc = &nfs3_procedures[NFS3PROC_GETATTR];
                msg.rpc_argp = fhandle;
                msg.rpc_resp = fattr;
-               status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+               status = rpc_call_sync(NFS_CLIENT(dir), &msg, task_flags);
        }
        nfs_free_fattr(res.dir_attr);
        dprintk("NFS reply lookup: %d\n", status);
@@ -990,7 +1000,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
        .nlmclnt_ops    = &nlmclnt_fl_close_lock_ops,
        .getroot        = nfs3_proc_get_root,
        .submount       = nfs_submount,
-       .try_mount      = nfs_try_mount,
+       .try_get_tree   = nfs_try_get_tree,
        .getattr        = nfs3_proc_getattr,
        .setattr        = nfs3_proc_setattr,
        .lookup         = nfs3_proc_lookup,
index 927eb68..69971f6 100644 (file)
@@ -2334,6 +2334,7 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
                                   void *data)
 {
        struct nfs_commitres *result = data;
+       struct nfs_writeverf *verf = result->verf;
        enum nfs_stat status;
        int error;
 
@@ -2346,7 +2347,9 @@ static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req,
        result->op_status = status;
        if (status != NFS3_OK)
                goto out_status;
-       error = decode_writeverf3(xdr, &result->verf->verifier);
+       error = decode_writeverf3(xdr, &verf->verifier);
+       if (!error)
+               verf->committed = NFS_FILE_SYNC;
 out:
        return error;
 out_status:
index 1fe83e0..e2ae54b 100644 (file)
@@ -61,8 +61,11 @@ static int _nfs42_proc_fallocate(struct rpc_message *msg, struct file *filep,
 
        status = nfs4_set_rw_stateid(&args.falloc_stateid, lock->open_context,
                        lock, FMODE_WRITE);
-       if (status)
+       if (status) {
+               if (status == -EAGAIN)
+                       status = -NFS4ERR_BAD_STATEID;
                return status;
+       }
 
        res.falloc_fattr = nfs_alloc_fattr();
        if (!res.falloc_fattr)
@@ -287,8 +290,11 @@ static ssize_t _nfs42_proc_copy(struct file *src,
        } else {
                status = nfs4_set_rw_stateid(&args->src_stateid,
                                src_lock->open_context, src_lock, FMODE_READ);
-               if (status)
+               if (status) {
+                       if (status == -EAGAIN)
+                               status = -NFS4ERR_BAD_STATEID;
                        return status;
+               }
        }
        status = nfs_filemap_write_and_wait_range(file_inode(src)->i_mapping,
                        pos_src, pos_src + (loff_t)count - 1);
@@ -297,8 +303,11 @@ static ssize_t _nfs42_proc_copy(struct file *src,
 
        status = nfs4_set_rw_stateid(&args->dst_stateid, dst_lock->open_context,
                                     dst_lock, FMODE_WRITE);
-       if (status)
+       if (status) {
+               if (status == -EAGAIN)
+                       status = -NFS4ERR_BAD_STATEID;
                return status;
+       }
 
        status = nfs_sync_inode(dst_inode);
        if (status)
@@ -334,14 +343,14 @@ static ssize_t _nfs42_proc_copy(struct file *src,
                status = handle_async_copy(res, dst_server, src_server, src,
                                dst, &args->src_stateid, restart);
                if (status)
-                       return status;
+                       goto out;
        }
 
        if ((!res->synchronous || !args->sync) &&
                        res->write_res.verifier.committed != NFS_FILE_SYNC) {
                status = process_copy_commit(dst, pos_dst, res);
                if (status)
-                       return status;
+                       goto out;
        }
 
        truncate_pagecache_range(dst_inode, pos_dst,
@@ -546,8 +555,11 @@ static int _nfs42_proc_copy_notify(struct file *src, struct file *dst,
        status = nfs4_set_rw_stateid(&args->cna_src_stateid, ctx, l_ctx,
                                     FMODE_READ);
        nfs_put_lock_context(l_ctx);
-       if (status)
+       if (status) {
+               if (status == -EAGAIN)
+                       status = -NFS4ERR_BAD_STATEID;
                return status;
+       }
 
        status = nfs4_call_sync(src_server->client, src_server, &msg,
                                &args->cna_seq_args, &res->cnr_seq_res, 0);
@@ -618,8 +630,11 @@ static loff_t _nfs42_proc_llseek(struct file *filep,
 
        status = nfs4_set_rw_stateid(&args.sa_stateid, lock->open_context,
                        lock, FMODE_READ);
-       if (status)
+       if (status) {
+               if (status == -EAGAIN)
+                       status = -NFS4ERR_BAD_STATEID;
                return status;
+       }
 
        status = nfs_filemap_write_and_wait_range(inode->i_mapping,
                        offset, LLONG_MAX);
@@ -994,13 +1009,18 @@ static int _nfs42_proc_clone(struct rpc_message *msg, struct file *src_f,
 
        status = nfs4_set_rw_stateid(&args.src_stateid, src_lock->open_context,
                        src_lock, FMODE_READ);
-       if (status)
+       if (status) {
+               if (status == -EAGAIN)
+                       status = -NFS4ERR_BAD_STATEID;
                return status;
-
+       }
        status = nfs4_set_rw_stateid(&args.dst_stateid, dst_lock->open_context,
                        dst_lock, FMODE_WRITE);
-       if (status)
+       if (status) {
+               if (status == -EAGAIN)
+                       status = -NFS4ERR_BAD_STATEID;
                return status;
+       }
 
        res.dst_fattr = nfs_alloc_fattr();
        if (!res.dst_fattr)
index a7a73b1..8be1ba7 100644 (file)
@@ -268,14 +268,13 @@ extern const struct dentry_operations nfs4_dentry_operations;
 int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
                    unsigned, umode_t);
 
-/* super.c */
+/* fs_context.c */
 extern struct file_system_type nfs4_fs_type;
 
 /* nfs4namespace.c */
 struct rpc_clnt *nfs4_negotiate_security(struct rpc_clnt *, struct inode *,
                                         const struct qstr *);
-struct vfsmount *nfs4_submount(struct nfs_server *, struct dentry *,
-                              struct nfs_fh *, struct nfs_fattr *);
+int nfs4_submount(struct fs_context *, struct nfs_server *);
 int nfs4_replace_transport(struct nfs_server *server,
                                const struct nfs4_fs_locations *locations);
 
@@ -303,8 +302,10 @@ extern int nfs4_proc_fs_locations(struct rpc_clnt *, struct inode *, const struc
 extern int nfs4_proc_get_locations(struct inode *, struct nfs4_fs_locations *,
                struct page *page, const struct cred *);
 extern int nfs4_proc_fsid_present(struct inode *, const struct cred *);
-extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *, const struct qstr *,
-                           struct nfs_fh *, struct nfs_fattr *);
+extern struct rpc_clnt *nfs4_proc_lookup_mountpoint(struct inode *,
+                                                   struct dentry *,
+                                                   struct nfs_fh *,
+                                                   struct nfs_fattr *);
 extern int nfs4_proc_secinfo(struct inode *, const struct qstr *, struct nfs4_secinfo_flavors *);
 extern const struct xattr_handler *nfs4_xattr_handlers[];
 extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
@@ -446,9 +447,7 @@ extern void nfs4_schedule_state_renewal(struct nfs_client *);
 extern void nfs4_renewd_prepare_shutdown(struct nfs_server *);
 extern void nfs4_kill_renewd(struct nfs_client *);
 extern void nfs4_renew_state(struct work_struct *);
-extern void nfs4_set_lease_period(struct nfs_client *clp,
-               unsigned long lease,
-               unsigned long lastrenewed);
+extern void nfs4_set_lease_period(struct nfs_client *clp, unsigned long lease);
 
 
 /* nfs4state.c */
@@ -526,7 +525,6 @@ extern const nfs4_stateid invalid_stateid;
 /* nfs4super.c */
 struct nfs_mount_info;
 extern struct nfs_subversion nfs_v4;
-struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *);
 extern bool nfs4_disable_idmapping;
 extern unsigned short max_session_slots;
 extern unsigned short max_session_cb_slots;
@@ -536,6 +534,9 @@ extern bool recover_lost_locks;
 #define NFS4_CLIENT_ID_UNIQ_LEN                (64)
 extern char nfs4_client_id_uniquifier[NFS4_CLIENT_ID_UNIQ_LEN];
 
+extern int nfs4_try_get_tree(struct fs_context *);
+extern int nfs4_get_referral_tree(struct fs_context *);
+
 /* nfs4sysctl.c */
 #ifdef CONFIG_SYSCTL
 int nfs4_register_sysctl(void);
index 460d625..0cd767e 100644 (file)
@@ -1055,66 +1055,64 @@ out:
 /*
  * Create a version 4 volume record
  */
-static int nfs4_init_server(struct nfs_server *server,
-               struct nfs_parsed_mount_data *data)
+static int nfs4_init_server(struct nfs_server *server, struct fs_context *fc)
 {
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
        struct rpc_timeout timeparms;
        int error;
 
-       nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
-                       data->timeo, data->retrans);
+       nfs_init_timeout_values(&timeparms, ctx->nfs_server.protocol,
+                               ctx->timeo, ctx->retrans);
 
        /* Initialise the client representation from the mount data */
-       server->flags = data->flags;
-       server->options = data->options;
-       server->auth_info = data->auth_info;
+       server->flags = ctx->flags;
+       server->options = ctx->options;
+       server->auth_info = ctx->auth_info;
 
        /* Use the first specified auth flavor. If this flavor isn't
         * allowed by the server, use the SECINFO path to try the
         * other specified flavors */
-       if (data->auth_info.flavor_len >= 1)
-               data->selected_flavor = data->auth_info.flavors[0];
+       if (ctx->auth_info.flavor_len >= 1)
+               ctx->selected_flavor = ctx->auth_info.flavors[0];
        else
-               data->selected_flavor = RPC_AUTH_UNIX;
+               ctx->selected_flavor = RPC_AUTH_UNIX;
 
        /* Get a client record */
        error = nfs4_set_client(server,
-                       data->nfs_server.hostname,
-                       (const struct sockaddr *)&data->nfs_server.address,
-                       data->nfs_server.addrlen,
-                       data->client_address,
-                       data->nfs_server.protocol,
-                       &timeparms,
-                       data->minorversion,
-                       data->nfs_server.nconnect,
-                       data->net);
+                               ctx->nfs_server.hostname,
+                               &ctx->nfs_server.address,
+                               ctx->nfs_server.addrlen,
+                               ctx->client_address,
+                               ctx->nfs_server.protocol,
+                               &timeparms,
+                               ctx->minorversion,
+                               ctx->nfs_server.nconnect,
+                               fc->net_ns);
        if (error < 0)
                return error;
 
-       if (data->rsize)
-               server->rsize = nfs_block_size(data->rsize, NULL);
-       if (data->wsize)
-               server->wsize = nfs_block_size(data->wsize, NULL);
+       if (ctx->rsize)
+               server->rsize = nfs_block_size(ctx->rsize, NULL);
+       if (ctx->wsize)
+               server->wsize = nfs_block_size(ctx->wsize, NULL);
 
-       server->acregmin = data->acregmin * HZ;
-       server->acregmax = data->acregmax * HZ;
-       server->acdirmin = data->acdirmin * HZ;
-       server->acdirmax = data->acdirmax * HZ;
-       server->port     = data->nfs_server.port;
+       server->acregmin = ctx->acregmin * HZ;
+       server->acregmax = ctx->acregmax * HZ;
+       server->acdirmin = ctx->acdirmin * HZ;
+       server->acdirmax = ctx->acdirmax * HZ;
+       server->port     = ctx->nfs_server.port;
 
        return nfs_init_server_rpcclient(server, &timeparms,
-                                        data->selected_flavor);
+                                        ctx->selected_flavor);
 }
 
 /*
  * Create a version 4 volume record
  * - keyed on server and FSID
  */
-/*struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
-                                     struct nfs_fh *mntfh)*/
-struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
-                                     struct nfs_subversion *nfs_mod)
+struct nfs_server *nfs4_create_server(struct fs_context *fc)
 {
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
        struct nfs_server *server;
        bool auth_probe;
        int error;
@@ -1125,14 +1123,14 @@ struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
 
        server->cred = get_cred(current_cred());
 
-       auth_probe = mount_info->parsed->auth_info.flavor_len < 1;
+       auth_probe = ctx->auth_info.flavor_len < 1;
 
        /* set up the general RPC client */
-       error = nfs4_init_server(server, mount_info->parsed);
+       error = nfs4_init_server(server, fc);
        if (error < 0)
                goto error;
 
-       error = nfs4_server_common_setup(server, mount_info->mntfh, auth_probe);
+       error = nfs4_server_common_setup(server, ctx->mntfh, auth_probe);
        if (error < 0)
                goto error;
 
@@ -1146,9 +1144,9 @@ error:
 /*
  * Create an NFS4 referral server record
  */
-struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
-                                              struct nfs_fh *mntfh)
+struct nfs_server *nfs4_create_referral_server(struct fs_context *fc)
 {
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
        struct nfs_client *parent_client;
        struct nfs_server *server, *parent_server;
        bool auth_probe;
@@ -1158,7 +1156,7 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
        if (!server)
                return ERR_PTR(-ENOMEM);
 
-       parent_server = NFS_SB(data->sb);
+       parent_server = NFS_SB(ctx->clone_data.sb);
        parent_client = parent_server->nfs_client;
 
        server->cred = get_cred(parent_server->cred);
@@ -1168,10 +1166,11 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 
        /* Get a client representation */
 #if IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA)
-       rpc_set_port(data->addr, NFS_RDMA_PORT);
-       error = nfs4_set_client(server, data->hostname,
-                               data->addr,
-                               data->addrlen,
+       rpc_set_port(&ctx->nfs_server.address, NFS_RDMA_PORT);
+       error = nfs4_set_client(server,
+                               ctx->nfs_server.hostname,
+                               &ctx->nfs_server.address,
+                               ctx->nfs_server.addrlen,
                                parent_client->cl_ipaddr,
                                XPRT_TRANSPORT_RDMA,
                                parent_server->client->cl_timeout,
@@ -1182,10 +1181,11 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
                goto init_server;
 #endif /* IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA) */
 
-       rpc_set_port(data->addr, NFS_PORT);
-       error = nfs4_set_client(server, data->hostname,
-                               data->addr,
-                               data->addrlen,
+       rpc_set_port(&ctx->nfs_server.address, NFS_PORT);
+       error = nfs4_set_client(server,
+                               ctx->nfs_server.hostname,
+                               &ctx->nfs_server.address,
+                               ctx->nfs_server.addrlen,
                                parent_client->cl_ipaddr,
                                XPRT_TRANSPORT_TCP,
                                parent_server->client->cl_timeout,
@@ -1198,13 +1198,14 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data,
 #if IS_ENABLED(CONFIG_SUNRPC_XPRT_RDMA)
 init_server:
 #endif
-       error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor);
+       error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout,
+                                         ctx->selected_flavor);
        if (error < 0)
                goto error;
 
        auth_probe = parent_server->auth_info.flavor_len < 1;
 
-       error = nfs4_server_common_setup(server, mntfh, auth_probe);
+       error = nfs4_server_common_setup(server, ctx->mntfh, auth_probe);
        if (error < 0)
                goto error;
 
index 620de90..be4eb72 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/fs.h>
 #include <linux/file.h>
 #include <linux/falloc.h>
+#include <linux/mount.h>
 #include <linux/nfs_fs.h>
 #include "delegation.h"
 #include "internal.h"
index 2e460c3..84026e7 100644 (file)
@@ -8,6 +8,7 @@
  * NFSv4 namespace
  */
 
+#include <linux/module.h>
 #include <linux/dcache.h>
 #include <linux/mount.h>
 #include <linux/namei.h>
 #include <linux/inet.h>
 #include "internal.h"
 #include "nfs4_fs.h"
+#include "nfs.h"
 #include "dns_resolve.h"
 
 #define NFSDBG_FACILITY                NFSDBG_VFS
 
 /*
+ * Work out the length that an NFSv4 path would render to as a standard posix
+ * path, with a leading slash but no terminating slash.
+ */
+static ssize_t nfs4_pathname_len(const struct nfs4_pathname *pathname)
+{
+       ssize_t len = 0;
+       int i;
+
+       for (i = 0; i < pathname->ncomponents; i++) {
+               const struct nfs4_string *component = &pathname->components[i];
+
+               if (component->len > NAME_MAX)
+                       goto too_long;
+               len += 1 + component->len; /* Adding "/foo" */
+               if (len > PATH_MAX)
+                       goto too_long;
+       }
+       return len;
+
+too_long:
+       return -ENAMETOOLONG;
+}
+
+/*
  * Convert the NFSv4 pathname components into a standard posix path.
- *
- * Note that the resulting string will be placed at the end of the buffer
  */
-static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname,
-                                        char *buffer, ssize_t buflen)
+static char *nfs4_pathname_string(const struct nfs4_pathname *pathname,
+                                 unsigned short *_len)
 {
-       char *end = buffer + buflen;
-       int n;
+       ssize_t len;
+       char *buf, *p;
+       int i;
+
+       len = nfs4_pathname_len(pathname);
+       if (len < 0)
+               return ERR_PTR(len);
+       *_len = len;
+
+       p = buf = kmalloc(len + 1, GFP_KERNEL);
+       if (!buf)
+               return ERR_PTR(-ENOMEM);
+
+       for (i = 0; i < pathname->ncomponents; i++) {
+               const struct nfs4_string *component = &pathname->components[i];
 
-       *--end = '\0';
-       buflen--;
-
-       n = pathname->ncomponents;
-       while (--n >= 0) {
-               const struct nfs4_string *component = &pathname->components[n];
-               buflen -= component->len + 1;
-               if (buflen < 0)
-                       goto Elong;
-               end -= component->len;
-               memcpy(end, component->data, component->len);
-               *--end = '/';
+               *p++ = '/';
+               memcpy(p, component->data, component->len);
+               p += component->len;
        }
-       return end;
-Elong:
-       return ERR_PTR(-ENAMETOOLONG);
+
+       *p = 0;
+       return buf;
 }
 
 /*
@@ -100,21 +128,36 @@ static char *nfs4_path(struct dentry *dentry, char *buffer, ssize_t buflen)
  */
 static int nfs4_validate_fspath(struct dentry *dentry,
                                const struct nfs4_fs_locations *locations,
-                               char *page, char *page2)
+                               struct nfs_fs_context *ctx)
 {
-       const char *path, *fs_path;
+       const char *path;
+       char *fs_path;
+       unsigned short len;
+       char *buf;
+       int n;
 
-       path = nfs4_path(dentry, page, PAGE_SIZE);
-       if (IS_ERR(path))
+       buf = kmalloc(4096, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       path = nfs4_path(dentry, buf, 4096);
+       if (IS_ERR(path)) {
+               kfree(buf);
                return PTR_ERR(path);
+       }
 
-       fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE);
-       if (IS_ERR(fs_path))
+       fs_path = nfs4_pathname_string(&locations->fs_path, &len);
+       if (IS_ERR(fs_path)) {
+               kfree(buf);
                return PTR_ERR(fs_path);
+       }
 
-       if (strncmp(path, fs_path, strlen(fs_path)) != 0) {
+       n = strncmp(path, fs_path, len);
+       kfree(buf);
+       kfree(fs_path);
+       if (n != 0) {
                dprintk("%s: path %s does not begin with fsroot %s\n",
-                       __func__, path, fs_path);
+                       __func__, path, ctx->nfs_server.export_path);
                return -ENOENT;
        }
 
@@ -236,55 +279,77 @@ out:
        return new;
 }
 
-static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
-                                    char *page, char *page2,
-                                    const struct nfs4_fs_location *location)
+static int try_location(struct fs_context *fc,
+                       const struct nfs4_fs_location *location)
 {
-       const size_t addr_bufsize = sizeof(struct sockaddr_storage);
-       struct net *net = rpc_net_ns(NFS_SB(mountdata->sb)->client);
-       struct vfsmount *mnt = ERR_PTR(-ENOENT);
-       char *mnt_path;
-       unsigned int maxbuflen;
-       unsigned int s;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       unsigned int len, s;
+       char *export_path, *source, *p;
+       int ret = -ENOENT;
+
+       /* Allocate a buffer big enough to hold any of the hostnames plus a
+        * terminating char and also a buffer big enough to hold the hostname
+        * plus a colon plus the path.
+        */
+       len = 0;
+       for (s = 0; s < location->nservers; s++) {
+               const struct nfs4_string *buf = &location->servers[s];
+               if (buf->len > len)
+                       len = buf->len;
+       }
 
-       mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
-       if (IS_ERR(mnt_path))
-               return ERR_CAST(mnt_path);
-       mountdata->mnt_path = mnt_path;
-       maxbuflen = mnt_path - 1 - page2;
+       kfree(ctx->nfs_server.hostname);
+       ctx->nfs_server.hostname = kmalloc(len + 1, GFP_KERNEL);
+       if (!ctx->nfs_server.hostname)
+               return -ENOMEM;
 
-       mountdata->addr = kmalloc(addr_bufsize, GFP_KERNEL);
-       if (mountdata->addr == NULL)
-               return ERR_PTR(-ENOMEM);
+       export_path = nfs4_pathname_string(&location->rootpath,
+                                          &ctx->nfs_server.export_path_len);
+       if (IS_ERR(export_path))
+               return PTR_ERR(export_path);
+
+       ctx->nfs_server.export_path = export_path;
+
+       source = kmalloc(len + 1 + ctx->nfs_server.export_path_len + 1,
+                        GFP_KERNEL);
+       if (!source)
+               return -ENOMEM;
 
+       kfree(fc->source);
+       fc->source = source;
        for (s = 0; s < location->nservers; s++) {
                const struct nfs4_string *buf = &location->servers[s];
 
-               if (buf->len <= 0 || buf->len >= maxbuflen)
-                       continue;
-
                if (memchr(buf->data, IPV6_SCOPE_DELIMITER, buf->len))
                        continue;
 
-               mountdata->addrlen = nfs_parse_server_name(buf->data, buf->len,
-                               mountdata->addr, addr_bufsize, net);
-               if (mountdata->addrlen == 0)
+               ctx->nfs_server.addrlen =
+                       nfs_parse_server_name(buf->data, buf->len,
+                                             &ctx->nfs_server.address,
+                                             sizeof(ctx->nfs_server._address),
+                                             fc->net_ns);
+               if (ctx->nfs_server.addrlen == 0)
                        continue;
 
-               memcpy(page2, buf->data, buf->len);
-               page2[buf->len] = '\0';
-               mountdata->hostname = page2;
+               rpc_set_port(&ctx->nfs_server.address, NFS_PORT);
 
-               snprintf(page, PAGE_SIZE, "%s:%s",
-                               mountdata->hostname,
-                               mountdata->mnt_path);
+               memcpy(ctx->nfs_server.hostname, buf->data, buf->len);
+               ctx->nfs_server.hostname[buf->len] = '\0';
 
-               mnt = vfs_submount(mountdata->dentry, &nfs4_referral_fs_type, page, mountdata);
-               if (!IS_ERR(mnt))
-                       break;
+               p = source;
+               memcpy(p, buf->data, buf->len);
+               p += buf->len;
+               *p++ = ':';
+               memcpy(p, ctx->nfs_server.export_path, ctx->nfs_server.export_path_len);
+               p += ctx->nfs_server.export_path_len;
+               *p = 0;
+
+               ret = nfs4_get_referral_tree(fc);
+               if (ret == 0)
+                       return 0;
        }
-       kfree(mountdata->addr);
-       return mnt;
+
+       return ret;
 }
 
 /**
@@ -293,38 +358,23 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata,
  * @locations: array of NFSv4 server location information
  *
  */
-static struct vfsmount *nfs_follow_referral(struct dentry *dentry,
-                                           const struct nfs4_fs_locations *locations)
+static int nfs_follow_referral(struct fs_context *fc,
+                              const struct nfs4_fs_locations *locations)
 {
-       struct vfsmount *mnt = ERR_PTR(-ENOENT);
-       struct nfs_clone_mount mountdata = {
-               .sb = dentry->d_sb,
-               .dentry = dentry,
-               .authflavor = NFS_SB(dentry->d_sb)->client->cl_auth->au_flavor,
-       };
-       char *page = NULL, *page2 = NULL;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
        int loc, error;
 
        if (locations == NULL || locations->nlocations <= 0)
-               goto out;
-
-       dprintk("%s: referral at %pd2\n", __func__, dentry);
-
-       page = (char *) __get_free_page(GFP_USER);
-       if (!page)
-               goto out;
+               return -ENOENT;
 
-       page2 = (char *) __get_free_page(GFP_USER);
-       if (!page2)
-               goto out;
+       dprintk("%s: referral at %pd2\n", __func__, ctx->clone_data.dentry);
 
        /* Ensure fs path is a prefix of current dentry path */
-       error = nfs4_validate_fspath(dentry, locations, page, page2);
-       if (error < 0) {
-               mnt = ERR_PTR(error);
-               goto out;
-       }
+       error = nfs4_validate_fspath(ctx->clone_data.dentry, locations, ctx);
+       if (error < 0)
+               return error;
 
+       error = -ENOENT;
        for (loc = 0; loc < locations->nlocations; loc++) {
                const struct nfs4_fs_location *location = &locations->locations[loc];
 
@@ -332,15 +382,12 @@ static struct vfsmount *nfs_follow_referral(struct dentry *dentry,
                    location->rootpath.ncomponents == 0)
                        continue;
 
-               mnt = try_location(&mountdata, page, page2, location);
-               if (!IS_ERR(mnt))
-                       break;
+               error = try_location(fc, location);
+               if (error == 0)
+                       return 0;
        }
 
-out:
-       free_page((unsigned long) page);
-       free_page((unsigned long) page2);
-       return mnt;
+       return error;
 }
 
 /*
@@ -348,71 +395,72 @@ out:
  * @dentry - dentry of referral
  *
  */
-static struct vfsmount *nfs_do_refmount(struct rpc_clnt *client, struct dentry *dentry)
+static int nfs_do_refmount(struct fs_context *fc, struct rpc_clnt *client)
 {
-       struct vfsmount *mnt = ERR_PTR(-ENOMEM);
-       struct dentry *parent;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct dentry *dentry, *parent;
        struct nfs4_fs_locations *fs_locations = NULL;
        struct page *page;
-       int err;
+       int err = -ENOMEM;
 
        /* BUG_ON(IS_ROOT(dentry)); */
        page = alloc_page(GFP_KERNEL);
-       if (page == NULL)
-               return mnt;
+       if (!page)
+               return -ENOMEM;
 
        fs_locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
-       if (fs_locations == NULL)
+       if (!fs_locations)
                goto out_free;
 
        /* Get locations */
-       mnt = ERR_PTR(-ENOENT);
-
+       dentry = ctx->clone_data.dentry;
        parent = dget_parent(dentry);
        dprintk("%s: getting locations for %pd2\n",
                __func__, dentry);
 
        err = nfs4_proc_fs_locations(client, d_inode(parent), &dentry->d_name, fs_locations, page);
        dput(parent);
-       if (err != 0 ||
-           fs_locations->nlocations <= 0 ||
+       if (err != 0)
+               goto out_free_2;
+
+       err = -ENOENT;
+       if (fs_locations->nlocations <= 0 ||
            fs_locations->fs_path.ncomponents <= 0)
-               goto out_free;
+               goto out_free_2;
 
-       mnt = nfs_follow_referral(dentry, fs_locations);
+       err = nfs_follow_referral(fc, fs_locations);
+out_free_2:
+       kfree(fs_locations);
 out_free:
        __free_page(page);
-       kfree(fs_locations);
-       return mnt;
+       return err;
 }
 
-struct vfsmount *nfs4_submount(struct nfs_server *server, struct dentry *dentry,
-                              struct nfs_fh *fh, struct nfs_fattr *fattr)
+int nfs4_submount(struct fs_context *fc, struct nfs_server *server)
 {
-       rpc_authflavor_t flavor = server->client->cl_auth->au_flavor;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct dentry *dentry = ctx->clone_data.dentry;
        struct dentry *parent = dget_parent(dentry);
        struct inode *dir = d_inode(parent);
-       const struct qstr *name = &dentry->d_name;
        struct rpc_clnt *client;
-       struct vfsmount *mnt;
+       int ret;
 
        /* Look it up again to get its attributes and sec flavor */
-       client = nfs4_proc_lookup_mountpoint(dir, name, fh, fattr);
+       client = nfs4_proc_lookup_mountpoint(dir, dentry, ctx->mntfh,
+                                            ctx->clone_data.fattr);
        dput(parent);
        if (IS_ERR(client))
-               return ERR_CAST(client);
+               return PTR_ERR(client);
 
-       if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
-               mnt = nfs_do_refmount(client, dentry);
-               goto out;
+       ctx->selected_flavor = client->cl_auth->au_flavor;
+       if (ctx->clone_data.fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) {
+               ret = nfs_do_refmount(fc, client);
+       } else {
+               ret = nfs_do_submount(fc);
        }
 
-       if (client->cl_auth->au_flavor != flavor)
-               flavor = client->cl_auth->au_flavor;
-       mnt = nfs_do_submount(dentry, fh, fattr, flavor);
-out:
        rpc_shutdown_client(client);
-       return mnt;
+       return ret;
 }
 
 /*
@@ -453,7 +501,7 @@ static int nfs4_try_replacing_one_location(struct nfs_server *server,
                rpc_set_port(sap, NFS_PORT);
 
                error = -ENOMEM;
-               hostname = kstrndup(buf->data, buf->len, GFP_KERNEL);
+               hostname = kmemdup_nul(buf->data, buf->len, GFP_KERNEL);
                if (hostname == NULL)
                        break;
 
index 76d3716..95d07a3 100644 (file)
@@ -1097,11 +1097,12 @@ static int nfs4_call_sync_custom(struct rpc_task_setup *task_setup)
        return ret;
 }
 
-static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
-                                  struct nfs_server *server,
-                                  struct rpc_message *msg,
-                                  struct nfs4_sequence_args *args,
-                                  struct nfs4_sequence_res *res)
+static int nfs4_do_call_sync(struct rpc_clnt *clnt,
+                            struct nfs_server *server,
+                            struct rpc_message *msg,
+                            struct nfs4_sequence_args *args,
+                            struct nfs4_sequence_res *res,
+                            unsigned short task_flags)
 {
        struct nfs_client *clp = server->nfs_client;
        struct nfs4_call_sync_data data = {
@@ -1113,12 +1114,23 @@ static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
                .rpc_client = clnt,
                .rpc_message = msg,
                .callback_ops = clp->cl_mvops->call_sync_ops,
-               .callback_data = &data
+               .callback_data = &data,
+               .flags = task_flags,
        };
 
        return nfs4_call_sync_custom(&task_setup);
 }
 
+static int nfs4_call_sync_sequence(struct rpc_clnt *clnt,
+                                  struct nfs_server *server,
+                                  struct rpc_message *msg,
+                                  struct nfs4_sequence_args *args,
+                                  struct nfs4_sequence_res *res)
+{
+       return nfs4_do_call_sync(clnt, server, msg, args, res, 0);
+}
+
+
 int nfs4_call_sync(struct rpc_clnt *clnt,
                   struct nfs_server *server,
                   struct rpc_message *msg,
@@ -3187,6 +3199,11 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir,
                        exception.retry = 1;
                        continue;
                }
+               if (status == -NFS4ERR_EXPIRED) {
+                       nfs4_schedule_lease_recovery(server->nfs_client);
+                       exception.retry = 1;
+                       continue;
+               }
                if (status == -EAGAIN) {
                        /* We must have found a delegation */
                        exception.retry = 1;
@@ -3239,6 +3256,8 @@ static int _nfs4_do_setattr(struct inode *inode,
                nfs_put_lock_context(l_ctx);
                if (status == -EIO)
                        return -EBADF;
+               else if (status == -EAGAIN)
+                       goto zero_stateid;
        } else {
 zero_stateid:
                nfs4_stateid_copy(&arg->stateid, &zero_stateid);
@@ -4064,11 +4083,18 @@ static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        nfs4_bitmap_copy_adjust(bitmask, nfs4_bitmask(server, label), inode);
 
        nfs_fattr_init(fattr);
-       return nfs4_call_sync(server->client, server, &msg, &args.seq_args, &res.seq_res, 0);
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
+       return nfs4_do_call_sync(server->client, server, &msg,
+                       &args.seq_args, &res.seq_res, task_flags);
 }
 
 int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
@@ -4156,7 +4182,7 @@ nfs4_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 }
 
 static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
-               const struct qstr *name, struct nfs_fh *fhandle,
+               struct dentry *dentry, struct nfs_fh *fhandle,
                struct nfs_fattr *fattr, struct nfs4_label *label)
 {
        struct nfs_server *server = NFS_SERVER(dir);
@@ -4164,7 +4190,7 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
        struct nfs4_lookup_arg args = {
                .bitmask = server->attr_bitmask,
                .dir_fh = NFS_FH(dir),
-               .name = name,
+               .name = &dentry->d_name,
        };
        struct nfs4_lookup_res res = {
                .server = server,
@@ -4177,13 +4203,20 @@ static int _nfs4_proc_lookup(struct rpc_clnt *clnt, struct inode *dir,
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (nfs_lookup_is_soft_revalidate(dentry))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        args.bitmask = nfs4_bitmask(server, label);
 
        nfs_fattr_init(fattr);
 
-       dprintk("NFS call  lookup %s\n", name->name);
-       status = nfs4_call_sync(clnt, server, &msg, &args.seq_args, &res.seq_res, 0);
+       dprintk("NFS call  lookup %pd2\n", dentry);
+       nfs4_init_sequence(&args.seq_args, &res.seq_res, 0, 0);
+       status = nfs4_do_call_sync(clnt, server, &msg,
+                       &args.seq_args, &res.seq_res, task_flags);
        dprintk("NFS reply lookup: %d\n", status);
        return status;
 }
@@ -4197,16 +4230,17 @@ static void nfs_fixup_secinfo_attributes(struct nfs_fattr *fattr)
 }
 
 static int nfs4_proc_lookup_common(struct rpc_clnt **clnt, struct inode *dir,
-                                  const struct qstr *name, struct nfs_fh *fhandle,
+                                  struct dentry *dentry, struct nfs_fh *fhandle,
                                   struct nfs_fattr *fattr, struct nfs4_label *label)
 {
        struct nfs4_exception exception = {
                .interruptible = true,
        };
        struct rpc_clnt *client = *clnt;
+       const struct qstr *name = &dentry->d_name;
        int err;
        do {
-               err = _nfs4_proc_lookup(client, dir, name, fhandle, fattr, label);
+               err = _nfs4_proc_lookup(client, dir, dentry, fhandle, fattr, label);
                trace_nfs4_lookup(dir, name, err);
                switch (err) {
                case -NFS4ERR_BADNAME:
@@ -4241,14 +4275,14 @@ out:
        return err;
 }
 
-static int nfs4_proc_lookup(struct inode *dir, const struct qstr *name,
+static int nfs4_proc_lookup(struct inode *dir, struct dentry *dentry,
                            struct nfs_fh *fhandle, struct nfs_fattr *fattr,
                            struct nfs4_label *label)
 {
        int status;
        struct rpc_clnt *client = NFS_CLIENT(dir);
 
-       status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, label);
+       status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, label);
        if (client != NFS_CLIENT(dir)) {
                rpc_shutdown_client(client);
                nfs_fixup_secinfo_attributes(fattr);
@@ -4257,13 +4291,13 @@ static int nfs4_proc_lookup(struct inode *dir, const struct qstr *name,
 }
 
 struct rpc_clnt *
-nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name,
+nfs4_proc_lookup_mountpoint(struct inode *dir, struct dentry *dentry,
                            struct nfs_fh *fhandle, struct nfs_fattr *fattr)
 {
        struct rpc_clnt *client = NFS_CLIENT(dir);
        int status;
 
-       status = nfs4_proc_lookup_common(&client, dir, name, fhandle, fattr, NULL);
+       status = nfs4_proc_lookup_common(&client, dir, dentry, fhandle, fattr, NULL);
        if (status < 0)
                return ERR_PTR(status);
        return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
@@ -5019,16 +5053,13 @@ static int nfs4_do_fsinfo(struct nfs_server *server, struct nfs_fh *fhandle, str
        struct nfs4_exception exception = {
                .interruptible = true,
        };
-       unsigned long now = jiffies;
        int err;
 
        do {
                err = _nfs4_do_fsinfo(server, fhandle, fsinfo);
                trace_nfs4_fsinfo(server, fhandle, fsinfo->fattr, err);
                if (err == 0) {
-                       nfs4_set_lease_period(server->nfs_client,
-                                       fsinfo->lease_time * HZ,
-                                       now);
+                       nfs4_set_lease_period(server->nfs_client, fsinfo->lease_time * HZ);
                        break;
                }
                err = nfs4_handle_exception(server, err, &exception);
@@ -5582,10 +5613,9 @@ out:
  */
 static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t buflen)
 {
-       struct page *pages[NFS4ACL_MAXPAGES + 1] = {NULL, };
+       struct page **pages;
        struct nfs_getaclargs args = {
                .fh = NFS_FH(inode),
-               .acl_pages = pages,
                .acl_len = buflen,
        };
        struct nfs_getaclres res = {
@@ -5596,11 +5626,19 @@ static ssize_t __nfs4_get_acl_uncached(struct inode *inode, void *buf, size_t bu
                .rpc_argp = &args,
                .rpc_resp = &res,
        };
-       unsigned int npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
+       unsigned int npages;
        int ret = -ENOMEM, i;
+       struct nfs_server *server = NFS_SERVER(inode);
 
-       if (npages > ARRAY_SIZE(pages))
-               return -ERANGE;
+       if (buflen == 0)
+               buflen = server->rsize;
+
+       npages = DIV_ROUND_UP(buflen, PAGE_SIZE) + 1;
+       pages = kmalloc_array(npages, sizeof(struct page *), GFP_NOFS);
+       if (!pages)
+               return -ENOMEM;
+
+       args.acl_pages = pages;
 
        for (i = 0; i < npages; i++) {
                pages[i] = alloc_page(GFP_KERNEL);
@@ -5646,6 +5684,7 @@ out_free:
                        __free_page(pages[i]);
        if (res.acl_scratch)
                __free_page(res.acl_scratch);
+       kfree(pages);
        return ret;
 }
 
@@ -6084,6 +6123,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
                .callback_data = &setclientid,
                .flags = RPC_TASK_TIMEOUT | RPC_TASK_NO_ROUND_ROBIN,
        };
+       unsigned long now = jiffies;
        int status;
 
        /* nfs_client_id4 */
@@ -6116,6 +6156,9 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
                clp->cl_acceptor = rpcauth_stringify_acceptor(setclientid.sc_cred);
                put_rpccred(setclientid.sc_cred);
        }
+
+       if (status == 0)
+               do_renew_lease(clp, now);
 out:
        trace_nfs4_setclientid(clp, status);
        dprintk("NFS reply setclientid: %d\n", status);
@@ -6859,7 +6902,7 @@ static void nfs4_handle_setlk_error(struct nfs_server *server, struct nfs4_lock_
        case -NFS4ERR_STALE_STATEID:
                lsp->ls_seqid.flags &= ~NFS_SEQID_CONFIRMED;
                nfs4_schedule_lease_recovery(server->nfs_client);
-       };
+       }
 }
 
 static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *fl, int recovery_type)
@@ -8203,6 +8246,7 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre
        struct rpc_task *task;
        struct nfs41_exchange_id_args *argp;
        struct nfs41_exchange_id_res *resp;
+       unsigned long now = jiffies;
        int status;
 
        task = nfs4_run_exchange_id(clp, cred, sp4_how, NULL);
@@ -8223,6 +8267,8 @@ static int _nfs4_proc_exchange_id(struct nfs_client *clp, const struct cred *cre
        if (status != 0)
                goto out;
 
+       do_renew_lease(clp, now);
+
        clp->cl_clientid = resp->clientid;
        clp->cl_exchange_flags = resp->flags;
        clp->cl_seqid = resp->seqid;
@@ -8626,7 +8672,7 @@ static int _nfs4_proc_create_session(struct nfs_client *clp,
        case -EACCES:
        case -EAGAIN:
                goto out;
-       };
+       }
 
        clp->cl_seqid++;
        if (!status) {
@@ -10001,7 +10047,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
        .file_ops       = &nfs4_file_operations,
        .getroot        = nfs4_proc_get_root,
        .submount       = nfs4_submount,
-       .try_mount      = nfs4_try_mount,
+       .try_get_tree   = nfs4_try_get_tree,
        .getattr        = nfs4_proc_getattr,
        .setattr        = nfs4_proc_setattr,
        .lookup         = nfs4_proc_lookup,
index 6ea431b..ff876dd 100644 (file)
@@ -138,15 +138,12 @@ nfs4_kill_renewd(struct nfs_client *clp)
  *
  * @clp: pointer to nfs_client
  * @lease: new value for lease period
- * @lastrenewed: time at which lease was last renewed
  */
 void nfs4_set_lease_period(struct nfs_client *clp,
-               unsigned long lease,
-               unsigned long lastrenewed)
+               unsigned long lease)
 {
        spin_lock(&clp->cl_lock);
        clp->cl_lease_time = lease;
-       clp->cl_last_renewal = lastrenewed;
        spin_unlock(&clp->cl_lock);
 
        /* Cap maximum reconnect timeout at 1/2 lease period */
index 3455232..f7723d2 100644 (file)
@@ -92,17 +92,15 @@ static int nfs4_setup_state_renewal(struct nfs_client *clp)
 {
        int status;
        struct nfs_fsinfo fsinfo;
-       unsigned long now;
 
        if (!test_bit(NFS_CS_CHECK_LEASE_TIME, &clp->cl_res_state)) {
                nfs4_schedule_state_renewal(clp);
                return 0;
        }
 
-       now = jiffies;
        status = nfs4_proc_get_lease_time(clp, &fsinfo);
        if (status == 0) {
-               nfs4_set_lease_period(clp, fsinfo.lease_time * HZ, now);
+               nfs4_set_lease_period(clp, fsinfo.lease_time * HZ);
                nfs4_schedule_state_renewal(clp);
        }
 
@@ -766,6 +764,7 @@ void nfs4_put_open_state(struct nfs4_state *state)
        list_del(&state->open_states);
        spin_unlock(&inode->i_lock);
        spin_unlock(&owner->so_lock);
+       nfs4_inode_return_delegation_on_close(inode);
        iput(inode);
        nfs4_free_open_state(state);
        nfs4_put_state_owner(owner);
@@ -1135,7 +1134,7 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
                case -NFS4ERR_MOVED:
                        /* Non-seqid mutating errors */
                        return;
-       };
+       }
        /*
         * Note: no locking needed as we are guaranteed to be first
         * on the sequence list
index 2c9cbad..1475f93 100644 (file)
@@ -4,6 +4,7 @@
  */
 #include <linux/init.h>
 #include <linux/module.h>
+#include <linux/mount.h>
 #include <linux/nfs4_mount.h>
 #include <linux/nfs_fs.h>
 #include "delegation.h"
 
 static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc);
 static void nfs4_evict_inode(struct inode *inode);
-static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data);
-static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data);
-static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data);
-
-static struct file_system_type nfs4_remote_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "nfs4",
-       .mount          = nfs4_remote_mount,
-       .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
-};
-
-static struct file_system_type nfs4_remote_referral_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "nfs4",
-       .mount          = nfs4_remote_referral_mount,
-       .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
-};
-
-struct file_system_type nfs4_referral_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "nfs4",
-       .mount          = nfs4_referral_mount,
-       .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
-};
 
 static const struct super_operations nfs4_sops = {
        .alloc_inode    = nfs_alloc_inode,
@@ -61,16 +32,15 @@ static const struct super_operations nfs4_sops = {
        .show_devname   = nfs_show_devname,
        .show_path      = nfs_show_path,
        .show_stats     = nfs_show_stats,
-       .remount_fs     = nfs_remount,
 };
 
 struct nfs_subversion nfs_v4 = {
-       .owner = THIS_MODULE,
-       .nfs_fs   = &nfs4_fs_type,
-       .rpc_vers = &nfs_version4,
-       .rpc_ops  = &nfs_v4_clientops,
-       .sops     = &nfs4_sops,
-       .xattr    = nfs4_xattr_handlers,
+       .owner          = THIS_MODULE,
+       .nfs_fs         = &nfs4_fs_type,
+       .rpc_vers       = &nfs_version4,
+       .rpc_ops        = &nfs_v4_clientops,
+       .sops           = &nfs4_sops,
+       .xattr          = nfs4_xattr_handlers,
 };
 
 static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
@@ -101,53 +71,6 @@ static void nfs4_evict_inode(struct inode *inode)
        nfs_clear_inode(inode);
 }
 
-/*
- * Get the superblock for the NFS4 root partition
- */
-static struct dentry *
-nfs4_remote_mount(struct file_system_type *fs_type, int flags,
-                 const char *dev_name, void *info)
-{
-       struct nfs_mount_info *mount_info = info;
-       struct nfs_server *server;
-       struct dentry *mntroot = ERR_PTR(-ENOMEM);
-
-       mount_info->set_security = nfs_set_sb_security;
-
-       /* Get a volume representation */
-       server = nfs4_create_server(mount_info, &nfs_v4);
-       if (IS_ERR(server)) {
-               mntroot = ERR_CAST(server);
-               goto out;
-       }
-
-       mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4);
-
-out:
-       return mntroot;
-}
-
-static struct vfsmount *nfs_do_root_mount(struct file_system_type *fs_type,
-               int flags, void *data, const char *hostname)
-{
-       struct vfsmount *root_mnt;
-       char *root_devname;
-       size_t len;
-
-       len = strlen(hostname) + 5;
-       root_devname = kmalloc(len, GFP_KERNEL);
-       if (root_devname == NULL)
-               return ERR_PTR(-ENOMEM);
-       /* Does hostname needs to be enclosed in brackets? */
-       if (strchr(hostname, ':'))
-               snprintf(root_devname, len, "[%s]:/", hostname);
-       else
-               snprintf(root_devname, len, "%s:/", hostname);
-       root_mnt = vfs_kern_mount(fs_type, flags, root_devname, data);
-       kfree(root_devname);
-       return root_mnt;
-}
-
 struct nfs_referral_count {
        struct list_head list;
        const struct task_struct *task;
@@ -214,111 +137,125 @@ static void nfs_referral_loop_unprotect(void)
        kfree(p);
 }
 
-static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
-               const char *export_path)
+static int do_nfs4_mount(struct nfs_server *server,
+                        struct fs_context *fc,
+                        const char *hostname,
+                        const char *export_path)
 {
+       struct nfs_fs_context *root_ctx;
+       struct fs_context *root_fc;
+       struct vfsmount *root_mnt;
        struct dentry *dentry;
-       int err;
+       size_t len;
+       int ret;
 
-       if (IS_ERR(root_mnt))
-               return ERR_CAST(root_mnt);
+       struct fs_parameter param = {
+               .key    = "source",
+               .type   = fs_value_is_string,
+               .dirfd  = -1,
+       };
 
-       err = nfs_referral_loop_protect();
-       if (err) {
-               mntput(root_mnt);
-               return ERR_PTR(err);
+       if (IS_ERR(server))
+               return PTR_ERR(server);
+
+       root_fc = vfs_dup_fs_context(fc);
+       if (IS_ERR(root_fc)) {
+               nfs_free_server(server);
+               return PTR_ERR(root_fc);
        }
+       kfree(root_fc->source);
+       root_fc->source = NULL;
 
-       dentry = mount_subtree(root_mnt, export_path);
-       nfs_referral_loop_unprotect();
+       root_ctx = nfs_fc2context(root_fc);
+       root_ctx->internal = true;
+       root_ctx->server = server;
+       /* We leave export_path unset as it's not used to find the root. */
 
-       return dentry;
-}
+       len = strlen(hostname) + 5;
+       param.string = kmalloc(len, GFP_KERNEL);
+       if (param.string == NULL) {
+               put_fs_context(root_fc);
+               return -ENOMEM;
+       }
 
-struct dentry *nfs4_try_mount(int flags, const char *dev_name,
-                             struct nfs_mount_info *mount_info,
-                             struct nfs_subversion *nfs_mod)
-{
-       char *export_path;
-       struct vfsmount *root_mnt;
-       struct dentry *res;
-       struct nfs_parsed_mount_data *data = mount_info->parsed;
+       /* Does hostname needs to be enclosed in brackets? */
+       if (strchr(hostname, ':'))
+               param.size = snprintf(param.string, len, "[%s]:/", hostname);
+       else
+               param.size = snprintf(param.string, len, "%s:/", hostname);
+       ret = vfs_parse_fs_param(root_fc, &param);
+       kfree(param.string);
+       if (ret < 0) {
+               put_fs_context(root_fc);
+               return ret;
+       }
+       root_mnt = fc_mount(root_fc);
+       put_fs_context(root_fc);
+
+       if (IS_ERR(root_mnt))
+               return PTR_ERR(root_mnt);
 
-       dfprintk(MOUNT, "--> nfs4_try_mount()\n");
+       ret = nfs_referral_loop_protect();
+       if (ret) {
+               mntput(root_mnt);
+               return ret;
+       }
 
-       export_path = data->nfs_server.export_path;
-       data->nfs_server.export_path = "/";
-       root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
-                       data->nfs_server.hostname);
-       data->nfs_server.export_path = export_path;
+       dentry = mount_subtree(root_mnt, export_path);
+       nfs_referral_loop_unprotect();
 
-       res = nfs_follow_remote_path(root_mnt, export_path);
+       if (IS_ERR(dentry))
+               return PTR_ERR(dentry);
 
-       dfprintk(MOUNT, "<-- nfs4_try_mount() = %d%s\n",
-                PTR_ERR_OR_ZERO(res),
-                IS_ERR(res) ? " [error]" : "");
-       return res;
+       fc->root = dentry;
+       return 0;
 }
 
-static struct dentry *
-nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
-                          const char *dev_name, void *raw_data)
+int nfs4_try_get_tree(struct fs_context *fc)
 {
-       struct nfs_mount_info mount_info = {
-               .fill_super = nfs_fill_super,
-               .set_security = nfs_clone_sb_security,
-               .cloned = raw_data,
-       };
-       struct nfs_server *server;
-       struct dentry *mntroot = ERR_PTR(-ENOMEM);
-
-       dprintk("--> nfs4_referral_get_sb()\n");
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       int err;
 
-       mount_info.mntfh = nfs_alloc_fhandle();
-       if (mount_info.cloned == NULL || mount_info.mntfh == NULL)
-               goto out;
+       dfprintk(MOUNT, "--> nfs4_try_get_tree()\n");
 
-       /* create a new volume representation */
-       server = nfs4_create_referral_server(mount_info.cloned, mount_info.mntfh);
-       if (IS_ERR(server)) {
-               mntroot = ERR_CAST(server);
-               goto out;
+       /* We create a mount for the server's root, walk to the requested
+        * location and then create another mount for that.
+        */
+       err= do_nfs4_mount(nfs4_create_server(fc),
+                          fc, ctx->nfs_server.hostname,
+                          ctx->nfs_server.export_path);
+       if (err) {
+               nfs_errorf(fc, "NFS4: Couldn't follow remote path");
+               dfprintk(MOUNT, "<-- nfs4_try_get_tree() = %d [error]\n", err);
+       } else {
+               dfprintk(MOUNT, "<-- nfs4_try_get_tree() = 0\n");
        }
-
-       mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, &nfs_v4);
-out:
-       nfs_free_fhandle(mount_info.mntfh);
-       return mntroot;
+       return err;
 }
 
 /*
  * Create an NFS4 server record on referral traversal
  */
-static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
-               int flags, const char *dev_name, void *raw_data)
+int nfs4_get_referral_tree(struct fs_context *fc)
 {
-       struct nfs_clone_mount *data = raw_data;
-       char *export_path;
-       struct vfsmount *root_mnt;
-       struct dentry *res;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       int err;
 
        dprintk("--> nfs4_referral_mount()\n");
 
-       export_path = data->mnt_path;
-       data->mnt_path = "/";
-
-       root_mnt = nfs_do_root_mount(&nfs4_remote_referral_fs_type,
-                       flags, data, data->hostname);
-       data->mnt_path = export_path;
-
-       res = nfs_follow_remote_path(root_mnt, export_path);
-       dprintk("<-- nfs4_referral_mount() = %d%s\n",
-               PTR_ERR_OR_ZERO(res),
-               IS_ERR(res) ? " [error]" : "");
-       return res;
+       /* create a new volume representation */
+       err = do_nfs4_mount(nfs4_create_referral_server(fc),
+                           fc, ctx->nfs_server.hostname,
+                           ctx->nfs_server.export_path);
+       if (err) {
+               nfs_errorf(fc, "NFS4: Couldn't follow remote path");
+               dfprintk(MOUNT, "<-- nfs4_get_referral_tree() = %d [error]\n", err);
+       } else {
+               dfprintk(MOUNT, "<-- nfs4_get_referral_tree() = 0\n");
+       }
+       return err;
 }
 
-
 static int __init init_nfs_v4(void)
 {
        int err;
index 1a8f376..d9ac556 100644 (file)
@@ -24,4 +24,8 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(pnfs_mds_fallback_read_done);
 EXPORT_TRACEPOINT_SYMBOL_GPL(pnfs_mds_fallback_write_done);
 EXPORT_TRACEPOINT_SYMBOL_GPL(pnfs_mds_fallback_read_pagelist);
 EXPORT_TRACEPOINT_SYMBOL_GPL(pnfs_mds_fallback_write_pagelist);
+
+EXPORT_TRACEPOINT_SYMBOL_GPL(ff_layout_read_error);
+EXPORT_TRACEPOINT_SYMBOL_GPL(ff_layout_write_error);
+EXPORT_TRACEPOINT_SYMBOL_GPL(ff_layout_commit_error);
 #endif
index e60b6fb..1e97e5e 100644 (file)
@@ -155,6 +155,9 @@ TRACE_DEFINE_ENUM(NFS4ERR_WRONG_CRED);
 TRACE_DEFINE_ENUM(NFS4ERR_WRONG_TYPE);
 TRACE_DEFINE_ENUM(NFS4ERR_XDEV);
 
+TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_MDS);
+TRACE_DEFINE_ENUM(NFS4ERR_RESET_TO_PNFS);
+
 #define show_nfsv4_errors(error) \
        __print_symbolic(error, \
                { NFS4_OK, "OK" }, \
@@ -305,7 +308,10 @@ TRACE_DEFINE_ENUM(NFS4ERR_XDEV);
                { NFS4ERR_WRONGSEC, "WRONGSEC" }, \
                { NFS4ERR_WRONG_CRED, "WRONG_CRED" }, \
                { NFS4ERR_WRONG_TYPE, "WRONG_TYPE" }, \
-               { NFS4ERR_XDEV, "XDEV" })
+               { NFS4ERR_XDEV, "XDEV" }, \
+               /* ***** Internal to Linux NFS client ***** */ \
+               { NFS4ERR_RESET_TO_MDS, "RESET_TO_MDS" }, \
+               { NFS4ERR_RESET_TO_PNFS, "RESET_TO_PNFS" })
 
 #define show_open_flags(flags) \
        __print_flags(flags, "|", \
@@ -352,7 +358,7 @@ DECLARE_EVENT_CLASS(nfs4_clientid_event,
                ),
 
                TP_fast_assign(
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __assign_str(dstaddr, clp->cl_hostname);
                ),
 
@@ -432,7 +438,8 @@ TRACE_EVENT(nfs4_sequence_done,
                        __entry->target_highest_slotid =
                                        res->sr_target_highest_slotid;
                        __entry->status_flags = res->sr_status_flags;
-                       __entry->error = res->sr_status;
+                       __entry->error = res->sr_status < 0 ?
+                                       -res->sr_status : 0;
                ),
                TP_printk(
                        "error=%ld (%s) session=0x%08x slot_nr=%u seq_nr=%u "
@@ -640,7 +647,7 @@ TRACE_EVENT(nfs4_state_mgr_failed,
                ),
 
                TP_fast_assign(
-                       __entry->error = status;
+                       __entry->error = status < 0 ? -status : 0;
                        __entry->state = clp->cl_state;
                        __assign_str(hostname, clp->cl_hostname);
                        __assign_str(section, section);
@@ -659,7 +666,7 @@ TRACE_EVENT(nfs4_xdr_status,
                TP_PROTO(
                        const struct xdr_stream *xdr,
                        u32 op,
-                       int error
+                       u32 error
                ),
 
                TP_ARGS(xdr, op, error),
@@ -691,6 +698,41 @@ TRACE_EVENT(nfs4_xdr_status,
                )
 );
 
+DECLARE_EVENT_CLASS(nfs4_cb_error_class,
+               TP_PROTO(
+                       __be32 xid,
+                       u32 cb_ident
+               ),
+
+               TP_ARGS(xid, cb_ident),
+
+               TP_STRUCT__entry(
+                       __field(u32, xid)
+                       __field(u32, cbident)
+               ),
+
+               TP_fast_assign(
+                       __entry->xid = be32_to_cpu(xid);
+                       __entry->cbident = cb_ident;
+               ),
+
+               TP_printk(
+                       "xid=0x%08x cb_ident=0x%08x",
+                       __entry->xid, __entry->cbident
+               )
+);
+
+#define DEFINE_CB_ERROR_EVENT(name) \
+       DEFINE_EVENT(nfs4_cb_error_class, nfs_cb_##name, \
+                       TP_PROTO( \
+                               __be32 xid, \
+                               u32 cb_ident \
+                       ), \
+                       TP_ARGS(xid, cb_ident))
+
+DEFINE_CB_ERROR_EVENT(no_clp);
+DEFINE_CB_ERROR_EVENT(badprinc);
+
 DECLARE_EVENT_CLASS(nfs4_open_event,
                TP_PROTO(
                        const struct nfs_open_context *ctx,
@@ -849,7 +891,7 @@ TRACE_EVENT(nfs4_close,
                        __entry->fileid = NFS_FILEID(inode);
                        __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
                        __entry->fmode = (__force unsigned int)state->state;
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->stateid_seq =
                                be32_to_cpu(args->stateid.seqid);
                        __entry->stateid_hash =
@@ -914,7 +956,7 @@ DECLARE_EVENT_CLASS(nfs4_lock_event,
                TP_fast_assign(
                        const struct inode *inode = state->inode;
 
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->cmd = cmd;
                        __entry->type = request->fl_type;
                        __entry->start = request->fl_start;
@@ -986,7 +1028,7 @@ TRACE_EVENT(nfs4_set_lock,
                TP_fast_assign(
                        const struct inode *inode = state->inode;
 
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->cmd = cmd;
                        __entry->type = request->fl_type;
                        __entry->start = request->fl_start;
@@ -1164,7 +1206,7 @@ TRACE_EVENT(nfs4_delegreturn_exit,
                TP_fast_assign(
                        __entry->dev = res->server->s_dev;
                        __entry->fhandle = nfs_fhandle_hash(args->fhandle);
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->stateid_seq =
                                be32_to_cpu(args->stateid->seqid);
                        __entry->stateid_hash =
@@ -1204,7 +1246,7 @@ DECLARE_EVENT_CLASS(nfs4_test_stateid_event,
                TP_fast_assign(
                        const struct inode *inode = state->inode;
 
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = NFS_FILEID(inode);
                        __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
@@ -1306,7 +1348,7 @@ TRACE_EVENT(nfs4_lookupp,
                TP_fast_assign(
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->ino = NFS_FILEID(inode);
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                ),
 
                TP_printk(
@@ -1342,7 +1384,7 @@ TRACE_EVENT(nfs4_rename,
                        __entry->dev = olddir->i_sb->s_dev;
                        __entry->olddir = NFS_FILEID(olddir);
                        __entry->newdir = NFS_FILEID(newdir);
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __assign_str(oldname, oldname->name);
                        __assign_str(newname, newname->name);
                ),
@@ -1433,7 +1475,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_event,
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = NFS_FILEID(inode);
                        __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->stateid_seq =
                                be32_to_cpu(stateid->seqid);
                        __entry->stateid_hash =
@@ -1489,7 +1531,7 @@ DECLARE_EVENT_CLASS(nfs4_getattr_event,
                        __entry->valid = fattr->valid;
                        __entry->fhandle = nfs_fhandle_hash(fhandle);
                        __entry->fileid = (fattr->valid & NFS_ATTR_FATTR_FILEID) ? fattr->fileid : 0;
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                ),
 
                TP_printk(
@@ -1536,7 +1578,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_callback_event,
                ),
 
                TP_fast_assign(
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->fhandle = nfs_fhandle_hash(fhandle);
                        if (!IS_ERR_OR_NULL(inode)) {
                                __entry->fileid = NFS_FILEID(inode);
@@ -1593,7 +1635,7 @@ DECLARE_EVENT_CLASS(nfs4_inode_stateid_callback_event,
                ),
 
                TP_fast_assign(
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->fhandle = nfs_fhandle_hash(fhandle);
                        if (!IS_ERR_OR_NULL(inode)) {
                                __entry->fileid = NFS_FILEID(inode);
@@ -1694,7 +1736,8 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
                        __field(u32, fhandle)
                        __field(u64, fileid)
                        __field(loff_t, offset)
-                       __field(size_t, count)
+                       __field(u32, arg_count)
+                       __field(u32, res_count)
                        __field(unsigned long, error)
                        __field(int, stateid_seq)
                        __field(u32, stateid_hash)
@@ -1702,13 +1745,18 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
 
                TP_fast_assign(
                        const struct inode *inode = hdr->inode;
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = hdr->args.fh ?
+                                                 hdr->args.fh : &nfsi->fh;
                        const struct nfs4_state *state =
                                hdr->args.context->state;
+
                        __entry->dev = inode->i_sb->s_dev;
-                       __entry->fileid = NFS_FILEID(inode);
-                       __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                        __entry->offset = hdr->args.offset;
-                       __entry->count = hdr->args.count;
+                       __entry->arg_count = hdr->args.count;
+                       __entry->res_count = hdr->res.count;
                        __entry->error = error < 0 ? -error : 0;
                        __entry->stateid_seq =
                                be32_to_cpu(state->stateid.seqid);
@@ -1718,14 +1766,14 @@ DECLARE_EVENT_CLASS(nfs4_read_event,
 
                TP_printk(
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%zu stateid=%d:0x%08x",
+                       "offset=%lld count=%u res=%u stateid=%d:0x%08x",
                        -__entry->error,
                        show_nfsv4_errors(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
                        (long long)__entry->offset,
-                       __entry->count,
+                       __entry->arg_count, __entry->res_count,
                        __entry->stateid_seq, __entry->stateid_hash
                )
 );
@@ -1754,7 +1802,8 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
                        __field(u32, fhandle)
                        __field(u64, fileid)
                        __field(loff_t, offset)
-                       __field(size_t, count)
+                       __field(u32, arg_count)
+                       __field(u32, res_count)
                        __field(unsigned long, error)
                        __field(int, stateid_seq)
                        __field(u32, stateid_hash)
@@ -1762,13 +1811,18 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
 
                TP_fast_assign(
                        const struct inode *inode = hdr->inode;
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = hdr->args.fh ?
+                                                 hdr->args.fh : &nfsi->fh;
                        const struct nfs4_state *state =
                                hdr->args.context->state;
+
                        __entry->dev = inode->i_sb->s_dev;
-                       __entry->fileid = NFS_FILEID(inode);
-                       __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                        __entry->offset = hdr->args.offset;
-                       __entry->count = hdr->args.count;
+                       __entry->arg_count = hdr->args.count;
+                       __entry->res_count = hdr->res.count;
                        __entry->error = error < 0 ? -error : 0;
                        __entry->stateid_seq =
                                be32_to_cpu(state->stateid.seqid);
@@ -1778,14 +1832,14 @@ DECLARE_EVENT_CLASS(nfs4_write_event,
 
                TP_printk(
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%zu stateid=%d:0x%08x",
+                       "offset=%lld count=%u res=%u stateid=%d:0x%08x",
                        -__entry->error,
                        show_nfsv4_errors(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
                        (long long)__entry->offset,
-                       __entry->count,
+                       __entry->arg_count, __entry->res_count,
                        __entry->stateid_seq, __entry->stateid_hash
                )
 );
@@ -1814,24 +1868,28 @@ DECLARE_EVENT_CLASS(nfs4_commit_event,
                        __field(dev_t, dev)
                        __field(u32, fhandle)
                        __field(u64, fileid)
-                       __field(loff_t, offset)
-                       __field(size_t, count)
                        __field(unsigned long, error)
+                       __field(loff_t, offset)
+                       __field(u32, count)
                ),
 
                TP_fast_assign(
                        const struct inode *inode = data->inode;
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = data->args.fh ?
+                                                 data->args.fh : &nfsi->fh;
+
                        __entry->dev = inode->i_sb->s_dev;
-                       __entry->fileid = NFS_FILEID(inode);
-                       __entry->fhandle = nfs_fhandle_hash(NFS_FH(inode));
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                        __entry->offset = data->args.offset;
                        __entry->count = data->args.count;
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                ),
 
                TP_printk(
                        "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%zu",
+                       "offset=%lld count=%u",
                        -__entry->error,
                        show_nfsv4_errors(__entry->error),
                        MAJOR(__entry->dev), MINOR(__entry->dev),
@@ -1896,7 +1954,7 @@ TRACE_EVENT(nfs4_layoutget,
                        __entry->iomode = args->iomode;
                        __entry->offset = args->offset;
                        __entry->count = args->length;
-                       __entry->error = error;
+                       __entry->error = error < 0 ? -error : 0;
                        __entry->stateid_seq =
                                be32_to_cpu(state->stateid.seqid);
                        __entry->stateid_hash =
@@ -2094,6 +2152,115 @@ DEFINE_PNFS_LAYOUT_EVENT(pnfs_mds_fallback_write_done);
 DEFINE_PNFS_LAYOUT_EVENT(pnfs_mds_fallback_read_pagelist);
 DEFINE_PNFS_LAYOUT_EVENT(pnfs_mds_fallback_write_pagelist);
 
+DECLARE_EVENT_CLASS(nfs4_flexfiles_io_event,
+               TP_PROTO(
+                       const struct nfs_pgio_header *hdr
+               ),
+
+               TP_ARGS(hdr),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+                       __field(loff_t, offset)
+                       __field(u32, count)
+                       __field(int, stateid_seq)
+                       __field(u32, stateid_hash)
+                       __string(dstaddr, hdr->ds_clp ?
+                               rpc_peeraddr2str(hdr->ds_clp->cl_rpcclient,
+                                       RPC_DISPLAY_ADDR) : "unknown")
+               ),
+
+               TP_fast_assign(
+                       const struct inode *inode = hdr->inode;
+
+                       __entry->error = hdr->res.op_status;
+                       __entry->fhandle = nfs_fhandle_hash(hdr->args.fh);
+                       __entry->fileid = NFS_FILEID(inode);
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->offset = hdr->args.offset;
+                       __entry->count = hdr->args.count;
+                       __entry->stateid_seq =
+                               be32_to_cpu(hdr->args.stateid.seqid);
+                       __entry->stateid_hash =
+                               nfs_stateid_hash(&hdr->args.stateid);
+                       __assign_str(dstaddr, hdr->ds_clp ?
+                               rpc_peeraddr2str(hdr->ds_clp->cl_rpcclient,
+                                       RPC_DISPLAY_ADDR) : "unknown");
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
+                       "offset=%llu count=%u stateid=%d:0x%08x dstaddr=%s",
+                       -__entry->error,
+                       show_nfsv4_errors(__entry->error),
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle,
+                       __entry->offset, __entry->count,
+                       __entry->stateid_seq, __entry->stateid_hash,
+                       __get_str(dstaddr)
+               )
+);
+
+#define DEFINE_NFS4_FLEXFILES_IO_EVENT(name) \
+       DEFINE_EVENT(nfs4_flexfiles_io_event, name, \
+                       TP_PROTO( \
+                               const struct nfs_pgio_header *hdr \
+                       ), \
+                       TP_ARGS(hdr))
+DEFINE_NFS4_FLEXFILES_IO_EVENT(ff_layout_read_error);
+DEFINE_NFS4_FLEXFILES_IO_EVENT(ff_layout_write_error);
+
+TRACE_EVENT(ff_layout_commit_error,
+               TP_PROTO(
+                       const struct nfs_commit_data *data
+               ),
+
+               TP_ARGS(data),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(u64, fileid)
+                       __field(loff_t, offset)
+                       __field(u32, count)
+                       __string(dstaddr, data->ds_clp ?
+                               rpc_peeraddr2str(data->ds_clp->cl_rpcclient,
+                                       RPC_DISPLAY_ADDR) : "unknown")
+               ),
+
+               TP_fast_assign(
+                       const struct inode *inode = data->inode;
+
+                       __entry->error = data->res.op_status;
+                       __entry->fhandle = nfs_fhandle_hash(data->args.fh);
+                       __entry->fileid = NFS_FILEID(inode);
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->offset = data->args.offset;
+                       __entry->count = data->args.count;
+                       __assign_str(dstaddr, data->ds_clp ?
+                               rpc_peeraddr2str(data->ds_clp->cl_rpcclient,
+                                       RPC_DISPLAY_ADDR) : "unknown");
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
+                       "offset=%llu count=%u dstaddr=%s",
+                       -__entry->error,
+                       show_nfsv4_errors(__entry->error),
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle,
+                       __entry->offset, __entry->count,
+                       __get_str(dstaddr)
+               )
+);
+
+
 #endif /* CONFIG_NFS_V4_1 */
 
 #endif /* _TRACE_NFS4_H */
index 728d88b..47817ef 100644 (file)
@@ -1061,7 +1061,7 @@ static void encode_nfs4_verifier(struct xdr_stream *xdr, const nfs4_verifier *ve
 static __be32 *
 xdr_encode_nfstime4(__be32 *p, const struct timespec64 *t)
 {
-       p = xdr_encode_hyper(p, (__s64)t->tv_sec);
+       p = xdr_encode_hyper(p, t->tv_sec);
        *p++ = cpu_to_be32(t->tv_nsec);
        return p;
 }
@@ -4313,11 +4313,14 @@ static int decode_write_verifier(struct xdr_stream *xdr, struct nfs_write_verifi
 
 static int decode_commit(struct xdr_stream *xdr, struct nfs_commitres *res)
 {
+       struct nfs_writeverf *verf = res->verf;
        int status;
 
        status = decode_op_hdr(xdr, OP_COMMIT);
        if (!status)
-               status = decode_write_verifier(xdr, &res->verf->verifier);
+               status = decode_write_verifier(xdr, &verf->verifier);
+       if (!status)
+               verf->committed = NFS_FILE_SYNC;
        return status;
 }
 
index 2a82dcc..a9588d1 100644 (file)
@@ -198,7 +198,66 @@ DEFINE_NFS_INODE_EVENT_DONE(nfs_writeback_inode_exit);
 DEFINE_NFS_INODE_EVENT(nfs_fsync_enter);
 DEFINE_NFS_INODE_EVENT_DONE(nfs_fsync_exit);
 DEFINE_NFS_INODE_EVENT(nfs_access_enter);
-DEFINE_NFS_INODE_EVENT_DONE(nfs_access_exit);
+
+TRACE_EVENT(nfs_access_exit,
+               TP_PROTO(
+                       const struct inode *inode,
+                       unsigned int mask,
+                       unsigned int permitted,
+                       int error
+               ),
+
+               TP_ARGS(inode, mask, permitted, error),
+
+               TP_STRUCT__entry(
+                       __field(unsigned long, error)
+                       __field(dev_t, dev)
+                       __field(u32, fhandle)
+                       __field(unsigned char, type)
+                       __field(u64, fileid)
+                       __field(u64, version)
+                       __field(loff_t, size)
+                       __field(unsigned long, nfsi_flags)
+                       __field(unsigned long, cache_validity)
+                       __field(unsigned int, mask)
+                       __field(unsigned int, permitted)
+               ),
+
+               TP_fast_assign(
+                       const struct nfs_inode *nfsi = NFS_I(inode);
+                       __entry->error = error < 0 ? -error : 0;
+                       __entry->dev = inode->i_sb->s_dev;
+                       __entry->fileid = nfsi->fileid;
+                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->type = nfs_umode_to_dtype(inode->i_mode);
+                       __entry->version = inode_peek_iversion_raw(inode);
+                       __entry->size = i_size_read(inode);
+                       __entry->nfsi_flags = nfsi->flags;
+                       __entry->cache_validity = nfsi->cache_validity;
+                       __entry->mask = mask;
+                       __entry->permitted = permitted;
+               ),
+
+               TP_printk(
+                       "error=%ld (%s) fileid=%02x:%02x:%llu fhandle=0x%08x "
+                       "type=%u (%s) version=%llu size=%lld "
+                       "cache_validity=0x%lx (%s) nfs_flags=0x%lx (%s) "
+                       "mask=0x%x permitted=0x%x",
+                       -__entry->error, nfs_show_status(__entry->error),
+                       MAJOR(__entry->dev), MINOR(__entry->dev),
+                       (unsigned long long)__entry->fileid,
+                       __entry->fhandle,
+                       __entry->type,
+                       nfs_show_file_type(__entry->type),
+                       (unsigned long long)__entry->version,
+                       (long long)__entry->size,
+                       __entry->cache_validity,
+                       nfs_show_cache_validity(__entry->cache_validity),
+                       __entry->nfsi_flags,
+                       nfs_show_nfsi_flags(__entry->nfsi_flags),
+                       __entry->mask, __entry->permitted
+               )
+);
 
 TRACE_DEFINE_ENUM(LOOKUP_FOLLOW);
 TRACE_DEFINE_ENUM(LOOKUP_DIRECTORY);
@@ -818,75 +877,85 @@ TRACE_EVENT(nfs_sillyrename_unlink,
 
 TRACE_EVENT(nfs_initiate_read,
                TP_PROTO(
-                       const struct inode *inode,
-                       loff_t offset, unsigned long count
+                       const struct nfs_pgio_header *hdr
                ),
 
-               TP_ARGS(inode, offset, count),
+               TP_ARGS(hdr),
 
                TP_STRUCT__entry(
-                       __field(loff_t, offset)
-                       __field(unsigned long, count)
                        __field(dev_t, dev)
                        __field(u32, fhandle)
                        __field(u64, fileid)
+                       __field(loff_t, offset)
+                       __field(u32, count)
                ),
 
                TP_fast_assign(
+                       const struct inode *inode = hdr->inode;
                        const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = hdr->args.fh ?
+                                                 hdr->args.fh : &nfsi->fh;
 
-                       __entry->offset = offset;
-                       __entry->count = count;
+                       __entry->offset = hdr->args.offset;
+                       __entry->count = hdr->args.count;
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
-                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                ),
 
                TP_printk(
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%lu",
+                       "offset=%lld count=%u",
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       __entry->offset, __entry->count
+                       (long long)__entry->offset, __entry->count
                )
 );
 
 TRACE_EVENT(nfs_readpage_done,
                TP_PROTO(
-                       const struct inode *inode,
-                       int status, loff_t offset, bool eof
+                       const struct rpc_task *task,
+                       const struct nfs_pgio_header *hdr
                ),
 
-               TP_ARGS(inode, status, offset, eof),
+               TP_ARGS(task, hdr),
 
                TP_STRUCT__entry(
-                       __field(int, status)
-                       __field(loff_t, offset)
-                       __field(bool, eof)
                        __field(dev_t, dev)
                        __field(u32, fhandle)
                        __field(u64, fileid)
+                       __field(loff_t, offset)
+                       __field(u32, arg_count)
+                       __field(u32, res_count)
+                       __field(bool, eof)
+                       __field(int, status)
                ),
 
                TP_fast_assign(
+                       const struct inode *inode = hdr->inode;
                        const struct nfs_inode *nfsi = NFS_I(inode);
-
-                       __entry->status = status;
-                       __entry->offset = offset;
-                       __entry->eof = eof;
+                       const struct nfs_fh *fh = hdr->args.fh ?
+                                                 hdr->args.fh : &nfsi->fh;
+
+                       __entry->status = task->tk_status;
+                       __entry->offset = hdr->args.offset;
+                       __entry->arg_count = hdr->args.count;
+                       __entry->res_count = hdr->res.count;
+                       __entry->eof = hdr->res.eof;
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
-                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                ),
 
                TP_printk(
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld status=%d%s",
+                       "offset=%lld count=%u res=%u status=%d%s",
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       __entry->offset, __entry->status,
+                       (long long)__entry->offset, __entry->arg_count,
+                       __entry->res_count, __entry->status,
                        __entry->eof ? " eof" : ""
                )
 );
@@ -903,90 +972,144 @@ TRACE_DEFINE_ENUM(NFS_FILE_SYNC);
 
 TRACE_EVENT(nfs_initiate_write,
                TP_PROTO(
-                       const struct inode *inode,
-                       loff_t offset, unsigned long count,
-                       enum nfs3_stable_how stable
+                       const struct nfs_pgio_header *hdr
                ),
 
-               TP_ARGS(inode, offset, count, stable),
+               TP_ARGS(hdr),
 
                TP_STRUCT__entry(
-                       __field(loff_t, offset)
-                       __field(unsigned long, count)
-                       __field(enum nfs3_stable_how, stable)
                        __field(dev_t, dev)
                        __field(u32, fhandle)
                        __field(u64, fileid)
+                       __field(loff_t, offset)
+                       __field(u32, count)
+                       __field(enum nfs3_stable_how, stable)
                ),
 
                TP_fast_assign(
+                       const struct inode *inode = hdr->inode;
                        const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = hdr->args.fh ?
+                                                 hdr->args.fh : &nfsi->fh;
 
-                       __entry->offset = offset;
-                       __entry->count = count;
-                       __entry->stable = stable;
+                       __entry->offset = hdr->args.offset;
+                       __entry->count = hdr->args.count;
+                       __entry->stable = hdr->args.stable;
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
-                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                ),
 
                TP_printk(
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%lu stable=%s",
+                       "offset=%lld count=%u stable=%s",
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       __entry->offset, __entry->count,
+                       (long long)__entry->offset, __entry->count,
                        nfs_show_stable(__entry->stable)
                )
 );
 
 TRACE_EVENT(nfs_writeback_done,
                TP_PROTO(
-                       const struct inode *inode,
-                       int status,
-                       loff_t offset,
-                       struct nfs_writeverf *writeverf
+                       const struct rpc_task *task,
+                       const struct nfs_pgio_header *hdr
                ),
 
-               TP_ARGS(inode, status, offset, writeverf),
+               TP_ARGS(task, hdr),
 
                TP_STRUCT__entry(
-                       __field(int, status)
-                       __field(loff_t, offset)
-                       __field(enum nfs3_stable_how, stable)
-                       __field(unsigned long long, verifier)
                        __field(dev_t, dev)
                        __field(u32, fhandle)
                        __field(u64, fileid)
+                       __field(loff_t, offset)
+                       __field(u32, arg_count)
+                       __field(u32, res_count)
+                       __field(int, status)
+                       __field(enum nfs3_stable_how, stable)
+                       __array(char, verifier, NFS4_VERIFIER_SIZE)
                ),
 
                TP_fast_assign(
+                       const struct inode *inode = hdr->inode;
                        const struct nfs_inode *nfsi = NFS_I(inode);
-
-                       __entry->status = status;
-                       __entry->offset = offset;
-                       __entry->stable = writeverf->committed;
-                       memcpy(&__entry->verifier, &writeverf->verifier,
-                              sizeof(__entry->verifier));
+                       const struct nfs_fh *fh = hdr->args.fh ?
+                                                 hdr->args.fh : &nfsi->fh;
+                       const struct nfs_writeverf *verf = hdr->res.verf;
+
+                       __entry->status = task->tk_status;
+                       __entry->offset = hdr->args.offset;
+                       __entry->arg_count = hdr->args.count;
+                       __entry->res_count = hdr->res.count;
+                       __entry->stable = verf->committed;
+                       memcpy(__entry->verifier,
+                               &verf->verifier,
+                               NFS4_VERIFIER_SIZE);
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
-                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                ),
 
                TP_printk(
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld status=%d stable=%s "
-                       "verifier 0x%016llx",
+                       "offset=%lld count=%u res=%u status=%d stable=%s "
+                       "verifier=%s",
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       __entry->offset, __entry->status,
+                       (long long)__entry->offset, __entry->arg_count,
+                       __entry->res_count, __entry->status,
                        nfs_show_stable(__entry->stable),
-                       __entry->verifier
+                       __print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE)
                )
 );
 
+DECLARE_EVENT_CLASS(nfs_page_error_class,
+               TP_PROTO(
+                       const struct nfs_page *req,
+                       int error
+               ),
+
+               TP_ARGS(req, error),
+
+               TP_STRUCT__entry(
+                       __field(const void *, req)
+                       __field(pgoff_t, index)
+                       __field(unsigned int, offset)
+                       __field(unsigned int, pgbase)
+                       __field(unsigned int, bytes)
+                       __field(int, error)
+               ),
+
+               TP_fast_assign(
+                       __entry->req = req;
+                       __entry->index = req->wb_index;
+                       __entry->offset = req->wb_offset;
+                       __entry->pgbase = req->wb_pgbase;
+                       __entry->bytes = req->wb_bytes;
+                       __entry->error = error;
+               ),
+
+               TP_printk(
+                       "req=%p index=%lu offset=%u pgbase=%u bytes=%u error=%d",
+                       __entry->req, __entry->index, __entry->offset,
+                       __entry->pgbase, __entry->bytes, __entry->error
+               )
+);
+
+#define DEFINE_NFS_PAGEERR_EVENT(name) \
+       DEFINE_EVENT(nfs_page_error_class, name, \
+                       TP_PROTO( \
+                               const struct nfs_page *req, \
+                               int error \
+                       ), \
+                       TP_ARGS(req, error))
+
+DEFINE_NFS_PAGEERR_EVENT(nfs_write_error);
+DEFINE_NFS_PAGEERR_EVENT(nfs_comp_error);
+DEFINE_NFS_PAGEERR_EVENT(nfs_commit_error);
+
 TRACE_EVENT(nfs_initiate_commit,
                TP_PROTO(
                        const struct nfs_commit_data *data
@@ -995,71 +1118,81 @@ TRACE_EVENT(nfs_initiate_commit,
                TP_ARGS(data),
 
                TP_STRUCT__entry(
-                       __field(loff_t, offset)
-                       __field(unsigned long, count)
                        __field(dev_t, dev)
                        __field(u32, fhandle)
                        __field(u64, fileid)
+                       __field(loff_t, offset)
+                       __field(u32, count)
                ),
 
                TP_fast_assign(
                        const struct inode *inode = data->inode;
                        const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = data->args.fh ?
+                                                 data->args.fh : &nfsi->fh;
 
                        __entry->offset = data->args.offset;
                        __entry->count = data->args.count;
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
-                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                ),
 
                TP_printk(
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld count=%lu",
+                       "offset=%lld count=%u",
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       __entry->offset, __entry->count
+                       (long long)__entry->offset, __entry->count
                )
 );
 
 TRACE_EVENT(nfs_commit_done,
                TP_PROTO(
+                       const struct rpc_task *task,
                        const struct nfs_commit_data *data
                ),
 
-               TP_ARGS(data),
+               TP_ARGS(task, data),
 
                TP_STRUCT__entry(
-                       __field(int, status)
-                       __field(loff_t, offset)
-                       __field(unsigned long long, verifier)
                        __field(dev_t, dev)
                        __field(u32, fhandle)
                        __field(u64, fileid)
+                       __field(loff_t, offset)
+                       __field(int, status)
+                       __field(enum nfs3_stable_how, stable)
+                       __array(char, verifier, NFS4_VERIFIER_SIZE)
                ),
 
                TP_fast_assign(
                        const struct inode *inode = data->inode;
                        const struct nfs_inode *nfsi = NFS_I(inode);
+                       const struct nfs_fh *fh = data->args.fh ?
+                                                 data->args.fh : &nfsi->fh;
+                       const struct nfs_writeverf *verf = data->res.verf;
 
-                       __entry->status = data->res.op_status;
+                       __entry->status = task->tk_status;
                        __entry->offset = data->args.offset;
-                       memcpy(&__entry->verifier, &data->verf.verifier,
-                              sizeof(__entry->verifier));
+                       __entry->stable = verf->committed;
+                       memcpy(__entry->verifier,
+                               &verf->verifier,
+                               NFS4_VERIFIER_SIZE);
                        __entry->dev = inode->i_sb->s_dev;
                        __entry->fileid = nfsi->fileid;
-                       __entry->fhandle = nfs_fhandle_hash(&nfsi->fh);
+                       __entry->fhandle = nfs_fhandle_hash(fh);
                ),
 
                TP_printk(
                        "fileid=%02x:%02x:%llu fhandle=0x%08x "
-                       "offset=%lld status=%d verifier 0x%016llx",
+                       "offset=%lld status=%d stable=%s verifier=%s",
                        MAJOR(__entry->dev), MINOR(__entry->dev),
                        (unsigned long long)__entry->fileid,
                        __entry->fhandle,
-                       __entry->offset, __entry->status,
-                       __entry->verifier
+                       (long long)__entry->offset, __entry->status,
+                       nfs_show_stable(__entry->stable),
+                       __print_hex_str(__entry->verifier, NFS4_VERIFIER_SIZE)
                )
 );
 
index cec3070..542ea8d 100644 (file)
@@ -1425,7 +1425,7 @@ retry:
        /* lo ref dropped in pnfs_roc_release() */
        layoutreturn = pnfs_prepare_layoutreturn(lo, &stateid, &iomode);
        /* If the creds don't match, we can't compound the layoutreturn */
-       if (!layoutreturn || cred != lo->plh_lc_cred)
+       if (!layoutreturn || cred_fscmp(cred, lo->plh_lc_cred) != 0)
                goto out_noroc;
 
        roc = layoutreturn;
@@ -1998,8 +1998,6 @@ lookup_again:
                        trace_pnfs_update_layout(ino, pos, count,
                                        iomode, lo, lseg,
                                        PNFS_UPDATE_LAYOUT_INVALID_OPEN);
-                       if (status != -EAGAIN)
-                               goto out_unlock;
                        spin_unlock(&ino->i_lock);
                        nfs4_schedule_stateid_recovery(server, ctx->state);
                        pnfs_clear_first_layoutget(lo);
index f8a3806..0fafdad 100644 (file)
@@ -79,6 +79,10 @@ enum pnfs_try_status {
        PNFS_TRY_AGAIN     = 2,
 };
 
+/* error codes for internal use */
+#define NFS4ERR_RESET_TO_MDS   12001
+#define NFS4ERR_RESET_TO_PNFS  12002
+
 #ifdef CONFIG_NFS_V4_1
 
 #define LAYOUT_NFSV4_1_MODULE_PREFIX "nfs-layouttype4"
@@ -91,10 +95,6 @@ enum pnfs_try_status {
 #define NFS4_DEF_DS_RETRANS 5
 #define PNFS_DEVICE_RETRY_TIMEOUT (120*HZ)
 
-/* error codes for internal use */
-#define NFS4ERR_RESET_TO_MDS   12001
-#define NFS4ERR_RESET_TO_PNFS  12002
-
 enum {
        NFS_LAYOUT_RO_FAILED = 0,       /* get ro layout failed stop trying */
        NFS_LAYOUT_RW_FAILED,           /* get rw layout failed stop trying */
index 82af480..8b37e7f 100644 (file)
@@ -31,12 +31,11 @@ EXPORT_SYMBOL_GPL(pnfs_generic_rw_release);
 /* Fake up some data that will cause nfs_commit_release to retry the writes. */
 void pnfs_generic_prepare_to_resend_writes(struct nfs_commit_data *data)
 {
-       struct nfs_page *first = nfs_list_entry(data->pages.next);
+       struct nfs_writeverf *verf = data->res.verf;
 
        data->task.tk_status = 0;
-       memcpy(&data->verf.verifier, &first->wb_verf,
-              sizeof(data->verf.verifier));
-       data->verf.verifier.data[0]++; /* ensure verifier mismatch */
+       memset(&verf->verifier, 0, sizeof(verf->verifier));
+       verf->committed = NFS_UNSTABLE;
 }
 EXPORT_SYMBOL_GPL(pnfs_generic_prepare_to_resend_writes);
 
index 0f7288b..15c865c 100644 (file)
@@ -108,10 +108,15 @@ nfs_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
                .rpc_resp       = fattr,
        };
        int     status;
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (inode && (server->flags & NFS_MOUNT_SOFTREVAL))
+               task_flags |= RPC_TASK_TIMEOUT;
 
        dprintk("NFS call  getattr\n");
        nfs_fattr_init(fattr);
-       status = rpc_call_sync(server->client, &msg, 0);
+       status = rpc_call_sync(server->client, &msg, task_flags);
        dprintk("NFS reply getattr: %d\n", status);
        return status;
 }
@@ -147,14 +152,14 @@ nfs_proc_setattr(struct dentry *dentry, struct nfs_fattr *fattr,
 }
 
 static int
-nfs_proc_lookup(struct inode *dir, const struct qstr *name,
+nfs_proc_lookup(struct inode *dir, struct dentry *dentry,
                struct nfs_fh *fhandle, struct nfs_fattr *fattr,
                struct nfs4_label *label)
 {
        struct nfs_diropargs    arg = {
                .fh             = NFS_FH(dir),
-               .name           = name->name,
-               .len            = name->len
+               .name           = dentry->d_name.name,
+               .len            = dentry->d_name.len
        };
        struct nfs_diropok      res = {
                .fh             = fhandle,
@@ -166,10 +171,15 @@ nfs_proc_lookup(struct inode *dir, const struct qstr *name,
                .rpc_resp       = &res,
        };
        int                     status;
+       unsigned short task_flags = 0;
+
+       /* Is this is an attribute revalidation, subject to softreval? */
+       if (nfs_lookup_is_soft_revalidate(dentry))
+               task_flags |= RPC_TASK_TIMEOUT;
 
-       dprintk("NFS call  lookup %s\n", name->name);
+       dprintk("NFS call  lookup %pd2\n", dentry);
        nfs_fattr_init(fattr);
-       status = rpc_call_sync(NFS_CLIENT(dir), &msg, 0);
+       status = rpc_call_sync(NFS_CLIENT(dir), &msg, task_flags);
        dprintk("NFS reply lookup: %d\n", status);
        return status;
 }
@@ -710,7 +720,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
        .file_ops       = &nfs_file_operations,
        .getroot        = nfs_proc_get_root,
        .submount       = nfs_submount,
-       .try_mount      = nfs_try_mount,
+       .try_get_tree   = nfs_try_get_tree,
        .getattr        = nfs_proc_getattr,
        .setattr        = nfs_proc_setattr,
        .lookup         = nfs_proc_lookup,
index cfe0b58..34bb9ad 100644 (file)
@@ -214,7 +214,7 @@ static void nfs_initiate_read(struct nfs_pgio_header *hdr,
 
        task_setup_data->flags |= swap_flags;
        rpc_ops->read_setup(hdr, msg);
-       trace_nfs_initiate_read(inode, hdr->io_start, hdr->good_bytes);
+       trace_nfs_initiate_read(hdr);
 }
 
 static void
@@ -247,8 +247,7 @@ static int nfs_readpage_done(struct rpc_task *task,
                return status;
 
        nfs_add_stats(inode, NFSIOS_SERVERREADBYTES, hdr->res.count);
-       trace_nfs_readpage_done(inode, task->tk_status,
-                               hdr->args.offset, hdr->res.eof);
+       trace_nfs_readpage_done(task, hdr);
 
        if (task->tk_status == -ESTALE) {
                set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
@@ -282,6 +281,8 @@ static void nfs_readpage_retry(struct rpc_task *task,
        argp->offset += resp->count;
        argp->pgbase += resp->count;
        argp->count -= resp->count;
+       resp->count = 0;
+       resp->eof = 0;
        rpc_restart_call_prepare(task);
 }
 
index 8d8d04b..dada09b 100644 (file)
 #include "nfs.h"
 
 #define NFSDBG_FACILITY                NFSDBG_VFS
-#define NFS_TEXT_DATA          1
-
-#if IS_ENABLED(CONFIG_NFS_V3)
-#define NFS_DEFAULT_VERSION 3
-#else
-#define NFS_DEFAULT_VERSION 2
-#endif
-
-#define NFS_MAX_CONNECTIONS 16
-
-enum {
-       /* Mount options that take no arguments */
-       Opt_soft, Opt_softerr, Opt_hard,
-       Opt_posix, Opt_noposix,
-       Opt_cto, Opt_nocto,
-       Opt_ac, Opt_noac,
-       Opt_lock, Opt_nolock,
-       Opt_udp, Opt_tcp, Opt_rdma,
-       Opt_acl, Opt_noacl,
-       Opt_rdirplus, Opt_nordirplus,
-       Opt_sharecache, Opt_nosharecache,
-       Opt_resvport, Opt_noresvport,
-       Opt_fscache, Opt_nofscache,
-       Opt_migration, Opt_nomigration,
-
-       /* Mount options that take integer arguments */
-       Opt_port,
-       Opt_rsize, Opt_wsize, Opt_bsize,
-       Opt_timeo, Opt_retrans,
-       Opt_acregmin, Opt_acregmax,
-       Opt_acdirmin, Opt_acdirmax,
-       Opt_actimeo,
-       Opt_namelen,
-       Opt_mountport,
-       Opt_mountvers,
-       Opt_minorversion,
-
-       /* Mount options that take string arguments */
-       Opt_nfsvers,
-       Opt_sec, Opt_proto, Opt_mountproto, Opt_mounthost,
-       Opt_addr, Opt_mountaddr, Opt_clientaddr,
-       Opt_nconnect,
-       Opt_lookupcache,
-       Opt_fscache_uniq,
-       Opt_local_lock,
-
-       /* Special mount options */
-       Opt_userspace, Opt_deprecated, Opt_sloppy,
-
-       Opt_err
-};
-
-static const match_table_t nfs_mount_option_tokens = {
-       { Opt_userspace, "bg" },
-       { Opt_userspace, "fg" },
-       { Opt_userspace, "retry=%s" },
-
-       { Opt_sloppy, "sloppy" },
-
-       { Opt_soft, "soft" },
-       { Opt_softerr, "softerr" },
-       { Opt_hard, "hard" },
-       { Opt_deprecated, "intr" },
-       { Opt_deprecated, "nointr" },
-       { Opt_posix, "posix" },
-       { Opt_noposix, "noposix" },
-       { Opt_cto, "cto" },
-       { Opt_nocto, "nocto" },
-       { Opt_ac, "ac" },
-       { Opt_noac, "noac" },
-       { Opt_lock, "lock" },
-       { Opt_nolock, "nolock" },
-       { Opt_udp, "udp" },
-       { Opt_tcp, "tcp" },
-       { Opt_rdma, "rdma" },
-       { Opt_acl, "acl" },
-       { Opt_noacl, "noacl" },
-       { Opt_rdirplus, "rdirplus" },
-       { Opt_nordirplus, "nordirplus" },
-       { Opt_sharecache, "sharecache" },
-       { Opt_nosharecache, "nosharecache" },
-       { Opt_resvport, "resvport" },
-       { Opt_noresvport, "noresvport" },
-       { Opt_fscache, "fsc" },
-       { Opt_nofscache, "nofsc" },
-       { Opt_migration, "migration" },
-       { Opt_nomigration, "nomigration" },
-
-       { Opt_port, "port=%s" },
-       { Opt_rsize, "rsize=%s" },
-       { Opt_wsize, "wsize=%s" },
-       { Opt_bsize, "bsize=%s" },
-       { Opt_timeo, "timeo=%s" },
-       { Opt_retrans, "retrans=%s" },
-       { Opt_acregmin, "acregmin=%s" },
-       { Opt_acregmax, "acregmax=%s" },
-       { Opt_acdirmin, "acdirmin=%s" },
-       { Opt_acdirmax, "acdirmax=%s" },
-       { Opt_actimeo, "actimeo=%s" },
-       { Opt_namelen, "namlen=%s" },
-       { Opt_mountport, "mountport=%s" },
-       { Opt_mountvers, "mountvers=%s" },
-       { Opt_minorversion, "minorversion=%s" },
-
-       { Opt_nfsvers, "nfsvers=%s" },
-       { Opt_nfsvers, "vers=%s" },
-
-       { Opt_sec, "sec=%s" },
-       { Opt_proto, "proto=%s" },
-       { Opt_mountproto, "mountproto=%s" },
-       { Opt_addr, "addr=%s" },
-       { Opt_clientaddr, "clientaddr=%s" },
-       { Opt_mounthost, "mounthost=%s" },
-       { Opt_mountaddr, "mountaddr=%s" },
-
-       { Opt_nconnect, "nconnect=%s" },
-
-       { Opt_lookupcache, "lookupcache=%s" },
-       { Opt_fscache_uniq, "fsc=%s" },
-       { Opt_local_lock, "local_lock=%s" },
-
-       /* The following needs to be listed after all other options */
-       { Opt_nfsvers, "v%s" },
-
-       { Opt_err, NULL }
-};
-
-enum {
-       Opt_xprt_udp, Opt_xprt_udp6, Opt_xprt_tcp, Opt_xprt_tcp6, Opt_xprt_rdma,
-       Opt_xprt_rdma6,
-
-       Opt_xprt_err
-};
-
-static const match_table_t nfs_xprt_protocol_tokens = {
-       { Opt_xprt_udp, "udp" },
-       { Opt_xprt_udp6, "udp6" },
-       { Opt_xprt_tcp, "tcp" },
-       { Opt_xprt_tcp6, "tcp6" },
-       { Opt_xprt_rdma, "rdma" },
-       { Opt_xprt_rdma6, "rdma6" },
-
-       { Opt_xprt_err, NULL }
-};
-
-enum {
-       Opt_sec_none, Opt_sec_sys,
-       Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p,
-       Opt_sec_lkey, Opt_sec_lkeyi, Opt_sec_lkeyp,
-       Opt_sec_spkm, Opt_sec_spkmi, Opt_sec_spkmp,
-
-       Opt_sec_err
-};
-
-static const match_table_t nfs_secflavor_tokens = {
-       { Opt_sec_none, "none" },
-       { Opt_sec_none, "null" },
-       { Opt_sec_sys, "sys" },
-
-       { Opt_sec_krb5, "krb5" },
-       { Opt_sec_krb5i, "krb5i" },
-       { Opt_sec_krb5p, "krb5p" },
-
-       { Opt_sec_lkey, "lkey" },
-       { Opt_sec_lkeyi, "lkeyi" },
-       { Opt_sec_lkeyp, "lkeyp" },
-
-       { Opt_sec_spkm, "spkm3" },
-       { Opt_sec_spkmi, "spkm3i" },
-       { Opt_sec_spkmp, "spkm3p" },
-
-       { Opt_sec_err, NULL }
-};
-
-enum {
-       Opt_lookupcache_all, Opt_lookupcache_positive,
-       Opt_lookupcache_none,
-
-       Opt_lookupcache_err
-};
-
-static match_table_t nfs_lookupcache_tokens = {
-       { Opt_lookupcache_all, "all" },
-       { Opt_lookupcache_positive, "pos" },
-       { Opt_lookupcache_positive, "positive" },
-       { Opt_lookupcache_none, "none" },
-
-       { Opt_lookupcache_err, NULL }
-};
-
-enum {
-       Opt_local_lock_all, Opt_local_lock_flock, Opt_local_lock_posix,
-       Opt_local_lock_none,
-
-       Opt_local_lock_err
-};
-
-static match_table_t nfs_local_lock_tokens = {
-       { Opt_local_lock_all, "all" },
-       { Opt_local_lock_flock, "flock" },
-       { Opt_local_lock_posix, "posix" },
-       { Opt_local_lock_none, "none" },
-
-       { Opt_local_lock_err, NULL }
-};
-
-enum {
-       Opt_vers_2, Opt_vers_3, Opt_vers_4, Opt_vers_4_0,
-       Opt_vers_4_1, Opt_vers_4_2,
-
-       Opt_vers_err
-};
-
-static match_table_t nfs_vers_tokens = {
-       { Opt_vers_2, "2" },
-       { Opt_vers_3, "3" },
-       { Opt_vers_4, "4" },
-       { Opt_vers_4_0, "4.0" },
-       { Opt_vers_4_1, "4.1" },
-       { Opt_vers_4_2, "4.2" },
-
-       { Opt_vers_err, NULL }
-};
-
-static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
-               int flags, const char *dev_name, void *raw_data);
-
-struct file_system_type nfs_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "nfs",
-       .mount          = nfs_fs_mount,
-       .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
-};
-MODULE_ALIAS_FS("nfs");
-EXPORT_SYMBOL_GPL(nfs_fs_type);
-
-struct file_system_type nfs_xdev_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "nfs",
-       .mount          = nfs_xdev_mount,
-       .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
-};
 
 const struct super_operations nfs_sops = {
        .alloc_inode    = nfs_alloc_inode,
@@ -326,26 +82,10 @@ const struct super_operations nfs_sops = {
        .show_devname   = nfs_show_devname,
        .show_path      = nfs_show_path,
        .show_stats     = nfs_show_stats,
-       .remount_fs     = nfs_remount,
 };
 EXPORT_SYMBOL_GPL(nfs_sops);
 
 #if IS_ENABLED(CONFIG_NFS_V4)
-static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
-static int nfs4_validate_mount_data(void *options,
-       struct nfs_parsed_mount_data *args, const char *dev_name);
-
-struct file_system_type nfs4_fs_type = {
-       .owner          = THIS_MODULE,
-       .name           = "nfs4",
-       .mount          = nfs_fs_mount,
-       .kill_sb        = nfs_kill_super,
-       .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
-};
-MODULE_ALIAS_FS("nfs4");
-MODULE_ALIAS("nfs4");
-EXPORT_SYMBOL_GPL(nfs4_fs_type);
-
 static int __init register_nfs4_fs(void)
 {
        return register_filesystem(&nfs4_fs_type);
@@ -635,6 +375,7 @@ static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss,
        } nfs_info[] = {
                { NFS_MOUNT_SOFT, ",soft", "" },
                { NFS_MOUNT_SOFTERR, ",softerr", "" },
+               { NFS_MOUNT_SOFTREVAL, ",softreval", "" },
                { NFS_MOUNT_POSIX, ",posix", "" },
                { NFS_MOUNT_NOCTO, ",nocto", "" },
                { NFS_MOUNT_NOAC, ",noac", "" },
@@ -931,1305 +672,224 @@ void nfs_umount_begin(struct super_block *sb)
 }
 EXPORT_SYMBOL_GPL(nfs_umount_begin);
 
-static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
+/*
+ * Return true if 'match' is in auth_info or auth_info is empty.
+ * Return false otherwise.
+ */
+bool nfs_auth_info_match(const struct nfs_auth_info *auth_info,
+                        rpc_authflavor_t match)
 {
-       struct nfs_parsed_mount_data *data;
-
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (data) {
-               data->timeo             = NFS_UNSPEC_TIMEO;
-               data->retrans           = NFS_UNSPEC_RETRANS;
-               data->acregmin          = NFS_DEF_ACREGMIN;
-               data->acregmax          = NFS_DEF_ACREGMAX;
-               data->acdirmin          = NFS_DEF_ACDIRMIN;
-               data->acdirmax          = NFS_DEF_ACDIRMAX;
-               data->mount_server.port = NFS_UNSPEC_PORT;
-               data->nfs_server.port   = NFS_UNSPEC_PORT;
-               data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
-               data->selected_flavor   = RPC_AUTH_MAXFLAVOR;
-               data->minorversion      = 0;
-               data->need_mount        = true;
-               data->net               = current->nsproxy->net_ns;
-               data->lsm_opts          = NULL;
-       }
-       return data;
-}
+       int i;
 
-static void nfs_free_parsed_mount_data(struct nfs_parsed_mount_data *data)
-{
-       if (data) {
-               kfree(data->client_address);
-               kfree(data->mount_server.hostname);
-               kfree(data->nfs_server.export_path);
-               kfree(data->nfs_server.hostname);
-               kfree(data->fscache_uniq);
-               security_free_mnt_opts(&data->lsm_opts);
-               kfree(data);
+       if (!auth_info->flavor_len)
+               return true;
+
+       for (i = 0; i < auth_info->flavor_len; i++) {
+               if (auth_info->flavors[i] == match)
+                       return true;
        }
+       return false;
 }
+EXPORT_SYMBOL_GPL(nfs_auth_info_match);
 
 /*
- * Sanity-check a server address provided by the mount command.
- *
- * Address family must be initialized, and address must not be
- * the ANY address for that family.
+ * Ensure that a specified authtype in ctx->auth_info is supported by
+ * the server. Returns 0 and sets ctx->selected_flavor if it's ok, and
+ * -EACCES if not.
  */
-static int nfs_verify_server_address(struct sockaddr *addr)
+static int nfs_verify_authflavors(struct nfs_fs_context *ctx,
+                                 rpc_authflavor_t *server_authlist,
+                                 unsigned int count)
 {
-       switch (addr->sa_family) {
-       case AF_INET: {
-               struct sockaddr_in *sa = (struct sockaddr_in *)addr;
-               return sa->sin_addr.s_addr != htonl(INADDR_ANY);
-       }
-       case AF_INET6: {
-               struct in6_addr *sa = &((struct sockaddr_in6 *)addr)->sin6_addr;
-               return !ipv6_addr_any(sa);
-       }
-       }
+       rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR;
+       bool found_auth_null = false;
+       unsigned int i;
 
-       dfprintk(MOUNT, "NFS: Invalid IP address specified\n");
-       return 0;
-}
+       /*
+        * If the sec= mount option is used, the specified flavor or AUTH_NULL
+        * must be in the list returned by the server.
+        *
+        * AUTH_NULL has a special meaning when it's in the server list - it
+        * means that the server will ignore the rpc creds, so any flavor
+        * can be used but still use the sec= that was specified.
+        *
+        * Note also that the MNT procedure in MNTv1 does not return a list
+        * of supported security flavors. In this case, nfs_mount() fabricates
+        * a security flavor list containing just AUTH_NULL.
+        */
+       for (i = 0; i < count; i++) {
+               flavor = server_authlist[i];
 
-/*
- * Select between a default port value and a user-specified port value.
- * If a zero value is set, then autobind will be used.
- */
-static void nfs_set_port(struct sockaddr *sap, int *port,
-                                const unsigned short default_port)
-{
-       if (*port == NFS_UNSPEC_PORT)
-               *port = default_port;
+               if (nfs_auth_info_match(&ctx->auth_info, flavor))
+                       goto out;
 
-       rpc_set_port(sap, *port);
-}
+               if (flavor == RPC_AUTH_NULL)
+                       found_auth_null = true;
+       }
 
-/*
- * Sanity check the NFS transport protocol.
- *
- */
-static void nfs_validate_transport_protocol(struct nfs_parsed_mount_data *mnt)
-{
-       switch (mnt->nfs_server.protocol) {
-       case XPRT_TRANSPORT_UDP:
-       case XPRT_TRANSPORT_TCP:
-       case XPRT_TRANSPORT_RDMA:
-               break;
-       default:
-               mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
+       if (found_auth_null) {
+               flavor = ctx->auth_info.flavors[0];
+               goto out;
        }
+
+       dfprintk(MOUNT,
+                "NFS: specified auth flavors not supported by server\n");
+       return -EACCES;
+
+out:
+       ctx->selected_flavor = flavor;
+       dfprintk(MOUNT, "NFS: using auth flavor %u\n", ctx->selected_flavor);
+       return 0;
 }
 
 /*
- * For text based NFSv2/v3 mounts, the mount protocol transport default
- * settings should depend upon the specified NFS transport.
+ * Use the remote server's MOUNT service to request the NFS file handle
+ * corresponding to the provided path.
  */
-static void nfs_set_mount_transport_protocol(struct nfs_parsed_mount_data *mnt)
+static int nfs_request_mount(struct fs_context *fc,
+                            struct nfs_fh *root_fh,
+                            rpc_authflavor_t *server_authlist,
+                            unsigned int *server_authlist_len)
 {
-       nfs_validate_transport_protocol(mnt);
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct nfs_mount_request request = {
+               .sap            = (struct sockaddr *)
+                                               &ctx->mount_server.address,
+               .dirpath        = ctx->nfs_server.export_path,
+               .protocol       = ctx->mount_server.protocol,
+               .fh             = root_fh,
+               .noresvport     = ctx->flags & NFS_MOUNT_NORESVPORT,
+               .auth_flav_len  = server_authlist_len,
+               .auth_flavs     = server_authlist,
+               .net            = fc->net_ns,
+       };
+       int status;
 
-       if (mnt->mount_server.protocol == XPRT_TRANSPORT_UDP ||
-           mnt->mount_server.protocol == XPRT_TRANSPORT_TCP)
-                       return;
-       switch (mnt->nfs_server.protocol) {
-       case XPRT_TRANSPORT_UDP:
-               mnt->mount_server.protocol = XPRT_TRANSPORT_UDP;
-               break;
-       case XPRT_TRANSPORT_TCP:
-       case XPRT_TRANSPORT_RDMA:
-               mnt->mount_server.protocol = XPRT_TRANSPORT_TCP;
+       if (ctx->mount_server.version == 0) {
+               switch (ctx->version) {
+                       default:
+                               ctx->mount_server.version = NFS_MNT3_VERSION;
+                               break;
+                       case 2:
+                               ctx->mount_server.version = NFS_MNT_VERSION;
+               }
        }
-}
+       request.version = ctx->mount_server.version;
 
-/*
- * Add 'flavor' to 'auth_info' if not already present.
- * Returns true if 'flavor' ends up in the list, false otherwise
- */
-static bool nfs_auth_info_add(struct nfs_auth_info *auth_info,
-                             rpc_authflavor_t flavor)
-{
-       unsigned int i;
-       unsigned int max_flavor_len = ARRAY_SIZE(auth_info->flavors);
+       if (ctx->mount_server.hostname)
+               request.hostname = ctx->mount_server.hostname;
+       else
+               request.hostname = ctx->nfs_server.hostname;
 
-       /* make sure this flavor isn't already in the list */
-       for (i = 0; i < auth_info->flavor_len; i++) {
-               if (flavor == auth_info->flavors[i])
-                       return true;
+       /*
+        * Construct the mount server's address.
+        */
+       if (ctx->mount_server.address.sa_family == AF_UNSPEC) {
+               memcpy(request.sap, &ctx->nfs_server.address,
+                      ctx->nfs_server.addrlen);
+               ctx->mount_server.addrlen = ctx->nfs_server.addrlen;
        }
+       request.salen = ctx->mount_server.addrlen;
+       nfs_set_port(request.sap, &ctx->mount_server.port, 0);
 
-       if (auth_info->flavor_len + 1 >= max_flavor_len) {
-               dfprintk(MOUNT, "NFS: too many sec= flavors\n");
-               return false;
+       /*
+        * Now ask the mount server to map our export path
+        * to a file handle.
+        */
+       status = nfs_mount(&request);
+       if (status != 0) {
+               dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
+                               request.hostname, status);
+               return status;
        }
 
-       auth_info->flavors[auth_info->flavor_len++] = flavor;
-       return true;
+       return 0;
 }
 
-/*
- * Return true if 'match' is in auth_info or auth_info is empty.
- * Return false otherwise.
- */
-bool nfs_auth_info_match(const struct nfs_auth_info *auth_info,
-                        rpc_authflavor_t match)
+static struct nfs_server *nfs_try_mount_request(struct fs_context *fc)
 {
-       int i;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       int status;
+       unsigned int i;
+       bool tried_auth_unix = false;
+       bool auth_null_in_list = false;
+       struct nfs_server *server = ERR_PTR(-EACCES);
+       rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS];
+       unsigned int authlist_len = ARRAY_SIZE(authlist);
 
-       if (!auth_info->flavor_len)
-               return true;
+       status = nfs_request_mount(fc, ctx->mntfh, authlist, &authlist_len);
+       if (status)
+               return ERR_PTR(status);
 
-       for (i = 0; i < auth_info->flavor_len; i++) {
-               if (auth_info->flavors[i] == match)
-                       return true;
+       /*
+        * Was a sec= authflavor specified in the options? First, verify
+        * whether the server supports it, and then just try to use it if so.
+        */
+       if (ctx->auth_info.flavor_len > 0) {
+               status = nfs_verify_authflavors(ctx, authlist, authlist_len);
+               dfprintk(MOUNT, "NFS: using auth flavor %u\n",
+                        ctx->selected_flavor);
+               if (status)
+                       return ERR_PTR(status);
+               return ctx->nfs_mod->rpc_ops->create_server(fc);
        }
-       return false;
-}
-EXPORT_SYMBOL_GPL(nfs_auth_info_match);
-
-/*
- * Parse the value of the 'sec=' option.
- */
-static int nfs_parse_security_flavors(char *value,
-                                     struct nfs_parsed_mount_data *mnt)
-{
-       substring_t args[MAX_OPT_ARGS];
-       rpc_authflavor_t pseudoflavor;
-       char *p;
 
-       dfprintk(MOUNT, "NFS: parsing sec=%s option\n", value);
+       /*
+        * No sec= option was provided. RFC 2623, section 2.7 suggests we
+        * SHOULD prefer the flavor listed first. However, some servers list
+        * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
+        */
+       for (i = 0; i < authlist_len; ++i) {
+               rpc_authflavor_t flavor;
+               struct rpcsec_gss_info info;
 
-       while ((p = strsep(&value, ":")) != NULL) {
-               switch (match_token(p, nfs_secflavor_tokens, args)) {
-               case Opt_sec_none:
-                       pseudoflavor = RPC_AUTH_NULL;
-                       break;
-               case Opt_sec_sys:
-                       pseudoflavor = RPC_AUTH_UNIX;
-                       break;
-               case Opt_sec_krb5:
-                       pseudoflavor = RPC_AUTH_GSS_KRB5;
-                       break;
-               case Opt_sec_krb5i:
-                       pseudoflavor = RPC_AUTH_GSS_KRB5I;
-                       break;
-               case Opt_sec_krb5p:
-                       pseudoflavor = RPC_AUTH_GSS_KRB5P;
-                       break;
-               case Opt_sec_lkey:
-                       pseudoflavor = RPC_AUTH_GSS_LKEY;
-                       break;
-               case Opt_sec_lkeyi:
-                       pseudoflavor = RPC_AUTH_GSS_LKEYI;
-                       break;
-               case Opt_sec_lkeyp:
-                       pseudoflavor = RPC_AUTH_GSS_LKEYP;
-                       break;
-               case Opt_sec_spkm:
-                       pseudoflavor = RPC_AUTH_GSS_SPKM;
-                       break;
-               case Opt_sec_spkmi:
-                       pseudoflavor = RPC_AUTH_GSS_SPKMI;
-                       break;
-               case Opt_sec_spkmp:
-                       pseudoflavor = RPC_AUTH_GSS_SPKMP;
+               flavor = authlist[i];
+               switch (flavor) {
+               case RPC_AUTH_UNIX:
+                       tried_auth_unix = true;
                        break;
+               case RPC_AUTH_NULL:
+                       auth_null_in_list = true;
+                       continue;
                default:
-                       dfprintk(MOUNT,
-                                "NFS: sec= option '%s' not recognized\n", p);
-                       return 0;
+                       if (rpcauth_get_gssinfo(flavor, &info) != 0)
+                               continue;
+                       /* Fallthrough */
                }
-
-               if (!nfs_auth_info_add(&mnt->auth_info, pseudoflavor))
-                       return 0;
+               dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor);
+               ctx->selected_flavor = flavor;
+               server = ctx->nfs_mod->rpc_ops->create_server(fc);
+               if (!IS_ERR(server))
+                       return server;
        }
 
-       return 1;
-}
-
-static int nfs_parse_version_string(char *string,
-               struct nfs_parsed_mount_data *mnt,
-               substring_t *args)
-{
-       mnt->flags &= ~NFS_MOUNT_VER3;
-       switch (match_token(string, nfs_vers_tokens, args)) {
-       case Opt_vers_2:
-               mnt->version = 2;
-               break;
-       case Opt_vers_3:
-               mnt->flags |= NFS_MOUNT_VER3;
-               mnt->version = 3;
-               break;
-       case Opt_vers_4:
-               /* Backward compatibility option. In future,
-                * the mount program should always supply
-                * a NFSv4 minor version number.
-                */
-               mnt->version = 4;
-               break;
-       case Opt_vers_4_0:
-               mnt->version = 4;
-               mnt->minorversion = 0;
-               break;
-       case Opt_vers_4_1:
-               mnt->version = 4;
-               mnt->minorversion = 1;
-               break;
-       case Opt_vers_4_2:
-               mnt->version = 4;
-               mnt->minorversion = 2;
-               break;
-       default:
-               return 0;
-       }
-       return 1;
-}
+       /*
+        * Nothing we tried so far worked. At this point, give up if we've
+        * already tried AUTH_UNIX or if the server's list doesn't contain
+        * AUTH_NULL
+        */
+       if (tried_auth_unix || !auth_null_in_list)
+               return server;
 
-static int nfs_get_option_str(substring_t args[], char **option)
-{
-       kfree(*option);
-       *option = match_strdup(args);
-       return !*option;
+       /* Last chance! Try AUTH_UNIX */
+       dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
+       ctx->selected_flavor = RPC_AUTH_UNIX;
+       return ctx->nfs_mod->rpc_ops->create_server(fc);
 }
 
-static int nfs_get_option_ul(substring_t args[], unsigned long *option)
+int nfs_try_get_tree(struct fs_context *fc)
 {
-       int rc;
-       char *string;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
 
-       string = match_strdup(args);
-       if (string == NULL)
-               return -ENOMEM;
-       rc = kstrtoul(string, 10, option);
-       kfree(string);
+       if (ctx->need_mount)
+               ctx->server = nfs_try_mount_request(fc);
+       else
+               ctx->server = ctx->nfs_mod->rpc_ops->create_server(fc);
 
-       return rc;
+       return nfs_get_tree_common(fc);
 }
+EXPORT_SYMBOL_GPL(nfs_try_get_tree);
 
-static int nfs_get_option_ul_bound(substring_t args[], unsigned long *option,
-               unsigned long l_bound, unsigned long u_bound)
-{
-       int ret;
-
-       ret = nfs_get_option_ul(args, option);
-       if (ret != 0)
-               return ret;
-       if (*option < l_bound || *option > u_bound)
-               return -ERANGE;
-       return 0;
-}
-
-/*
- * Error-check and convert a string of mount options from user space into
- * a data structure.  The whole mount string is processed; bad options are
- * skipped as they are encountered.  If there were no errors, return 1;
- * otherwise return 0 (zero).
- */
-static int nfs_parse_mount_options(char *raw,
-                                  struct nfs_parsed_mount_data *mnt)
-{
-       char *p, *string;
-       int rc, sloppy = 0, invalid_option = 0;
-       unsigned short protofamily = AF_UNSPEC;
-       unsigned short mountfamily = AF_UNSPEC;
-
-       if (!raw) {
-               dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
-               return 1;
-       }
-       dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
-
-       rc = security_sb_eat_lsm_opts(raw, &mnt->lsm_opts);
-       if (rc)
-               goto out_security_failure;
-
-       while ((p = strsep(&raw, ",")) != NULL) {
-               substring_t args[MAX_OPT_ARGS];
-               unsigned long option;
-               int token;
-
-               if (!*p)
-                       continue;
-
-               dfprintk(MOUNT, "NFS:   parsing nfs mount option '%s'\n", p);
-
-               token = match_token(p, nfs_mount_option_tokens, args);
-               switch (token) {
-
-               /*
-                * boolean options:  foo/nofoo
-                */
-               case Opt_soft:
-                       mnt->flags |= NFS_MOUNT_SOFT;
-                       mnt->flags &= ~NFS_MOUNT_SOFTERR;
-                       break;
-               case Opt_softerr:
-                       mnt->flags |= NFS_MOUNT_SOFTERR;
-                       mnt->flags &= ~NFS_MOUNT_SOFT;
-                       break;
-               case Opt_hard:
-                       mnt->flags &= ~(NFS_MOUNT_SOFT|NFS_MOUNT_SOFTERR);
-                       break;
-               case Opt_posix:
-                       mnt->flags |= NFS_MOUNT_POSIX;
-                       break;
-               case Opt_noposix:
-                       mnt->flags &= ~NFS_MOUNT_POSIX;
-                       break;
-               case Opt_cto:
-                       mnt->flags &= ~NFS_MOUNT_NOCTO;
-                       break;
-               case Opt_nocto:
-                       mnt->flags |= NFS_MOUNT_NOCTO;
-                       break;
-               case Opt_ac:
-                       mnt->flags &= ~NFS_MOUNT_NOAC;
-                       break;
-               case Opt_noac:
-                       mnt->flags |= NFS_MOUNT_NOAC;
-                       break;
-               case Opt_lock:
-                       mnt->flags &= ~NFS_MOUNT_NONLM;
-                       mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK |
-                                       NFS_MOUNT_LOCAL_FCNTL);
-                       break;
-               case Opt_nolock:
-                       mnt->flags |= NFS_MOUNT_NONLM;
-                       mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK |
-                                      NFS_MOUNT_LOCAL_FCNTL);
-                       break;
-               case Opt_udp:
-                       mnt->flags &= ~NFS_MOUNT_TCP;
-                       mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
-                       break;
-               case Opt_tcp:
-                       mnt->flags |= NFS_MOUNT_TCP;
-                       mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
-                       break;
-               case Opt_rdma:
-                       mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */
-                       mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
-                       xprt_load_transport(p);
-                       break;
-               case Opt_acl:
-                       mnt->flags &= ~NFS_MOUNT_NOACL;
-                       break;
-               case Opt_noacl:
-                       mnt->flags |= NFS_MOUNT_NOACL;
-                       break;
-               case Opt_rdirplus:
-                       mnt->flags &= ~NFS_MOUNT_NORDIRPLUS;
-                       break;
-               case Opt_nordirplus:
-                       mnt->flags |= NFS_MOUNT_NORDIRPLUS;
-                       break;
-               case Opt_sharecache:
-                       mnt->flags &= ~NFS_MOUNT_UNSHARED;
-                       break;
-               case Opt_nosharecache:
-                       mnt->flags |= NFS_MOUNT_UNSHARED;
-                       break;
-               case Opt_resvport:
-                       mnt->flags &= ~NFS_MOUNT_NORESVPORT;
-                       break;
-               case Opt_noresvport:
-                       mnt->flags |= NFS_MOUNT_NORESVPORT;
-                       break;
-               case Opt_fscache:
-                       mnt->options |= NFS_OPTION_FSCACHE;
-                       kfree(mnt->fscache_uniq);
-                       mnt->fscache_uniq = NULL;
-                       break;
-               case Opt_nofscache:
-                       mnt->options &= ~NFS_OPTION_FSCACHE;
-                       kfree(mnt->fscache_uniq);
-                       mnt->fscache_uniq = NULL;
-                       break;
-               case Opt_migration:
-                       mnt->options |= NFS_OPTION_MIGRATION;
-                       break;
-               case Opt_nomigration:
-                       mnt->options &= ~NFS_OPTION_MIGRATION;
-                       break;
-
-               /*
-                * options that take numeric values
-                */
-               case Opt_port:
-                       if (nfs_get_option_ul(args, &option) ||
-                           option > USHRT_MAX)
-                               goto out_invalid_value;
-                       mnt->nfs_server.port = option;
-                       break;
-               case Opt_rsize:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->rsize = option;
-                       break;
-               case Opt_wsize:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->wsize = option;
-                       break;
-               case Opt_bsize:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->bsize = option;
-                       break;
-               case Opt_timeo:
-                       if (nfs_get_option_ul_bound(args, &option, 1, INT_MAX))
-                               goto out_invalid_value;
-                       mnt->timeo = option;
-                       break;
-               case Opt_retrans:
-                       if (nfs_get_option_ul_bound(args, &option, 0, INT_MAX))
-                               goto out_invalid_value;
-                       mnt->retrans = option;
-                       break;
-               case Opt_acregmin:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->acregmin = option;
-                       break;
-               case Opt_acregmax:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->acregmax = option;
-                       break;
-               case Opt_acdirmin:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->acdirmin = option;
-                       break;
-               case Opt_acdirmax:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->acdirmax = option;
-                       break;
-               case Opt_actimeo:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->acregmin = mnt->acregmax =
-                       mnt->acdirmin = mnt->acdirmax = option;
-                       break;
-               case Opt_namelen:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       mnt->namlen = option;
-                       break;
-               case Opt_mountport:
-                       if (nfs_get_option_ul(args, &option) ||
-                           option > USHRT_MAX)
-                               goto out_invalid_value;
-                       mnt->mount_server.port = option;
-                       break;
-               case Opt_mountvers:
-                       if (nfs_get_option_ul(args, &option) ||
-                           option < NFS_MNT_VERSION ||
-                           option > NFS_MNT3_VERSION)
-                               goto out_invalid_value;
-                       mnt->mount_server.version = option;
-                       break;
-               case Opt_minorversion:
-                       if (nfs_get_option_ul(args, &option))
-                               goto out_invalid_value;
-                       if (option > NFS4_MAX_MINOR_VERSION)
-                               goto out_invalid_value;
-                       mnt->minorversion = option;
-                       break;
-
-               /*
-                * options that take text values
-                */
-               case Opt_nfsvers:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-                       rc = nfs_parse_version_string(string, mnt, args);
-                       kfree(string);
-                       if (!rc)
-                               goto out_invalid_value;
-                       break;
-               case Opt_sec:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-                       rc = nfs_parse_security_flavors(string, mnt);
-                       kfree(string);
-                       if (!rc) {
-                               dfprintk(MOUNT, "NFS:   unrecognized "
-                                               "security flavor\n");
-                               return 0;
-                       }
-                       break;
-               case Opt_proto:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-                       token = match_token(string,
-                                           nfs_xprt_protocol_tokens, args);
-
-                       protofamily = AF_INET;
-                       switch (token) {
-                       case Opt_xprt_udp6:
-                               protofamily = AF_INET6;
-                               /* fall through */
-                       case Opt_xprt_udp:
-                               mnt->flags &= ~NFS_MOUNT_TCP;
-                               mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
-                               break;
-                       case Opt_xprt_tcp6:
-                               protofamily = AF_INET6;
-                               /* fall through */
-                       case Opt_xprt_tcp:
-                               mnt->flags |= NFS_MOUNT_TCP;
-                               mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
-                               break;
-                       case Opt_xprt_rdma6:
-                               protofamily = AF_INET6;
-                               /* fall through */
-                       case Opt_xprt_rdma:
-                               /* vector side protocols to TCP */
-                               mnt->flags |= NFS_MOUNT_TCP;
-                               mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
-                               xprt_load_transport(string);
-                               break;
-                       default:
-                               dfprintk(MOUNT, "NFS:   unrecognized "
-                                               "transport protocol\n");
-                               kfree(string);
-                               return 0;
-                       }
-                       kfree(string);
-                       break;
-               case Opt_mountproto:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-                       token = match_token(string,
-                                           nfs_xprt_protocol_tokens, args);
-                       kfree(string);
-
-                       mountfamily = AF_INET;
-                       switch (token) {
-                       case Opt_xprt_udp6:
-                               mountfamily = AF_INET6;
-                               /* fall through */
-                       case Opt_xprt_udp:
-                               mnt->mount_server.protocol = XPRT_TRANSPORT_UDP;
-                               break;
-                       case Opt_xprt_tcp6:
-                               mountfamily = AF_INET6;
-                               /* fall through */
-                       case Opt_xprt_tcp:
-                               mnt->mount_server.protocol = XPRT_TRANSPORT_TCP;
-                               break;
-                       case Opt_xprt_rdma: /* not used for side protocols */
-                       default:
-                               dfprintk(MOUNT, "NFS:   unrecognized "
-                                               "transport protocol\n");
-                               return 0;
-                       }
-                       break;
-               case Opt_addr:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-                       mnt->nfs_server.addrlen =
-                               rpc_pton(mnt->net, string, strlen(string),
-                                       (struct sockaddr *)
-                                       &mnt->nfs_server.address,
-                                       sizeof(mnt->nfs_server.address));
-                       kfree(string);
-                       if (mnt->nfs_server.addrlen == 0)
-                               goto out_invalid_address;
-                       break;
-               case Opt_clientaddr:
-                       if (nfs_get_option_str(args, &mnt->client_address))
-                               goto out_nomem;
-                       break;
-               case Opt_mounthost:
-                       if (nfs_get_option_str(args,
-                                              &mnt->mount_server.hostname))
-                               goto out_nomem;
-                       break;
-               case Opt_mountaddr:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-                       mnt->mount_server.addrlen =
-                               rpc_pton(mnt->net, string, strlen(string),
-                                       (struct sockaddr *)
-                                       &mnt->mount_server.address,
-                                       sizeof(mnt->mount_server.address));
-                       kfree(string);
-                       if (mnt->mount_server.addrlen == 0)
-                               goto out_invalid_address;
-                       break;
-               case Opt_nconnect:
-                       if (nfs_get_option_ul_bound(args, &option, 1, NFS_MAX_CONNECTIONS))
-                               goto out_invalid_value;
-                       mnt->nfs_server.nconnect = option;
-                       break;
-               case Opt_lookupcache:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-                       token = match_token(string,
-                                       nfs_lookupcache_tokens, args);
-                       kfree(string);
-                       switch (token) {
-                               case Opt_lookupcache_all:
-                                       mnt->flags &= ~(NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE);
-                                       break;
-                               case Opt_lookupcache_positive:
-                                       mnt->flags &= ~NFS_MOUNT_LOOKUP_CACHE_NONE;
-                                       mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG;
-                                       break;
-                               case Opt_lookupcache_none:
-                                       mnt->flags |= NFS_MOUNT_LOOKUP_CACHE_NONEG|NFS_MOUNT_LOOKUP_CACHE_NONE;
-                                       break;
-                               default:
-                                       dfprintk(MOUNT, "NFS:   invalid "
-                                                       "lookupcache argument\n");
-                                       return 0;
-                       }
-                       break;
-               case Opt_fscache_uniq:
-                       if (nfs_get_option_str(args, &mnt->fscache_uniq))
-                               goto out_nomem;
-                       mnt->options |= NFS_OPTION_FSCACHE;
-                       break;
-               case Opt_local_lock:
-                       string = match_strdup(args);
-                       if (string == NULL)
-                               goto out_nomem;
-                       token = match_token(string, nfs_local_lock_tokens,
-                                       args);
-                       kfree(string);
-                       switch (token) {
-                       case Opt_local_lock_all:
-                               mnt->flags |= (NFS_MOUNT_LOCAL_FLOCK |
-                                              NFS_MOUNT_LOCAL_FCNTL);
-                               break;
-                       case Opt_local_lock_flock:
-                               mnt->flags |= NFS_MOUNT_LOCAL_FLOCK;
-                               break;
-                       case Opt_local_lock_posix:
-                               mnt->flags |= NFS_MOUNT_LOCAL_FCNTL;
-                               break;
-                       case Opt_local_lock_none:
-                               mnt->flags &= ~(NFS_MOUNT_LOCAL_FLOCK |
-                                               NFS_MOUNT_LOCAL_FCNTL);
-                               break;
-                       default:
-                               dfprintk(MOUNT, "NFS:   invalid "
-                                               "local_lock argument\n");
-                               return 0;
-                       }
-                       break;
-
-               /*
-                * Special options
-                */
-               case Opt_sloppy:
-                       sloppy = 1;
-                       dfprintk(MOUNT, "NFS:   relaxing parsing rules\n");
-                       break;
-               case Opt_userspace:
-               case Opt_deprecated:
-                       dfprintk(MOUNT, "NFS:   ignoring mount option "
-                                       "'%s'\n", p);
-                       break;
-
-               default:
-                       invalid_option = 1;
-                       dfprintk(MOUNT, "NFS:   unrecognized mount option "
-                                       "'%s'\n", p);
-               }
-       }
-
-       if (!sloppy && invalid_option)
-               return 0;
-
-       if (mnt->minorversion && mnt->version != 4)
-               goto out_minorversion_mismatch;
-
-       if (mnt->options & NFS_OPTION_MIGRATION &&
-           (mnt->version != 4 || mnt->minorversion != 0))
-               goto out_migration_misuse;
-
-       /*
-        * verify that any proto=/mountproto= options match the address
-        * families in the addr=/mountaddr= options.
-        */
-       if (protofamily != AF_UNSPEC &&
-           protofamily != mnt->nfs_server.address.ss_family)
-               goto out_proto_mismatch;
-
-       if (mountfamily != AF_UNSPEC) {
-               if (mnt->mount_server.addrlen) {
-                       if (mountfamily != mnt->mount_server.address.ss_family)
-                               goto out_mountproto_mismatch;
-               } else {
-                       if (mountfamily != mnt->nfs_server.address.ss_family)
-                               goto out_mountproto_mismatch;
-               }
-       }
-
-       return 1;
-
-out_mountproto_mismatch:
-       printk(KERN_INFO "NFS: mount server address does not match mountproto= "
-                        "option\n");
-       return 0;
-out_proto_mismatch:
-       printk(KERN_INFO "NFS: server address does not match proto= option\n");
-       return 0;
-out_invalid_address:
-       printk(KERN_INFO "NFS: bad IP address specified: %s\n", p);
-       return 0;
-out_invalid_value:
-       printk(KERN_INFO "NFS: bad mount option value specified: %s\n", p);
-       return 0;
-out_minorversion_mismatch:
-       printk(KERN_INFO "NFS: mount option vers=%u does not support "
-                        "minorversion=%u\n", mnt->version, mnt->minorversion);
-       return 0;
-out_migration_misuse:
-       printk(KERN_INFO
-               "NFS: 'migration' not supported for this NFS version\n");
-       return 0;
-out_nomem:
-       printk(KERN_INFO "NFS: not enough memory to parse option\n");
-       return 0;
-out_security_failure:
-       printk(KERN_INFO "NFS: security options invalid: %d\n", rc);
-       return 0;
-}
-
-/*
- * Ensure that a specified authtype in args->auth_info is supported by
- * the server. Returns 0 and sets args->selected_flavor if it's ok, and
- * -EACCES if not.
- */
-static int nfs_verify_authflavors(struct nfs_parsed_mount_data *args,
-                       rpc_authflavor_t *server_authlist, unsigned int count)
-{
-       rpc_authflavor_t flavor = RPC_AUTH_MAXFLAVOR;
-       bool found_auth_null = false;
-       unsigned int i;
-
-       /*
-        * If the sec= mount option is used, the specified flavor or AUTH_NULL
-        * must be in the list returned by the server.
-        *
-        * AUTH_NULL has a special meaning when it's in the server list - it
-        * means that the server will ignore the rpc creds, so any flavor
-        * can be used but still use the sec= that was specified.
-        *
-        * Note also that the MNT procedure in MNTv1 does not return a list
-        * of supported security flavors. In this case, nfs_mount() fabricates
-        * a security flavor list containing just AUTH_NULL.
-        */
-       for (i = 0; i < count; i++) {
-               flavor = server_authlist[i];
-
-               if (nfs_auth_info_match(&args->auth_info, flavor))
-                       goto out;
-
-               if (flavor == RPC_AUTH_NULL)
-                       found_auth_null = true;
-       }
-
-       if (found_auth_null) {
-               flavor = args->auth_info.flavors[0];
-               goto out;
-       }
-
-       dfprintk(MOUNT,
-                "NFS: specified auth flavors not supported by server\n");
-       return -EACCES;
-
-out:
-       args->selected_flavor = flavor;
-       dfprintk(MOUNT, "NFS: using auth flavor %u\n", args->selected_flavor);
-       return 0;
-}
-
-/*
- * Use the remote server's MOUNT service to request the NFS file handle
- * corresponding to the provided path.
- */
-static int nfs_request_mount(struct nfs_parsed_mount_data *args,
-                            struct nfs_fh *root_fh,
-                            rpc_authflavor_t *server_authlist,
-                            unsigned int *server_authlist_len)
-{
-       struct nfs_mount_request request = {
-               .sap            = (struct sockaddr *)
-                                               &args->mount_server.address,
-               .dirpath        = args->nfs_server.export_path,
-               .protocol       = args->mount_server.protocol,
-               .fh             = root_fh,
-               .noresvport     = args->flags & NFS_MOUNT_NORESVPORT,
-               .auth_flav_len  = server_authlist_len,
-               .auth_flavs     = server_authlist,
-               .net            = args->net,
-       };
-       int status;
-
-       if (args->mount_server.version == 0) {
-               switch (args->version) {
-                       default:
-                               args->mount_server.version = NFS_MNT3_VERSION;
-                               break;
-                       case 2:
-                               args->mount_server.version = NFS_MNT_VERSION;
-               }
-       }
-       request.version = args->mount_server.version;
-
-       if (args->mount_server.hostname)
-               request.hostname = args->mount_server.hostname;
-       else
-               request.hostname = args->nfs_server.hostname;
-
-       /*
-        * Construct the mount server's address.
-        */
-       if (args->mount_server.address.ss_family == AF_UNSPEC) {
-               memcpy(request.sap, &args->nfs_server.address,
-                      args->nfs_server.addrlen);
-               args->mount_server.addrlen = args->nfs_server.addrlen;
-       }
-       request.salen = args->mount_server.addrlen;
-       nfs_set_port(request.sap, &args->mount_server.port, 0);
-
-       /*
-        * Now ask the mount server to map our export path
-        * to a file handle.
-        */
-       status = nfs_mount(&request);
-       if (status != 0) {
-               dfprintk(MOUNT, "NFS: unable to mount server %s, error %d\n",
-                               request.hostname, status);
-               return status;
-       }
-
-       return 0;
-}
-
-static struct nfs_server *nfs_try_mount_request(struct nfs_mount_info *mount_info,
-                                       struct nfs_subversion *nfs_mod)
-{
-       int status;
-       unsigned int i;
-       bool tried_auth_unix = false;
-       bool auth_null_in_list = false;
-       struct nfs_server *server = ERR_PTR(-EACCES);
-       struct nfs_parsed_mount_data *args = mount_info->parsed;
-       rpc_authflavor_t authlist[NFS_MAX_SECFLAVORS];
-       unsigned int authlist_len = ARRAY_SIZE(authlist);
-
-       status = nfs_request_mount(args, mount_info->mntfh, authlist,
-                                       &authlist_len);
-       if (status)
-               return ERR_PTR(status);
-
-       /*
-        * Was a sec= authflavor specified in the options? First, verify
-        * whether the server supports it, and then just try to use it if so.
-        */
-       if (args->auth_info.flavor_len > 0) {
-               status = nfs_verify_authflavors(args, authlist, authlist_len);
-               dfprintk(MOUNT, "NFS: using auth flavor %u\n",
-                        args->selected_flavor);
-               if (status)
-                       return ERR_PTR(status);
-               return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
-       }
-
-       /*
-        * No sec= option was provided. RFC 2623, section 2.7 suggests we
-        * SHOULD prefer the flavor listed first. However, some servers list
-        * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
-        */
-       for (i = 0; i < authlist_len; ++i) {
-               rpc_authflavor_t flavor;
-               struct rpcsec_gss_info info;
-
-               flavor = authlist[i];
-               switch (flavor) {
-               case RPC_AUTH_UNIX:
-                       tried_auth_unix = true;
-                       break;
-               case RPC_AUTH_NULL:
-                       auth_null_in_list = true;
-                       continue;
-               default:
-                       if (rpcauth_get_gssinfo(flavor, &info) != 0)
-                               continue;
-                       /* Fallthrough */
-               }
-               dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", flavor);
-               args->selected_flavor = flavor;
-               server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
-               if (!IS_ERR(server))
-                       return server;
-       }
-
-       /*
-        * Nothing we tried so far worked. At this point, give up if we've
-        * already tried AUTH_UNIX or if the server's list doesn't contain
-        * AUTH_NULL
-        */
-       if (tried_auth_unix || !auth_null_in_list)
-               return server;
-
-       /* Last chance! Try AUTH_UNIX */
-       dfprintk(MOUNT, "NFS: attempting to use auth flavor %u\n", RPC_AUTH_UNIX);
-       args->selected_flavor = RPC_AUTH_UNIX;
-       return nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
-}
-
-struct dentry *nfs_try_mount(int flags, const char *dev_name,
-                            struct nfs_mount_info *mount_info,
-                            struct nfs_subversion *nfs_mod)
-{
-       struct nfs_server *server;
-
-       if (mount_info->parsed->need_mount)
-               server = nfs_try_mount_request(mount_info, nfs_mod);
-       else
-               server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
-
-       if (IS_ERR(server))
-               return ERR_CAST(server);
-
-       return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
-}
-EXPORT_SYMBOL_GPL(nfs_try_mount);
-
-/*
- * Split "dev_name" into "hostname:export_path".
- *
- * The leftmost colon demarks the split between the server's hostname
- * and the export path.  If the hostname starts with a left square
- * bracket, then it may contain colons.
- *
- * Note: caller frees hostname and export path, even on error.
- */
-static int nfs_parse_devname(const char *dev_name,
-                            char **hostname, size_t maxnamlen,
-                            char **export_path, size_t maxpathlen)
-{
-       size_t len;
-       char *end;
-
-       if (unlikely(!dev_name || !*dev_name)) {
-               dfprintk(MOUNT, "NFS: device name not specified\n");
-               return -EINVAL;
-       }
-
-       /* Is the host name protected with square brakcets? */
-       if (*dev_name == '[') {
-               end = strchr(++dev_name, ']');
-               if (end == NULL || end[1] != ':')
-                       goto out_bad_devname;
-
-               len = end - dev_name;
-               end++;
-       } else {
-               char *comma;
-
-               end = strchr(dev_name, ':');
-               if (end == NULL)
-                       goto out_bad_devname;
-               len = end - dev_name;
-
-               /* kill possible hostname list: not supported */
-               comma = strchr(dev_name, ',');
-               if (comma != NULL && comma < end)
-                       len = comma - dev_name;
-       }
-
-       if (len > maxnamlen)
-               goto out_hostname;
-
-       /* N.B. caller will free nfs_server.hostname in all cases */
-       *hostname = kstrndup(dev_name, len, GFP_KERNEL);
-       if (*hostname == NULL)
-               goto out_nomem;
-       len = strlen(++end);
-       if (len > maxpathlen)
-               goto out_path;
-       *export_path = kstrndup(end, len, GFP_KERNEL);
-       if (!*export_path)
-               goto out_nomem;
-
-       dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", *export_path);
-       return 0;
-
-out_bad_devname:
-       dfprintk(MOUNT, "NFS: device name not in host:path format\n");
-       return -EINVAL;
-
-out_nomem:
-       dfprintk(MOUNT, "NFS: not enough memory to parse device name\n");
-       return -ENOMEM;
-
-out_hostname:
-       dfprintk(MOUNT, "NFS: server hostname too long\n");
-       return -ENAMETOOLONG;
-
-out_path:
-       dfprintk(MOUNT, "NFS: export pathname too long\n");
-       return -ENAMETOOLONG;
-}
-
-/*
- * Validate the NFS2/NFS3 mount data
- * - fills in the mount root filehandle
- *
- * For option strings, user space handles the following behaviors:
- *
- * + DNS: mapping server host name to IP address ("addr=" option)
- *
- * + failure mode: how to behave if a mount request can't be handled
- *   immediately ("fg/bg" option)
- *
- * + retry: how often to retry a mount request ("retry=" option)
- *
- * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
- *   mountproto=tcp after mountproto=udp, and so on
- */
-static int nfs23_validate_mount_data(void *options,
-                                    struct nfs_parsed_mount_data *args,
-                                    struct nfs_fh *mntfh,
-                                    const char *dev_name)
-{
-       struct nfs_mount_data *data = (struct nfs_mount_data *)options;
-       struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
-       int extra_flags = NFS_MOUNT_LEGACY_INTERFACE;
-
-       if (data == NULL)
-               goto out_no_data;
-
-       args->version = NFS_DEFAULT_VERSION;
-       switch (data->version) {
-       case 1:
-               data->namlen = 0; /* fall through */
-       case 2:
-               data->bsize = 0; /* fall through */
-       case 3:
-               if (data->flags & NFS_MOUNT_VER3)
-                       goto out_no_v3;
-               data->root.size = NFS2_FHSIZE;
-               memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
-               /* Turn off security negotiation */
-               extra_flags |= NFS_MOUNT_SECFLAVOUR;
-               /* fall through */
-       case 4:
-               if (data->flags & NFS_MOUNT_SECFLAVOUR)
-                       goto out_no_sec;
-               /* fall through */
-       case 5:
-               memset(data->context, 0, sizeof(data->context));
-               /* fall through */
-       case 6:
-               if (data->flags & NFS_MOUNT_VER3) {
-                       if (data->root.size > NFS3_FHSIZE || data->root.size == 0)
-                               goto out_invalid_fh;
-                       mntfh->size = data->root.size;
-                       args->version = 3;
-               } else {
-                       mntfh->size = NFS2_FHSIZE;
-                       args->version = 2;
-               }
-
-
-               memcpy(mntfh->data, data->root.data, mntfh->size);
-               if (mntfh->size < sizeof(mntfh->data))
-                       memset(mntfh->data + mntfh->size, 0,
-                              sizeof(mntfh->data) - mntfh->size);
-
-               /*
-                * Translate to nfs_parsed_mount_data, which nfs_fill_super
-                * can deal with.
-                */
-               args->flags             = data->flags & NFS_MOUNT_FLAGMASK;
-               args->flags             |= extra_flags;
-               args->rsize             = data->rsize;
-               args->wsize             = data->wsize;
-               args->timeo             = data->timeo;
-               args->retrans           = data->retrans;
-               args->acregmin          = data->acregmin;
-               args->acregmax          = data->acregmax;
-               args->acdirmin          = data->acdirmin;
-               args->acdirmax          = data->acdirmax;
-               args->need_mount        = false;
-
-               memcpy(sap, &data->addr, sizeof(data->addr));
-               args->nfs_server.addrlen = sizeof(data->addr);
-               args->nfs_server.port = ntohs(data->addr.sin_port);
-               if (sap->sa_family != AF_INET ||
-                   !nfs_verify_server_address(sap))
-                       goto out_no_address;
-
-               if (!(data->flags & NFS_MOUNT_TCP))
-                       args->nfs_server.protocol = XPRT_TRANSPORT_UDP;
-               /* N.B. caller will free nfs_server.hostname in all cases */
-               args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
-               args->namlen            = data->namlen;
-               args->bsize             = data->bsize;
-
-               if (data->flags & NFS_MOUNT_SECFLAVOUR)
-                       args->selected_flavor = data->pseudoflavor;
-               else
-                       args->selected_flavor = RPC_AUTH_UNIX;
-               if (!args->nfs_server.hostname)
-                       goto out_nomem;
-
-               if (!(data->flags & NFS_MOUNT_NONLM))
-                       args->flags &= ~(NFS_MOUNT_LOCAL_FLOCK|
-                                        NFS_MOUNT_LOCAL_FCNTL);
-               else
-                       args->flags |= (NFS_MOUNT_LOCAL_FLOCK|
-                                       NFS_MOUNT_LOCAL_FCNTL);
-               /*
-                * The legacy version 6 binary mount data from userspace has a
-                * field used only to transport selinux information into the
-                * the kernel.  To continue to support that functionality we
-                * have a touch of selinux knowledge here in the NFS code. The
-                * userspace code converted context=blah to just blah so we are
-                * converting back to the full string selinux understands.
-                */
-               if (data->context[0]){
-#ifdef CONFIG_SECURITY_SELINUX
-                       int rc;
-                       data->context[NFS_MAX_CONTEXT_LEN] = '\0';
-                       rc = security_add_mnt_opt("context", data->context,
-                                       strlen(data->context), &args->lsm_opts);
-                       if (rc)
-                               return rc;
-#else
-                       return -EINVAL;
-#endif
-               }
-
-               break;
-       default:
-               return NFS_TEXT_DATA;
-       }
-
-       return 0;
-
-out_no_data:
-       dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n");
-       return -EINVAL;
-
-out_no_v3:
-       dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n",
-                data->version);
-       return -EINVAL;
-
-out_no_sec:
-       dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
-       return -EINVAL;
-
-out_nomem:
-       dfprintk(MOUNT, "NFS: not enough memory to handle mount options\n");
-       return -ENOMEM;
-
-out_no_address:
-       dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
-       return -EINVAL;
-
-out_invalid_fh:
-       dfprintk(MOUNT, "NFS: invalid root filehandle\n");
-       return -EINVAL;
-}
-
-#if IS_ENABLED(CONFIG_NFS_V4)
-static int nfs_validate_mount_data(struct file_system_type *fs_type,
-                                  void *options,
-                                  struct nfs_parsed_mount_data *args,
-                                  struct nfs_fh *mntfh,
-                                  const char *dev_name)
-{
-       if (fs_type == &nfs_fs_type)
-               return nfs23_validate_mount_data(options, args, mntfh, dev_name);
-       return nfs4_validate_mount_data(options, args, dev_name);
-}
-#else
-static int nfs_validate_mount_data(struct file_system_type *fs_type,
-                                  void *options,
-                                  struct nfs_parsed_mount_data *args,
-                                  struct nfs_fh *mntfh,
-                                  const char *dev_name)
-{
-       return nfs23_validate_mount_data(options, args, mntfh, dev_name);
-}
-#endif
-
-static int nfs_validate_text_mount_data(void *options,
-                                       struct nfs_parsed_mount_data *args,
-                                       const char *dev_name)
-{
-       int port = 0;
-       int max_namelen = PAGE_SIZE;
-       int max_pathlen = NFS_MAXPATHLEN;
-       struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
-
-       if (nfs_parse_mount_options((char *)options, args) == 0)
-               return -EINVAL;
-
-       if (!nfs_verify_server_address(sap))
-               goto out_no_address;
-
-       if (args->version == 4) {
-#if IS_ENABLED(CONFIG_NFS_V4)
-               if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
-                       port = NFS_RDMA_PORT;
-               else
-                       port = NFS_PORT;
-               max_namelen = NFS4_MAXNAMLEN;
-               max_pathlen = NFS4_MAXPATHLEN;
-               nfs_validate_transport_protocol(args);
-               if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP)
-                       goto out_invalid_transport_udp;
-               nfs4_validate_mount_flags(args);
-#else
-               goto out_v4_not_compiled;
-#endif /* CONFIG_NFS_V4 */
-       } else {
-               nfs_set_mount_transport_protocol(args);
-               if (args->nfs_server.protocol == XPRT_TRANSPORT_RDMA)
-                       port = NFS_RDMA_PORT;
-       }
-
-       nfs_set_port(sap, &args->nfs_server.port, port);
-
-       return nfs_parse_devname(dev_name,
-                                  &args->nfs_server.hostname,
-                                  max_namelen,
-                                  &args->nfs_server.export_path,
-                                  max_pathlen);
-
-#if !IS_ENABLED(CONFIG_NFS_V4)
-out_v4_not_compiled:
-       dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
-       return -EPROTONOSUPPORT;
-#else
-out_invalid_transport_udp:
-       dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n");
-       return -EINVAL;
-#endif /* !CONFIG_NFS_V4 */
-
-out_no_address:
-       dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
-       return -EINVAL;
-}
 
 #define NFS_REMOUNT_CMP_FLAGMASK ~(NFS_MOUNT_INTR \
                | NFS_MOUNT_SECURE \
@@ -2246,39 +906,35 @@ out_no_address:
 
 static int
 nfs_compare_remount_data(struct nfs_server *nfss,
-                        struct nfs_parsed_mount_data *data)
-{
-       if ((data->flags ^ nfss->flags) & NFS_REMOUNT_CMP_FLAGMASK ||
-           data->rsize != nfss->rsize ||
-           data->wsize != nfss->wsize ||
-           data->version != nfss->nfs_client->rpc_ops->version ||
-           data->minorversion != nfss->nfs_client->cl_minorversion ||
-           data->retrans != nfss->client->cl_timeout->to_retries ||
-           !nfs_auth_info_match(&data->auth_info, nfss->client->cl_auth->au_flavor) ||
-           data->acregmin != nfss->acregmin / HZ ||
-           data->acregmax != nfss->acregmax / HZ ||
-           data->acdirmin != nfss->acdirmin / HZ ||
-           data->acdirmax != nfss->acdirmax / HZ ||
-           data->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
-           (data->options & NFS_OPTION_FSCACHE) != (nfss->options & NFS_OPTION_FSCACHE) ||
-           data->nfs_server.port != nfss->port ||
-           data->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
-           !rpc_cmp_addr((struct sockaddr *)&data->nfs_server.address,
+                        struct nfs_fs_context *ctx)
+{
+       if ((ctx->flags ^ nfss->flags) & NFS_REMOUNT_CMP_FLAGMASK ||
+           ctx->rsize != nfss->rsize ||
+           ctx->wsize != nfss->wsize ||
+           ctx->version != nfss->nfs_client->rpc_ops->version ||
+           ctx->minorversion != nfss->nfs_client->cl_minorversion ||
+           ctx->retrans != nfss->client->cl_timeout->to_retries ||
+           !nfs_auth_info_match(&ctx->auth_info, nfss->client->cl_auth->au_flavor) ||
+           ctx->acregmin != nfss->acregmin / HZ ||
+           ctx->acregmax != nfss->acregmax / HZ ||
+           ctx->acdirmin != nfss->acdirmin / HZ ||
+           ctx->acdirmax != nfss->acdirmax / HZ ||
+           ctx->timeo != (10U * nfss->client->cl_timeout->to_initval / HZ) ||
+           (ctx->options & NFS_OPTION_FSCACHE) != (nfss->options & NFS_OPTION_FSCACHE) ||
+           ctx->nfs_server.port != nfss->port ||
+           ctx->nfs_server.addrlen != nfss->nfs_client->cl_addrlen ||
+           !rpc_cmp_addr((struct sockaddr *)&ctx->nfs_server.address,
                          (struct sockaddr *)&nfss->nfs_client->cl_addr))
                return -EINVAL;
 
        return 0;
 }
 
-int
-nfs_remount(struct super_block *sb, int *flags, char *raw_data)
+int nfs_reconfigure(struct fs_context *fc)
 {
-       int error;
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
+       struct super_block *sb = fc->root->d_sb;
        struct nfs_server *nfss = sb->s_fs_info;
-       struct nfs_parsed_mount_data *data;
-       struct nfs_mount_data *options = (struct nfs_mount_data *)raw_data;
-       struct nfs4_mount_data *options4 = (struct nfs4_mount_data *)raw_data;
-       u32 nfsvers = nfss->nfs_client->rpc_ops->version;
 
        sync_filesystem(sb);
 
@@ -2288,92 +944,38 @@ nfs_remount(struct super_block *sb, int *flags, char *raw_data)
         * ones were explicitly specified. Fall back to legacy behavior and
         * just return success.
         */
-       if ((nfsvers == 4 && (!options4 || options4->version == 1)) ||
-           (nfsvers <= 3 && (!options || (options->version >= 1 &&
-                                          options->version <= 6))))
+       if (ctx->skip_reconfig_option_check)
                return 0;
 
-       data = nfs_alloc_parsed_mount_data();
-       if (data == NULL)
-               return -ENOMEM;
-
-       /* fill out struct with values from existing mount */
-       data->flags = nfss->flags;
-       data->rsize = nfss->rsize;
-       data->wsize = nfss->wsize;
-       data->retrans = nfss->client->cl_timeout->to_retries;
-       data->selected_flavor = nfss->client->cl_auth->au_flavor;
-       data->acregmin = nfss->acregmin / HZ;
-       data->acregmax = nfss->acregmax / HZ;
-       data->acdirmin = nfss->acdirmin / HZ;
-       data->acdirmax = nfss->acdirmax / HZ;
-       data->timeo = 10U * nfss->client->cl_timeout->to_initval / HZ;
-       data->nfs_server.port = nfss->port;
-       data->nfs_server.addrlen = nfss->nfs_client->cl_addrlen;
-       data->version = nfsvers;
-       data->minorversion = nfss->nfs_client->cl_minorversion;
-       data->net = current->nsproxy->net_ns;
-       memcpy(&data->nfs_server.address, &nfss->nfs_client->cl_addr,
-               data->nfs_server.addrlen);
-
-       /* overwrite those values with any that were specified */
-       error = -EINVAL;
-       if (!nfs_parse_mount_options((char *)options, data))
-               goto out;
-
        /*
         * noac is a special case. It implies -o sync, but that's not
-        * necessarily reflected in the mtab options. do_remount_sb
+        * necessarily reflected in the mtab options. reconfigure_super
         * will clear SB_SYNCHRONOUS if -o sync wasn't specified in the
         * remount options, so we have to explicitly reset it.
         */
-       if (data->flags & NFS_MOUNT_NOAC)
-               *flags |= SB_SYNCHRONOUS;
+       if (ctx->flags & NFS_MOUNT_NOAC) {
+               fc->sb_flags |= SB_SYNCHRONOUS;
+               fc->sb_flags_mask |= SB_SYNCHRONOUS;
+       }
 
        /* compare new mount options with old ones */
-       error = nfs_compare_remount_data(nfss, data);
-       if (!error)
-               error = security_sb_remount(sb, data->lsm_opts);
-out:
-       nfs_free_parsed_mount_data(data);
-       return error;
-}
-EXPORT_SYMBOL_GPL(nfs_remount);
-
-/*
- * Initialise the common bits of the superblock
- */
-static void nfs_initialise_sb(struct super_block *sb)
-{
-       struct nfs_server *server = NFS_SB(sb);
-
-       sb->s_magic = NFS_SUPER_MAGIC;
-
-       /* We probably want something more informative here */
-       snprintf(sb->s_id, sizeof(sb->s_id),
-                "%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev));
-
-       if (sb->s_blocksize == 0)
-               sb->s_blocksize = nfs_block_bits(server->wsize,
-                                                &sb->s_blocksize_bits);
-
-       nfs_super_set_maxbytes(sb, server->maxfilesize);
+       return nfs_compare_remount_data(nfss, ctx);
 }
+EXPORT_SYMBOL_GPL(nfs_reconfigure);
 
 /*
- * Finish setting up an NFS2/3 superblock
+ * Finish setting up an NFS superblock
  */
-void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
+static void nfs_fill_super(struct super_block *sb, struct nfs_fs_context *ctx)
 {
-       struct nfs_parsed_mount_data *data = mount_info->parsed;
        struct nfs_server *server = NFS_SB(sb);
 
        sb->s_blocksize_bits = 0;
        sb->s_blocksize = 0;
        sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
        sb->s_op = server->nfs_client->cl_nfs_mod->sops;
-       if (data && data->bsize)
-               sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
+       if (ctx && ctx->bsize)
+               sb->s_blocksize = nfs_block_size(ctx->bsize, &sb->s_blocksize_bits);
 
        if (server->nfs_client->rpc_ops->version != 2) {
                /* The VFS shouldn't apply the umask to mode bits. We will do
@@ -2393,53 +995,27 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
                sb->s_time_max = S64_MAX;
        }
 
-       nfs_initialise_sb(sb);
-}
-EXPORT_SYMBOL_GPL(nfs_fill_super);
-
-/*
- * Finish setting up a cloned NFS2/3/4 superblock
- */
-static void nfs_clone_super(struct super_block *sb,
-                           struct nfs_mount_info *mount_info)
-{
-       const struct super_block *old_sb = mount_info->cloned->sb;
-       struct nfs_server *server = NFS_SB(sb);
-
-       sb->s_blocksize_bits = old_sb->s_blocksize_bits;
-       sb->s_blocksize = old_sb->s_blocksize;
-       sb->s_maxbytes = old_sb->s_maxbytes;
-       sb->s_xattr = old_sb->s_xattr;
-       sb->s_op = old_sb->s_op;
-       sb->s_export_op = old_sb->s_export_op;
+       sb->s_magic = NFS_SUPER_MAGIC;
 
-       if (server->nfs_client->rpc_ops->version != 2) {
-               /* The VFS shouldn't apply the umask to mode bits. We will do
-                * so ourselves when necessary.
-                */
-               sb->s_flags |= SB_POSIXACL;
-               sb->s_time_gran = 1;
-       } else
-               sb->s_time_gran = 1000;
+       /* We probably want something more informative here */
+       snprintf(sb->s_id, sizeof(sb->s_id),
+                "%u:%u", MAJOR(sb->s_dev), MINOR(sb->s_dev));
 
-       if (server->nfs_client->rpc_ops->version != 4) {
-               sb->s_time_min = 0;
-               sb->s_time_max = U32_MAX;
-       } else {
-               sb->s_time_min = S64_MIN;
-               sb->s_time_max = S64_MAX;
-       }
+       if (sb->s_blocksize == 0)
+               sb->s_blocksize = nfs_block_bits(server->wsize,
+                                                &sb->s_blocksize_bits);
 
-       nfs_initialise_sb(sb);
+       nfs_super_set_maxbytes(sb, server->maxfilesize);
 }
 
-static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
+static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b,
+                                    const struct fs_context *fc)
 {
        const struct nfs_server *a = s->s_fs_info;
        const struct rpc_clnt *clnt_a = a->client;
        const struct rpc_clnt *clnt_b = b->client;
 
-       if ((s->s_flags & NFS_MS_MASK) != (flags & NFS_MS_MASK))
+       if ((s->s_flags & NFS_SB_MASK) != (fc->sb_flags & NFS_SB_MASK))
                goto Ebusy;
        if (a->nfs_client != b->nfs_client)
                goto Ebusy;
@@ -2464,19 +1040,11 @@ Ebusy:
        return 0;
 }
 
-struct nfs_sb_mountdata {
-       struct nfs_server *server;
-       int mntflags;
-};
-
-static int nfs_set_super(struct super_block *s, void *data)
+static int nfs_set_super(struct super_block *s, struct fs_context *fc)
 {
-       struct nfs_sb_mountdata *sb_mntdata = data;
-       struct nfs_server *server = sb_mntdata->server;
+       struct nfs_server *server = fc->s_fs_info;
        int ret;
 
-       s->s_flags = sb_mntdata->mntflags;
-       s->s_fs_info = server;
        s->s_d_op = server->nfs_client->rpc_ops->dentry_ops;
        ret = set_anon_super(s, server);
        if (ret == 0)
@@ -2541,11 +1109,9 @@ static int nfs_compare_userns(const struct nfs_server *old,
        return 1;
 }
 
-static int nfs_compare_super(struct super_block *sb, void *data)
+static int nfs_compare_super(struct super_block *sb, struct fs_context *fc)
 {
-       struct nfs_sb_mountdata *sb_mntdata = data;
-       struct nfs_server *server = sb_mntdata->server, *old = NFS_SB(sb);
-       int mntflags = sb_mntdata->mntflags;
+       struct nfs_server *server = fc->s_fs_info, *old = NFS_SB(sb);
 
        if (!nfs_compare_super_address(old, server))
                return 0;
@@ -2556,13 +1122,12 @@ static int nfs_compare_super(struct super_block *sb, void *data)
                return 0;
        if (!nfs_compare_userns(old, server))
                return 0;
-       return nfs_compare_mount_options(sb, server, mntflags);
+       return nfs_compare_mount_options(sb, server, fc);
 }
 
 #ifdef CONFIG_NFS_FSCACHE
 static void nfs_get_cache_cookie(struct super_block *sb,
-                                struct nfs_parsed_mount_data *parsed,
-                                struct nfs_clone_mount *cloned)
+                                struct nfs_fs_context *ctx)
 {
        struct nfs_server *nfss = NFS_SB(sb);
        char *uniq = NULL;
@@ -2571,80 +1136,36 @@ static void nfs_get_cache_cookie(struct super_block *sb,
        nfss->fscache_key = NULL;
        nfss->fscache = NULL;
 
-       if (parsed) {
-               if (!(parsed->options & NFS_OPTION_FSCACHE))
-                       return;
-               if (parsed->fscache_uniq) {
-                       uniq = parsed->fscache_uniq;
-                       ulen = strlen(parsed->fscache_uniq);
-               }
-       } else if (cloned) {
-               struct nfs_server *mnt_s = NFS_SB(cloned->sb);
+       if (!ctx)
+               return;
+
+       if (ctx->clone_data.sb) {
+               struct nfs_server *mnt_s = NFS_SB(ctx->clone_data.sb);
                if (!(mnt_s->options & NFS_OPTION_FSCACHE))
                        return;
                if (mnt_s->fscache_key) {
                        uniq = mnt_s->fscache_key->key.uniquifier;
                        ulen = mnt_s->fscache_key->key.uniq_len;
                }
-       } else
+       } else {
+               if (!(ctx->options & NFS_OPTION_FSCACHE))
+                       return;
+               if (ctx->fscache_uniq) {
+                       uniq = ctx->fscache_uniq;
+                       ulen = strlen(ctx->fscache_uniq);
+               }
                return;
+       }
 
        nfs_fscache_get_super_cookie(sb, uniq, ulen);
 }
 #else
 static void nfs_get_cache_cookie(struct super_block *sb,
-                                struct nfs_parsed_mount_data *parsed,
-                                struct nfs_clone_mount *cloned)
+                                struct nfs_fs_context *ctx)
 {
 }
 #endif
 
-int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
-                       struct nfs_mount_info *mount_info)
-{
-       int error;
-       unsigned long kflags = 0, kflags_out = 0;
-       if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
-               kflags |= SECURITY_LSM_NATIVE_LABELS;
-
-       error = security_sb_set_mnt_opts(s, mount_info->parsed->lsm_opts,
-                                               kflags, &kflags_out);
-       if (error)
-               goto err;
-
-       if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
-               !(kflags_out & SECURITY_LSM_NATIVE_LABELS))
-               NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
-err:
-       return error;
-}
-EXPORT_SYMBOL_GPL(nfs_set_sb_security);
-
-int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
-                         struct nfs_mount_info *mount_info)
-{
-       int error;
-       unsigned long kflags = 0, kflags_out = 0;
-
-       /* clone any lsm security options from the parent to the new sb */
-       if (d_inode(mntroot)->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops)
-               return -ESTALE;
-
-       if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
-               kflags |= SECURITY_LSM_NATIVE_LABELS;
-
-       error = security_sb_clone_mnt_opts(mount_info->cloned->sb, s, kflags,
-                       &kflags_out);
-       if (error)
-               return error;
-
-       if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
-               !(kflags_out & SECURITY_LSM_NATIVE_LABELS))
-               NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
-       return 0;
-}
-EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
-
 static void nfs_set_readahead(struct backing_dev_info *bdi,
                              unsigned long iomax_pages)
 {
@@ -2652,35 +1173,40 @@ static void nfs_set_readahead(struct backing_dev_info *bdi,
        bdi->io_pages = iomax_pages;
 }
 
-struct dentry *nfs_fs_mount_common(struct nfs_server *server,
-                                  int flags, const char *dev_name,
-                                  struct nfs_mount_info *mount_info,
-                                  struct nfs_subversion *nfs_mod)
+int nfs_get_tree_common(struct fs_context *fc)
 {
+       struct nfs_fs_context *ctx = nfs_fc2context(fc);
        struct super_block *s;
-       struct dentry *mntroot = ERR_PTR(-ENOMEM);
-       int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
-       struct nfs_sb_mountdata sb_mntdata = {
-               .mntflags = flags,
-               .server = server,
-       };
+       int (*compare_super)(struct super_block *, struct fs_context *) = nfs_compare_super;
+       struct nfs_server *server = ctx->server;
+       unsigned long kflags = 0, kflags_out = 0;
        int error;
 
+       ctx->server = NULL;
+       if (IS_ERR(server))
+               return PTR_ERR(server);
+
        if (server->flags & NFS_MOUNT_UNSHARED)
                compare_super = NULL;
 
        /* -o noac implies -o sync */
        if (server->flags & NFS_MOUNT_NOAC)
-               sb_mntdata.mntflags |= SB_SYNCHRONOUS;
+               fc->sb_flags |= SB_SYNCHRONOUS;
+
+       if (ctx->clone_data.sb)
+               if (ctx->clone_data.sb->s_flags & SB_SYNCHRONOUS)
+                       fc->sb_flags |= SB_SYNCHRONOUS;
 
-       if (mount_info->cloned != NULL && mount_info->cloned->sb != NULL)
-               if (mount_info->cloned->sb->s_flags & SB_SYNCHRONOUS)
-                       sb_mntdata.mntflags |= SB_SYNCHRONOUS;
+       if (server->caps & NFS_CAP_SECURITY_LABEL)
+               fc->lsm_flags |= SECURITY_LSM_NATIVE_LABELS;
 
        /* Get a superblock - note that we may end up sharing one that already exists */
-       s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata);
+       fc->s_fs_info = server;
+       s = sget_fc(fc, compare_super, nfs_set_super);
+       fc->s_fs_info = NULL;
        if (IS_ERR(s)) {
-               mntroot = ERR_CAST(s);
+               error = PTR_ERR(s);
+               nfs_errorf(fc, "NFS: Couldn't get superblock");
                goto out_err_nosb;
        }
 
@@ -2690,88 +1216,66 @@ struct dentry *nfs_fs_mount_common(struct nfs_server *server,
        } else {
                error = super_setup_bdi_name(s, "%u:%u", MAJOR(server->s_dev),
                                             MINOR(server->s_dev));
-               if (error) {
-                       mntroot = ERR_PTR(error);
+               if (error)
                        goto error_splat_super;
-               }
                nfs_set_readahead(s->s_bdi, server->rpages);
                server->super = s;
        }
 
        if (!s->s_root) {
+               unsigned bsize = ctx->clone_data.inherited_bsize;
                /* initial superblock/root creation */
-               mount_info->fill_super(s, mount_info);
-               nfs_get_cache_cookie(s, mount_info->parsed, mount_info->cloned);
-               if (!(server->flags & NFS_MOUNT_UNSHARED))
-                       s->s_iflags |= SB_I_MULTIROOT;
+               nfs_fill_super(s, ctx);
+               if (bsize) {
+                       s->s_blocksize_bits = bsize;
+                       s->s_blocksize = 1U << bsize;
+               }
+               nfs_get_cache_cookie(s, ctx);
        }
 
-       mntroot = nfs_get_root(s, mount_info->mntfh, dev_name);
-       if (IS_ERR(mntroot))
+       error = nfs_get_root(s, fc);
+       if (error < 0) {
+               nfs_errorf(fc, "NFS: Couldn't get root dentry");
                goto error_splat_super;
+       }
 
-       error = mount_info->set_security(s, mntroot, mount_info);
+       if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
+               kflags |= SECURITY_LSM_NATIVE_LABELS;
+       if (ctx->clone_data.sb) {
+               if (d_inode(fc->root)->i_fop != &nfs_dir_operations) {
+                       error = -ESTALE;
+                       goto error_splat_root;
+               }
+               /* clone any lsm security options from the parent to the new sb */
+               error = security_sb_clone_mnt_opts(ctx->clone_data.sb, s, kflags,
+                               &kflags_out);
+       } else {
+               error = security_sb_set_mnt_opts(s, fc->security,
+                                                       kflags, &kflags_out);
+       }
        if (error)
                goto error_splat_root;
+       if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
+               !(kflags_out & SECURITY_LSM_NATIVE_LABELS))
+               NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
 
        s->s_flags |= SB_ACTIVE;
+       error = 0;
 
 out:
-       return mntroot;
+       return error;
 
 out_err_nosb:
        nfs_free_server(server);
        goto out;
 
 error_splat_root:
-       dput(mntroot);
-       mntroot = ERR_PTR(error);
+       dput(fc->root);
+       fc->root = NULL;
 error_splat_super:
        deactivate_locked_super(s);
        goto out;
 }
-EXPORT_SYMBOL_GPL(nfs_fs_mount_common);
-
-struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
-       int flags, const char *dev_name, void *raw_data)
-{
-       struct nfs_mount_info mount_info = {
-               .fill_super = nfs_fill_super,
-               .set_security = nfs_set_sb_security,
-       };
-       struct dentry *mntroot = ERR_PTR(-ENOMEM);
-       struct nfs_subversion *nfs_mod;
-       int error;
-
-       mount_info.parsed = nfs_alloc_parsed_mount_data();
-       mount_info.mntfh = nfs_alloc_fhandle();
-       if (mount_info.parsed == NULL || mount_info.mntfh == NULL)
-               goto out;
-
-       /* Validate the mount data */
-       error = nfs_validate_mount_data(fs_type, raw_data, mount_info.parsed, mount_info.mntfh, dev_name);
-       if (error == NFS_TEXT_DATA)
-               error = nfs_validate_text_mount_data(raw_data, mount_info.parsed, dev_name);
-       if (error < 0) {
-               mntroot = ERR_PTR(error);
-               goto out;
-       }
-
-       nfs_mod = get_nfs_version(mount_info.parsed->version);
-       if (IS_ERR(nfs_mod)) {
-               mntroot = ERR_CAST(nfs_mod);
-               goto out;
-       }
-
-       mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod);
-
-       put_nfs_version(nfs_mod);
-out:
-       nfs_free_parsed_mount_data(mount_info.parsed);
-       nfs_free_fhandle(mount_info.mntfh);
-       return mntroot;
-}
-EXPORT_SYMBOL_GPL(nfs_fs_mount);
 
 /*
  * Destroy an NFS2/3 superblock
@@ -2790,150 +1294,8 @@ void nfs_kill_super(struct super_block *s)
 }
 EXPORT_SYMBOL_GPL(nfs_kill_super);
 
-/*
- * Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
- */
-static struct dentry *
-nfs_xdev_mount(struct file_system_type *fs_type, int flags,
-               const char *dev_name, void *raw_data)
-{
-       struct nfs_clone_mount *data = raw_data;
-       struct nfs_mount_info mount_info = {
-               .fill_super = nfs_clone_super,
-               .set_security = nfs_clone_sb_security,
-               .cloned = data,
-       };
-       struct nfs_server *server;
-       struct dentry *mntroot = ERR_PTR(-ENOMEM);
-       struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod;
-
-       dprintk("--> nfs_xdev_mount()\n");
-
-       mount_info.mntfh = mount_info.cloned->fh;
-
-       /* create a new volume representation */
-       server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
-
-       if (IS_ERR(server))
-               mntroot = ERR_CAST(server);
-       else
-               mntroot = nfs_fs_mount_common(server, flags,
-                               dev_name, &mount_info, nfs_mod);
-
-       dprintk("<-- nfs_xdev_mount() = %ld\n",
-                       IS_ERR(mntroot) ? PTR_ERR(mntroot) : 0L);
-       return mntroot;
-}
-
 #if IS_ENABLED(CONFIG_NFS_V4)
 
-static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
-{
-       args->flags &= ~(NFS_MOUNT_NONLM|NFS_MOUNT_NOACL|NFS_MOUNT_VER3|
-                        NFS_MOUNT_LOCAL_FLOCK|NFS_MOUNT_LOCAL_FCNTL);
-}
-
-/*
- * Validate NFSv4 mount options
- */
-static int nfs4_validate_mount_data(void *options,
-                                   struct nfs_parsed_mount_data *args,
-                                   const char *dev_name)
-{
-       struct sockaddr *sap = (struct sockaddr *)&args->nfs_server.address;
-       struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
-       char *c;
-
-       if (data == NULL)
-               goto out_no_data;
-
-       args->version = 4;
-
-       switch (data->version) {
-       case 1:
-               if (data->host_addrlen > sizeof(args->nfs_server.address))
-                       goto out_no_address;
-               if (data->host_addrlen == 0)
-                       goto out_no_address;
-               args->nfs_server.addrlen = data->host_addrlen;
-               if (copy_from_user(sap, data->host_addr, data->host_addrlen))
-                       return -EFAULT;
-               if (!nfs_verify_server_address(sap))
-                       goto out_no_address;
-               args->nfs_server.port = ntohs(((struct sockaddr_in *)sap)->sin_port);
-
-               if (data->auth_flavourlen) {
-                       rpc_authflavor_t pseudoflavor;
-                       if (data->auth_flavourlen > 1)
-                               goto out_inval_auth;
-                       if (copy_from_user(&pseudoflavor,
-                                          data->auth_flavours,
-                                          sizeof(pseudoflavor)))
-                               return -EFAULT;
-                       args->selected_flavor = pseudoflavor;
-               } else
-                       args->selected_flavor = RPC_AUTH_UNIX;
-
-               c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
-               if (IS_ERR(c))
-                       return PTR_ERR(c);
-               args->nfs_server.hostname = c;
-
-               c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
-               if (IS_ERR(c))
-                       return PTR_ERR(c);
-               args->nfs_server.export_path = c;
-               dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
-
-               c = strndup_user(data->client_addr.data, 16);
-               if (IS_ERR(c))
-                       return PTR_ERR(c);
-               args->client_address = c;
-
-               /*
-                * Translate to nfs_parsed_mount_data, which nfs4_fill_super
-                * can deal with.
-                */
-
-               args->flags     = data->flags & NFS4_MOUNT_FLAGMASK;
-               args->rsize     = data->rsize;
-               args->wsize     = data->wsize;
-               args->timeo     = data->timeo;
-               args->retrans   = data->retrans;
-               args->acregmin  = data->acregmin;
-               args->acregmax  = data->acregmax;
-               args->acdirmin  = data->acdirmin;
-               args->acdirmax  = data->acdirmax;
-               args->nfs_server.protocol = data->proto;
-               nfs_validate_transport_protocol(args);
-               if (args->nfs_server.protocol == XPRT_TRANSPORT_UDP)
-                       goto out_invalid_transport_udp;
-
-               break;
-       default:
-               return NFS_TEXT_DATA;
-       }
-
-       return 0;
-
-out_no_data:
-       dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n");
-       return -EINVAL;
-
-out_inval_auth:
-       dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n",
-                data->auth_flavourlen);
-       return -EINVAL;
-
-out_no_address:
-       dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
-       return -EINVAL;
-
-out_invalid_transport_udp:
-       dfprintk(MOUNT, "NFSv4: Unsupported transport protocol udp\n");
-       return -EINVAL;
-}
-
 /*
  * NFS v4 module parameters need to stay in the
  * NFS client for backwards compatibility
index 52cab65..c478b77 100644 (file)
@@ -243,13 +243,24 @@ out:
 /* A writeback failed: mark the page as bad, and invalidate the page cache */
 static void nfs_set_pageerror(struct address_space *mapping)
 {
+       struct inode *inode = mapping->host;
+
        nfs_zap_mapping(mapping->host, mapping);
+       /* Force file size revalidation */
+       spin_lock(&inode->i_lock);
+       NFS_I(inode)->cache_validity |= NFS_INO_REVAL_FORCED |
+                                       NFS_INO_REVAL_PAGECACHE |
+                                       NFS_INO_INVALID_SIZE;
+       spin_unlock(&inode->i_lock);
 }
 
 static void nfs_mapping_set_error(struct page *page, int error)
 {
+       struct address_space *mapping = page_file_mapping(page);
+
        SetPageError(page);
-       mapping_set_error(page_file_mapping(page), error);
+       mapping_set_error(mapping, error);
+       nfs_set_pageerror(mapping);
 }
 
 /*
@@ -592,7 +603,7 @@ release_request:
 
 static void nfs_write_error(struct nfs_page *req, int error)
 {
-       nfs_set_pageerror(page_file_mapping(req->wb_page));
+       trace_nfs_write_error(req, error);
        nfs_mapping_set_error(req->wb_page, error);
        nfs_inode_remove_request(req);
        nfs_end_page_writeback(req);
@@ -998,7 +1009,7 @@ static void nfs_write_completion(struct nfs_pgio_header *hdr)
                nfs_list_remove_request(req);
                if (test_bit(NFS_IOHDR_ERROR, &hdr->flags) &&
                    (hdr->good_bytes < bytes)) {
-                       nfs_set_pageerror(page_file_mapping(req->wb_page));
+                       trace_nfs_comp_error(req, hdr->error);
                        nfs_mapping_set_error(req->wb_page, hdr->error);
                        goto remove_req;
                }
@@ -1403,8 +1414,7 @@ static void nfs_initiate_write(struct nfs_pgio_header *hdr,
 
        task_setup_data->priority = priority;
        rpc_ops->write_setup(hdr, msg, &task_setup_data->rpc_client);
-       trace_nfs_initiate_write(hdr->inode, hdr->io_start, hdr->good_bytes,
-                                hdr->args.stable);
+       trace_nfs_initiate_write(hdr);
 }
 
 /* If a nfs_flush_* function fails, it should remove reqs from @head and
@@ -1568,8 +1578,7 @@ static int nfs_writeback_done(struct rpc_task *task,
                return status;
 
        nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, hdr->res.count);
-       trace_nfs_writeback_done(inode, task->tk_status,
-                                hdr->args.offset, hdr->res.verf);
+       trace_nfs_writeback_done(task, hdr);
 
        if (hdr->res.verf->committed < hdr->args.stable &&
            task->tk_status >= 0) {
@@ -1649,6 +1658,8 @@ static void nfs_writeback_result(struct rpc_task *task,
                         */
                        argp->stable = NFS_FILE_SYNC;
                }
+               resp->count = 0;
+               resp->verf->committed = 0;
                rpc_restart_call_prepare(task);
        }
 }
@@ -1824,11 +1835,12 @@ static void nfs_commit_done(struct rpc_task *task, void *calldata)
 
        /* Call the NFS version-specific code */
        NFS_PROTO(data->inode)->commit_done(task, data);
-       trace_nfs_commit_done(data);
+       trace_nfs_commit_done(task, data);
 }
 
 static void nfs_commit_release_pages(struct nfs_commit_data *data)
 {
+       const struct nfs_writeverf *verf = data->res.verf;
        struct nfs_page *req;
        int status = data->task.tk_status;
        struct nfs_commit_info cinfo;
@@ -1847,6 +1859,7 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
                        (long long)req_offset(req));
                if (status < 0) {
                        if (req->wb_page) {
+                               trace_nfs_commit_error(req, status);
                                nfs_mapping_set_error(req->wb_page, status);
                                nfs_inode_remove_request(req);
                        }
@@ -1856,7 +1869,8 @@ static void nfs_commit_release_pages(struct nfs_commit_data *data)
 
                /* Okay, COMMIT succeeded, apparently. Check the verifier
                 * returned by the server against all stored verfs. */
-               if (!nfs_write_verifier_cmp(&req->wb_verf, &data->verf.verifier)) {
+               if (verf->committed > NFS_UNSTABLE &&
+                   !nfs_write_verifier_cmp(&req->wb_verf, &verf->verifier)) {
                        /* We have a match */
                        if (req->wb_page)
                                nfs_inode_remove_request(req);
index f2f8156..f368f32 100644 (file)
@@ -134,6 +134,16 @@ config NFSD_FLEXFILELAYOUT
 
          If unsure, say N.
 
+config NFSD_V4_2_INTER_SSC
+       bool "NFSv4.2 inter server to server COPY"
+       depends on NFSD_V4 && NFS_V4_1 && NFS_V4_2
+       help
+         This option enables support for NFSv4.2 inter server to
+         server copy where the destination server calls the NFSv4.2
+         client to read the data to copy from the source server.
+
+         If unsure, say N.
+
 config NFSD_V4_SECURITY_LABEL
        bool "Provide Security Label support for NFSv4 server"
        depends on NFSD_V4 && SECURITY
index 32a9bf2..22e77ed 100644 (file)
@@ -27,7 +27,6 @@
 #define NFSD_FILE_HASH_SIZE                  (1 << NFSD_FILE_HASH_BITS)
 #define NFSD_LAUNDRETTE_DELAY               (2 * HZ)
 
-#define NFSD_FILE_LRU_RESCAN                (0)
 #define NFSD_FILE_SHUTDOWN                  (1)
 #define NFSD_FILE_LRU_THRESHOLD                     (4096UL)
 #define NFSD_FILE_LRU_LIMIT                 (NFSD_FILE_LRU_THRESHOLD << 2)
@@ -44,6 +43,17 @@ struct nfsd_fcache_bucket {
 
 static DEFINE_PER_CPU(unsigned long, nfsd_file_cache_hits);
 
+struct nfsd_fcache_disposal {
+       struct list_head list;
+       struct work_struct work;
+       struct net *net;
+       spinlock_t lock;
+       struct list_head freeme;
+       struct rcu_head rcu;
+};
+
+static struct workqueue_struct *nfsd_filecache_wq __read_mostly;
+
 static struct kmem_cache               *nfsd_file_slab;
 static struct kmem_cache               *nfsd_file_mark_slab;
 static struct nfsd_fcache_bucket       *nfsd_file_hashtbl;
@@ -52,32 +62,21 @@ static long                         nfsd_file_lru_flags;
 static struct fsnotify_group           *nfsd_file_fsnotify_group;
 static atomic_long_t                   nfsd_filecache_count;
 static struct delayed_work             nfsd_filecache_laundrette;
+static DEFINE_SPINLOCK(laundrette_lock);
+static LIST_HEAD(laundrettes);
 
-enum nfsd_file_laundrette_ctl {
-       NFSD_FILE_LAUNDRETTE_NOFLUSH = 0,
-       NFSD_FILE_LAUNDRETTE_MAY_FLUSH
-};
+static void nfsd_file_gc(void);
 
 static void
-nfsd_file_schedule_laundrette(enum nfsd_file_laundrette_ctl ctl)
+nfsd_file_schedule_laundrette(void)
 {
        long count = atomic_long_read(&nfsd_filecache_count);
 
        if (count == 0 || test_bit(NFSD_FILE_SHUTDOWN, &nfsd_file_lru_flags))
                return;
 
-       /* Be more aggressive about scanning if over the threshold */
-       if (count > NFSD_FILE_LRU_THRESHOLD)
-               mod_delayed_work(system_wq, &nfsd_filecache_laundrette, 0);
-       else
-               schedule_delayed_work(&nfsd_filecache_laundrette, NFSD_LAUNDRETTE_DELAY);
-
-       if (ctl == NFSD_FILE_LAUNDRETTE_NOFLUSH)
-               return;
-
-       /* ...and don't delay flushing if we're out of control */
-       if (count >= NFSD_FILE_LRU_LIMIT)
-               flush_delayed_work(&nfsd_filecache_laundrette);
+       queue_delayed_work(system_wq, &nfsd_filecache_laundrette,
+                       NFSD_LAUNDRETTE_DELAY);
 }
 
 static void
@@ -101,7 +100,7 @@ nfsd_file_mark_free(struct fsnotify_mark *mark)
 static struct nfsd_file_mark *
 nfsd_file_mark_get(struct nfsd_file_mark *nfm)
 {
-       if (!atomic_inc_not_zero(&nfm->nfm_ref))
+       if (!refcount_inc_not_zero(&nfm->nfm_ref))
                return NULL;
        return nfm;
 }
@@ -109,8 +108,7 @@ nfsd_file_mark_get(struct nfsd_file_mark *nfm)
 static void
 nfsd_file_mark_put(struct nfsd_file_mark *nfm)
 {
-       if (atomic_dec_and_test(&nfm->nfm_ref)) {
-
+       if (refcount_dec_and_test(&nfm->nfm_ref)) {
                fsnotify_destroy_mark(&nfm->nfm_mark, nfsd_file_fsnotify_group);
                fsnotify_put_mark(&nfm->nfm_mark);
        }
@@ -133,9 +131,13 @@ nfsd_file_mark_find_or_create(struct nfsd_file *nf)
                                                 struct nfsd_file_mark,
                                                 nfm_mark));
                        mutex_unlock(&nfsd_file_fsnotify_group->mark_mutex);
-                       fsnotify_put_mark(mark);
-                       if (likely(nfm))
+                       if (nfm) {
+                               fsnotify_put_mark(mark);
                                break;
+                       }
+                       /* Avoid soft lockup race with nfsd_file_mark_put() */
+                       fsnotify_destroy_mark(mark, nfsd_file_fsnotify_group);
+                       fsnotify_put_mark(mark);
                } else
                        mutex_unlock(&nfsd_file_fsnotify_group->mark_mutex);
 
@@ -145,7 +147,7 @@ nfsd_file_mark_find_or_create(struct nfsd_file *nf)
                        return NULL;
                fsnotify_init_mark(&new->nfm_mark, nfsd_file_fsnotify_group);
                new->nfm_mark.mask = FS_ATTRIB|FS_DELETE_SELF;
-               atomic_set(&new->nfm_ref, 1);
+               refcount_set(&new->nfm_ref, 1);
 
                err = fsnotify_add_inode_mark(&new->nfm_mark, inode, 0);
 
@@ -183,7 +185,7 @@ nfsd_file_alloc(struct inode *inode, unsigned int may, unsigned int hashval,
                nf->nf_flags = 0;
                nf->nf_inode = inode;
                nf->nf_hashval = hashval;
-               atomic_set(&nf->nf_ref, 1);
+               refcount_set(&nf->nf_ref, 1);
                nf->nf_may = may & NFSD_FILE_MAY_MASK;
                if (may & NFSD_MAY_NOT_BREAK_LEASE) {
                        if (may & NFSD_MAY_WRITE)
@@ -192,6 +194,7 @@ nfsd_file_alloc(struct inode *inode, unsigned int may, unsigned int hashval,
                                __set_bit(NFSD_FILE_BREAK_READ, &nf->nf_flags);
                }
                nf->nf_mark = NULL;
+               init_rwsem(&nf->nf_rwsem);
                trace_nfsd_file_alloc(nf);
        }
        return nf;
@@ -238,13 +241,6 @@ nfsd_file_check_write_error(struct nfsd_file *nf)
        return filemap_check_wb_err(file->f_mapping, READ_ONCE(file->f_wb_err));
 }
 
-static bool
-nfsd_file_in_use(struct nfsd_file *nf)
-{
-       return nfsd_file_check_writeback(nf) ||
-                       nfsd_file_check_write_error(nf);
-}
-
 static void
 nfsd_file_do_unhash(struct nfsd_file *nf)
 {
@@ -256,8 +252,6 @@ nfsd_file_do_unhash(struct nfsd_file *nf)
                nfsd_reset_boot_verifier(net_generic(nf->nf_net, nfsd_net_id));
        --nfsd_file_hashtbl[nf->nf_hashval].nfb_count;
        hlist_del_rcu(&nf->nf_node);
-       if (!list_empty(&nf->nf_lru))
-               list_lru_del(&nfsd_file_lru, &nf->nf_lru);
        atomic_long_dec(&nfsd_filecache_count);
 }
 
@@ -266,6 +260,8 @@ nfsd_file_unhash(struct nfsd_file *nf)
 {
        if (test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
                nfsd_file_do_unhash(nf);
+               if (!list_empty(&nf->nf_lru))
+                       list_lru_del(&nfsd_file_lru, &nf->nf_lru);
                return true;
        }
        return false;
@@ -283,42 +279,48 @@ nfsd_file_unhash_and_release_locked(struct nfsd_file *nf, struct list_head *disp
        if (!nfsd_file_unhash(nf))
                return false;
        /* keep final reference for nfsd_file_lru_dispose */
-       if (atomic_add_unless(&nf->nf_ref, -1, 1))
+       if (refcount_dec_not_one(&nf->nf_ref))
                return true;
 
        list_add(&nf->nf_lru, dispose);
        return true;
 }
 
-static int
+static void
 nfsd_file_put_noref(struct nfsd_file *nf)
 {
-       int count;
        trace_nfsd_file_put(nf);
 
-       count = atomic_dec_return(&nf->nf_ref);
-       if (!count) {
+       if (refcount_dec_and_test(&nf->nf_ref)) {
                WARN_ON(test_bit(NFSD_FILE_HASHED, &nf->nf_flags));
                nfsd_file_free(nf);
        }
-       return count;
 }
 
 void
 nfsd_file_put(struct nfsd_file *nf)
 {
-       bool is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
-       bool unused = !nfsd_file_in_use(nf);
+       bool is_hashed;
 
        set_bit(NFSD_FILE_REFERENCED, &nf->nf_flags);
-       if (nfsd_file_put_noref(nf) == 1 && is_hashed && unused)
-               nfsd_file_schedule_laundrette(NFSD_FILE_LAUNDRETTE_MAY_FLUSH);
+       if (refcount_read(&nf->nf_ref) > 2 || !nf->nf_file) {
+               nfsd_file_put_noref(nf);
+               return;
+       }
+
+       filemap_flush(nf->nf_file->f_mapping);
+       is_hashed = test_bit(NFSD_FILE_HASHED, &nf->nf_flags) != 0;
+       nfsd_file_put_noref(nf);
+       if (is_hashed)
+               nfsd_file_schedule_laundrette();
+       if (atomic_long_read(&nfsd_filecache_count) >= NFSD_FILE_LRU_LIMIT)
+               nfsd_file_gc();
 }
 
 struct nfsd_file *
 nfsd_file_get(struct nfsd_file *nf)
 {
-       if (likely(atomic_inc_not_zero(&nf->nf_ref)))
+       if (likely(refcount_inc_not_zero(&nf->nf_ref)))
                return nf;
        return NULL;
 }
@@ -344,7 +346,7 @@ nfsd_file_dispose_list_sync(struct list_head *dispose)
        while(!list_empty(dispose)) {
                nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
                list_del(&nf->nf_lru);
-               if (!atomic_dec_and_test(&nf->nf_ref))
+               if (!refcount_dec_and_test(&nf->nf_ref))
                        continue;
                if (nfsd_file_free(nf))
                        flush = true;
@@ -353,6 +355,58 @@ nfsd_file_dispose_list_sync(struct list_head *dispose)
                flush_delayed_fput();
 }
 
+static void
+nfsd_file_list_remove_disposal(struct list_head *dst,
+               struct nfsd_fcache_disposal *l)
+{
+       spin_lock(&l->lock);
+       list_splice_init(&l->freeme, dst);
+       spin_unlock(&l->lock);
+}
+
+static void
+nfsd_file_list_add_disposal(struct list_head *files, struct net *net)
+{
+       struct nfsd_fcache_disposal *l;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(l, &laundrettes, list) {
+               if (l->net == net) {
+                       spin_lock(&l->lock);
+                       list_splice_tail_init(files, &l->freeme);
+                       spin_unlock(&l->lock);
+                       queue_work(nfsd_filecache_wq, &l->work);
+                       break;
+               }
+       }
+       rcu_read_unlock();
+}
+
+static void
+nfsd_file_list_add_pernet(struct list_head *dst, struct list_head *src,
+               struct net *net)
+{
+       struct nfsd_file *nf, *tmp;
+
+       list_for_each_entry_safe(nf, tmp, src, nf_lru) {
+               if (nf->nf_net == net)
+                       list_move_tail(&nf->nf_lru, dst);
+       }
+}
+
+static void
+nfsd_file_dispose_list_delayed(struct list_head *dispose)
+{
+       LIST_HEAD(list);
+       struct nfsd_file *nf;
+
+       while(!list_empty(dispose)) {
+               nf = list_first_entry(dispose, struct nfsd_file, nf_lru);
+               nfsd_file_list_add_pernet(&list, dispose, nf->nf_net);
+               nfsd_file_list_add_disposal(&list, nf->nf_net);
+       }
+}
+
 /*
  * Note this can deadlock with nfsd_file_cache_purge.
  */
@@ -375,7 +429,7 @@ nfsd_file_lru_cb(struct list_head *item, struct list_lru_one *lru,
         * counter. Here we check the counter and then test and clear the flag.
         * That order is deliberate to ensure that we can do this locklessly.
         */
-       if (atomic_read(&nf->nf_ref) > 1)
+       if (refcount_read(&nf->nf_ref) > 1)
                goto out_skip;
 
        /*
@@ -386,31 +440,51 @@ nfsd_file_lru_cb(struct list_head *item, struct list_lru_one *lru,
                goto out_skip;
 
        if (test_and_clear_bit(NFSD_FILE_REFERENCED, &nf->nf_flags))
-               goto out_rescan;
+               goto out_skip;
 
        if (!test_and_clear_bit(NFSD_FILE_HASHED, &nf->nf_flags))
                goto out_skip;
 
        list_lru_isolate_move(lru, &nf->nf_lru, head);
        return LRU_REMOVED;
-out_rescan:
-       set_bit(NFSD_FILE_LRU_RESCAN, &nfsd_file_lru_flags);
 out_skip:
        return LRU_SKIP;
 }
 
-static void
-nfsd_file_lru_dispose(struct list_head *head)
+static unsigned long
+nfsd_file_lru_walk_list(struct shrink_control *sc)
 {
-       while(!list_empty(head)) {
-               struct nfsd_file *nf = list_first_entry(head,
-                               struct nfsd_file, nf_lru);
-               list_del_init(&nf->nf_lru);
+       LIST_HEAD(head);
+       struct nfsd_file *nf;
+       unsigned long ret;
+
+       if (sc)
+               ret = list_lru_shrink_walk(&nfsd_file_lru, sc,
+                               nfsd_file_lru_cb, &head);
+       else
+               ret = list_lru_walk(&nfsd_file_lru,
+                               nfsd_file_lru_cb,
+                               &head, LONG_MAX);
+       list_for_each_entry(nf, &head, nf_lru) {
                spin_lock(&nfsd_file_hashtbl[nf->nf_hashval].nfb_lock);
                nfsd_file_do_unhash(nf);
                spin_unlock(&nfsd_file_hashtbl[nf->nf_hashval].nfb_lock);
-               nfsd_file_put_noref(nf);
        }
+       nfsd_file_dispose_list_delayed(&head);
+       return ret;
+}
+
+static void
+nfsd_file_gc(void)
+{
+       nfsd_file_lru_walk_list(NULL);
+}
+
+static void
+nfsd_file_gc_worker(struct work_struct *work)
+{
+       nfsd_file_gc();
+       nfsd_file_schedule_laundrette();
 }
 
 static unsigned long
@@ -422,12 +496,7 @@ nfsd_file_lru_count(struct shrinker *s, struct shrink_control *sc)
 static unsigned long
 nfsd_file_lru_scan(struct shrinker *s, struct shrink_control *sc)
 {
-       LIST_HEAD(head);
-       unsigned long ret;
-
-       ret = list_lru_shrink_walk(&nfsd_file_lru, sc, nfsd_file_lru_cb, &head);
-       nfsd_file_lru_dispose(&head);
-       return ret;
+       return nfsd_file_lru_walk_list(sc);
 }
 
 static struct shrinker nfsd_file_shrinker = {
@@ -489,7 +558,7 @@ nfsd_file_close_inode(struct inode *inode)
 
        __nfsd_file_close_inode(inode, hashval, &dispose);
        trace_nfsd_file_close_inode(inode, hashval, !list_empty(&dispose));
-       nfsd_file_dispose_list(&dispose);
+       nfsd_file_dispose_list_delayed(&dispose);
 }
 
 /**
@@ -505,16 +574,11 @@ static void
 nfsd_file_delayed_close(struct work_struct *work)
 {
        LIST_HEAD(head);
+       struct nfsd_fcache_disposal *l = container_of(work,
+                       struct nfsd_fcache_disposal, work);
 
-       list_lru_walk(&nfsd_file_lru, nfsd_file_lru_cb, &head, LONG_MAX);
-
-       if (test_and_clear_bit(NFSD_FILE_LRU_RESCAN, &nfsd_file_lru_flags))
-               nfsd_file_schedule_laundrette(NFSD_FILE_LAUNDRETTE_NOFLUSH);
-
-       if (!list_empty(&head)) {
-               nfsd_file_lru_dispose(&head);
-               flush_delayed_fput();
-       }
+       nfsd_file_list_remove_disposal(&head, l);
+       nfsd_file_dispose_list(&head);
 }
 
 static int
@@ -575,6 +639,10 @@ nfsd_file_cache_init(void)
        if (nfsd_file_hashtbl)
                return 0;
 
+       nfsd_filecache_wq = alloc_workqueue("nfsd_filecache", 0, 0);
+       if (!nfsd_filecache_wq)
+               goto out;
+
        nfsd_file_hashtbl = kcalloc(NFSD_FILE_HASH_SIZE,
                                sizeof(*nfsd_file_hashtbl), GFP_KERNEL);
        if (!nfsd_file_hashtbl) {
@@ -628,7 +696,7 @@ nfsd_file_cache_init(void)
                spin_lock_init(&nfsd_file_hashtbl[i].nfb_lock);
        }
 
-       INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_delayed_close);
+       INIT_DELAYED_WORK(&nfsd_filecache_laundrette, nfsd_file_gc_worker);
 out:
        return ret;
 out_notifier:
@@ -644,6 +712,8 @@ out_err:
        nfsd_file_mark_slab = NULL;
        kfree(nfsd_file_hashtbl);
        nfsd_file_hashtbl = NULL;
+       destroy_workqueue(nfsd_filecache_wq);
+       nfsd_filecache_wq = NULL;
        goto out;
 }
 
@@ -682,6 +752,88 @@ nfsd_file_cache_purge(struct net *net)
        }
 }
 
+static struct nfsd_fcache_disposal *
+nfsd_alloc_fcache_disposal(struct net *net)
+{
+       struct nfsd_fcache_disposal *l;
+
+       l = kmalloc(sizeof(*l), GFP_KERNEL);
+       if (!l)
+               return NULL;
+       INIT_WORK(&l->work, nfsd_file_delayed_close);
+       l->net = net;
+       spin_lock_init(&l->lock);
+       INIT_LIST_HEAD(&l->freeme);
+       return l;
+}
+
+static void
+nfsd_free_fcache_disposal(struct nfsd_fcache_disposal *l)
+{
+       rcu_assign_pointer(l->net, NULL);
+       cancel_work_sync(&l->work);
+       nfsd_file_dispose_list(&l->freeme);
+       kfree_rcu(l, rcu);
+}
+
+static void
+nfsd_add_fcache_disposal(struct nfsd_fcache_disposal *l)
+{
+       spin_lock(&laundrette_lock);
+       list_add_tail_rcu(&l->list, &laundrettes);
+       spin_unlock(&laundrette_lock);
+}
+
+static void
+nfsd_del_fcache_disposal(struct nfsd_fcache_disposal *l)
+{
+       spin_lock(&laundrette_lock);
+       list_del_rcu(&l->list);
+       spin_unlock(&laundrette_lock);
+}
+
+static int
+nfsd_alloc_fcache_disposal_net(struct net *net)
+{
+       struct nfsd_fcache_disposal *l;
+
+       l = nfsd_alloc_fcache_disposal(net);
+       if (!l)
+               return -ENOMEM;
+       nfsd_add_fcache_disposal(l);
+       return 0;
+}
+
+static void
+nfsd_free_fcache_disposal_net(struct net *net)
+{
+       struct nfsd_fcache_disposal *l;
+
+       rcu_read_lock();
+       list_for_each_entry_rcu(l, &laundrettes, list) {
+               if (l->net != net)
+                       continue;
+               nfsd_del_fcache_disposal(l);
+               rcu_read_unlock();
+               nfsd_free_fcache_disposal(l);
+               return;
+       }
+       rcu_read_unlock();
+}
+
+int
+nfsd_file_cache_start_net(struct net *net)
+{
+       return nfsd_alloc_fcache_disposal_net(net);
+}
+
+void
+nfsd_file_cache_shutdown_net(struct net *net)
+{
+       nfsd_file_cache_purge(net);
+       nfsd_free_fcache_disposal_net(net);
+}
+
 void
 nfsd_file_cache_shutdown(void)
 {
@@ -706,6 +858,8 @@ nfsd_file_cache_shutdown(void)
        nfsd_file_mark_slab = NULL;
        kfree(nfsd_file_hashtbl);
        nfsd_file_hashtbl = NULL;
+       destroy_workqueue(nfsd_filecache_wq);
+       nfsd_filecache_wq = NULL;
 }
 
 static bool
@@ -789,6 +943,7 @@ nfsd_file_acquire(struct svc_rqst *rqstp, struct svc_fh *fhp,
        struct nfsd_file *nf, *new;
        struct inode *inode;
        unsigned int hashval;
+       bool retry = true;
 
        /* FIXME: skip this if fh_dentry is already set? */
        status = fh_verify(rqstp, fhp, S_IFREG,
@@ -824,6 +979,11 @@ wait_for_construction:
 
        /* Did construction of this file fail? */
        if (!test_bit(NFSD_FILE_HASHED, &nf->nf_flags)) {
+               if (!retry) {
+                       status = nfserr_jukebox;
+                       goto out;
+               }
+               retry = false;
                nfsd_file_put_noref(nf);
                goto retry;
        }
@@ -858,7 +1018,7 @@ out:
 open_file:
        nf = new;
        /* Take reference for the hashtable */
-       atomic_inc(&nf->nf_ref);
+       refcount_inc(&nf->nf_ref);
        __set_bit(NFSD_FILE_HASHED, &nf->nf_flags);
        __set_bit(NFSD_FILE_PENDING, &nf->nf_flags);
        list_lru_add(&nfsd_file_lru, &nf->nf_lru);
@@ -867,7 +1027,8 @@ open_file:
        nfsd_file_hashtbl[hashval].nfb_maxcount = max(nfsd_file_hashtbl[hashval].nfb_maxcount,
                        nfsd_file_hashtbl[hashval].nfb_count);
        spin_unlock(&nfsd_file_hashtbl[hashval].nfb_lock);
-       atomic_long_inc(&nfsd_filecache_count);
+       if (atomic_long_inc_return(&nfsd_filecache_count) >= NFSD_FILE_LRU_THRESHOLD)
+               nfsd_file_gc();
 
        nf->nf_mark = nfsd_file_mark_find_or_create(nf);
        if (nf->nf_mark)
index 851d9ab..7872df5 100644 (file)
@@ -19,7 +19,7 @@
  */
 struct nfsd_file_mark {
        struct fsnotify_mark    nfm_mark;
-       atomic_t                nfm_ref;
+       refcount_t              nfm_ref;
 };
 
 /*
@@ -43,14 +43,17 @@ struct nfsd_file {
        unsigned long           nf_flags;
        struct inode            *nf_inode;
        unsigned int            nf_hashval;
-       atomic_t                nf_ref;
+       refcount_t              nf_ref;
        unsigned char           nf_may;
        struct nfsd_file_mark   *nf_mark;
+       struct rw_semaphore     nf_rwsem;
 };
 
 int nfsd_file_cache_init(void);
 void nfsd_file_cache_purge(struct net *);
 void nfsd_file_cache_shutdown(void);
+int nfsd_file_cache_start_net(struct net *net);
+void nfsd_file_cache_shutdown_net(struct net *net);
 void nfsd_file_put(struct nfsd_file *nf);
 struct nfsd_file *nfsd_file_get(struct nfsd_file *nf);
 void nfsd_file_close_inode_sync(struct inode *inode);
index 9a4ef81..2baf323 100644 (file)
@@ -40,7 +40,7 @@ struct nfsd_net {
 
        struct lock_manager nfsd4_manager;
        bool grace_ended;
-       time_t boot_time;
+       time64_t boot_time;
 
        /* internal mount of the "nfsd" pseudofilesystem: */
        struct vfsmount *nfsd_mnt;
@@ -92,8 +92,8 @@ struct nfsd_net {
        bool in_grace;
        const struct nfsd4_client_tracking_ops *client_tracking_ops;
 
-       time_t nfsd4_lease;
-       time_t nfsd4_grace;
+       time64_t nfsd4_lease;
+       time64_t nfsd4_grace;
        bool somebody_reclaimed;
 
        bool track_reclaim_completes;
index cea68d8..288bc76 100644 (file)
@@ -203,7 +203,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
                RETURN_STATUS(nfserr_io);
        nfserr = nfsd_write(rqstp, &resp->fh, argp->offset,
                            rqstp->rq_vec, nvecs, &cnt,
-                           resp->committed);
+                           resp->committed, resp->verf);
        resp->count = cnt;
        RETURN_STATUS(nfserr);
 }
@@ -683,7 +683,8 @@ nfsd3_proc_commit(struct svc_rqst *rqstp)
                RETURN_STATUS(nfserr_inval);
 
        fh_copy(&resp->fh, &argp->fh);
-       nfserr = nfsd_commit(rqstp, &resp->fh, argp->offset, argp->count);
+       nfserr = nfsd_commit(rqstp, &resp->fh, argp->offset, argp->count,
+                       resp->verf);
 
        RETURN_STATUS(nfserr);
 }
index 195ab7a..aae514d 100644 (file)
@@ -32,14 +32,14 @@ static u32  nfs3_ftypes[] = {
  * XDR functions for basic NFS types
  */
 static __be32 *
-encode_time3(__be32 *p, struct timespec *time)
+encode_time3(__be32 *p, struct timespec64 *time)
 {
        *p++ = htonl((u32) time->tv_sec); *p++ = htonl(time->tv_nsec);
        return p;
 }
 
 static __be32 *
-decode_time3(__be32 *p, struct timespec *time)
+decode_time3(__be32 *p, struct timespec64 *time)
 {
        time->tv_sec = ntohl(*p++);
        time->tv_nsec = ntohl(*p++);
@@ -167,7 +167,6 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
              struct kstat *stat)
 {
        struct user_namespace *userns = nfsd_user_namespace(rqstp);
-       struct timespec ts;
        *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
        *p++ = htonl((u32) (stat->mode & S_IALLUGO));
        *p++ = htonl((u32) stat->nlink);
@@ -183,12 +182,9 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
        *p++ = htonl((u32) MINOR(stat->rdev));
        p = encode_fsid(p, fhp);
        p = xdr_encode_hyper(p, stat->ino);
-       ts = timespec64_to_timespec(stat->atime);
-       p = encode_time3(p, &ts);
-       ts = timespec64_to_timespec(stat->mtime);
-       p = encode_time3(p, &ts);
-       ts = timespec64_to_timespec(stat->ctime);
-       p = encode_time3(p, &ts);
+       p = encode_time3(p, &stat->atime);
+       p = encode_time3(p, &stat->mtime);
+       p = encode_time3(p, &stat->ctime);
 
        return p;
 }
@@ -277,8 +273,8 @@ void fill_pre_wcc(struct svc_fh *fhp)
                stat.size  = inode->i_size;
        }
 
-       fhp->fh_pre_mtime = timespec64_to_timespec(stat.mtime);
-       fhp->fh_pre_ctime = timespec64_to_timespec(stat.ctime);
+       fhp->fh_pre_mtime = stat.mtime;
+       fhp->fh_pre_ctime = stat.ctime;
        fhp->fh_pre_size  = stat.size;
        fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
        fhp->fh_pre_saved = true;
@@ -330,7 +326,7 @@ nfs3svc_decode_sattrargs(struct svc_rqst *rqstp, __be32 *p)
        p = decode_sattr3(p, &args->attrs, nfsd_user_namespace(rqstp));
 
        if ((args->check_guard = ntohl(*p++)) != 0) { 
-               struct timespec time; 
+               struct timespec64 time;
                p = decode_time3(p, &time);
                args->guardtime = time.tv_sec;
        }
@@ -751,17 +747,13 @@ int
 nfs3svc_encode_writeres(struct svc_rqst *rqstp, __be32 *p)
 {
        struct nfsd3_writeres *resp = rqstp->rq_resp;
-       struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
-       __be32 verf[2];
 
        p = encode_wcc_data(rqstp, p, &resp->fh);
        if (resp->status == 0) {
                *p++ = htonl(resp->count);
                *p++ = htonl(resp->committed);
-               /* unique identifier, y2038 overflow can be ignored */
-               nfsd_copy_boot_verifier(verf, nn);
-               *p++ = verf[0];
-               *p++ = verf[1];
+               *p++ = resp->verf[0];
+               *p++ = resp->verf[1];
        }
        return xdr_ressize_check(rqstp, p);
 }
@@ -1125,16 +1117,12 @@ int
 nfs3svc_encode_commitres(struct svc_rqst *rqstp, __be32 *p)
 {
        struct nfsd3_commitres *resp = rqstp->rq_resp;
-       struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
-       __be32 verf[2];
 
        p = encode_wcc_data(rqstp, p, &resp->fh);
        /* Write verifier */
        if (resp->status == 0) {
-               /* unique identifier, y2038 overflow can be ignored */
-               nfsd_copy_boot_verifier(verf, nn);
-               *p++ = verf[0];
-               *p++ = verf[1];
+               *p++ = resp->verf[0];
+               *p++ = resp->verf[1];
        }
        return xdr_ressize_check(rqstp, p);
 }
index 24534db..c3b11a7 100644 (file)
@@ -823,7 +823,16 @@ static const struct rpc_program cb_program = {
 static int max_cb_time(struct net *net)
 {
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
-       return max(nn->nfsd4_lease/10, (time_t)1) * HZ;
+
+       /*
+        * nfsd4_lease is set to at most one hour in __nfsd4_write_time,
+        * so we can use 32-bit math on it. Warn if that assumption
+        * ever stops being true.
+        */
+       if (WARN_ON_ONCE(nn->nfsd4_lease > 3600))
+               return 360 * HZ;
+
+       return max(((u32)nn->nfsd4_lease)/10, 1u) * HZ;
 }
 
 static struct workqueue_struct *callback_wq;
index 2681c70..e12409e 100644 (file)
@@ -675,7 +675,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
 
                /* Client gets 2 lease periods to return it */
                cutoff = ktime_add_ns(task->tk_start,
-                                        nn->nfsd4_lease * NSEC_PER_SEC * 2);
+                                        (u64)nn->nfsd4_lease * NSEC_PER_SEC * 2);
 
                if (ktime_before(now, cutoff)) {
                        rpc_delay(task, HZ/100); /* 10 mili-seconds */
index 4798667..0e75f7f 100644 (file)
@@ -37,6 +37,7 @@
 #include <linux/falloc.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/sunrpc/addr.h>
 
 #include "idmap.h"
 #include "cache.h"
@@ -232,7 +233,7 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
        if (!*resfh)
                return nfserr_jukebox;
        fh_init(*resfh, NFS4_FHSIZE);
-       open->op_truncate = 0;
+       open->op_truncate = false;
 
        if (open->op_create) {
                /* FIXME: check session persistence and pnfs flags.
@@ -365,7 +366,7 @@ nfsd4_open(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (open->op_create && open->op_claim_type != NFS4_OPEN_CLAIM_NULL)
                return nfserr_inval;
 
-       open->op_created = 0;
+       open->op_created = false;
        /*
         * RFC5661 18.51.3
         * Before RECLAIM_COMPLETE done, server should deny new lock
@@ -503,12 +504,20 @@ nfsd4_putfh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
            union nfsd4_op_u *u)
 {
        struct nfsd4_putfh *putfh = &u->putfh;
+       __be32 ret;
 
        fh_put(&cstate->current_fh);
        cstate->current_fh.fh_handle.fh_size = putfh->pf_fhlen;
        memcpy(&cstate->current_fh.fh_handle.fh_base, putfh->pf_fhval,
               putfh->pf_fhlen);
-       return fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS);
+       ret = fh_verify(rqstp, &cstate->current_fh, 0, NFSD_MAY_BYPASS_GSS);
+#ifdef CONFIG_NFSD_V4_2_INTER_SSC
+       if (ret == nfserr_stale && putfh->no_verify) {
+               SET_FH_FLAG(&cstate->current_fh, NFSD4_FH_FOREIGN);
+               ret = 0;
+       }
+#endif
+       return ret;
 }
 
 static __be32
@@ -530,9 +539,9 @@ nfsd4_restorefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                return nfserr_restorefh;
 
        fh_dup2(&cstate->current_fh, &cstate->save_fh);
-       if (HAS_STATE_ID(cstate, SAVED_STATE_ID_FLAG)) {
+       if (HAS_CSTATE_FLAG(cstate, SAVED_STATE_ID_FLAG)) {
                memcpy(&cstate->current_stateid, &cstate->save_stateid, sizeof(stateid_t));
-               SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
+               SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG);
        }
        return nfs_ok;
 }
@@ -542,9 +551,9 @@ nfsd4_savefh(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
             union nfsd4_op_u *u)
 {
        fh_dup2(&cstate->save_fh, &cstate->current_fh);
-       if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG)) {
+       if (HAS_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG)) {
                memcpy(&cstate->save_stateid, &cstate->current_stateid, sizeof(stateid_t));
-               SET_STATE_ID(cstate, SAVED_STATE_ID_FLAG);
+               SET_CSTATE_FLAG(cstate, SAVED_STATE_ID_FLAG);
        }
        return nfs_ok;
 }
@@ -581,9 +590,9 @@ nfsd4_commit(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 {
        struct nfsd4_commit *commit = &u->commit;
 
-       gen_boot_verifier(&commit->co_verf, SVC_NET(rqstp));
        return nfsd_commit(rqstp, &cstate->current_fh, commit->co_offset,
-                            commit->co_count);
+                            commit->co_count,
+                            (__be32 *)commit->co_verf.data);
 }
 
 static __be32
@@ -776,7 +785,7 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        /* check stateid */
        status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
                                        &read->rd_stateid, RD_STATE,
-                                       &read->rd_nf);
+                                       &read->rd_nf, NULL);
        if (status) {
                dprintk("NFSD: nfsd4_read: couldn't process stateid!\n");
                goto out;
@@ -948,7 +957,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (setattr->sa_iattr.ia_valid & ATTR_SIZE) {
                status = nfs4_preprocess_stateid_op(rqstp, cstate,
                                &cstate->current_fh, &setattr->sa_stateid,
-                               WR_STATE, NULL);
+                               WR_STATE, NULL, NULL);
                if (status) {
                        dprintk("NFSD: nfsd4_setattr: couldn't process stateid!\n");
                        return status;
@@ -975,7 +984,7 @@ nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (status)
                goto out;
        status = nfsd_setattr(rqstp, &cstate->current_fh, &setattr->sa_iattr,
-                               0, (time_t)0);
+                               0, (time64_t)0);
 out:
        fh_drop_write(&cstate->current_fh);
        return status;
@@ -999,22 +1008,22 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        trace_nfsd_write_start(rqstp, &cstate->current_fh,
                               write->wr_offset, cnt);
        status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
-                                               stateid, WR_STATE, &nf);
+                                               stateid, WR_STATE, &nf, NULL);
        if (status) {
                dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
                return status;
        }
 
        write->wr_how_written = write->wr_stable_how;
-       gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));
 
        nvecs = svc_fill_write_vector(rqstp, write->wr_pagelist,
                                      &write->wr_head, write->wr_buflen);
        WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
 
-       status = nfsd_vfs_write(rqstp, &cstate->current_fh, nf->nf_file,
+       status = nfsd_vfs_write(rqstp, &cstate->current_fh, nf,
                                write->wr_offset, rqstp->rq_vec, nvecs, &cnt,
-                               write->wr_how_written);
+                               write->wr_how_written,
+                               (__be32 *)write->wr_verifier.data);
        nfsd_file_put(nf);
 
        write->wr_bytes_written = cnt;
@@ -1034,14 +1043,14 @@ nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                return nfserr_nofilehandle;
 
        status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh,
-                                           src_stateid, RD_STATE, src);
+                                           src_stateid, RD_STATE, src, NULL);
        if (status) {
                dprintk("NFSD: %s: couldn't process src stateid!\n", __func__);
                goto out;
        }
 
        status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
-                                           dst_stateid, WR_STATE, dst);
+                                           dst_stateid, WR_STATE, dst, NULL);
        if (status) {
                dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__);
                goto out_put_src;
@@ -1076,8 +1085,8 @@ nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        if (status)
                goto out;
 
-       status = nfsd4_clone_file_range(src->nf_file, clone->cl_src_pos,
-                       dst->nf_file, clone->cl_dst_pos, clone->cl_count,
+       status = nfsd4_clone_file_range(src, clone->cl_src_pos,
+                       dst, clone->cl_dst_pos, clone->cl_count,
                        EX_ISSYNC(cstate->current_fh.fh_export));
 
        nfsd_file_put(dst);
@@ -1135,6 +1144,207 @@ void nfsd4_shutdown_copy(struct nfs4_client *clp)
        while ((copy = nfsd4_get_copy(clp)) != NULL)
                nfsd4_stop_copy(copy);
 }
+#ifdef CONFIG_NFSD_V4_2_INTER_SSC
+
+extern struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
+                                  struct nfs_fh *src_fh,
+                                  nfs4_stateid *stateid);
+extern void nfs42_ssc_close(struct file *filep);
+
+extern void nfs_sb_deactive(struct super_block *sb);
+
+#define NFSD42_INTERSSC_MOUNTOPS "vers=4.2,addr=%s,sec=sys"
+
+/**
+ * Support one copy source server for now.
+ */
+static __be32
+nfsd4_interssc_connect(struct nl4_server *nss, struct svc_rqst *rqstp,
+                      struct vfsmount **mount)
+{
+       struct file_system_type *type;
+       struct vfsmount *ss_mnt;
+       struct nfs42_netaddr *naddr;
+       struct sockaddr_storage tmp_addr;
+       size_t tmp_addrlen, match_netid_len = 3;
+       char *startsep = "", *endsep = "", *match_netid = "tcp";
+       char *ipaddr, *dev_name, *raw_data;
+       int len, raw_len;
+       __be32 status = nfserr_inval;
+
+       naddr = &nss->u.nl4_addr;
+       tmp_addrlen = rpc_uaddr2sockaddr(SVC_NET(rqstp), naddr->addr,
+                                        naddr->addr_len,
+                                        (struct sockaddr *)&tmp_addr,
+                                        sizeof(tmp_addr));
+       if (tmp_addrlen == 0)
+               goto out_err;
+
+       if (tmp_addr.ss_family == AF_INET6) {
+               startsep = "[";
+               endsep = "]";
+               match_netid = "tcp6";
+               match_netid_len = 4;
+       }
+
+       if (naddr->netid_len != match_netid_len ||
+               strncmp(naddr->netid, match_netid, naddr->netid_len))
+               goto out_err;
+
+       /* Construct the raw data for the vfs_kern_mount call */
+       len = RPC_MAX_ADDRBUFLEN + 1;
+       ipaddr = kzalloc(len, GFP_KERNEL);
+       if (!ipaddr)
+               goto out_err;
+
+       rpc_ntop((struct sockaddr *)&tmp_addr, ipaddr, len);
+
+       /* 2 for ipv6 endsep and startsep. 3 for ":/" and trailing '/0'*/
+
+       raw_len = strlen(NFSD42_INTERSSC_MOUNTOPS) + strlen(ipaddr);
+       raw_data = kzalloc(raw_len, GFP_KERNEL);
+       if (!raw_data)
+               goto out_free_ipaddr;
+
+       snprintf(raw_data, raw_len, NFSD42_INTERSSC_MOUNTOPS, ipaddr);
+
+       status = nfserr_nodev;
+       type = get_fs_type("nfs");
+       if (!type)
+               goto out_free_rawdata;
+
+       /* Set the server:<export> for the vfs_kern_mount call */
+       dev_name = kzalloc(len + 5, GFP_KERNEL);
+       if (!dev_name)
+               goto out_free_rawdata;
+       snprintf(dev_name, len + 5, "%s%s%s:/", startsep, ipaddr, endsep);
+
+       /* Use an 'internal' mount: SB_KERNMOUNT -> MNT_INTERNAL */
+       ss_mnt = vfs_kern_mount(type, SB_KERNMOUNT, dev_name, raw_data);
+       module_put(type->owner);
+       if (IS_ERR(ss_mnt))
+               goto out_free_devname;
+
+       status = 0;
+       *mount = ss_mnt;
+
+out_free_devname:
+       kfree(dev_name);
+out_free_rawdata:
+       kfree(raw_data);
+out_free_ipaddr:
+       kfree(ipaddr);
+out_err:
+       return status;
+}
+
+static void
+nfsd4_interssc_disconnect(struct vfsmount *ss_mnt)
+{
+       nfs_sb_deactive(ss_mnt->mnt_sb);
+       mntput(ss_mnt);
+}
+
+/**
+ * nfsd4_setup_inter_ssc
+ *
+ * Verify COPY destination stateid.
+ * Connect to the source server with NFSv4.1.
+ * Create the source struct file for nfsd_copy_range.
+ * Called with COPY cstate:
+ *    SAVED_FH: source filehandle
+ *    CURRENT_FH: destination filehandle
+ */
+static __be32
+nfsd4_setup_inter_ssc(struct svc_rqst *rqstp,
+                     struct nfsd4_compound_state *cstate,
+                     struct nfsd4_copy *copy, struct vfsmount **mount)
+{
+       struct svc_fh *s_fh = NULL;
+       stateid_t *s_stid = &copy->cp_src_stateid;
+       __be32 status = nfserr_inval;
+
+       /* Verify the destination stateid and set dst struct file*/
+       status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
+                                           &copy->cp_dst_stateid,
+                                           WR_STATE, &copy->nf_dst, NULL);
+       if (status)
+               goto out;
+
+       status = nfsd4_interssc_connect(&copy->cp_src, rqstp, mount);
+       if (status)
+               goto out;
+
+       s_fh = &cstate->save_fh;
+
+       copy->c_fh.size = s_fh->fh_handle.fh_size;
+       memcpy(copy->c_fh.data, &s_fh->fh_handle.fh_base, copy->c_fh.size);
+       copy->stateid.seqid = cpu_to_be32(s_stid->si_generation);
+       memcpy(copy->stateid.other, (void *)&s_stid->si_opaque,
+              sizeof(stateid_opaque_t));
+
+       status = 0;
+out:
+       return status;
+}
+
+static void
+nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src,
+                       struct nfsd_file *dst)
+{
+       nfs42_ssc_close(src->nf_file);
+       nfsd_file_put(src);
+       nfsd_file_put(dst);
+       mntput(ss_mnt);
+}
+
+#else /* CONFIG_NFSD_V4_2_INTER_SSC */
+
+static __be32
+nfsd4_setup_inter_ssc(struct svc_rqst *rqstp,
+                     struct nfsd4_compound_state *cstate,
+                     struct nfsd4_copy *copy,
+                     struct vfsmount **mount)
+{
+       *mount = NULL;
+       return nfserr_inval;
+}
+
+static void
+nfsd4_cleanup_inter_ssc(struct vfsmount *ss_mnt, struct nfsd_file *src,
+                       struct nfsd_file *dst)
+{
+}
+
+static void
+nfsd4_interssc_disconnect(struct vfsmount *ss_mnt)
+{
+}
+
+static struct file *nfs42_ssc_open(struct vfsmount *ss_mnt,
+                                  struct nfs_fh *src_fh,
+                                  nfs4_stateid *stateid)
+{
+       return NULL;
+}
+#endif /* CONFIG_NFSD_V4_2_INTER_SSC */
+
+static __be32
+nfsd4_setup_intra_ssc(struct svc_rqst *rqstp,
+                     struct nfsd4_compound_state *cstate,
+                     struct nfsd4_copy *copy)
+{
+       return nfsd4_verify_copy(rqstp, cstate, &copy->cp_src_stateid,
+                                &copy->nf_src, &copy->cp_dst_stateid,
+                                &copy->nf_dst);
+}
+
+static void
+nfsd4_cleanup_intra_ssc(struct nfsd_file *src, struct nfsd_file *dst)
+{
+       nfsd_file_put(src);
+       nfsd_file_put(dst);
+}
 
 static void nfsd4_cb_offload_release(struct nfsd4_callback *cb)
 {
@@ -1200,12 +1410,16 @@ static __be32 nfsd4_do_copy(struct nfsd4_copy *copy, bool sync)
                status = nfs_ok;
        }
 
-       nfsd_file_put(copy->nf_src);
-       nfsd_file_put(copy->nf_dst);
+       if (!copy->cp_intra) /* Inter server SSC */
+               nfsd4_cleanup_inter_ssc(copy->ss_mnt, copy->nf_src,
+                                       copy->nf_dst);
+       else
+               nfsd4_cleanup_intra_ssc(copy->nf_src, copy->nf_dst);
+
        return status;
 }
 
-static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst)
+static int dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst)
 {
        dst->cp_src_pos = src->cp_src_pos;
        dst->cp_dst_pos = src->cp_dst_pos;
@@ -1215,15 +1429,25 @@ static void dup_copy_fields(struct nfsd4_copy *src, struct nfsd4_copy *dst)
        memcpy(&dst->fh, &src->fh, sizeof(src->fh));
        dst->cp_clp = src->cp_clp;
        dst->nf_dst = nfsd_file_get(src->nf_dst);
-       dst->nf_src = nfsd_file_get(src->nf_src);
+       dst->cp_intra = src->cp_intra;
+       if (src->cp_intra) /* for inter, file_src doesn't exist yet */
+               dst->nf_src = nfsd_file_get(src->nf_src);
+
        memcpy(&dst->cp_stateid, &src->cp_stateid, sizeof(src->cp_stateid));
+       memcpy(&dst->cp_src, &src->cp_src, sizeof(struct nl4_server));
+       memcpy(&dst->stateid, &src->stateid, sizeof(src->stateid));
+       memcpy(&dst->c_fh, &src->c_fh, sizeof(src->c_fh));
+       dst->ss_mnt = src->ss_mnt;
+
+       return 0;
 }
 
 static void cleanup_async_copy(struct nfsd4_copy *copy)
 {
-       nfs4_free_cp_state(copy);
+       nfs4_free_copy_state(copy);
        nfsd_file_put(copy->nf_dst);
-       nfsd_file_put(copy->nf_src);
+       if (copy->cp_intra)
+               nfsd_file_put(copy->nf_src);
        spin_lock(&copy->cp_clp->async_lock);
        list_del(&copy->copies);
        spin_unlock(&copy->cp_clp->async_lock);
@@ -1235,7 +1459,24 @@ static int nfsd4_do_async_copy(void *data)
        struct nfsd4_copy *copy = (struct nfsd4_copy *)data;
        struct nfsd4_copy *cb_copy;
 
+       if (!copy->cp_intra) { /* Inter server SSC */
+               copy->nf_src = kzalloc(sizeof(struct nfsd_file), GFP_KERNEL);
+               if (!copy->nf_src) {
+                       copy->nfserr = nfserr_serverfault;
+                       nfsd4_interssc_disconnect(copy->ss_mnt);
+                       goto do_callback;
+               }
+               copy->nf_src->nf_file = nfs42_ssc_open(copy->ss_mnt, &copy->c_fh,
+                                             &copy->stateid);
+               if (IS_ERR(copy->nf_src->nf_file)) {
+                       copy->nfserr = nfserr_offload_denied;
+                       nfsd4_interssc_disconnect(copy->ss_mnt);
+                       goto do_callback;
+               }
+       }
+
        copy->nfserr = nfsd4_do_copy(copy, 0);
+do_callback:
        cb_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL);
        if (!cb_copy)
                goto out;
@@ -1247,6 +1488,8 @@ static int nfsd4_do_async_copy(void *data)
                        &nfsd4_cb_offload_ops, NFSPROC4_CLNT_CB_OFFLOAD);
        nfsd4_run_cb(&cb_copy->cp_cb);
 out:
+       if (!copy->cp_intra)
+               kfree(copy->nf_src);
        cleanup_async_copy(copy);
        return 0;
 }
@@ -1259,11 +1502,20 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        __be32 status;
        struct nfsd4_copy *async_copy = NULL;
 
-       status = nfsd4_verify_copy(rqstp, cstate, &copy->cp_src_stateid,
-                                  &copy->nf_src, &copy->cp_dst_stateid,
-                                  &copy->nf_dst);
-       if (status)
-               goto out;
+       if (!copy->cp_intra) { /* Inter server SSC */
+               if (!inter_copy_offload_enable || copy->cp_synchronous) {
+                       status = nfserr_notsupp;
+                       goto out;
+               }
+               status = nfsd4_setup_inter_ssc(rqstp, cstate, copy,
+                               &copy->ss_mnt);
+               if (status)
+                       return nfserr_offload_denied;
+       } else {
+               status = nfsd4_setup_intra_ssc(rqstp, cstate, copy);
+               if (status)
+                       return status;
+       }
 
        copy->cp_clp = cstate->clp;
        memcpy(&copy->fh, &cstate->current_fh.fh_handle,
@@ -1274,15 +1526,15 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                status = nfserrno(-ENOMEM);
                async_copy = kzalloc(sizeof(struct nfsd4_copy), GFP_KERNEL);
                if (!async_copy)
-                       goto out;
-               if (!nfs4_init_cp_state(nn, copy)) {
-                       kfree(async_copy);
-                       goto out;
-               }
+                       goto out_err;
+               if (!nfs4_init_copy_state(nn, copy))
+                       goto out_err;
                refcount_set(&async_copy->refcount, 1);
                memcpy(&copy->cp_res.cb_stateid, &copy->cp_stateid,
                        sizeof(copy->cp_stateid));
-               dup_copy_fields(copy, async_copy);
+               status = dup_copy_fields(copy, async_copy);
+               if (status)
+                       goto out_err;
                async_copy->copy_task = kthread_create(nfsd4_do_async_copy,
                                async_copy, "%s", "copy thread");
                if (IS_ERR(async_copy->copy_task))
@@ -1293,13 +1545,17 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                spin_unlock(&async_copy->cp_clp->async_lock);
                wake_up_process(async_copy->copy_task);
                status = nfs_ok;
-       } else
+       } else {
                status = nfsd4_do_copy(copy, 1);
+       }
 out:
        return status;
 out_err:
        if (async_copy)
                cleanup_async_copy(async_copy);
+       status = nfserrno(-ENOMEM);
+       if (!copy->cp_intra)
+               nfsd4_interssc_disconnect(copy->ss_mnt);
        goto out;
 }
 
@@ -1310,7 +1566,7 @@ find_async_copy(struct nfs4_client *clp, stateid_t *stateid)
 
        spin_lock(&clp->async_lock);
        list_for_each_entry(copy, &clp->async_copies, copies) {
-               if (memcmp(&copy->cp_stateid, stateid, NFS4_STATEID_SIZE))
+               if (memcmp(&copy->cp_stateid.stid, stateid, NFS4_STATEID_SIZE))
                        continue;
                refcount_inc(&copy->refcount);
                spin_unlock(&clp->async_lock);
@@ -1326,16 +1582,61 @@ nfsd4_offload_cancel(struct svc_rqst *rqstp,
                     union nfsd4_op_u *u)
 {
        struct nfsd4_offload_status *os = &u->offload_status;
-       __be32 status = 0;
        struct nfsd4_copy *copy;
        struct nfs4_client *clp = cstate->clp;
 
        copy = find_async_copy(clp, &os->stateid);
-       if (copy)
+       if (!copy) {
+               struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
+
+               return manage_cpntf_state(nn, &os->stateid, clp, NULL);
+       } else
                nfsd4_stop_copy(copy);
-       else
-               status = nfserr_bad_stateid;
 
+       return nfs_ok;
+}
+
+static __be32
+nfsd4_copy_notify(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
+                 union nfsd4_op_u *u)
+{
+       struct nfsd4_copy_notify *cn = &u->copy_notify;
+       __be32 status;
+       struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
+       struct nfs4_stid *stid;
+       struct nfs4_cpntf_state *cps;
+       struct nfs4_client *clp = cstate->clp;
+
+       status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
+                                       &cn->cpn_src_stateid, RD_STATE, NULL,
+                                       &stid);
+       if (status)
+               return status;
+
+       cn->cpn_sec = nn->nfsd4_lease;
+       cn->cpn_nsec = 0;
+
+       status = nfserrno(-ENOMEM);
+       cps = nfs4_alloc_init_cpntf_state(nn, stid);
+       if (!cps)
+               goto out;
+       memcpy(&cn->cpn_cnr_stateid, &cps->cp_stateid.stid, sizeof(stateid_t));
+       memcpy(&cps->cp_p_stateid, &stid->sc_stateid, sizeof(stateid_t));
+       memcpy(&cps->cp_p_clid, &clp->cl_clientid, sizeof(clientid_t));
+
+       /* For now, only return one server address in cpn_src, the
+        * address used by the client to connect to this server.
+        */
+       cn->cpn_src.nl4_type = NL4_NETADDR;
+       status = nfsd4_set_netaddr((struct sockaddr *)&rqstp->rq_daddr,
+                                &cn->cpn_src.u.nl4_addr);
+       WARN_ON_ONCE(status);
+       if (status) {
+               nfs4_put_cpntf_state(nn, cps);
+               goto out;
+       }
+out:
+       nfs4_put_stid(stid);
        return status;
 }
 
@@ -1348,7 +1649,7 @@ nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
                                            &fallocate->falloc_stateid,
-                                           WR_STATE, &nf);
+                                           WR_STATE, &nf, NULL);
        if (status != nfs_ok) {
                dprintk("NFSD: nfsd4_fallocate: couldn't process stateid!\n");
                return status;
@@ -1407,7 +1708,7 @@ nfsd4_seek(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
                                            &seek->seek_stateid,
-                                           RD_STATE, &nf);
+                                           RD_STATE, &nf, NULL);
        if (status) {
                dprintk("NFSD: nfsd4_seek: couldn't process stateid!\n");
                return status;
@@ -1912,6 +2213,45 @@ static void svcxdr_init_encode(struct svc_rqst *rqstp,
                - rqstp->rq_auth_slack;
 }
 
+#ifdef CONFIG_NFSD_V4_2_INTER_SSC
+static void
+check_if_stalefh_allowed(struct nfsd4_compoundargs *args)
+{
+       struct nfsd4_op *op, *current_op = NULL, *saved_op = NULL;
+       struct nfsd4_copy *copy;
+       struct nfsd4_putfh *putfh;
+       int i;
+
+       /* traverse all operation and if it's a COPY compound, mark the
+        * source filehandle to skip verification
+        */
+       for (i = 0; i < args->opcnt; i++) {
+               op = &args->ops[i];
+               if (op->opnum == OP_PUTFH)
+                       current_op = op;
+               else if (op->opnum == OP_SAVEFH)
+                       saved_op = current_op;
+               else if (op->opnum == OP_RESTOREFH)
+                       current_op = saved_op;
+               else if (op->opnum == OP_COPY) {
+                       copy = (struct nfsd4_copy *)&op->u;
+                       if (!saved_op) {
+                               op->status = nfserr_nofilehandle;
+                               return;
+                       }
+                       putfh = (struct nfsd4_putfh *)&saved_op->u;
+                       if (!copy->cp_intra)
+                               putfh->no_verify = true;
+               }
+       }
+}
+#else
+static void
+check_if_stalefh_allowed(struct nfsd4_compoundargs *args)
+{
+}
+#endif
+
 /*
  * COMPOUND call.
  */
@@ -1960,6 +2300,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
                resp->opcnt = 1;
                goto encode_op;
        }
+       check_if_stalefh_allowed(args);
 
        trace_nfsd_compound(rqstp, args->opcnt);
        while (!status && resp->opcnt < args->opcnt) {
@@ -1975,13 +2316,14 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
                                op->status = nfsd4_open_omfg(rqstp, cstate, op);
                        goto encode_op;
                }
-
-               if (!current_fh->fh_dentry) {
+               if (!current_fh->fh_dentry &&
+                               !HAS_FH_FLAG(current_fh, NFSD4_FH_FOREIGN)) {
                        if (!(op->opdesc->op_flags & ALLOWED_WITHOUT_FH)) {
                                op->status = nfserr_nofilehandle;
                                goto encode_op;
                        }
-               } else if (current_fh->fh_export->ex_fslocs.migrated &&
+               } else if (current_fh->fh_export &&
+                          current_fh->fh_export->ex_fslocs.migrated &&
                          !(op->opdesc->op_flags & ALLOWED_ON_ABSENT_FS)) {
                        op->status = nfserr_moved;
                        goto encode_op;
@@ -2025,7 +2367,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
                        if (op->opdesc->op_flags & OP_CLEAR_STATEID)
                                clear_current_stateid(cstate);
 
-                       if (need_wrongsec_check(rqstp))
+                       if (current_fh->fh_export &&
+                                       need_wrongsec_check(rqstp))
                                op->status = check_nfsd_access(current_fh->fh_export, rqstp);
                }
 encode_op:
@@ -2292,6 +2635,21 @@ static inline u32 nfsd4_offload_status_rsize(struct svc_rqst *rqstp,
                1 /* osr_complete<1> optional 0 for now */) * sizeof(__be32);
 }
 
+static inline u32 nfsd4_copy_notify_rsize(struct svc_rqst *rqstp,
+                                       struct nfsd4_op *op)
+{
+       return (op_encode_hdr_size +
+               3 /* cnr_lease_time */ +
+               1 /* We support one cnr_source_server */ +
+               1 /* cnr_stateid seq */ +
+               op_encode_stateid_maxsz /* cnr_stateid */ +
+               1 /* num cnr_source_server*/ +
+               1 /* nl4_type */ +
+               1 /* nl4 size */ +
+               XDR_QUADLEN(NFS4_OPAQUE_LIMIT) /*nl4_loc + nl4_loc_sz */)
+               * sizeof(__be32);
+}
+
 #ifdef CONFIG_NFSD_PNFS
 static inline u32 nfsd4_getdeviceinfo_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op)
 {
@@ -2716,6 +3074,12 @@ static const struct nfsd4_operation nfsd4_ops[] = {
                .op_name = "OP_OFFLOAD_CANCEL",
                .op_rsize_bop = nfsd4_only_status_rsize,
        },
+       [OP_COPY_NOTIFY] = {
+               .op_func = nfsd4_copy_notify,
+               .op_flags = OP_MODIFIES_SOMETHING,
+               .op_name = "OP_COPY_NOTIFY",
+               .op_rsize_bop = nfsd4_copy_notify_rsize,
+       },
 };
 
 /**
index 2481e76..a8fb186 100644 (file)
@@ -1445,7 +1445,7 @@ nfsd4_cld_grace_done_v0(struct nfsd_net *nn)
        }
 
        cup->cu_u.cu_msg.cm_cmd = Cld_GraceDone;
-       cup->cu_u.cu_msg.cm_u.cm_gracetime = (int64_t)nn->boot_time;
+       cup->cu_u.cu_msg.cm_u.cm_gracetime = nn->boot_time;
        ret = cld_pipe_upcall(cn->cn_pipe, &cup->cu_u.cu_msg);
        if (!ret)
                ret = cup->cu_u.cu_msg.cm_status;
@@ -1782,7 +1782,7 @@ nfsd4_cltrack_client_has_session(struct nfs4_client *clp)
 }
 
 static char *
-nfsd4_cltrack_grace_start(time_t grace_start)
+nfsd4_cltrack_grace_start(time64_t grace_start)
 {
        int copied;
        size_t len;
@@ -1795,7 +1795,7 @@ nfsd4_cltrack_grace_start(time_t grace_start)
        if (!result)
                return result;
 
-       copied = snprintf(result, len, GRACE_START_ENV_PREFIX "%ld",
+       copied = snprintf(result, len, GRACE_START_ENV_PREFIX "%lld",
                                grace_start);
        if (copied >= len) {
                /* just return nothing if output was truncated */
@@ -2004,7 +2004,7 @@ nfsd4_umh_cltrack_grace_done(struct nfsd_net *nn)
        char *legacy;
        char timestr[22]; /* FIXME: better way to determine max size? */
 
-       sprintf(timestr, "%ld", nn->boot_time);
+       sprintf(timestr, "%lld", nn->boot_time);
        legacy = nfsd4_cltrack_legacy_topdir();
        nfsd4_umh_cltrack_upcall("gracedone", timestr, legacy, NULL);
        kfree(legacy);
index 369e574..65cfe9a 100644 (file)
@@ -80,6 +80,7 @@ static u64 current_sessionid = 1;
 static bool check_for_locks(struct nfs4_file *fp, struct nfs4_lockowner *lowner);
 static void nfs4_free_ol_stateid(struct nfs4_stid *stid);
 void nfsd4_end_grace(struct nfsd_net *nn);
+static void _free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps);
 
 /* Locking: */
 
@@ -170,7 +171,7 @@ renew_client_locked(struct nfs4_client *clp)
                        clp->cl_clientid.cl_boot,
                        clp->cl_clientid.cl_id);
        list_move_tail(&clp->cl_lru, &nn->client_lru);
-       clp->cl_time = get_seconds();
+       clp->cl_time = ktime_get_boottime_seconds();
 }
 
 static void put_client_renew_locked(struct nfs4_client *clp)
@@ -722,6 +723,7 @@ struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *sla
        /* Will be incremented before return to client: */
        refcount_set(&stid->sc_count, 1);
        spin_lock_init(&stid->sc_lock);
+       INIT_LIST_HEAD(&stid->sc_cp_list);
 
        /*
         * It shouldn't be a problem to reuse an opaque stateid value.
@@ -741,30 +743,76 @@ out_free:
 /*
  * Create a unique stateid_t to represent each COPY.
  */
-int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy)
+static int nfs4_init_cp_state(struct nfsd_net *nn, copy_stateid_t *stid,
+                             unsigned char sc_type)
 {
        int new_id;
 
+       stid->stid.si_opaque.so_clid.cl_boot = (u32)nn->boot_time;
+       stid->stid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id;
+       stid->sc_type = sc_type;
+
        idr_preload(GFP_KERNEL);
        spin_lock(&nn->s2s_cp_lock);
-       new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, copy, 0, 0, GFP_NOWAIT);
+       new_id = idr_alloc_cyclic(&nn->s2s_cp_stateids, stid, 0, 0, GFP_NOWAIT);
+       stid->stid.si_opaque.so_id = new_id;
        spin_unlock(&nn->s2s_cp_lock);
        idr_preload_end();
        if (new_id < 0)
                return 0;
-       copy->cp_stateid.si_opaque.so_id = new_id;
-       copy->cp_stateid.si_opaque.so_clid.cl_boot = nn->boot_time;
-       copy->cp_stateid.si_opaque.so_clid.cl_id = nn->s2s_cp_cl_id;
        return 1;
 }
 
-void nfs4_free_cp_state(struct nfsd4_copy *copy)
+int nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy)
+{
+       return nfs4_init_cp_state(nn, &copy->cp_stateid, NFS4_COPY_STID);
+}
+
+struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn,
+                                                    struct nfs4_stid *p_stid)
+{
+       struct nfs4_cpntf_state *cps;
+
+       cps = kzalloc(sizeof(struct nfs4_cpntf_state), GFP_KERNEL);
+       if (!cps)
+               return NULL;
+       cps->cpntf_time = ktime_get_boottime_seconds();
+       refcount_set(&cps->cp_stateid.sc_count, 1);
+       if (!nfs4_init_cp_state(nn, &cps->cp_stateid, NFS4_COPYNOTIFY_STID))
+               goto out_free;
+       spin_lock(&nn->s2s_cp_lock);
+       list_add(&cps->cp_list, &p_stid->sc_cp_list);
+       spin_unlock(&nn->s2s_cp_lock);
+       return cps;
+out_free:
+       kfree(cps);
+       return NULL;
+}
+
+void nfs4_free_copy_state(struct nfsd4_copy *copy)
 {
        struct nfsd_net *nn;
 
+       WARN_ON_ONCE(copy->cp_stateid.sc_type != NFS4_COPY_STID);
        nn = net_generic(copy->cp_clp->net, nfsd_net_id);
        spin_lock(&nn->s2s_cp_lock);
-       idr_remove(&nn->s2s_cp_stateids, copy->cp_stateid.si_opaque.so_id);
+       idr_remove(&nn->s2s_cp_stateids,
+                  copy->cp_stateid.stid.si_opaque.so_id);
+       spin_unlock(&nn->s2s_cp_lock);
+}
+
+static void nfs4_free_cpntf_statelist(struct net *net, struct nfs4_stid *stid)
+{
+       struct nfs4_cpntf_state *cps;
+       struct nfsd_net *nn;
+
+       nn = net_generic(net, nfsd_net_id);
+       spin_lock(&nn->s2s_cp_lock);
+       while (!list_empty(&stid->sc_cp_list)) {
+               cps = list_first_entry(&stid->sc_cp_list,
+                                      struct nfs4_cpntf_state, cp_list);
+               _free_cpntf_state_locked(nn, cps);
+       }
        spin_unlock(&nn->s2s_cp_lock);
 }
 
@@ -806,7 +854,7 @@ static void nfs4_free_deleg(struct nfs4_stid *stid)
 static DEFINE_SPINLOCK(blocked_delegations_lock);
 static struct bloom_pair {
        int     entries, old_entries;
-       time_t  swap_time;
+       time64_t swap_time;
        int     new; /* index into 'set' */
        DECLARE_BITMAP(set[2], 256);
 } blocked_delegations;
@@ -818,15 +866,15 @@ static int delegation_blocked(struct knfsd_fh *fh)
 
        if (bd->entries == 0)
                return 0;
-       if (seconds_since_boot() - bd->swap_time > 30) {
+       if (ktime_get_seconds() - bd->swap_time > 30) {
                spin_lock(&blocked_delegations_lock);
-               if (seconds_since_boot() - bd->swap_time > 30) {
+               if (ktime_get_seconds() - bd->swap_time > 30) {
                        bd->entries -= bd->old_entries;
                        bd->old_entries = bd->entries;
                        memset(bd->set[bd->new], 0,
                               sizeof(bd->set[0]));
                        bd->new = 1-bd->new;
-                       bd->swap_time = seconds_since_boot();
+                       bd->swap_time = ktime_get_seconds();
                }
                spin_unlock(&blocked_delegations_lock);
        }
@@ -856,7 +904,7 @@ static void block_delegations(struct knfsd_fh *fh)
        __set_bit((hash>>8)&255, bd->set[bd->new]);
        __set_bit((hash>>16)&255, bd->set[bd->new]);
        if (bd->entries == 0)
-               bd->swap_time = seconds_since_boot();
+               bd->swap_time = ktime_get_seconds();
        bd->entries += 1;
        spin_unlock(&blocked_delegations_lock);
 }
@@ -915,6 +963,7 @@ nfs4_put_stid(struct nfs4_stid *s)
                return;
        }
        idr_remove(&clp->cl_stateids, s->sc_stateid.si_opaque.so_id);
+       nfs4_free_cpntf_statelist(clp->net, s);
        spin_unlock(&clp->cl_lock);
        s->sc_free(s);
        if (fp)
@@ -1862,7 +1911,7 @@ STALE_CLIENTID(clientid_t *clid, struct nfsd_net *nn)
         */
        if (clid->cl_boot == (u32)nn->boot_time)
                return 0;
-       dprintk("NFSD stale clientid (%08x/%08x) boot_time %08lx\n",
+       dprintk("NFSD stale clientid (%08x/%08x) boot_time %08llx\n",
                clid->cl_boot, clid->cl_id, nn->boot_time);
        return 1;
 }
@@ -2215,14 +2264,14 @@ static void gen_confirm(struct nfs4_client *clp, struct nfsd_net *nn)
         * This is opaque to client, so no need to byte-swap. Use
         * __force to keep sparse happy
         */
-       verf[0] = (__force __be32)get_seconds();
+       verf[0] = (__force __be32)(u32)ktime_get_real_seconds();
        verf[1] = (__force __be32)nn->clverifier_counter++;
        memcpy(clp->cl_confirm.data, verf, sizeof(clp->cl_confirm.data));
 }
 
 static void gen_clid(struct nfs4_client *clp, struct nfsd_net *nn)
 {
-       clp->cl_clientid.cl_boot = nn->boot_time;
+       clp->cl_clientid.cl_boot = (u32)nn->boot_time;
        clp->cl_clientid.cl_id = nn->clientid_counter++;
        gen_confirm(clp, nn);
 }
@@ -2292,7 +2341,7 @@ static int client_info_show(struct seq_file *m, void *v)
                                        clp->cl_nii_domain.len);
                seq_printf(m, "\nImplementation name: ");
                seq_quote_mem(m, clp->cl_nii_name.data, clp->cl_nii_name.len);
-               seq_printf(m, "\nImplementation time: [%ld, %ld]\n",
+               seq_printf(m, "\nImplementation time: [%lld, %ld]\n",
                        clp->cl_nii_time.tv_sec, clp->cl_nii_time.tv_nsec);
        }
        drop_client(clp);
@@ -2612,7 +2661,7 @@ static struct nfs4_client *create_client(struct xdr_netobj name,
        gen_clid(clp, nn);
        kref_init(&clp->cl_nfsdfs.cl_ref);
        nfsd4_init_cb(&clp->cl_cb_null, clp, NULL, NFSPROC4_CLNT_CB_NULL);
-       clp->cl_time = get_seconds();
+       clp->cl_time = ktime_get_boottime_seconds();
        clear_bit(0, &clp->cl_cb_slot_busy);
        copy_verf(clp, verf);
        memcpy(&clp->cl_addr, sa, sizeof(struct sockaddr_storage));
@@ -2946,8 +2995,7 @@ static __be32 copy_impl_id(struct nfs4_client *clp,
        xdr_netobj_dup(&clp->cl_nii_name, &exid->nii_name, GFP_KERNEL);
        if (!clp->cl_nii_name.data)
                return nfserr_jukebox;
-       clp->cl_nii_time.tv_sec = exid->nii_time.tv_sec;
-       clp->cl_nii_time.tv_nsec = exid->nii_time.tv_nsec;
+       clp->cl_nii_time = exid->nii_time;
        return 0;
 }
 
@@ -3373,7 +3421,7 @@ static __be32 nfsd4_map_bcts_dir(u32 *dir)
        case NFS4_CDFC4_BACK_OR_BOTH:
                *dir = NFS4_CDFC4_BOTH;
                return nfs_ok;
-       };
+       }
        return nfserr_inval;
 }
 
@@ -4283,7 +4331,7 @@ move_to_close_lru(struct nfs4_ol_stateid *s, struct net *net)
        last = oo->oo_last_closed_stid;
        oo->oo_last_closed_stid = s;
        list_move_tail(&oo->oo_close_lru, &nn->close_lru);
-       oo->oo_time = get_seconds();
+       oo->oo_time = ktime_get_boottime_seconds();
        spin_unlock(&nn->client_lock);
        if (last)
                nfs4_put_stid(&last->st_stid);
@@ -4378,7 +4426,7 @@ static void nfsd4_cb_recall_prepare(struct nfsd4_callback *cb)
         */
        spin_lock(&state_lock);
        if (dp->dl_time == 0) {
-               dp->dl_time = get_seconds();
+               dp->dl_time = ktime_get_boottime_seconds();
                list_add_tail(&dp->dl_recall_lru, &nn->del_recall_lru);
        }
        spin_unlock(&state_lock);
@@ -4490,7 +4538,8 @@ static __be32 nfsd4_check_seqid(struct nfsd4_compound_state *cstate, struct nfs4
 
 static __be32 lookup_clientid(clientid_t *clid,
                struct nfsd4_compound_state *cstate,
-               struct nfsd_net *nn)
+               struct nfsd_net *nn,
+               bool sessions)
 {
        struct nfs4_client *found;
 
@@ -4511,7 +4560,7 @@ static __be32 lookup_clientid(clientid_t *clid,
         */
        WARN_ON_ONCE(cstate->session);
        spin_lock(&nn->client_lock);
-       found = find_confirmed_client(clid, false, nn);
+       found = find_confirmed_client(clid, sessions, nn);
        if (!found) {
                spin_unlock(&nn->client_lock);
                return nfserr_expired;
@@ -4544,7 +4593,7 @@ nfsd4_process_open1(struct nfsd4_compound_state *cstate,
        if (open->op_file == NULL)
                return nfserr_jukebox;
 
-       status = lookup_clientid(clientid, cstate, nn);
+       status = lookup_clientid(clientid, cstate, nn, false);
        if (status)
                return status;
        clp = cstate->clp;
@@ -4672,7 +4721,7 @@ nfsd4_truncate(struct svc_rqst *rqstp, struct svc_fh *fh,
                return 0;
        if (!(open->op_share_access & NFS4_SHARE_ACCESS_WRITE))
                return nfserr_inval;
-       return nfsd_setattr(rqstp, fh, &iattr, 0, (time_t)0);
+       return nfsd_setattr(rqstp, fh, &iattr, 0, (time64_t)0);
 }
 
 static __be32 nfs4_get_vfs_file(struct svc_rqst *rqstp, struct nfs4_file *fp,
@@ -5133,7 +5182,7 @@ nfsd4_renew(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        dprintk("process_renew(%08x/%08x): starting\n", 
                        clid->cl_boot, clid->cl_id);
-       status = lookup_clientid(clid, cstate, nn);
+       status = lookup_clientid(clid, cstate, nn, false);
        if (status)
                goto out;
        clp = cstate->clp;
@@ -5184,9 +5233,8 @@ nfsd4_end_grace(struct nfsd_net *nn)
  */
 static bool clients_still_reclaiming(struct nfsd_net *nn)
 {
-       unsigned long now = get_seconds();
-       unsigned long double_grace_period_end = nn->boot_time +
-                                               2 * nn->nfsd4_lease;
+       time64_t double_grace_period_end = nn->boot_time +
+                                          2 * nn->nfsd4_lease;
 
        if (nn->track_reclaim_completes &&
                        atomic_read(&nn->nr_reclaim_complete) ==
@@ -5199,12 +5247,12 @@ static bool clients_still_reclaiming(struct nfsd_net *nn)
         * If we've given them *two* lease times to reclaim, and they're
         * still not done, give up:
         */
-       if (time_after(now, double_grace_period_end))
+       if (ktime_get_boottime_seconds() > double_grace_period_end)
                return false;
        return true;
 }
 
-static time_t
+static time64_t
 nfs4_laundromat(struct nfsd_net *nn)
 {
        struct nfs4_client *clp;
@@ -5213,8 +5261,11 @@ nfs4_laundromat(struct nfsd_net *nn)
        struct nfs4_ol_stateid *stp;
        struct nfsd4_blocked_lock *nbl;
        struct list_head *pos, *next, reaplist;
-       time_t cutoff = get_seconds() - nn->nfsd4_lease;
-       time_t t, new_timeo = nn->nfsd4_lease;
+       time64_t cutoff = ktime_get_boottime_seconds() - nn->nfsd4_lease;
+       time64_t t, new_timeo = nn->nfsd4_lease;
+       struct nfs4_cpntf_state *cps;
+       copy_stateid_t *cps_t;
+       int i;
 
        dprintk("NFSD: laundromat service - starting\n");
 
@@ -5225,10 +5276,20 @@ nfs4_laundromat(struct nfsd_net *nn)
        dprintk("NFSD: end of grace period\n");
        nfsd4_end_grace(nn);
        INIT_LIST_HEAD(&reaplist);
+
+       spin_lock(&nn->s2s_cp_lock);
+       idr_for_each_entry(&nn->s2s_cp_stateids, cps_t, i) {
+               cps = container_of(cps_t, struct nfs4_cpntf_state, cp_stateid);
+               if (cps->cp_stateid.sc_type == NFS4_COPYNOTIFY_STID &&
+                               cps->cpntf_time > cutoff)
+                       _free_cpntf_state_locked(nn, cps);
+       }
+       spin_unlock(&nn->s2s_cp_lock);
+
        spin_lock(&nn->client_lock);
        list_for_each_safe(pos, next, &nn->client_lru) {
                clp = list_entry(pos, struct nfs4_client, cl_lru);
-               if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
+               if (clp->cl_time > cutoff) {
                        t = clp->cl_time - cutoff;
                        new_timeo = min(new_timeo, t);
                        break;
@@ -5251,7 +5312,7 @@ nfs4_laundromat(struct nfsd_net *nn)
        spin_lock(&state_lock);
        list_for_each_safe(pos, next, &nn->del_recall_lru) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
-               if (time_after((unsigned long)dp->dl_time, (unsigned long)cutoff)) {
+               if (dp->dl_time > cutoff) {
                        t = dp->dl_time - cutoff;
                        new_timeo = min(new_timeo, t);
                        break;
@@ -5271,8 +5332,7 @@ nfs4_laundromat(struct nfsd_net *nn)
        while (!list_empty(&nn->close_lru)) {
                oo = list_first_entry(&nn->close_lru, struct nfs4_openowner,
                                        oo_close_lru);
-               if (time_after((unsigned long)oo->oo_time,
-                              (unsigned long)cutoff)) {
+               if (oo->oo_time > cutoff) {
                        t = oo->oo_time - cutoff;
                        new_timeo = min(new_timeo, t);
                        break;
@@ -5302,8 +5362,7 @@ nfs4_laundromat(struct nfsd_net *nn)
        while (!list_empty(&nn->blocked_locks_lru)) {
                nbl = list_first_entry(&nn->blocked_locks_lru,
                                        struct nfsd4_blocked_lock, nbl_lru);
-               if (time_after((unsigned long)nbl->nbl_time,
-                              (unsigned long)cutoff)) {
+               if (nbl->nbl_time > cutoff) {
                        t = nbl->nbl_time - cutoff;
                        new_timeo = min(new_timeo, t);
                        break;
@@ -5320,7 +5379,7 @@ nfs4_laundromat(struct nfsd_net *nn)
                free_blocked_lock(nbl);
        }
 out:
-       new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
+       new_timeo = max_t(time64_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
        return new_timeo;
 }
 
@@ -5330,13 +5389,13 @@ static void laundromat_main(struct work_struct *);
 static void
 laundromat_main(struct work_struct *laundry)
 {
-       time_t t;
+       time64_t t;
        struct delayed_work *dwork = to_delayed_work(laundry);
        struct nfsd_net *nn = container_of(dwork, struct nfsd_net,
                                           laundromat_work);
 
        t = nfs4_laundromat(nn);
-       dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
+       dprintk("NFSD: laundromat_main - sleeping for %lld seconds\n", t);
        queue_delayed_work(laundry_wq, &nn->laundromat_work, t*HZ);
 }
 
@@ -5521,7 +5580,8 @@ nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
        if (ZERO_STATEID(stateid) || ONE_STATEID(stateid) ||
                CLOSE_STATEID(stateid))
                return nfserr_bad_stateid;
-       status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn);
+       status = lookup_clientid(&stateid->si_opaque.so_clid, cstate, nn,
+                                false);
        if (status == nfserr_stale_clientid) {
                if (cstate->session)
                        return nfserr_bad_stateid;
@@ -5600,6 +5660,85 @@ nfs4_check_file(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfs4_stid *s,
 out:
        return status;
 }
+static void
+_free_cpntf_state_locked(struct nfsd_net *nn, struct nfs4_cpntf_state *cps)
+{
+       WARN_ON_ONCE(cps->cp_stateid.sc_type != NFS4_COPYNOTIFY_STID);
+       if (!refcount_dec_and_test(&cps->cp_stateid.sc_count))
+               return;
+       list_del(&cps->cp_list);
+       idr_remove(&nn->s2s_cp_stateids,
+                  cps->cp_stateid.stid.si_opaque.so_id);
+       kfree(cps);
+}
+/*
+ * A READ from an inter server to server COPY will have a
+ * copy stateid. Look up the copy notify stateid from the
+ * idr structure and take a reference on it.
+ */
+__be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st,
+                         struct nfs4_client *clp,
+                         struct nfs4_cpntf_state **cps)
+{
+       copy_stateid_t *cps_t;
+       struct nfs4_cpntf_state *state = NULL;
+
+       if (st->si_opaque.so_clid.cl_id != nn->s2s_cp_cl_id)
+               return nfserr_bad_stateid;
+       spin_lock(&nn->s2s_cp_lock);
+       cps_t = idr_find(&nn->s2s_cp_stateids, st->si_opaque.so_id);
+       if (cps_t) {
+               state = container_of(cps_t, struct nfs4_cpntf_state,
+                                    cp_stateid);
+               if (state->cp_stateid.sc_type != NFS4_COPYNOTIFY_STID) {
+                       state = NULL;
+                       goto unlock;
+               }
+               if (!clp)
+                       refcount_inc(&state->cp_stateid.sc_count);
+               else
+                       _free_cpntf_state_locked(nn, state);
+       }
+unlock:
+       spin_unlock(&nn->s2s_cp_lock);
+       if (!state)
+               return nfserr_bad_stateid;
+       if (!clp && state)
+               *cps = state;
+       return 0;
+}
+
+static __be32 find_cpntf_state(struct nfsd_net *nn, stateid_t *st,
+                              struct nfs4_stid **stid)
+{
+       __be32 status;
+       struct nfs4_cpntf_state *cps = NULL;
+       struct nfsd4_compound_state cstate;
+
+       status = manage_cpntf_state(nn, st, NULL, &cps);
+       if (status)
+               return status;
+
+       cps->cpntf_time = ktime_get_boottime_seconds();
+       memset(&cstate, 0, sizeof(cstate));
+       status = lookup_clientid(&cps->cp_p_clid, &cstate, nn, true);
+       if (status)
+               goto out;
+       status = nfsd4_lookup_stateid(&cstate, &cps->cp_p_stateid,
+                               NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
+                               stid, nn);
+       put_client_renew(cstate.clp);
+out:
+       nfs4_put_cpntf_state(nn, cps);
+       return status;
+}
+
+void nfs4_put_cpntf_state(struct nfsd_net *nn, struct nfs4_cpntf_state *cps)
+{
+       spin_lock(&nn->s2s_cp_lock);
+       _free_cpntf_state_locked(nn, cps);
+       spin_unlock(&nn->s2s_cp_lock);
+}
 
 /*
  * Checks for stateid operations
@@ -5607,7 +5746,8 @@ out:
 __be32
 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *cstate, struct svc_fh *fhp,
-               stateid_t *stateid, int flags, struct nfsd_file **nfp)
+               stateid_t *stateid, int flags, struct nfsd_file **nfp,
+               struct nfs4_stid **cstid)
 {
        struct inode *ino = d_inode(fhp->fh_dentry);
        struct net *net = SVC_NET(rqstp);
@@ -5629,6 +5769,8 @@ nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
        status = nfsd4_lookup_stateid(cstate, stateid,
                                NFS4_DELEG_STID|NFS4_OPEN_STID|NFS4_LOCK_STID,
                                &s, nn);
+       if (status == nfserr_bad_stateid)
+               status = find_cpntf_state(nn, stateid, &s);
        if (status)
                return status;
        status = nfsd4_stid_check_stateid_generation(stateid, s,
@@ -5656,8 +5798,12 @@ done:
        if (status == nfs_ok && nfp)
                status = nfs4_check_file(rqstp, fhp, s, nfp, flags);
 out:
-       if (s)
-               nfs4_put_stid(s);
+       if (s) {
+               if (!status && cstid)
+                       *cstid = s;
+               else
+                       nfs4_put_stid(s);
+       }
        return status;
 }
 
@@ -6550,7 +6696,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
        }
 
        if (fl_flags & FL_SLEEP) {
-               nbl->nbl_time = jiffies;
+               nbl->nbl_time = ktime_get_boottime_seconds();
                spin_lock(&nn->blocked_locks_lock);
                list_add_tail(&nbl->nbl_list, &lock_sop->lo_blocked);
                list_add_tail(&nbl->nbl_lru, &nn->blocked_locks_lru);
@@ -6657,7 +6803,8 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                 return nfserr_inval;
 
        if (!nfsd4_has_session(cstate)) {
-               status = lookup_clientid(&lockt->lt_clientid, cstate, nn);
+               status = lookup_clientid(&lockt->lt_clientid, cstate, nn,
+                                        false);
                if (status)
                        goto out;
        }
@@ -6841,7 +6988,7 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
        dprintk("nfsd4_release_lockowner clientid: (%08x/%08x):\n",
                clid->cl_boot, clid->cl_id);
 
-       status = lookup_clientid(clid, cstate, nn);
+       status = lookup_clientid(clid, cstate, nn, false);
        if (status)
                return status;
 
@@ -6988,7 +7135,7 @@ nfs4_check_open_reclaim(clientid_t *clid,
        __be32 status;
 
        /* find clientid in conf_id_hashtbl */
-       status = lookup_clientid(clid, cstate, nn);
+       status = lookup_clientid(clid, cstate, nn, false);
        if (status)
                return nfserr_reclaim_bad;
 
@@ -7641,7 +7788,7 @@ static int nfs4_state_create_net(struct net *net)
                INIT_LIST_HEAD(&nn->sessionid_hashtbl[i]);
        nn->conf_name_tree = RB_ROOT;
        nn->unconf_name_tree = RB_ROOT;
-       nn->boot_time = get_seconds();
+       nn->boot_time = ktime_get_real_seconds();
        nn->grace_ended = false;
        nn->nfsd4_manager.block_opens = true;
        INIT_LIST_HEAD(&nn->nfsd4_manager.list);
@@ -7710,7 +7857,7 @@ nfs4_state_start_net(struct net *net)
        nfsd4_client_tracking_init(net);
        if (nn->track_reclaim_completes && nn->reclaim_str_hashtbl_size == 0)
                goto skip_grace;
-       printk(KERN_INFO "NFSD: starting %ld-second grace period (net %x)\n",
+       printk(KERN_INFO "NFSD: starting %lld-second grace period (net %x)\n",
               nn->nfsd4_grace, net->ns.inum);
        queue_delayed_work(laundry_wq, &nn->laundromat_work, nn->nfsd4_grace * HZ);
        return 0;
@@ -7786,7 +7933,8 @@ nfs4_state_shutdown(void)
 static void
 get_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
 {
-       if (HAS_STATE_ID(cstate, CURRENT_STATE_ID_FLAG) && CURRENT_STATEID(stateid))
+       if (HAS_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG) &&
+           CURRENT_STATEID(stateid))
                memcpy(stateid, &cstate->current_stateid, sizeof(stateid_t));
 }
 
@@ -7795,14 +7943,14 @@ put_stateid(struct nfsd4_compound_state *cstate, stateid_t *stateid)
 {
        if (cstate->minorversion) {
                memcpy(&cstate->current_stateid, stateid, sizeof(stateid_t));
-               SET_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
+               SET_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG);
        }
 }
 
 void
 clear_current_stateid(struct nfsd4_compound_state *cstate)
 {
-       CLEAR_STATE_ID(cstate, CURRENT_STATE_ID_FLAG);
+       CLEAR_CSTATE_FLAG(cstate, CURRENT_STATE_ID_FLAG);
 }
 
 /*
index d2dc4c0..9761512 100644 (file)
@@ -40,6 +40,7 @@
 #include <linux/utsname.h>
 #include <linux/pagemap.h>
 #include <linux/sunrpc/svcauth_gss.h>
+#include <linux/sunrpc/addr.h>
 
 #include "idmap.h"
 #include "acl.h"
@@ -1744,10 +1745,47 @@ nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
        DECODE_TAIL;
 }
 
+static __be32 nfsd4_decode_nl4_server(struct nfsd4_compoundargs *argp,
+                                     struct nl4_server *ns)
+{
+       DECODE_HEAD;
+       struct nfs42_netaddr *naddr;
+
+       READ_BUF(4);
+       ns->nl4_type = be32_to_cpup(p++);
+
+       /* currently support for 1 inter-server source server */
+       switch (ns->nl4_type) {
+       case NL4_NETADDR:
+               naddr = &ns->u.nl4_addr;
+
+               READ_BUF(4);
+               naddr->netid_len = be32_to_cpup(p++);
+               if (naddr->netid_len > RPCBIND_MAXNETIDLEN)
+                       goto xdr_error;
+
+               READ_BUF(naddr->netid_len + 4); /* 4 for uaddr len */
+               COPYMEM(naddr->netid, naddr->netid_len);
+
+               naddr->addr_len = be32_to_cpup(p++);
+               if (naddr->addr_len > RPCBIND_MAXUADDRLEN)
+                       goto xdr_error;
+
+               READ_BUF(naddr->addr_len);
+               COPYMEM(naddr->addr, naddr->addr_len);
+               break;
+       default:
+               goto xdr_error;
+       }
+       DECODE_TAIL;
+}
+
 static __be32
 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 {
        DECODE_HEAD;
+       struct nl4_server *ns_dummy;
+       int i, count;
 
        status = nfsd4_decode_stateid(argp, &copy->cp_src_stateid);
        if (status)
@@ -1762,7 +1800,32 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
        p = xdr_decode_hyper(p, &copy->cp_count);
        p++; /* ca_consecutive: we always do consecutive copies */
        copy->cp_synchronous = be32_to_cpup(p++);
-       /* tmp = be32_to_cpup(p); Source server list not supported */
+
+       count = be32_to_cpup(p++);
+
+       copy->cp_intra = false;
+       if (count == 0) { /* intra-server copy */
+               copy->cp_intra = true;
+               goto intra;
+       }
+
+       /* decode all the supplied server addresses but use first */
+       status = nfsd4_decode_nl4_server(argp, &copy->cp_src);
+       if (status)
+               return status;
+
+       ns_dummy = kmalloc(sizeof(struct nl4_server), GFP_KERNEL);
+       if (ns_dummy == NULL)
+               return nfserrno(-ENOMEM);
+       for (i = 0; i < count - 1; i++) {
+               status = nfsd4_decode_nl4_server(argp, ns_dummy);
+               if (status) {
+                       kfree(ns_dummy);
+                       return status;
+               }
+       }
+       kfree(ns_dummy);
+intra:
 
        DECODE_TAIL;
 }
@@ -1775,6 +1838,18 @@ nfsd4_decode_offload_status(struct nfsd4_compoundargs *argp,
 }
 
 static __be32
+nfsd4_decode_copy_notify(struct nfsd4_compoundargs *argp,
+                        struct nfsd4_copy_notify *cn)
+{
+       int status;
+
+       status = nfsd4_decode_stateid(argp, &cn->cpn_src_stateid);
+       if (status)
+               return status;
+       return nfsd4_decode_nl4_server(argp, &cn->cpn_dst);
+}
+
+static __be32
 nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
 {
        DECODE_HEAD;
@@ -1875,7 +1950,7 @@ static const nfsd4_dec nfsd4_dec_ops[] = {
        /* new operations for NFSv4.2 */
        [OP_ALLOCATE]           = (nfsd4_dec)nfsd4_decode_fallocate,
        [OP_COPY]               = (nfsd4_dec)nfsd4_decode_copy,
-       [OP_COPY_NOTIFY]        = (nfsd4_dec)nfsd4_decode_notsupp,
+       [OP_COPY_NOTIFY]        = (nfsd4_dec)nfsd4_decode_copy_notify,
        [OP_DEALLOCATE]         = (nfsd4_dec)nfsd4_decode_fallocate,
        [OP_IO_ADVISE]          = (nfsd4_dec)nfsd4_decode_notsupp,
        [OP_LAYOUTERROR]        = (nfsd4_dec)nfsd4_decode_notsupp,
@@ -2024,11 +2099,11 @@ static __be32 *encode_change(__be32 *p, struct kstat *stat, struct inode *inode,
  */
 static __be32 *encode_time_delta(__be32 *p, struct inode *inode)
 {
-       struct timespec ts;
+       struct timespec64 ts;
        u32 ns;
 
        ns = max_t(u32, NSEC_PER_SEC/HZ, inode->i_sb->s_time_gran);
-       ts = ns_to_timespec(ns);
+       ts = ns_to_timespec64(ns);
 
        p = xdr_encode_hyper(p, ts.tv_sec);
        *p++ = cpu_to_be32(ts.tv_nsec);
@@ -4244,6 +4319,46 @@ nfsd42_encode_write_res(struct nfsd4_compoundres *resp,
 }
 
 static __be32
+nfsd42_encode_nl4_server(struct nfsd4_compoundres *resp, struct nl4_server *ns)
+{
+       struct xdr_stream *xdr = &resp->xdr;
+       struct nfs42_netaddr *addr;
+       __be32 *p;
+
+       p = xdr_reserve_space(xdr, 4);
+       *p++ = cpu_to_be32(ns->nl4_type);
+
+       switch (ns->nl4_type) {
+       case NL4_NETADDR:
+               addr = &ns->u.nl4_addr;
+
+               /* netid_len, netid, uaddr_len, uaddr (port included
+                * in RPCBIND_MAXUADDRLEN)
+                */
+               p = xdr_reserve_space(xdr,
+                       4 /* netid len */ +
+                       (XDR_QUADLEN(addr->netid_len) * 4) +
+                       4 /* uaddr len */ +
+                       (XDR_QUADLEN(addr->addr_len) * 4));
+               if (!p)
+                       return nfserr_resource;
+
+               *p++ = cpu_to_be32(addr->netid_len);
+               p = xdr_encode_opaque_fixed(p, addr->netid,
+                                           addr->netid_len);
+               *p++ = cpu_to_be32(addr->addr_len);
+               p = xdr_encode_opaque_fixed(p, addr->addr,
+                                       addr->addr_len);
+               break;
+       default:
+               WARN_ON_ONCE(ns->nl4_type != NL4_NETADDR);
+               return nfserr_inval;
+       }
+
+       return 0;
+}
+
+static __be32
 nfsd4_encode_copy(struct nfsd4_compoundres *resp, __be32 nfserr,
                  struct nfsd4_copy *copy)
 {
@@ -4277,6 +4392,40 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
 }
 
 static __be32
+nfsd4_encode_copy_notify(struct nfsd4_compoundres *resp, __be32 nfserr,
+                        struct nfsd4_copy_notify *cn)
+{
+       struct xdr_stream *xdr = &resp->xdr;
+       __be32 *p;
+
+       if (nfserr)
+               return nfserr;
+
+       /* 8 sec, 4 nsec */
+       p = xdr_reserve_space(xdr, 12);
+       if (!p)
+               return nfserr_resource;
+
+       /* cnr_lease_time */
+       p = xdr_encode_hyper(p, cn->cpn_sec);
+       *p++ = cpu_to_be32(cn->cpn_nsec);
+
+       /* cnr_stateid */
+       nfserr = nfsd4_encode_stateid(xdr, &cn->cpn_cnr_stateid);
+       if (nfserr)
+               return nfserr;
+
+       /* cnr_src.nl_nsvr */
+       p = xdr_reserve_space(xdr, 4);
+       if (!p)
+               return nfserr_resource;
+
+       *p++ = cpu_to_be32(1);
+
+       return nfsd42_encode_nl4_server(resp, &cn->cpn_src);
+}
+
+static __be32
 nfsd4_encode_seek(struct nfsd4_compoundres *resp, __be32 nfserr,
                  struct nfsd4_seek *seek)
 {
@@ -4373,7 +4522,7 @@ static const nfsd4_enc nfsd4_enc_ops[] = {
        /* NFSv4.2 operations */
        [OP_ALLOCATE]           = (nfsd4_enc)nfsd4_encode_noop,
        [OP_COPY]               = (nfsd4_enc)nfsd4_encode_copy,
-       [OP_COPY_NOTIFY]        = (nfsd4_enc)nfsd4_encode_noop,
+       [OP_COPY_NOTIFY]        = (nfsd4_enc)nfsd4_encode_copy_notify,
        [OP_DEALLOCATE]         = (nfsd4_enc)nfsd4_encode_noop,
        [OP_IO_ADVISE]          = (nfsd4_enc)nfsd4_encode_noop,
        [OP_LAYOUTERROR]        = (nfsd4_enc)nfsd4_encode_noop,
@@ -4500,8 +4649,6 @@ nfsd4_encode_replay(struct xdr_stream *xdr, struct nfsd4_op *op)
        __be32 *p;
        struct nfs4_replay *rp = op->replay;
 
-       BUG_ON(!rp);
-
        p = xdr_reserve_space(xdr, 8 + rp->rp_buflen);
        if (!p) {
                WARN_ON_ONCE(1);
index 11b42c5..e109a10 100644 (file)
@@ -157,11 +157,11 @@ static int exports_proc_open(struct inode *inode, struct file *file)
        return exports_net_open(current->nsproxy->net_ns, file);
 }
 
-static const struct file_operations exports_proc_operations = {
-       .open           = exports_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops exports_proc_ops = {
+       .proc_open      = exports_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 static int exports_nfsd_open(struct inode *inode, struct file *file)
@@ -956,7 +956,7 @@ static ssize_t write_maxconn(struct file *file, char *buf, size_t size)
 
 #ifdef CONFIG_NFSD_V4
 static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
-                                 time_t *time, struct nfsd_net *nn)
+                                 time64_t *time, struct nfsd_net *nn)
 {
        char *mesg = buf;
        int rv, i;
@@ -984,11 +984,11 @@ static ssize_t __nfsd4_write_time(struct file *file, char *buf, size_t size,
                *time = i;
        }
 
-       return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%ld\n", *time);
+       return scnprintf(buf, SIMPLE_TRANSACTION_LIMIT, "%lld\n", *time);
 }
 
 static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
-                               time_t *time, struct nfsd_net *nn)
+                               time64_t *time, struct nfsd_net *nn)
 {
        ssize_t rv;
 
@@ -1431,8 +1431,7 @@ static int create_proc_exports_entry(void)
        entry = proc_mkdir("fs/nfs", NULL);
        if (!entry)
                return -ENOMEM;
-       entry = proc_create("exports", 0, entry,
-                                &exports_proc_operations);
+       entry = proc_create("exports", 0, entry, &exports_proc_ops);
        if (!entry) {
                remove_proc_entry("fs/nfs", NULL);
                return -ENOMEM;
index 57b93d9..2ab5569 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sunrpc/svc.h>
 #include <linux/sunrpc/svc_xprt.h>
 #include <linux/sunrpc/msg_prot.h>
+#include <linux/sunrpc/addr.h>
 
 #include <uapi/linux/nfsd/debug.h>
 
@@ -142,7 +143,6 @@ int nfs4_state_start(void);
 int nfs4_state_start_net(struct net *net);
 void nfs4_state_shutdown(void);
 void nfs4_state_shutdown_net(struct net *net);
-void nfs4_reset_lease(time_t leasetime);
 int nfs4_reset_recoverydir(char *recdir);
 char * nfs4_recoverydir(void);
 bool nfsd4_spo_must_allow(struct svc_rqst *rqstp);
@@ -153,7 +153,6 @@ static inline int nfs4_state_start(void) { return 0; }
 static inline int nfs4_state_start_net(struct net *net) { return 0; }
 static inline void nfs4_state_shutdown(void) { }
 static inline void nfs4_state_shutdown_net(struct net *net) { }
-static inline void nfs4_reset_lease(time_t leasetime) { }
 static inline int nfs4_reset_recoverydir(char *recdir) { return 0; }
 static inline char * nfs4_recoverydir(void) {return NULL; }
 static inline bool nfsd4_spo_must_allow(struct svc_rqst *rqstp)
@@ -387,6 +386,37 @@ void               nfsd_lockd_shutdown(void);
 
 extern const u32 nfsd_suppattrs[3][3];
 
+static inline __be32 nfsd4_set_netaddr(struct sockaddr *addr,
+                                   struct nfs42_netaddr *netaddr)
+{
+       struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+       struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)addr;
+       unsigned int port;
+       size_t ret_addr, ret_port;
+
+       switch (addr->sa_family) {
+       case AF_INET:
+               port = ntohs(sin->sin_port);
+               sprintf(netaddr->netid, "tcp");
+               netaddr->netid_len = 3;
+               break;
+       case AF_INET6:
+               port = ntohs(sin6->sin6_port);
+               sprintf(netaddr->netid, "tcp6");
+               netaddr->netid_len = 4;
+               break;
+       default:
+               return nfserr_inval;
+       }
+       ret_addr = rpc_ntop(addr, netaddr->addr, sizeof(netaddr->addr));
+       ret_port = snprintf(netaddr->addr + ret_addr,
+                           RPCBIND_MAXUADDRLEN + 1 - ret_addr,
+                           ".%u.%u", port >> 8, port & 0xff);
+       WARN_ON(ret_port >= RPCBIND_MAXUADDRLEN + 1 - ret_addr);
+       netaddr->addr_len = ret_addr + ret_port;
+       return 0;
+}
+
 static inline bool bmval_is_subset(const u32 *bm1, const u32 *bm2)
 {
        return !((bm1[0] & ~bm2[0]) ||
index 755e256..56cfbc3 100644 (file)
@@ -35,15 +35,15 @@ typedef struct svc_fh {
 
        bool                    fh_locked;      /* inode locked by us */
        bool                    fh_want_write;  /* remount protection taken */
-
+       int                     fh_flags;       /* FH flags */
 #ifdef CONFIG_NFSD_V3
        bool                    fh_post_saved;  /* post-op attrs saved */
        bool                    fh_pre_saved;   /* pre-op attrs saved */
 
        /* Pre-op attributes saved during fh_lock */
        __u64                   fh_pre_size;    /* size before operation */
-       struct timespec         fh_pre_mtime;   /* mtime before oper */
-       struct timespec         fh_pre_ctime;   /* ctime before oper */
+       struct timespec64       fh_pre_mtime;   /* mtime before oper */
+       struct timespec64       fh_pre_ctime;   /* ctime before oper */
        /*
         * pre-op nfsv4 change attr: note must check IS_I_VERSION(inode)
         *  to find out if it is valid.
@@ -56,6 +56,9 @@ typedef struct svc_fh {
 #endif /* CONFIG_NFSD_V3 */
 
 } svc_fh;
+#define NFSD4_FH_FOREIGN (1<<0)
+#define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f))
+#define HAS_FH_FLAG(c, f) ((c)->fh_flags & (f))
 
 enum nfsd_fsid {
        FSID_DEV = 0,
index c83ddac..543bbe0 100644 (file)
@@ -94,7 +94,7 @@ nfsd_proc_setattr(struct svc_rqst *rqstp)
                 * Solaris, at least, doesn't seem to care what the time
                 * request is.  We require it be within 30 minutes of now.
                 */
-               time_t delta = iap->ia_atime.tv_sec - get_seconds();
+               time64_t delta = iap->ia_atime.tv_sec - ktime_get_real_seconds();
 
                nfserr = fh_verify(rqstp, fhp, 0, NFSD_MAY_NOP);
                if (nfserr)
@@ -113,7 +113,7 @@ nfsd_proc_setattr(struct svc_rqst *rqstp)
                }
        }
 
-       nfserr = nfsd_setattr(rqstp, fhp, iap, 0, (time_t)0);
+       nfserr = nfsd_setattr(rqstp, fhp, iap, 0, (time64_t)0);
 done:
        return nfsd_return_attrs(nfserr, resp);
 }
@@ -226,7 +226,7 @@ nfsd_proc_write(struct svc_rqst *rqstp)
                return nfserr_io;
        nfserr = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh),
                            argp->offset, rqstp->rq_vec, nvecs,
-                           &cnt, NFS_DATA_SYNC);
+                           &cnt, NFS_DATA_SYNC, NULL);
        return nfsd_return_attrs(nfserr, resp);
 }
 
@@ -380,7 +380,7 @@ nfsd_proc_create(struct svc_rqst *rqstp)
                 */
                attr->ia_valid &= ATTR_SIZE;
                if (attr->ia_valid)
-                       nfserr = nfsd_setattr(rqstp, newfhp, attr, 0, (time_t)0);
+                       nfserr = nfsd_setattr(rqstp, newfhp, attr, 0, (time64_t)0);
        }
 
 out_unlock:
index e8bee8f..3b77b90 100644 (file)
 
 #define NFSDDBG_FACILITY       NFSDDBG_SVC
 
+bool inter_copy_offload_enable;
+EXPORT_SYMBOL_GPL(inter_copy_offload_enable);
+module_param(inter_copy_offload_enable, bool, 0644);
+MODULE_PARM_DESC(inter_copy_offload_enable,
+                "Enable inter server to server copy offload. Default: false");
+
 extern struct svc_program      nfsd_program;
 static int                     nfsd(void *vrqstp);
 #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL)
@@ -391,20 +397,25 @@ static int nfsd_startup_net(int nrservs, struct net *net, const struct cred *cre
                ret = lockd_up(net, cred);
                if (ret)
                        goto out_socks;
-               nn->lockd_up = 1;
+               nn->lockd_up = true;
        }
 
-       ret = nfs4_state_start_net(net);
+       ret = nfsd_file_cache_start_net(net);
        if (ret)
                goto out_lockd;
+       ret = nfs4_state_start_net(net);
+       if (ret)
+               goto out_filecache;
 
        nn->nfsd_net_up = true;
        return 0;
 
+out_filecache:
+       nfsd_file_cache_shutdown_net(net);
 out_lockd:
        if (nn->lockd_up) {
                lockd_down(net);
-               nn->lockd_up = 0;
+               nn->lockd_up = false;
        }
 out_socks:
        nfsd_shutdown_generic();
@@ -415,11 +426,11 @@ static void nfsd_shutdown_net(struct net *net)
 {
        struct nfsd_net *nn = net_generic(net, nfsd_net_id);
 
-       nfsd_file_cache_purge(net);
+       nfsd_file_cache_shutdown_net(net);
        nfs4_state_shutdown_net(net);
        if (nn->lockd_up) {
                lockd_down(net);
-               nn->lockd_up = 0;
+               nn->lockd_up = false;
        }
        nn->nfsd_net_up = false;
        nfsd_shutdown_generic();
index d61b83b..68d3f30 100644 (file)
@@ -56,6 +56,14 @@ typedef struct {
        stateid_opaque_t        si_opaque;
 } stateid_t;
 
+typedef struct {
+       stateid_t               stid;
+#define NFS4_COPY_STID 1
+#define NFS4_COPYNOTIFY_STID 2
+       unsigned char           sc_type;
+       refcount_t              sc_count;
+} copy_stateid_t;
+
 #define STATEID_FMT    "(%08x/%08x/%08x/%08x)"
 #define STATEID_VAL(s) \
        (s)->si_opaque.so_clid.cl_boot, \
@@ -96,6 +104,7 @@ struct nfs4_stid {
 #define NFS4_REVOKED_DELEG_STID 16
 #define NFS4_CLOSED_DELEG_STID 32
 #define NFS4_LAYOUT_STID 64
+       struct list_head        sc_cp_list;
        unsigned char           sc_type;
        stateid_t               sc_stateid;
        spinlock_t              sc_lock;
@@ -104,6 +113,17 @@ struct nfs4_stid {
        void                    (*sc_free)(struct nfs4_stid *);
 };
 
+/* Keep a list of stateids issued by the COPY_NOTIFY, associate it with the
+ * parent OPEN/LOCK/DELEG stateid.
+ */
+struct nfs4_cpntf_state {
+       copy_stateid_t          cp_stateid;
+       struct list_head        cp_list;        /* per parent nfs4_stid */
+       stateid_t               cp_p_stateid;   /* copy of parent's stateid */
+       clientid_t              cp_p_clid;      /* copy of parent's clid */
+       time64_t                cpntf_time;     /* last time stateid used */
+};
+
 /*
  * Represents a delegation stateid. The nfs4_client holds references to these
  * and they are put when it is being destroyed or when the delegation is
@@ -132,7 +152,7 @@ struct nfs4_delegation {
        struct list_head        dl_recall_lru;  /* delegation recalled */
        struct nfs4_clnt_odstate *dl_clnt_odstate;
        u32                     dl_type;
-       time_t                  dl_time;
+       time64_t                dl_time;
 /* For recall: */
        int                     dl_retries;
        struct nfsd4_callback   dl_recall;
@@ -310,7 +330,7 @@ struct nfs4_client {
 #endif
        struct xdr_netobj       cl_name;        /* id generated by client */
        nfs4_verifier           cl_verifier;    /* generated by client */
-       time_t                  cl_time;        /* time of last lease renewal */
+       time64_t                cl_time;        /* time of last lease renewal */
        struct sockaddr_storage cl_addr;        /* client ipaddress */
        bool                    cl_mach_cred;   /* SP4_MACH_CRED in force */
        struct svc_cred         cl_cred;        /* setclientid principal */
@@ -320,7 +340,7 @@ struct nfs4_client {
        /* NFSv4.1 client implementation id: */
        struct xdr_netobj       cl_nii_domain;
        struct xdr_netobj       cl_nii_name;
-       struct timespec         cl_nii_time;
+       struct timespec64       cl_nii_time;
 
        /* for v4.0 and v4.1 callbacks: */
        struct nfs4_cb_conn     cl_cb_conn;
@@ -449,7 +469,7 @@ struct nfs4_openowner {
         */
        struct list_head        oo_close_lru;
        struct nfs4_ol_stateid *oo_last_closed_stid;
-       time_t                  oo_time; /* time of placement on so_close_lru */
+       time64_t                oo_time; /* time of placement on so_close_lru */
 #define NFS4_OO_CONFIRMED   1
        unsigned char           oo_flags;
 };
@@ -606,7 +626,7 @@ static inline bool nfsd4_stateid_generation_after(stateid_t *a, stateid_t *b)
 struct nfsd4_blocked_lock {
        struct list_head        nbl_list;
        struct list_head        nbl_lru;
-       unsigned long           nbl_time;
+       time64_t                nbl_time;
        struct file_lock        nbl_lock;
        struct knfsd_fh         nbl_fh;
        struct nfsd4_callback   nbl_cb;
@@ -618,14 +638,17 @@ struct nfsd4_copy;
 
 extern __be32 nfs4_preprocess_stateid_op(struct svc_rqst *rqstp,
                struct nfsd4_compound_state *cstate, struct svc_fh *fhp,
-               stateid_t *stateid, int flags, struct nfsd_file **filp);
+               stateid_t *stateid, int flags, struct nfsd_file **filp,
+               struct nfs4_stid **cstid);
 __be32 nfsd4_lookup_stateid(struct nfsd4_compound_state *cstate,
                     stateid_t *stateid, unsigned char typemask,
                     struct nfs4_stid **s, struct nfsd_net *nn);
 struct nfs4_stid *nfs4_alloc_stid(struct nfs4_client *cl, struct kmem_cache *slab,
                                  void (*sc_free)(struct nfs4_stid *));
-int nfs4_init_cp_state(struct nfsd_net *nn, struct nfsd4_copy *copy);
-void nfs4_free_cp_state(struct nfsd4_copy *copy);
+int nfs4_init_copy_state(struct nfsd_net *nn, struct nfsd4_copy *copy);
+void nfs4_free_copy_state(struct nfsd4_copy *copy);
+struct nfs4_cpntf_state *nfs4_alloc_init_cpntf_state(struct nfsd_net *nn,
+                       struct nfs4_stid *p_stid);
 void nfs4_unhash_stid(struct nfs4_stid *s);
 void nfs4_put_stid(struct nfs4_stid *s);
 void nfs4_inc_and_copy_stateid(stateid_t *dst, struct nfs4_stid *stid);
@@ -655,6 +678,11 @@ void put_nfs4_file(struct nfs4_file *fi);
 extern void nfs4_put_copy(struct nfsd4_copy *copy);
 extern struct nfsd4_copy *
 find_async_copy(struct nfs4_client *clp, stateid_t *staetid);
+extern void nfs4_put_cpntf_state(struct nfsd_net *nn,
+                                struct nfs4_cpntf_state *cps);
+extern __be32 manage_cpntf_state(struct nfsd_net *nn, stateid_t *st,
+                                struct nfs4_client *clp,
+                                struct nfs4_cpntf_state **cps);
 static inline void get_nfs4_file(struct nfs4_file *fi)
 {
        refcount_inc(&fi->fi_ref);
index 9bce3b9..b1bc582 100644 (file)
@@ -84,17 +84,17 @@ static int nfsd_proc_open(struct inode *inode, struct file *file)
        return single_open(file, nfsd_proc_show, NULL);
 }
 
-static const struct file_operations nfsd_proc_fops = {
-       .open = nfsd_proc_open,
-       .read  = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
+static const struct proc_ops nfsd_proc_ops = {
+       .proc_open      = nfsd_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 void
 nfsd_stat_init(void)
 {
-       svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_fops);
+       svc_proc_register(&init_net, &nfsd_svcstats, &nfsd_proc_ops);
 }
 
 void
index ffc78a0..06dd0d3 100644 (file)
@@ -166,6 +166,12 @@ DEFINE_STATEID_EVENT(layout_recall_done);
 DEFINE_STATEID_EVENT(layout_recall_fail);
 DEFINE_STATEID_EVENT(layout_recall_release);
 
+TRACE_DEFINE_ENUM(NFSD_FILE_HASHED);
+TRACE_DEFINE_ENUM(NFSD_FILE_PENDING);
+TRACE_DEFINE_ENUM(NFSD_FILE_BREAK_READ);
+TRACE_DEFINE_ENUM(NFSD_FILE_BREAK_WRITE);
+TRACE_DEFINE_ENUM(NFSD_FILE_REFERENCED);
+
 #define show_nf_flags(val)                                             \
        __print_flags(val, "|",                                         \
                { 1 << NFSD_FILE_HASHED,        "HASHED" },             \
@@ -195,7 +201,7 @@ DECLARE_EVENT_CLASS(nfsd_file_class,
        TP_fast_assign(
                __entry->nf_hashval = nf->nf_hashval;
                __entry->nf_inode = nf->nf_inode;
-               __entry->nf_ref = atomic_read(&nf->nf_ref);
+               __entry->nf_ref = refcount_read(&nf->nf_ref);
                __entry->nf_flags = nf->nf_flags;
                __entry->nf_may = nf->nf_may;
                __entry->nf_file = nf->nf_file;
@@ -228,7 +234,7 @@ TRACE_EVENT(nfsd_file_acquire,
        TP_ARGS(rqstp, hash, inode, may_flags, nf, status),
 
        TP_STRUCT__entry(
-               __field(__be32, xid)
+               __field(u32, xid)
                __field(unsigned int, hash)
                __field(void *, inode)
                __field(unsigned int, may_flags)
@@ -236,27 +242,27 @@ TRACE_EVENT(nfsd_file_acquire,
                __field(unsigned long, nf_flags)
                __field(unsigned char, nf_may)
                __field(struct file *, nf_file)
-               __field(__be32, status)
+               __field(u32, status)
        ),
 
        TP_fast_assign(
-               __entry->xid = rqstp->rq_xid;
+               __entry->xid = be32_to_cpu(rqstp->rq_xid);
                __entry->hash = hash;
                __entry->inode = inode;
                __entry->may_flags = may_flags;
-               __entry->nf_ref = nf ? atomic_read(&nf->nf_ref) : 0;
+               __entry->nf_ref = nf ? refcount_read(&nf->nf_ref) : 0;
                __entry->nf_flags = nf ? nf->nf_flags : 0;
                __entry->nf_may = nf ? nf->nf_may : 0;
                __entry->nf_file = nf ? nf->nf_file : NULL;
-               __entry->status = status;
+               __entry->status = be32_to_cpu(status);
        ),
 
        TP_printk("xid=0x%x hash=0x%x inode=0x%p may_flags=%s ref=%d nf_flags=%s nf_may=%s nf_file=0x%p status=%u",
-                       be32_to_cpu(__entry->xid), __entry->hash, __entry->inode,
+                       __entry->xid, __entry->hash, __entry->inode,
                        show_nf_may(__entry->may_flags), __entry->nf_ref,
                        show_nf_flags(__entry->nf_flags),
                        show_nf_may(__entry->nf_may), __entry->nf_file,
-                       be32_to_cpu(__entry->status))
+                       __entry->status)
 );
 
 DECLARE_EVENT_CLASS(nfsd_file_search_class,
index c0dc491..0aa02eb 100644 (file)
@@ -280,19 +280,25 @@ out:
  * Commit metadata changes to stable storage.
  */
 static int
-commit_metadata(struct svc_fh *fhp)
+commit_inode_metadata(struct inode *inode)
 {
-       struct inode *inode = d_inode(fhp->fh_dentry);
        const struct export_operations *export_ops = inode->i_sb->s_export_op;
 
-       if (!EX_ISSYNC(fhp->fh_export))
-               return 0;
-
        if (export_ops->commit_metadata)
                return export_ops->commit_metadata(inode);
        return sync_inode_metadata(inode, 1);
 }
 
+static int
+commit_metadata(struct svc_fh *fhp)
+{
+       struct inode *inode = d_inode(fhp->fh_dentry);
+
+       if (!EX_ISSYNC(fhp->fh_export))
+               return 0;
+       return commit_inode_metadata(inode);
+}
+
 /*
  * Go over the attributes and take care of the small differences between
  * NFS semantics and what Linux expects.
@@ -358,7 +364,7 @@ out_nfserrno:
  */
 __be32
 nfsd_setattr(struct svc_rqst *rqstp, struct svc_fh *fhp, struct iattr *iap,
-            int check_guard, time_t guardtime)
+            int check_guard, time64_t guardtime)
 {
        struct dentry   *dentry;
        struct inode    *inode;
@@ -524,23 +530,39 @@ __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, bool sync)
+__be32 nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
+               struct nfsd_file *nf_dst, u64 dst_pos, u64 count, bool sync)
 {
+       struct file *src = nf_src->nf_file;
+       struct file *dst = nf_dst->nf_file;
        loff_t cloned;
+       __be32 ret = 0;
 
+       down_write(&nf_dst->nf_rwsem);
        cloned = vfs_clone_file_range(src, src_pos, dst, dst_pos, count, 0);
-       if (cloned < 0)
-               return nfserrno(cloned);
-       if (count && cloned != count)
-               return nfserrno(-EINVAL);
+       if (cloned < 0) {
+               ret = nfserrno(cloned);
+               goto out_err;
+       }
+       if (count && cloned != count) {
+               ret = nfserrno(-EINVAL);
+               goto out_err;
+       }
        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);
+
+               if (!status)
+                       status = commit_inode_metadata(file_inode(src));
+               if (status < 0) {
+                       nfsd_reset_boot_verifier(net_generic(nf_dst->nf_net,
+                                                nfsd_net_id));
+                       ret = nfserrno(status);
+               }
        }
-       return 0;
+out_err:
+       up_write(&nf_dst->nf_rwsem);
+       return ret;
 }
 
 ssize_t nfsd_copy_file_range(struct file *src, u64 src_pos, struct file *dst,
@@ -938,10 +960,12 @@ static int wait_for_concurrent_writes(struct file *file)
 }
 
 __be32
-nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
+nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf,
                                loff_t offset, struct kvec *vec, int vlen,
-                               unsigned long *cnt, int stable)
+                               unsigned long *cnt, int stable,
+                               __be32 *verf)
 {
+       struct file             *file = nf->nf_file;
        struct svc_export       *exp;
        struct iov_iter         iter;
        __be32                  nfserr;
@@ -972,9 +996,28 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file,
                flags |= RWF_SYNC;
 
        iov_iter_kvec(&iter, WRITE, vec, vlen, *cnt);
-       host_err = vfs_iter_write(file, &iter, &pos, flags);
-       if (host_err < 0)
+       if (flags & RWF_SYNC) {
+               down_write(&nf->nf_rwsem);
+               host_err = vfs_iter_write(file, &iter, &pos, flags);
+               if (host_err < 0)
+                       nfsd_reset_boot_verifier(net_generic(SVC_NET(rqstp),
+                                                nfsd_net_id));
+               up_write(&nf->nf_rwsem);
+       } else {
+               down_read(&nf->nf_rwsem);
+               if (verf)
+                       nfsd_copy_boot_verifier(verf,
+                                       net_generic(SVC_NET(rqstp),
+                                       nfsd_net_id));
+               host_err = vfs_iter_write(file, &iter, &pos, flags);
+               up_read(&nf->nf_rwsem);
+       }
+       if (host_err < 0) {
+               nfsd_reset_boot_verifier(net_generic(SVC_NET(rqstp),
+                                        nfsd_net_id));
                goto out_nfserr;
+       }
+       *cnt = host_err;
        nfsdstats.io_write += *cnt;
        fsnotify_modify(file);
 
@@ -1036,7 +1079,8 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
  */
 __be32
 nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
-          struct kvec *vec, int vlen, unsigned long *cnt, int stable)
+          struct kvec *vec, int vlen, unsigned long *cnt, int stable,
+          __be32 *verf)
 {
        struct nfsd_file *nf;
        __be32 err;
@@ -1047,8 +1091,8 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset,
        if (err)
                goto out;
 
-       err = nfsd_vfs_write(rqstp, fhp, nf->nf_file, offset, vec,
-                       vlen, cnt, stable);
+       err = nfsd_vfs_write(rqstp, fhp, nf, offset, vec,
+                       vlen, cnt, stable, verf);
        nfsd_file_put(nf);
 out:
        trace_nfsd_write_done(rqstp, fhp, offset, *cnt);
@@ -1067,7 +1111,7 @@ out:
  */
 __be32
 nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
-               loff_t offset, unsigned long count)
+               loff_t offset, unsigned long count, __be32 *verf)
 {
        struct nfsd_file        *nf;
        loff_t                  end = LLONG_MAX;
@@ -1086,10 +1130,14 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
        if (err)
                goto out;
        if (EX_ISSYNC(fhp->fh_export)) {
-               int err2 = vfs_fsync_range(nf->nf_file, offset, end, 0);
+               int err2;
 
+               down_write(&nf->nf_rwsem);
+               err2 = vfs_fsync_range(nf->nf_file, offset, end, 0);
                switch (err2) {
                case 0:
+                       nfsd_copy_boot_verifier(verf, net_generic(nf->nf_net,
+                                               nfsd_net_id));
                        break;
                case -EINVAL:
                        err = nfserr_notsupp;
@@ -1099,7 +1147,10 @@ nfsd_commit(struct svc_rqst *rqstp, struct svc_fh *fhp,
                        nfsd_reset_boot_verifier(net_generic(nf->nf_net,
                                                 nfsd_net_id));
                }
-       }
+               up_write(&nf->nf_rwsem);
+       } else
+               nfsd_copy_boot_verifier(verf, net_generic(nf->nf_net,
+                                       nfsd_net_id));
 
        nfsd_file_put(nf);
 out:
@@ -1123,7 +1174,7 @@ nfsd_create_setattr(struct svc_rqst *rqstp, struct svc_fh *resfhp,
        if (!uid_eq(current_fsuid(), GLOBAL_ROOT_UID))
                iap->ia_valid &= ~(ATTR_UID|ATTR_GID);
        if (iap->ia_valid)
-               return nfsd_setattr(rqstp, resfhp, iap, 0, (time_t)0);
+               return nfsd_setattr(rqstp, resfhp, iap, 0, (time64_t)0);
        /* Callers expect file metadata to be committed here */
        return nfserrno(commit_metadata(resfhp));
 }
@@ -1386,7 +1437,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                            && d_inode(dchild)->i_atime.tv_sec == v_atime
                            && d_inode(dchild)->i_size  == 0 ) {
                                if (created)
-                                       *created = 1;
+                                       *created = true;
                                break;
                        }
                        /* fall through */
@@ -1395,7 +1446,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                            && d_inode(dchild)->i_atime.tv_sec == v_atime
                            && d_inode(dchild)->i_size  == 0 ) {
                                if (created)
-                                       *created = 1;
+                                       *created = true;
                                goto set_attr;
                        }
                        /* fall through */
@@ -1412,7 +1463,7 @@ do_nfsd_create(struct svc_rqst *rqstp, struct svc_fh *fhp,
                goto out_nfserr;
        }
        if (created)
-               *created = 1;
+               *created = true;
 
        nfsd_check_ignore_resizing(iap);
 
index cc110a1..3eb660a 100644 (file)
@@ -34,6 +34,8 @@
 #define NFSD_MAY_CREATE                (NFSD_MAY_EXEC|NFSD_MAY_WRITE)
 #define NFSD_MAY_REMOVE                (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC)
 
+struct nfsd_file;
+
 /*
  * Callback function for readdir
  */
@@ -48,15 +50,16 @@ __be32               nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *,
                                const char *, unsigned int,
                                struct svc_export **, struct dentry **);
 __be32         nfsd_setattr(struct svc_rqst *, struct svc_fh *,
-                               struct iattr *, int, time_t);
+                               struct iattr *, int, time64_t);
 int nfsd_mountpoint(struct dentry *, struct svc_export *);
 #ifdef CONFIG_NFSD_V4
 __be32          nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
                    struct xdr_netobj *);
 __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, bool);
+__be32         nfsd4_clone_file_range(struct nfsd_file *nf_src, u64 src_pos,
+                                      struct nfsd_file *nf_dst, u64 dst_pos,
+                                      u64 count, bool sync);
 #endif /* CONFIG_NFSD_V4 */
 __be32         nfsd_create_locked(struct svc_rqst *, struct svc_fh *,
                                char *name, int len, struct iattr *attrs,
@@ -71,7 +74,7 @@ __be32                do_nfsd_create(struct svc_rqst *, struct svc_fh *,
                                struct svc_fh *res, int createmode,
                                u32 *verifier, bool *truncp, bool *created);
 __be32         nfsd_commit(struct svc_rqst *, struct svc_fh *,
-                               loff_t, unsigned long);
+                               loff_t, unsigned long, __be32 *verf);
 #endif /* CONFIG_NFSD_V3 */
 int            nfsd_open_break_lease(struct inode *, int);
 __be32         nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
@@ -91,11 +94,12 @@ __be32              nfsd_read(struct svc_rqst *, struct svc_fh *,
                                loff_t, struct kvec *, int, unsigned long *,
                                u32 *eof);
 __be32                 nfsd_write(struct svc_rqst *, struct svc_fh *, loff_t,
-                               struct kvec *, int, unsigned long *, int);
+                               struct kvec *, int, unsigned long *,
+                               int stable, __be32 *verf);
 __be32         nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp,
-                               struct file *file, loff_t offset,
+                               struct nfsd_file *nf, loff_t offset,
                                struct kvec *vec, int vlen, unsigned long *cnt,
-                               int stable);
+                               int stable, __be32 *verf);
 __be32         nfsd_readlink(struct svc_rqst *, struct svc_fh *,
                                char *, int *);
 __be32         nfsd_symlink(struct svc_rqst *, struct svc_fh *,
index 99ff9f4..4155fd7 100644 (file)
@@ -14,7 +14,7 @@ struct nfsd3_sattrargs {
        struct svc_fh           fh;
        struct iattr            attrs;
        int                     check_guard;
-       time_t                  guardtime;
+       time64_t                guardtime;
 };
 
 struct nfsd3_diropargs {
@@ -159,6 +159,7 @@ struct nfsd3_writeres {
        struct svc_fh           fh;
        unsigned long           count;
        int                     committed;
+       __be32                  verf[2];
 };
 
 struct nfsd3_renameres {
@@ -223,6 +224,7 @@ struct nfsd3_pathconfres {
 struct nfsd3_commitres {
        __be32                  status;
        struct svc_fh           fh;
+       __be32                  verf[2];
 };
 
 struct nfsd3_getaclres {
index f4737d6..db63d39 100644 (file)
@@ -46,9 +46,9 @@
 #define CURRENT_STATE_ID_FLAG (1<<0)
 #define SAVED_STATE_ID_FLAG (1<<1)
 
-#define SET_STATE_ID(c, f) ((c)->sid_flags |= (f))
-#define HAS_STATE_ID(c, f) ((c)->sid_flags & (f))
-#define CLEAR_STATE_ID(c, f) ((c)->sid_flags &= ~(f))
+#define SET_CSTATE_FLAG(c, f) ((c)->sid_flags |= (f))
+#define HAS_CSTATE_FLAG(c, f) ((c)->sid_flags & (f))
+#define CLEAR_CSTATE_FLAG(c, f) ((c)->sid_flags &= ~(f))
 
 struct nfsd4_compound_state {
        struct svc_fh           current_fh;
@@ -221,6 +221,7 @@ struct nfsd4_lookup {
 struct nfsd4_putfh {
        u32             pf_fhlen;           /* request */
        char            *pf_fhval;          /* request */
+       bool            no_verify;          /* represents foreigh fh */
 };
 
 struct nfsd4_open {
@@ -518,11 +519,13 @@ struct nfsd42_write_res {
 
 struct nfsd4_copy {
        /* request */
-       stateid_t       cp_src_stateid;
-       stateid_t       cp_dst_stateid;
-       u64             cp_src_pos;
-       u64             cp_dst_pos;
-       u64             cp_count;
+       stateid_t               cp_src_stateid;
+       stateid_t               cp_dst_stateid;
+       u64                     cp_src_pos;
+       u64                     cp_dst_pos;
+       u64                     cp_count;
+       struct nl4_server       cp_src;
+       bool                    cp_intra;
 
        /* both */
        bool            cp_synchronous;
@@ -540,13 +543,18 @@ struct nfsd4_copy {
        struct nfsd_file        *nf_src;
        struct nfsd_file        *nf_dst;
 
-       stateid_t               cp_stateid;
+       copy_stateid_t          cp_stateid;
 
        struct list_head        copies;
        struct task_struct      *copy_task;
        refcount_t              refcount;
        bool                    stopped;
+
+       struct vfsmount         *ss_mnt;
+       struct nfs_fh           c_fh;
+       nfs4_stateid            stateid;
 };
+extern bool inter_copy_offload_enable;
 
 struct nfsd4_seek {
        /* request */
@@ -568,6 +576,18 @@ struct nfsd4_offload_status {
        u32             status;
 };
 
+struct nfsd4_copy_notify {
+       /* request */
+       stateid_t               cpn_src_stateid;
+       struct nl4_server       cpn_dst;
+
+       /* response */
+       stateid_t               cpn_cnr_stateid;
+       u64                     cpn_sec;
+       u32                     cpn_nsec;
+       struct nl4_server       cpn_src;
+};
+
 struct nfsd4_op {
        int                                     opnum;
        const struct nfsd4_operation *          opdesc;
@@ -627,6 +647,7 @@ struct nfsd4_op {
                struct nfsd4_clone              clone;
                struct nfsd4_copy               copy;
                struct nfsd4_offload_status     offload_status;
+               struct nfsd4_copy_notify        copy_notify;
                struct nfsd4_seek               seek;
        } u;
        struct nfs4_replay *                    replay;
index 6c73884..d4359a1 100644 (file)
@@ -2899,18 +2899,12 @@ int ntfs_setattr(struct dentry *dentry, struct iattr *attr)
                        ia_valid |= ATTR_MTIME | ATTR_CTIME;
                }
        }
-       if (ia_valid & ATTR_ATIME) {
-               vi->i_atime = timestamp_truncate(attr->ia_atime,
-                                              vi);
-       }
-       if (ia_valid & ATTR_MTIME) {
-               vi->i_mtime = timestamp_truncate(attr->ia_mtime,
-                                              vi);
-       }
-       if (ia_valid & ATTR_CTIME) {
-               vi->i_ctime = timestamp_truncate(attr->ia_ctime,
-                                              vi);
-       }
+       if (ia_valid & ATTR_ATIME)
+               vi->i_atime = attr->ia_atime;
+       if (ia_valid & ATTR_MTIME)
+               vi->i_mtime = attr->ia_mtime;
+       if (ia_valid & ATTR_CTIME)
+               vi->i_ctime = attr->ia_ctime;
        mark_inode_dirty(vi);
 out:
        return err;
index 9876db5..6cd5e49 100644 (file)
@@ -2101,17 +2101,15 @@ static int ocfs2_is_io_unaligned(struct inode *inode, size_t count, loff_t pos)
 static int ocfs2_inode_lock_for_extent_tree(struct inode *inode,
                                            struct buffer_head **di_bh,
                                            int meta_level,
-                                           int overwrite_io,
                                            int write_sem,
                                            int wait)
 {
        int ret = 0;
 
        if (wait)
-               ret = ocfs2_inode_lock(inode, NULL, meta_level);
+               ret = ocfs2_inode_lock(inode, di_bh, meta_level);
        else
-               ret = ocfs2_try_inode_lock(inode,
-                       overwrite_io ? NULL : di_bh, meta_level);
+               ret = ocfs2_try_inode_lock(inode, di_bh, meta_level);
        if (ret < 0)
                goto out;
 
@@ -2136,6 +2134,7 @@ static int ocfs2_inode_lock_for_extent_tree(struct inode *inode,
 
 out_unlock:
        brelse(*di_bh);
+       *di_bh = NULL;
        ocfs2_inode_unlock(inode, meta_level);
 out:
        return ret;
@@ -2177,7 +2176,6 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
                ret = ocfs2_inode_lock_for_extent_tree(inode,
                                                       &di_bh,
                                                       meta_level,
-                                                      overwrite_io,
                                                       write_sem,
                                                       wait);
                if (ret < 0) {
@@ -2233,13 +2231,13 @@ static int ocfs2_prepare_inode_for_write(struct file *file,
                                                           &di_bh,
                                                           meta_level,
                                                           write_sem);
+                       meta_level = 1;
+                       write_sem = 1;
                        ret = ocfs2_inode_lock_for_extent_tree(inode,
                                                               &di_bh,
                                                               meta_level,
-                                                              overwrite_io,
-                                                              1,
+                                                              write_sem,
                                                               wait);
-                       write_sem = 1;
                        if (ret < 0) {
                                if (ret != -EAGAIN)
                                        mlog_errno(ret);
index 4180c3e..939df99 100644 (file)
@@ -696,7 +696,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
 
        bg_bh = ocfs2_block_group_alloc_contig(osb, handle, alloc_inode,
                                               ac, cl);
-       if (IS_ERR(bg_bh) && (PTR_ERR(bg_bh) == -ENOSPC))
+       if (PTR_ERR(bg_bh) == -ENOSPC)
                bg_bh = ocfs2_block_group_alloc_discontig(handle,
                                                          alloc_inode,
                                                          ac, cl);
index 25543a9..29eaa45 100644 (file)
@@ -273,6 +273,7 @@ static void *help_start(struct seq_file *m, loff_t *pos)
 
 static void *help_next(struct seq_file *m, void *v, loff_t *pos)
 {
+       (*pos)++;
        gossip_debug(GOSSIP_DEBUGFS_DEBUG, "help_next: start\n");
 
        return NULL;
index 6220642..9fc47c2 100644 (file)
@@ -24,7 +24,7 @@
 
 static int ovl_ccup_set(const char *buf, const struct kernel_param *param)
 {
-       pr_warn("overlayfs: \"check_copy_up\" module option is obsolete\n");
+       pr_warn("\"check_copy_up\" module option is obsolete\n");
        return 0;
 }
 
@@ -123,6 +123,9 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
        loff_t old_pos = 0;
        loff_t new_pos = 0;
        loff_t cloned;
+       loff_t data_pos = -1;
+       loff_t hole_len;
+       bool skip_hole = false;
        int error = 0;
 
        if (len == 0)
@@ -144,7 +147,11 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
                goto out;
        /* Couldn't clone, so now we try to copy the data */
 
-       /* FIXME: copy up sparse files efficiently */
+       /* Check if lower fs supports seek operation */
+       if (old_file->f_mode & FMODE_LSEEK &&
+           old_file->f_op->llseek)
+               skip_hole = true;
+
        while (len) {
                size_t this_len = OVL_COPY_UP_CHUNK_SIZE;
                long bytes;
@@ -157,6 +164,36 @@ static int ovl_copy_up_data(struct path *old, struct path *new, loff_t len)
                        break;
                }
 
+               /*
+                * Fill zero for hole will cost unnecessary disk space
+                * and meanwhile slow down the copy-up speed, so we do
+                * an optimization for hole during copy-up, it relies
+                * on SEEK_DATA implementation in lower fs so if lower
+                * fs does not support it, copy-up will behave as before.
+                *
+                * Detail logic of hole detection as below:
+                * When we detect next data position is larger than current
+                * position we will skip that hole, otherwise we copy
+                * data in the size of OVL_COPY_UP_CHUNK_SIZE. Actually,
+                * it may not recognize all kind of holes and sometimes
+                * only skips partial of hole area. However, it will be
+                * enough for most of the use cases.
+                */
+
+               if (skip_hole && data_pos < old_pos) {
+                       data_pos = vfs_llseek(old_file, old_pos, SEEK_DATA);
+                       if (data_pos > old_pos) {
+                               hole_len = data_pos - old_pos;
+                               len -= hole_len;
+                               old_pos = new_pos = data_pos;
+                               continue;
+                       } else if (data_pos == -ENXIO) {
+                               break;
+                       } else if (data_pos < 0) {
+                               skip_hole = false;
+                       }
+               }
+
                bytes = do_splice_direct(old_file, &old_pos,
                                         new_file, &new_pos,
                                         this_len, SPLICE_F_MOVE);
@@ -480,7 +517,7 @@ static int ovl_copy_up_inode(struct ovl_copy_up_ctx *c, struct dentry *temp)
        }
 
        inode_lock(temp->d_inode);
-       if (c->metacopy)
+       if (S_ISREG(c->stat.mode))
                err = ovl_set_size(temp, &c->stat);
        if (!err)
                err = ovl_set_attr(temp, &c->stat);
index 29abdb1..8e57d53 100644 (file)
@@ -35,7 +35,7 @@ int ovl_cleanup(struct inode *wdir, struct dentry *wdentry)
        dput(wdentry);
 
        if (err) {
-               pr_err("overlayfs: cleanup of '%pd2' failed (%i)\n",
+               pr_err("cleanup of '%pd2' failed (%i)\n",
                       wdentry, err);
        }
 
@@ -53,7 +53,7 @@ static struct dentry *ovl_lookup_temp(struct dentry *workdir)
 
        temp = lookup_one_len(name, workdir, strlen(name));
        if (!IS_ERR(temp) && temp->d_inode) {
-               pr_err("overlayfs: workdir/%s already exists\n", name);
+               pr_err("workdir/%s already exists\n", name);
                dput(temp);
                temp = ERR_PTR(-EIO);
        }
@@ -134,7 +134,7 @@ static int ovl_mkdir_real(struct inode *dir, struct dentry **newdentry,
        d = lookup_one_len(dentry->d_name.name, dentry->d_parent,
                           dentry->d_name.len);
        if (IS_ERR(d)) {
-               pr_warn("overlayfs: failed lookup after mkdir (%pd2, err=%i).\n",
+               pr_warn("failed lookup after mkdir (%pd2, err=%i).\n",
                        dentry, err);
                return PTR_ERR(d);
        }
@@ -267,7 +267,7 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
 
        d_instantiate(dentry, inode);
        if (inode != oip.newinode) {
-               pr_warn_ratelimited("overlayfs: newly created inode found in cache (%pd2)\n",
+               pr_warn_ratelimited("newly created inode found in cache (%pd2)\n",
                                    dentry);
        }
 
@@ -1009,7 +1009,7 @@ static int ovl_set_redirect(struct dentry *dentry, bool samedir)
                spin_unlock(&dentry->d_lock);
        } else {
                kfree(redirect);
-               pr_warn_ratelimited("overlayfs: failed to set redirect (%i)\n",
+               pr_warn_ratelimited("failed to set redirect (%i)\n",
                                    err);
                /* Fall back to userspace copy-up */
                err = -EXDEV;
index 70e5558..6f54d70 100644 (file)
@@ -30,7 +30,7 @@ static int ovl_encode_maybe_copy_up(struct dentry *dentry)
        }
 
        if (err) {
-               pr_warn_ratelimited("overlayfs: failed to copy up on encode (%pd2, err=%i)\n",
+               pr_warn_ratelimited("failed to copy up on encode (%pd2, err=%i)\n",
                                    dentry, err);
        }
 
@@ -244,7 +244,7 @@ out:
        return err;
 
 fail:
-       pr_warn_ratelimited("overlayfs: failed to encode file handle (%pd2, err=%i, buflen=%d, len=%d, type=%d)\n",
+       pr_warn_ratelimited("failed to encode file handle (%pd2, err=%i, buflen=%d, len=%d, type=%d)\n",
                            dentry, err, buflen, fh ? (int)fh->fb.len : 0,
                            fh ? fh->fb.type : 0);
        goto out;
@@ -358,7 +358,7 @@ static struct dentry *ovl_dentry_real_at(struct dentry *dentry, int idx)
  */
 static struct dentry *ovl_lookup_real_one(struct dentry *connected,
                                          struct dentry *real,
-                                         struct ovl_layer *layer)
+                                         const struct ovl_layer *layer)
 {
        struct inode *dir = d_inode(connected);
        struct dentry *this, *parent = NULL;
@@ -406,7 +406,7 @@ out:
        return this;
 
 fail:
-       pr_warn_ratelimited("overlayfs: failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
+       pr_warn_ratelimited("failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
                            real, layer->idx, connected, err);
        this = ERR_PTR(err);
        goto out;
@@ -414,17 +414,16 @@ fail:
 
 static struct dentry *ovl_lookup_real(struct super_block *sb,
                                      struct dentry *real,
-                                     struct ovl_layer *layer);
+                                     const struct ovl_layer *layer);
 
 /*
  * Lookup an indexed or hashed overlay dentry by real inode.
  */
 static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
                                            struct dentry *real,
-                                           struct ovl_layer *layer)
+                                           const struct ovl_layer *layer)
 {
        struct ovl_fs *ofs = sb->s_fs_info;
-       struct ovl_layer upper_layer = { .mnt = ofs->upper_mnt };
        struct dentry *index = NULL;
        struct dentry *this = NULL;
        struct inode *inode;
@@ -466,7 +465,7 @@ static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
                 * recursive call walks back from indexed upper to the topmost
                 * connected/hashed upper parent (or up to root).
                 */
-               this = ovl_lookup_real(sb, upper, &upper_layer);
+               this = ovl_lookup_real(sb, upper, &ofs->layers[0]);
                dput(upper);
        }
 
@@ -487,7 +486,7 @@ static struct dentry *ovl_lookup_real_inode(struct super_block *sb,
  */
 static struct dentry *ovl_lookup_real_ancestor(struct super_block *sb,
                                               struct dentry *real,
-                                              struct ovl_layer *layer)
+                                              const struct ovl_layer *layer)
 {
        struct dentry *next, *parent = NULL;
        struct dentry *ancestor = ERR_PTR(-EIO);
@@ -540,7 +539,7 @@ static struct dentry *ovl_lookup_real_ancestor(struct super_block *sb,
  */
 static struct dentry *ovl_lookup_real(struct super_block *sb,
                                      struct dentry *real,
-                                     struct ovl_layer *layer)
+                                     const struct ovl_layer *layer)
 {
        struct dentry *connected;
        int err = 0;
@@ -631,7 +630,7 @@ static struct dentry *ovl_lookup_real(struct super_block *sb,
        return connected;
 
 fail:
-       pr_warn_ratelimited("overlayfs: failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
+       pr_warn_ratelimited("failed to lookup by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
                            real, layer->idx, connected, err);
        dput(connected);
        return ERR_PTR(err);
@@ -646,8 +645,7 @@ static struct dentry *ovl_get_dentry(struct super_block *sb,
                                     struct dentry *index)
 {
        struct ovl_fs *ofs = sb->s_fs_info;
-       struct ovl_layer upper_layer = { .mnt = ofs->upper_mnt };
-       struct ovl_layer *layer = upper ? &upper_layer : lowerpath->layer;
+       const struct ovl_layer *layer = upper ? &ofs->layers[0] : lowerpath->layer;
        struct dentry *real = upper ?: (index ?: lowerpath->dentry);
 
        /*
@@ -822,7 +820,7 @@ out:
        return dentry;
 
 out_err:
-       pr_warn_ratelimited("overlayfs: failed to decode file handle (len=%d, type=%d, flags=%x, err=%i)\n",
+       pr_warn_ratelimited("failed to decode file handle (len=%d, type=%d, flags=%x, err=%i)\n",
                            fh_len, fh_type, flags, err);
        dentry = ERR_PTR(err);
        goto out;
@@ -831,7 +829,7 @@ out_err:
 static struct dentry *ovl_fh_to_parent(struct super_block *sb, struct fid *fid,
                                       int fh_len, int fh_type)
 {
-       pr_warn_ratelimited("overlayfs: connectable file handles not supported; use 'no_subtree_check' exportfs option.\n");
+       pr_warn_ratelimited("connectable file handles not supported; use 'no_subtree_check' exportfs option.\n");
        return ERR_PTR(-EACCES);
 }
 
index e235a63..a531721 100644 (file)
@@ -9,8 +9,19 @@
 #include <linux/xattr.h>
 #include <linux/uio.h>
 #include <linux/uaccess.h>
+#include <linux/splice.h>
+#include <linux/mm.h>
+#include <linux/fs.h>
 #include "overlayfs.h"
 
+struct ovl_aio_req {
+       struct kiocb iocb;
+       struct kiocb *orig_iocb;
+       struct fd fd;
+};
+
+static struct kmem_cache *ovl_aio_request_cachep;
+
 static char ovl_whatisit(struct inode *inode, struct inode *realinode)
 {
        if (realinode != ovl_inode_upper(inode))
@@ -146,7 +157,7 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
        struct inode *inode = file_inode(file);
        struct fd real;
        const struct cred *old_cred;
-       ssize_t ret;
+       loff_t ret;
 
        /*
         * The two special cases below do not need to involve real fs,
@@ -171,7 +182,7 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
         * limitations that are more strict than ->s_maxbytes for specific
         * files, so we use the real file to perform seeks.
         */
-       inode_lock(inode);
+       ovl_inode_lock(inode);
        real.file->f_pos = file->f_pos;
 
        old_cred = ovl_override_creds(inode->i_sb);
@@ -179,7 +190,7 @@ static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
        revert_creds(old_cred);
 
        file->f_pos = real.file->f_pos;
-       inode_unlock(inode);
+       ovl_inode_unlock(inode);
 
        fdput(real);
 
@@ -225,6 +236,33 @@ static rwf_t ovl_iocb_to_rwf(struct kiocb *iocb)
        return flags;
 }
 
+static void ovl_aio_cleanup_handler(struct ovl_aio_req *aio_req)
+{
+       struct kiocb *iocb = &aio_req->iocb;
+       struct kiocb *orig_iocb = aio_req->orig_iocb;
+
+       if (iocb->ki_flags & IOCB_WRITE) {
+               struct inode *inode = file_inode(orig_iocb->ki_filp);
+
+               file_end_write(iocb->ki_filp);
+               ovl_copyattr(ovl_inode_real(inode), inode);
+       }
+
+       orig_iocb->ki_pos = iocb->ki_pos;
+       fdput(aio_req->fd);
+       kmem_cache_free(ovl_aio_request_cachep, aio_req);
+}
+
+static void ovl_aio_rw_complete(struct kiocb *iocb, long res, long res2)
+{
+       struct ovl_aio_req *aio_req = container_of(iocb,
+                                                  struct ovl_aio_req, iocb);
+       struct kiocb *orig_iocb = aio_req->orig_iocb;
+
+       ovl_aio_cleanup_handler(aio_req);
+       orig_iocb->ki_complete(orig_iocb, res, res2);
+}
+
 static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
 {
        struct file *file = iocb->ki_filp;
@@ -240,10 +278,28 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
                return ret;
 
        old_cred = ovl_override_creds(file_inode(file)->i_sb);
-       ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
-                           ovl_iocb_to_rwf(iocb));
+       if (is_sync_kiocb(iocb)) {
+               ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
+                                   ovl_iocb_to_rwf(iocb));
+       } else {
+               struct ovl_aio_req *aio_req;
+
+               ret = -ENOMEM;
+               aio_req = kmem_cache_zalloc(ovl_aio_request_cachep, GFP_KERNEL);
+               if (!aio_req)
+                       goto out;
+
+               aio_req->fd = real;
+               real.flags = 0;
+               aio_req->orig_iocb = iocb;
+               kiocb_clone(&aio_req->iocb, iocb, real.file);
+               aio_req->iocb.ki_complete = ovl_aio_rw_complete;
+               ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter);
+               if (ret != -EIOCBQUEUED)
+                       ovl_aio_cleanup_handler(aio_req);
+       }
+out:
        revert_creds(old_cred);
-
        ovl_file_accessed(file);
 
        fdput(real);
@@ -274,15 +330,33 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
                goto out_unlock;
 
        old_cred = ovl_override_creds(file_inode(file)->i_sb);
-       file_start_write(real.file);
-       ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
-                            ovl_iocb_to_rwf(iocb));
-       file_end_write(real.file);
+       if (is_sync_kiocb(iocb)) {
+               file_start_write(real.file);
+               ret = vfs_iter_write(real.file, iter, &iocb->ki_pos,
+                                    ovl_iocb_to_rwf(iocb));
+               file_end_write(real.file);
+               /* Update size */
+               ovl_copyattr(ovl_inode_real(inode), inode);
+       } else {
+               struct ovl_aio_req *aio_req;
+
+               ret = -ENOMEM;
+               aio_req = kmem_cache_zalloc(ovl_aio_request_cachep, GFP_KERNEL);
+               if (!aio_req)
+                       goto out;
+
+               file_start_write(real.file);
+               aio_req->fd = real;
+               real.flags = 0;
+               aio_req->orig_iocb = iocb;
+               kiocb_clone(&aio_req->iocb, iocb, real.file);
+               aio_req->iocb.ki_complete = ovl_aio_rw_complete;
+               ret = vfs_iocb_iter_write(real.file, &aio_req->iocb, iter);
+               if (ret != -EIOCBQUEUED)
+                       ovl_aio_cleanup_handler(aio_req);
+       }
+out:
        revert_creds(old_cred);
-
-       /* Update size */
-       ovl_copyattr(ovl_inode_real(inode), inode);
-
        fdput(real);
 
 out_unlock:
@@ -291,6 +365,48 @@ out_unlock:
        return ret;
 }
 
+static ssize_t ovl_splice_read(struct file *in, loff_t *ppos,
+                        struct pipe_inode_info *pipe, size_t len,
+                        unsigned int flags)
+{
+       ssize_t ret;
+       struct fd real;
+       const struct cred *old_cred;
+
+       ret = ovl_real_fdget(in, &real);
+       if (ret)
+               return ret;
+
+       old_cred = ovl_override_creds(file_inode(in)->i_sb);
+       ret = generic_file_splice_read(real.file, ppos, pipe, len, flags);
+       revert_creds(old_cred);
+
+       ovl_file_accessed(in);
+       fdput(real);
+       return ret;
+}
+
+static ssize_t
+ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
+                         loff_t *ppos, size_t len, unsigned int flags)
+{
+       struct fd real;
+       const struct cred *old_cred;
+       ssize_t ret;
+
+       ret = ovl_real_fdget(out, &real);
+       if (ret)
+               return ret;
+
+       old_cred = ovl_override_creds(file_inode(out)->i_sb);
+       ret = iter_file_splice_write(pipe, real.file, ppos, len, flags);
+       revert_creds(old_cred);
+
+       ovl_file_accessed(out);
+       fdput(real);
+       return ret;
+}
+
 static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
 {
        struct fd real;
@@ -647,7 +763,25 @@ const struct file_operations ovl_file_operations = {
        .fadvise        = ovl_fadvise,
        .unlocked_ioctl = ovl_ioctl,
        .compat_ioctl   = ovl_compat_ioctl,
+       .splice_read    = ovl_splice_read,
+       .splice_write   = ovl_splice_write,
 
        .copy_file_range        = ovl_copy_file_range,
        .remap_file_range       = ovl_remap_file_range,
 };
+
+int __init ovl_aio_request_cache_init(void)
+{
+       ovl_aio_request_cachep = kmem_cache_create("ovl_aio_req",
+                                                  sizeof(struct ovl_aio_req),
+                                                  0, SLAB_HWCACHE_ALIGN, NULL);
+       if (!ovl_aio_request_cachep)
+               return -ENOMEM;
+
+       return 0;
+}
+
+void ovl_aio_request_cache_destroy(void)
+{
+       kmem_cache_destroy(ovl_aio_request_cachep);
+}
index b045cf1..79e8994 100644 (file)
@@ -75,10 +75,9 @@ out:
        return err;
 }
 
-static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat,
-                          struct ovl_layer *lower_layer)
+static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat, int fsid)
 {
-       bool samefs = ovl_same_sb(dentry->d_sb);
+       bool samefs = ovl_same_fs(dentry->d_sb);
        unsigned int xinobits = ovl_xino_bits(dentry->d_sb);
 
        if (samefs) {
@@ -100,12 +99,10 @@ static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat,
                 * persistent for a given layer configuration.
                 */
                if (stat->ino >> shift) {
-                       pr_warn_ratelimited("overlayfs: inode number too big (%pd2, ino=%llu, xinobits=%d)\n",
+                       pr_warn_ratelimited("inode number too big (%pd2, ino=%llu, xinobits=%d)\n",
                                            dentry, stat->ino, xinobits);
                } else {
-                       if (lower_layer)
-                               stat->ino |= ((u64)lower_layer->fsid) << shift;
-
+                       stat->ino |= ((u64)fsid) << shift;
                        stat->dev = dentry->d_sb->s_dev;
                        return 0;
                }
@@ -124,15 +121,14 @@ static int ovl_map_dev_ino(struct dentry *dentry, struct kstat *stat,
                 */
                stat->dev = dentry->d_sb->s_dev;
                stat->ino = dentry->d_inode->i_ino;
-       } else if (lower_layer && lower_layer->fsid) {
+       } else {
                /*
                 * For non-samefs setup, if we cannot map all layers st_ino
                 * to a unified address space, we need to make sure that st_dev
-                * is unique per lower fs. Upper layer uses real st_dev and
-                * lower layers use the unique anonymous bdev assigned to the
-                * lower fs.
+                * is unique per underlying fs, so we use the unique anonymous
+                * bdev assigned to the underlying fs.
                 */
-               stat->dev = lower_layer->fs->pseudo_dev;
+               stat->dev = OVL_FS(dentry->d_sb)->fs[fsid].pseudo_dev;
        }
 
        return 0;
@@ -146,8 +142,7 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
        struct path realpath;
        const struct cred *old_cred;
        bool is_dir = S_ISDIR(dentry->d_inode->i_mode);
-       bool samefs = ovl_same_sb(dentry->d_sb);
-       struct ovl_layer *lower_layer = NULL;
+       int fsid = 0;
        int err;
        bool metacopy_blocks = false;
 
@@ -168,9 +163,9 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
         * If lower filesystem supports NFS file handles, this also guaranties
         * persistent st_ino across mount cycle.
         */
-       if (!is_dir || samefs || ovl_xino_bits(dentry->d_sb)) {
+       if (!is_dir || ovl_same_dev(dentry->d_sb)) {
                if (!OVL_TYPE_UPPER(type)) {
-                       lower_layer = ovl_layer_lower(dentry);
+                       fsid = ovl_layer_lower(dentry)->fsid;
                } else if (OVL_TYPE_ORIGIN(type)) {
                        struct kstat lowerstat;
                        u32 lowermask = STATX_INO | STATX_BLOCKS |
@@ -200,14 +195,8 @@ 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))) {
-                               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;
+                               fsid = ovl_layer_lower(dentry)->fsid;
+                               stat->ino = lowerstat.ino;
                        }
 
                        /*
@@ -241,7 +230,7 @@ int ovl_getattr(const struct path *path, struct kstat *stat,
                }
        }
 
-       err = ovl_map_dev_ino(dentry, stat, lower_layer);
+       err = ovl_map_dev_ino(dentry, stat, fsid);
        if (err)
                goto out;
 
@@ -527,6 +516,27 @@ static const struct address_space_operations ovl_aops = {
  * [...] &ovl_i_mutex_dir_key[depth]   (stack_depth=2)
  * [...] &ovl_i_mutex_dir_key[depth]#2 (stack_depth=1)
  * [...] &type->i_mutex_dir_key        (stack_depth=0)
+ *
+ * Locking order w.r.t ovl_want_write() is important for nested overlayfs.
+ *
+ * This chain is valid:
+ * - inode->i_rwsem                    (inode_lock[2])
+ * - upper_mnt->mnt_sb->s_writers      (ovl_want_write[0])
+ * - OVL_I(inode)->lock                        (ovl_inode_lock[2])
+ * - OVL_I(lowerinode)->lock           (ovl_inode_lock[1])
+ *
+ * And this chain is valid:
+ * - inode->i_rwsem                    (inode_lock[2])
+ * - OVL_I(inode)->lock                        (ovl_inode_lock[2])
+ * - lowerinode->i_rwsem               (inode_lock[1])
+ * - OVL_I(lowerinode)->lock           (ovl_inode_lock[1])
+ *
+ * But lowerinode->i_rwsem SHOULD NOT be acquired while ovl_want_write() is
+ * held, because it is in reverse order of the non-nested case using the same
+ * upper fs:
+ * - inode->i_rwsem                    (inode_lock[1])
+ * - upper_mnt->mnt_sb->s_writers      (ovl_want_write[0])
+ * - OVL_I(inode)->lock                        (ovl_inode_lock[1])
  */
 #define OVL_MAX_NESTING FILESYSTEM_MAX_STACK_DEPTH
 
@@ -565,7 +575,7 @@ static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev,
         * ovl_new_inode(), ino arg is 0, so i_ino will be updated to real
         * upper inode i_ino on ovl_inode_init() or ovl_inode_update().
         */
-       if (ovl_same_sb(inode->i_sb) || xinobits) {
+       if (ovl_same_dev(inode->i_sb)) {
                inode->i_ino = ino;
                if (xinobits && fsid && !(ino >> (64 - xinobits)))
                        inode->i_ino |= (unsigned long)fsid << (64 - xinobits);
@@ -698,7 +708,7 @@ unsigned int ovl_get_nlink(struct dentry *lowerdentry,
        return nlink;
 
 fail:
-       pr_warn_ratelimited("overlayfs: failed to get index nlink (%pd2, err=%i)\n",
+       pr_warn_ratelimited("failed to get index nlink (%pd2, err=%i)\n",
                            upperdentry, err);
        return fallback;
 }
@@ -969,7 +979,7 @@ out:
        return inode;
 
 out_err:
-       pr_warn_ratelimited("overlayfs: failed to get inode (%i)\n", err);
+       pr_warn_ratelimited("failed to get inode (%i)\n", err);
        inode = ERR_PTR(err);
        goto out;
 }
index 76ff663..ed9e129 100644 (file)
@@ -141,10 +141,10 @@ out:
        return NULL;
 
 fail:
-       pr_warn_ratelimited("overlayfs: failed to get origin (%i)\n", res);
+       pr_warn_ratelimited("failed to get origin (%i)\n", res);
        goto out;
 invalid:
-       pr_warn_ratelimited("overlayfs: invalid origin (%*phN)\n", res, fh);
+       pr_warn_ratelimited("invalid origin (%*phN)\n", res, fh);
        goto out;
 }
 
@@ -322,16 +322,16 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
        struct dentry *origin = NULL;
        int i;
 
-       for (i = 0; i < ofs->numlower; i++) {
+       for (i = 1; i < ofs->numlayer; 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)
+               if (ofs->layers[i].fsid &&
+                   ofs->layers[i].fs->bad_uuid)
                        continue;
 
-               origin = ovl_decode_real_fh(fh, ofs->lower_layers[i].mnt,
+               origin = ovl_decode_real_fh(fh, ofs->layers[i].mnt,
                                            connected);
                if (origin)
                        break;
@@ -354,13 +354,13 @@ int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
        }
        **stackp = (struct ovl_path){
                .dentry = origin,
-               .layer = &ofs->lower_layers[i]
+               .layer = &ofs->layers[i]
        };
 
        return 0;
 
 invalid:
-       pr_warn_ratelimited("overlayfs: invalid origin (%pd2, ftype=%x, origin ftype=%x).\n",
+       pr_warn_ratelimited("invalid origin (%pd2, ftype=%x, origin ftype=%x).\n",
                            upperdentry, d_inode(upperdentry)->i_mode & S_IFMT,
                            d_inode(origin)->i_mode & S_IFMT);
        dput(origin);
@@ -449,7 +449,7 @@ out:
 
 fail:
        inode = d_inode(real);
-       pr_warn_ratelimited("overlayfs: failed to verify %s (%pd2, ino=%lu, err=%i)\n",
+       pr_warn_ratelimited("failed to verify %s (%pd2, ino=%lu, err=%i)\n",
                            is_upper ? "upper" : "origin", real,
                            inode ? inode->i_ino : 0, err);
        goto out;
@@ -475,7 +475,7 @@ struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index)
                return upper ?: ERR_PTR(-ESTALE);
 
        if (!d_is_dir(upper)) {
-               pr_warn_ratelimited("overlayfs: invalid index upper (%pd2, upper=%pd2).\n",
+               pr_warn_ratelimited("invalid index upper (%pd2, upper=%pd2).\n",
                                    index, upper);
                dput(upper);
                return ERR_PTR(-EIO);
@@ -589,12 +589,12 @@ out:
        return err;
 
 fail:
-       pr_warn_ratelimited("overlayfs: failed to verify index (%pd2, ftype=%x, err=%i)\n",
+       pr_warn_ratelimited("failed to verify index (%pd2, ftype=%x, err=%i)\n",
                            index, d_inode(index)->i_mode & S_IFMT, err);
        goto out;
 
 orphan:
-       pr_warn_ratelimited("overlayfs: orphan index entry (%pd2, ftype=%x, nlink=%u)\n",
+       pr_warn_ratelimited("orphan index entry (%pd2, ftype=%x, nlink=%u)\n",
                            index, d_inode(index)->i_mode & S_IFMT,
                            d_inode(index)->i_nlink);
        err = -ENOENT;
@@ -696,7 +696,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
                        index = NULL;
                        goto out;
                }
-               pr_warn_ratelimited("overlayfs: failed inode index lookup (ino=%lu, key=%.*s, err=%i);\n"
+               pr_warn_ratelimited("failed inode index lookup (ino=%lu, key=%.*s, err=%i);\n"
                                    "overlayfs: mount with '-o index=off' to disable inodes index.\n",
                                    d_inode(origin)->i_ino, name.len, name.name,
                                    err);
@@ -723,13 +723,13 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
                 * unlinked, which means that finding a lower origin on lookup
                 * whose index is a whiteout should be treated as an error.
                 */
-               pr_warn_ratelimited("overlayfs: bad index found (index=%pd2, ftype=%x, origin ftype=%x).\n",
+               pr_warn_ratelimited("bad index found (index=%pd2, ftype=%x, origin ftype=%x).\n",
                                    index, d_inode(index)->i_mode & S_IFMT,
                                    d_inode(origin)->i_mode & S_IFMT);
                goto fail;
        } else if (is_dir && verify) {
                if (!upper) {
-                       pr_warn_ratelimited("overlayfs: suspected uncovered redirected dir found (origin=%pd2, index=%pd2).\n",
+                       pr_warn_ratelimited("suspected uncovered redirected dir found (origin=%pd2, index=%pd2).\n",
                                            origin, index);
                        goto fail;
                }
@@ -738,7 +738,7 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
                err = ovl_verify_upper(index, upper, false);
                if (err) {
                        if (err == -ESTALE) {
-                               pr_warn_ratelimited("overlayfs: suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n",
+                               pr_warn_ratelimited("suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n",
                                                    upper, origin, index);
                        }
                        goto fail;
@@ -885,7 +885,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
 
        if (!d.stop && poe->numlower) {
                err = -ENOMEM;
-               stack = kcalloc(ofs->numlower, sizeof(struct ovl_path),
+               stack = kcalloc(ofs->numlayer - 1, sizeof(struct ovl_path),
                                GFP_KERNEL);
                if (!stack)
                        goto out_put_upper;
@@ -967,7 +967,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                 */
                err = -EPERM;
                if (d.redirect && !ofs->config.redirect_follow) {
-                       pr_warn_ratelimited("overlayfs: refusing to follow redirect for (%pd2)\n",
+                       pr_warn_ratelimited("refusing to follow redirect for (%pd2)\n",
                                            dentry);
                        goto out_put;
                }
@@ -994,7 +994,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
 
                err = -EPERM;
                if (!ofs->config.metacopy) {
-                       pr_warn_ratelimited("overlay: refusing to follow metacopy origin for (%pd2)\n",
+                       pr_warn_ratelimited("refusing to follow metacopy origin for (%pd2)\n",
                                            dentry);
                        goto out_put;
                }
index f283b1d..3623d28 100644 (file)
@@ -9,6 +9,9 @@
 #include <linux/fs.h>
 #include "ovl_entry.h"
 
+#undef pr_fmt
+#define pr_fmt(fmt) "overlayfs: " fmt
+
 enum ovl_path_type {
        __OVL_PATH_UPPER        = (1 << 0),
        __OVL_PATH_MERGE        = (1 << 1),
@@ -221,7 +224,6 @@ int ovl_want_write(struct dentry *dentry);
 void ovl_drop_write(struct dentry *dentry);
 struct dentry *ovl_workdir(struct dentry *dentry);
 const struct cred *ovl_override_creds(struct super_block *sb);
-struct super_block *ovl_same_sb(struct super_block *sb);
 int ovl_can_decode_fh(struct super_block *sb);
 struct dentry *ovl_indexdir(struct super_block *sb);
 bool ovl_index_all(struct super_block *sb);
@@ -237,7 +239,7 @@ enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path);
 struct dentry *ovl_dentry_upper(struct dentry *dentry);
 struct dentry *ovl_dentry_lower(struct dentry *dentry);
 struct dentry *ovl_dentry_lowerdata(struct dentry *dentry);
-struct ovl_layer *ovl_layer_lower(struct dentry *dentry);
+const struct ovl_layer *ovl_layer_lower(struct dentry *dentry);
 struct dentry *ovl_dentry_real(struct dentry *dentry);
 struct dentry *ovl_i_dentry_upper(struct inode *inode);
 struct inode *ovl_inode_upper(struct inode *inode);
@@ -299,11 +301,21 @@ static inline bool ovl_is_impuredir(struct dentry *dentry)
        return ovl_check_dir_xattr(dentry, OVL_XATTR_IMPURE);
 }
 
-static inline unsigned int ovl_xino_bits(struct super_block *sb)
+/* All layers on same fs? */
+static inline bool ovl_same_fs(struct super_block *sb)
+{
+       return OVL_FS(sb)->xino_mode == 0;
+}
+
+/* All overlay inodes have same st_dev? */
+static inline bool ovl_same_dev(struct super_block *sb)
 {
-       struct ovl_fs *ofs = sb->s_fs_info;
+       return OVL_FS(sb)->xino_mode >= 0;
+}
 
-       return ofs->xino_bits;
+static inline unsigned int ovl_xino_bits(struct super_block *sb)
+{
+       return ovl_same_dev(sb) ? OVL_FS(sb)->xino_mode : 0;
 }
 
 static inline int ovl_inode_lock(struct inode *inode)
@@ -438,6 +450,8 @@ struct dentry *ovl_create_temp(struct dentry *workdir, struct ovl_cattr *attr);
 
 /* file.c */
 extern const struct file_operations ovl_file_operations;
+int __init ovl_aio_request_cache_init(void);
+void ovl_aio_request_cache_destroy(void);
 
 /* copy_up.c */
 int ovl_copy_up(struct dentry *dentry);
index 28348c4..89015ea 100644 (file)
@@ -24,6 +24,8 @@ struct ovl_sb {
        dev_t pseudo_dev;
        /* Unusable (conflicting) uuid */
        bool bad_uuid;
+       /* Used as a lower layer (but maybe also as upper) */
+       bool is_lower;
 };
 
 struct ovl_layer {
@@ -38,18 +40,18 @@ struct ovl_layer {
 };
 
 struct ovl_path {
-       struct ovl_layer *layer;
+       const struct ovl_layer *layer;
        struct dentry *dentry;
 };
 
 /* private information held for overlayfs's superblock */
 struct ovl_fs {
        struct vfsmount *upper_mnt;
-       unsigned int numlower;
-       /* Number of unique lower sb that differ from upper sb */
-       unsigned int numlowerfs;
-       struct ovl_layer *lower_layers;
-       struct ovl_sb *lower_fs;
+       unsigned int numlayer;
+       /* Number of unique fs among layers including upper fs */
+       unsigned int numfs;
+       const struct ovl_layer *layers;
+       struct ovl_sb *fs;
        /* workbasedir is the path at workdir= mount option */
        struct dentry *workbasedir;
        /* workdir is the 'work' directory under workbasedir */
@@ -71,10 +73,15 @@ struct ovl_fs {
        struct inode *workbasedir_trap;
        struct inode *workdir_trap;
        struct inode *indexdir_trap;
-       /* Inode numbers in all layers do not use the high xino_bits */
-       unsigned int xino_bits;
+       /* -1: disabled, 0: same fs, 1..32: number of unused ino bits */
+       int xino_mode;
 };
 
+static inline struct ovl_fs *OVL_FS(struct super_block *sb)
+{
+       return (struct ovl_fs *)sb->s_fs_info;
+}
+
 /* private information held for every overlayfs dentry */
 struct ovl_entry {
        union {
index 47a91c9..40ac9ce 100644 (file)
@@ -441,7 +441,7 @@ static u64 ovl_remap_lower_ino(u64 ino, int xinobits, int fsid,
                               const char *name, int namelen)
 {
        if (ino >> (64 - xinobits)) {
-               pr_warn_ratelimited("overlayfs: d_ino too big (%.*s, ino=%llu, xinobits=%d)\n",
+               pr_warn_ratelimited("d_ino too big (%.*s, ino=%llu, xinobits=%d)\n",
                                    namelen, name, ino, xinobits);
                return ino;
        }
@@ -469,7 +469,7 @@ static int ovl_cache_update_ino(struct path *path, struct ovl_cache_entry *p)
        int xinobits = ovl_xino_bits(dir->d_sb);
        int err = 0;
 
-       if (!ovl_same_sb(dir->d_sb) && !xinobits)
+       if (!ovl_same_dev(dir->d_sb))
                goto out;
 
        if (p->name[0] == '.') {
@@ -504,7 +504,13 @@ get:
                if (err)
                        goto fail;
 
-               WARN_ON_ONCE(dir->d_sb->s_dev != stat.dev);
+               /*
+                * Directory inode is always on overlay st_dev.
+                * Non-dir with ovl_same_dev() could be on pseudo st_dev in case
+                * of xino bits overflow.
+                */
+               WARN_ON_ONCE(S_ISDIR(stat.mode) &&
+                            dir->d_sb->s_dev != stat.dev);
                ino = stat.ino;
        } else if (xinobits && !OVL_TYPE_UPPER(type)) {
                ino = ovl_remap_lower_ino(ino, xinobits,
@@ -518,7 +524,7 @@ out:
        return err;
 
 fail:
-       pr_warn_ratelimited("overlayfs: failed to look up (%s) for ino (%i)\n",
+       pr_warn_ratelimited("failed to look up (%s) for ino (%i)\n",
                            p->name, err);
        goto out;
 }
@@ -685,7 +691,7 @@ static int ovl_iterate_real(struct file *file, struct dir_context *ctx)
        int err;
        struct ovl_dir_file *od = file->private_data;
        struct dentry *dir = file->f_path.dentry;
-       struct ovl_layer *lower_layer = ovl_layer_lower(dir);
+       const struct ovl_layer *lower_layer = ovl_layer_lower(dir);
        struct ovl_readdir_translate rdt = {
                .ctx.actor = ovl_fill_real,
                .orig_ctx = ctx,
@@ -738,7 +744,7 @@ static int ovl_iterate(struct file *file, struct dir_context *ctx)
                 * entries.
                 */
                if (ovl_xino_bits(dentry->d_sb) ||
-                   (ovl_same_sb(dentry->d_sb) &&
+                   (ovl_same_fs(dentry->d_sb) &&
                     (ovl_is_impure_dir(file) ||
                      OVL_TYPE_MERGE(ovl_path_type(dentry->d_parent))))) {
                        return ovl_iterate_real(file, ctx);
@@ -965,7 +971,7 @@ void ovl_cleanup_whiteouts(struct dentry *upper, struct list_head *list)
 
                dentry = lookup_one_len(p->name, upper, p->len);
                if (IS_ERR(dentry)) {
-                       pr_err("overlayfs: lookup '%s/%.*s' failed (%i)\n",
+                       pr_err("lookup '%s/%.*s' failed (%i)\n",
                               upper->d_name.name, p->len, p->name,
                               (int) PTR_ERR(dentry));
                        continue;
@@ -1147,6 +1153,6 @@ next:
 out:
        ovl_cache_free(&list);
        if (err)
-               pr_err("overlayfs: failed index dir cleanup (%i)\n", err);
+               pr_err("failed index dir cleanup (%i)\n", err);
        return err;
 }
index 7621ff1..319fe0d 100644 (file)
@@ -224,14 +224,14 @@ static void ovl_free_fs(struct ovl_fs *ofs)
        if (ofs->upperdir_locked)
                ovl_inuse_unlock(ofs->upper_mnt->mnt_root);
        mntput(ofs->upper_mnt);
-       for (i = 0; i < ofs->numlower; i++) {
-               iput(ofs->lower_layers[i].trap);
-               mntput(ofs->lower_layers[i].mnt);
+       for (i = 1; i < ofs->numlayer; i++) {
+               iput(ofs->layers[i].trap);
+               mntput(ofs->layers[i].mnt);
        }
-       for (i = 0; i < ofs->numlowerfs; i++)
-               free_anon_bdev(ofs->lower_fs[i].pseudo_dev);
-       kfree(ofs->lower_layers);
-       kfree(ofs->lower_fs);
+       kfree(ofs->layers);
+       for (i = 0; i < ofs->numfs; i++)
+               free_anon_bdev(ofs->fs[i].pseudo_dev);
+       kfree(ofs->fs);
 
        kfree(ofs->config.lowerdir);
        kfree(ofs->config.upperdir);
@@ -358,7 +358,7 @@ static int ovl_show_options(struct seq_file *m, struct dentry *dentry)
        if (ofs->config.nfs_export != ovl_nfs_export_def)
                seq_printf(m, ",nfs_export=%s", ofs->config.nfs_export ?
                                                "on" : "off");
-       if (ofs->config.xino != ovl_xino_def())
+       if (ofs->config.xino != ovl_xino_def() && !ovl_same_fs(sb))
                seq_printf(m, ",xino=%s", ovl_xino_str[ofs->config.xino]);
        if (ofs->config.metacopy != ovl_metacopy_def)
                seq_printf(m, ",metacopy=%s",
@@ -462,7 +462,7 @@ static int ovl_parse_redirect_mode(struct ovl_config *config, const char *mode)
                if (ovl_redirect_always_follow)
                        config->redirect_follow = true;
        } else if (strcmp(mode, "nofollow") != 0) {
-               pr_err("overlayfs: bad mount option \"redirect_dir=%s\"\n",
+               pr_err("bad mount option \"redirect_dir=%s\"\n",
                       mode);
                return -EINVAL;
        }
@@ -560,14 +560,15 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
                        break;
 
                default:
-                       pr_err("overlayfs: unrecognized mount option \"%s\" or missing value\n", p);
+                       pr_err("unrecognized mount option \"%s\" or missing value\n",
+                                       p);
                        return -EINVAL;
                }
        }
 
        /* Workdir is useless in non-upper mount */
        if (!config->upperdir && config->workdir) {
-               pr_info("overlayfs: option \"workdir=%s\" is useless in a non-upper mount, ignore\n",
+               pr_info("option \"workdir=%s\" is useless in a non-upper mount, ignore\n",
                        config->workdir);
                kfree(config->workdir);
                config->workdir = NULL;
@@ -587,7 +588,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
        /* Resolve metacopy -> redirect_dir dependency */
        if (config->metacopy && !config->redirect_dir) {
                if (metacopy_opt && redirect_opt) {
-                       pr_err("overlayfs: conflicting options: metacopy=on,redirect_dir=%s\n",
+                       pr_err("conflicting options: metacopy=on,redirect_dir=%s\n",
                               config->redirect_mode);
                        return -EINVAL;
                }
@@ -596,7 +597,7 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
                         * There was an explicit redirect_dir=... that resulted
                         * in this conflict.
                         */
-                       pr_info("overlayfs: disabling metacopy due to redirect_dir=%s\n",
+                       pr_info("disabling metacopy due to redirect_dir=%s\n",
                                config->redirect_mode);
                        config->metacopy = false;
                } else {
@@ -692,7 +693,7 @@ out_unlock:
 out_dput:
        dput(work);
 out_err:
-       pr_warn("overlayfs: failed to create directory %s/%s (errno: %i); mounting read-only\n",
+       pr_warn("failed to create directory %s/%s (errno: %i); mounting read-only\n",
                ofs->config.workdir, name, -err);
        work = NULL;
        goto out_unlock;
@@ -716,21 +717,21 @@ static int ovl_mount_dir_noesc(const char *name, struct path *path)
        int err = -EINVAL;
 
        if (!*name) {
-               pr_err("overlayfs: empty lowerdir\n");
+               pr_err("empty lowerdir\n");
                goto out;
        }
        err = kern_path(name, LOOKUP_FOLLOW, path);
        if (err) {
-               pr_err("overlayfs: failed to resolve '%s': %i\n", name, err);
+               pr_err("failed to resolve '%s': %i\n", name, err);
                goto out;
        }
        err = -EINVAL;
        if (ovl_dentry_weird(path->dentry)) {
-               pr_err("overlayfs: filesystem on '%s' not supported\n", name);
+               pr_err("filesystem on '%s' not supported\n", name);
                goto out_put;
        }
        if (!d_is_dir(path->dentry)) {
-               pr_err("overlayfs: '%s' not a directory\n", name);
+               pr_err("'%s' not a directory\n", name);
                goto out_put;
        }
        return 0;
@@ -752,7 +753,7 @@ static int ovl_mount_dir(const char *name, struct path *path)
 
                if (!err)
                        if (ovl_dentry_remote(path->dentry)) {
-                               pr_err("overlayfs: filesystem on '%s' not supported as upperdir\n",
+                               pr_err("filesystem on '%s' not supported as upperdir\n",
                                       tmp);
                                path_put_init(path);
                                err = -EINVAL;
@@ -769,7 +770,7 @@ static int ovl_check_namelen(struct path *path, struct ovl_fs *ofs,
        int err = vfs_statfs(path, &statfs);
 
        if (err)
-               pr_err("overlayfs: statfs failed on '%s'\n", name);
+               pr_err("statfs failed on '%s'\n", name);
        else
                ofs->namelen = max(ofs->namelen, statfs.f_namelen);
 
@@ -804,13 +805,13 @@ static int ovl_lower_dir(const char *name, struct path *path,
             (ofs->config.index && ofs->config.upperdir)) && !fh_type) {
                ofs->config.index = false;
                ofs->config.nfs_export = false;
-               pr_warn("overlayfs: fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n",
+               pr_warn("fs on '%s' does not support file handles, falling back to index=off,nfs_export=off.\n",
                        name);
        }
 
        /* Check if lower fs has 32bit inode numbers */
        if (fh_type != FILEID_INO32_GEN)
-               ofs->xino_bits = 0;
+               ofs->xino_mode = -1;
 
        return 0;
 
@@ -996,7 +997,7 @@ static int ovl_setup_trap(struct super_block *sb, struct dentry *dir,
        err = PTR_ERR_OR_ZERO(trap);
        if (err) {
                if (err == -ELOOP)
-                       pr_err("overlayfs: conflicting %s path\n", name);
+                       pr_err("conflicting %s path\n", name);
                return err;
        }
 
@@ -1013,11 +1014,11 @@ static int ovl_setup_trap(struct super_block *sb, struct dentry *dir,
 static int ovl_report_in_use(struct ovl_fs *ofs, const char *name)
 {
        if (ofs->config.index) {
-               pr_err("overlayfs: %s is in-use as upperdir/workdir of another mount, mount with '-o index=off' to override exclusive upperdir protection.\n",
+               pr_err("%s is in-use as upperdir/workdir of another mount, mount with '-o index=off' to override exclusive upperdir protection.\n",
                       name);
                return -EBUSY;
        } else {
-               pr_warn("overlayfs: %s is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.\n",
+               pr_warn("%s is in-use as upperdir/workdir of another mount, accessing files from both mounts will result in undefined behavior.\n",
                        name);
                return 0;
        }
@@ -1035,7 +1036,7 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
 
        /* Upper fs should not be r/o */
        if (sb_rdonly(upperpath->mnt->mnt_sb)) {
-               pr_err("overlayfs: upper fs is r/o, try multi-lower layers mount\n");
+               pr_err("upper fs is r/o, try multi-lower layers mount\n");
                err = -EINVAL;
                goto out;
        }
@@ -1052,7 +1053,7 @@ static int ovl_get_upper(struct super_block *sb, struct ovl_fs *ofs,
        upper_mnt = clone_private_mount(upperpath);
        err = PTR_ERR(upper_mnt);
        if (IS_ERR(upper_mnt)) {
-               pr_err("overlayfs: failed to clone upperpath\n");
+               pr_err("failed to clone upperpath\n");
                goto out;
        }
 
@@ -1108,7 +1109,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
         * kernel upgrade. So warn instead of erroring out.
         */
        if (!err)
-               pr_warn("overlayfs: upper fs needs to support d_type.\n");
+               pr_warn("upper fs needs to support d_type.\n");
 
        /* Check if upper/work fs supports O_TMPFILE */
        temp = ovl_do_tmpfile(ofs->workdir, S_IFREG | 0);
@@ -1116,7 +1117,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
        if (ofs->tmpfile)
                dput(temp);
        else
-               pr_warn("overlayfs: upper fs does not support tmpfile.\n");
+               pr_warn("upper fs does not support tmpfile.\n");
 
        /*
         * Check if upper/work fs supports trusted.overlay.* xattr
@@ -1126,7 +1127,7 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
                ofs->noxattr = true;
                ofs->config.index = false;
                ofs->config.metacopy = false;
-               pr_warn("overlayfs: upper fs does not support xattr, falling back to index=off and metacopy=off.\n");
+               pr_warn("upper fs does not support xattr, falling back to index=off and metacopy=off.\n");
                err = 0;
        } else {
                vfs_removexattr(ofs->workdir, OVL_XATTR_OPAQUE);
@@ -1136,16 +1137,16 @@ static int ovl_make_workdir(struct super_block *sb, struct ovl_fs *ofs,
        fh_type = ovl_can_decode_fh(ofs->workdir->d_sb);
        if (ofs->config.index && !fh_type) {
                ofs->config.index = false;
-               pr_warn("overlayfs: upper fs does not support file handles, falling back to index=off.\n");
+               pr_warn("upper fs does not support file handles, falling back to index=off.\n");
        }
 
        /* Check if upper fs has 32bit inode numbers */
        if (fh_type != FILEID_INO32_GEN)
-               ofs->xino_bits = 0;
+               ofs->xino_mode = -1;
 
        /* NFS export of r/w mount depends on index */
        if (ofs->config.nfs_export && !ofs->config.index) {
-               pr_warn("overlayfs: NFS export requires \"index=on\", falling back to nfs_export=off.\n");
+               pr_warn("NFS export requires \"index=on\", falling back to nfs_export=off.\n");
                ofs->config.nfs_export = false;
        }
 out:
@@ -1165,11 +1166,11 @@ static int ovl_get_workdir(struct super_block *sb, struct ovl_fs *ofs,
 
        err = -EINVAL;
        if (upperpath->mnt != workpath.mnt) {
-               pr_err("overlayfs: workdir and upperdir must reside under the same mount\n");
+               pr_err("workdir and upperdir must reside under the same mount\n");
                goto out;
        }
        if (!ovl_workdir_ok(workpath.dentry, upperpath->dentry)) {
-               pr_err("overlayfs: workdir and upperdir must be separate subtrees\n");
+               pr_err("workdir and upperdir must be separate subtrees\n");
                goto out;
        }
 
@@ -1210,7 +1211,7 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
        err = ovl_verify_origin(upperpath->dentry, oe->lowerstack[0].dentry,
                                true);
        if (err) {
-               pr_err("overlayfs: failed to verify upper root origin\n");
+               pr_err("failed to verify upper root origin\n");
                goto out;
        }
 
@@ -1233,18 +1234,18 @@ static int ovl_get_indexdir(struct super_block *sb, struct ovl_fs *ofs,
                        err = ovl_verify_set_fh(ofs->indexdir, OVL_XATTR_ORIGIN,
                                                upperpath->dentry, true, false);
                        if (err)
-                               pr_err("overlayfs: failed to verify index dir 'origin' xattr\n");
+                               pr_err("failed to verify index dir 'origin' xattr\n");
                }
                err = ovl_verify_upper(ofs->indexdir, upperpath->dentry, true);
                if (err)
-                       pr_err("overlayfs: failed to verify index dir 'upper' xattr\n");
+                       pr_err("failed to verify index dir 'upper' xattr\n");
 
                /* Cleanup bad/stale/orphan index entries */
                if (!err)
                        err = ovl_indexdir_cleanup(ofs);
        }
        if (err || !ofs->indexdir)
-               pr_warn("overlayfs: try deleting index dir or mounting with '-o index=off' to disable inodes index.\n");
+               pr_warn("try deleting index dir or mounting with '-o index=off' to disable inodes index.\n");
 
 out:
        mnt_drop_write(mnt);
@@ -1258,7 +1259,7 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid)
        if (!ofs->config.nfs_export && !ofs->upper_mnt)
                return true;
 
-       for (i = 0; i < ofs->numlowerfs; i++) {
+       for (i = 0; i < ofs->numfs; i++) {
                /*
                 * 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
@@ -1266,8 +1267,9 @@ static bool ovl_lower_uuid_ok(struct ovl_fs *ofs, const uuid_t *uuid)
                 * 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)) {
-                       ofs->lower_fs[i].bad_uuid = true;
+               if (ofs->fs[i].is_lower &&
+                   uuid_equal(&ofs->fs[i].sb->s_uuid, uuid)) {
+                       ofs->fs[i].bad_uuid = true;
                        return false;
                }
        }
@@ -1283,13 +1285,9 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
        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)
-               return 0;
-
-       for (i = 0; i < ofs->numlowerfs; i++) {
-               if (ofs->lower_fs[i].sb == sb)
-                       return i + 1;
+       for (i = 0; i < ofs->numfs; i++) {
+               if (ofs->fs[i].sb == sb)
+                       return i;
        }
 
        if (!ovl_lower_uuid_ok(ofs, &sb->s_uuid)) {
@@ -1297,7 +1295,7 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
                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",
+                       pr_warn("%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);
@@ -1306,35 +1304,59 @@ static int ovl_get_fsid(struct ovl_fs *ofs, const struct path *path)
 
        err = get_anon_bdev(&dev);
        if (err) {
-               pr_err("overlayfs: failed to get anonymous bdev for lowerpath\n");
+               pr_err("failed to get anonymous bdev for lowerpath\n");
                return err;
        }
 
-       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++;
+       ofs->fs[ofs->numfs].sb = sb;
+       ofs->fs[ofs->numfs].pseudo_dev = dev;
+       ofs->fs[ofs->numfs].bad_uuid = bad_uuid;
 
-       return ofs->numlowerfs;
+       return ofs->numfs++;
 }
 
-static int ovl_get_lower_layers(struct super_block *sb, struct ovl_fs *ofs,
-                               struct path *stack, unsigned int numlower)
+static int ovl_get_layers(struct super_block *sb, struct ovl_fs *ofs,
+                         struct path *stack, unsigned int numlower)
 {
        int err;
        unsigned int i;
+       struct ovl_layer *layers;
 
        err = -ENOMEM;
-       ofs->lower_layers = kcalloc(numlower, sizeof(struct ovl_layer),
-                                   GFP_KERNEL);
-       if (ofs->lower_layers == NULL)
+       layers = kcalloc(numlower + 1, sizeof(struct ovl_layer), GFP_KERNEL);
+       if (!layers)
                goto out;
+       ofs->layers = layers;
 
-       ofs->lower_fs = kcalloc(numlower, sizeof(struct ovl_sb),
-                               GFP_KERNEL);
-       if (ofs->lower_fs == NULL)
+       ofs->fs = kcalloc(numlower + 1, sizeof(struct ovl_sb), GFP_KERNEL);
+       if (ofs->fs == NULL)
                goto out;
 
+       /* idx/fsid 0 are reserved for upper fs even with lower only overlay */
+       ofs->numfs++;
+
+       layers[0].mnt = ofs->upper_mnt;
+       layers[0].idx = 0;
+       layers[0].fsid = 0;
+       ofs->numlayer = 1;
+
+       /*
+        * All lower layers that share the same fs as upper layer, use the same
+        * pseudo_dev as upper layer.  Allocate fs[0].pseudo_dev even for lower
+        * only overlay to simplify ovl_fs_free().
+        * is_lower will be set if upper fs is shared with a lower layer.
+        */
+       err = get_anon_bdev(&ofs->fs[0].pseudo_dev);
+       if (err) {
+               pr_err("failed to get anonymous bdev for upper fs\n");
+               goto out;
+       }
+
+       if (ofs->upper_mnt) {
+               ofs->fs[0].sb = ofs->upper_mnt->mnt_sb;
+               ofs->fs[0].is_lower = false;
+       }
+
        for (i = 0; i < numlower; i++) {
                struct vfsmount *mnt;
                struct inode *trap;
@@ -1357,7 +1379,7 @@ static int ovl_get_lower_layers(struct super_block *sb, struct ovl_fs *ofs,
                mnt = clone_private_mount(&stack[i]);
                err = PTR_ERR(mnt);
                if (IS_ERR(mnt)) {
-                       pr_err("overlayfs: failed to clone lowerpath\n");
+                       pr_err("failed to clone lowerpath\n");
                        iput(trap);
                        goto out;
                }
@@ -1368,15 +1390,13 @@ static int ovl_get_lower_layers(struct super_block *sb, struct ovl_fs *ofs,
                 */
                mnt->mnt_flags |= MNT_READONLY | MNT_NOATIME;
 
-               ofs->lower_layers[ofs->numlower].trap = trap;
-               ofs->lower_layers[ofs->numlower].mnt = mnt;
-               ofs->lower_layers[ofs->numlower].idx = i + 1;
-               ofs->lower_layers[ofs->numlower].fsid = fsid;
-               if (fsid) {
-                       ofs->lower_layers[ofs->numlower].fs =
-                               &ofs->lower_fs[fsid - 1];
-               }
-               ofs->numlower++;
+               layers[ofs->numlayer].trap = trap;
+               layers[ofs->numlayer].mnt = mnt;
+               layers[ofs->numlayer].idx = ofs->numlayer;
+               layers[ofs->numlayer].fsid = fsid;
+               layers[ofs->numlayer].fs = &ofs->fs[fsid];
+               ofs->numlayer++;
+               ofs->fs[fsid].is_lower = true;
        }
 
        /*
@@ -1387,22 +1407,23 @@ static int ovl_get_lower_layers(struct super_block *sb, struct ovl_fs *ofs,
         * bits reserved for fsid, it emits a warning and uses the original
         * inode number.
         */
-       if (!ofs->numlowerfs || (ofs->numlowerfs == 1 && !ofs->upper_mnt)) {
-               ofs->xino_bits = 0;
-               ofs->config.xino = OVL_XINO_OFF;
-       } else if (ofs->config.xino == OVL_XINO_ON && !ofs->xino_bits) {
+       if (ofs->numfs - !ofs->upper_mnt == 1) {
+               if (ofs->config.xino == OVL_XINO_ON)
+                       pr_info("\"xino=on\" is useless with all layers on same fs, ignore.\n");
+               ofs->xino_mode = 0;
+       } else if (ofs->config.xino == OVL_XINO_ON && ofs->xino_mode < 0) {
                /*
-                * This is a roundup of number of bits needed for numlowerfs+1
-                * (i.e. ilog2(numlowerfs+1 - 1) + 1). fsid 0 is reserved for
-                * upper fs even with non upper overlay.
+                * This is a roundup of number of bits needed for encoding
+                * fsid, where fsid 0 is reserved for upper fs even with
+                * lower only overlay.
                 */
                BUILD_BUG_ON(ilog2(OVL_MAX_STACK) > 31);
-               ofs->xino_bits = ilog2(ofs->numlowerfs) + 1;
+               ofs->xino_mode = ilog2(ofs->numfs - 1) + 1;
        }
 
-       if (ofs->xino_bits) {
-               pr_info("overlayfs: \"xino\" feature enabled using %d upper inode bits.\n",
-                       ofs->xino_bits);
+       if (ofs->xino_mode > 0) {
+               pr_info("\"xino\" feature enabled using %d upper inode bits.\n",
+                       ofs->xino_mode);
        }
 
        err = 0;
@@ -1428,15 +1449,15 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
        err = -EINVAL;
        stacklen = ovl_split_lowerdirs(lowertmp);
        if (stacklen > OVL_MAX_STACK) {
-               pr_err("overlayfs: too many lower directories, limit is %d\n",
+               pr_err("too many lower directories, limit is %d\n",
                       OVL_MAX_STACK);
                goto out_err;
        } else if (!ofs->config.upperdir && stacklen == 1) {
-               pr_err("overlayfs: at least 2 lowerdir are needed while upperdir nonexistent\n");
+               pr_err("at least 2 lowerdir are needed while upperdir nonexistent\n");
                goto out_err;
        } else if (!ofs->config.upperdir && ofs->config.nfs_export &&
                   ofs->config.redirect_follow) {
-               pr_warn("overlayfs: NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
+               pr_warn("NFS export requires \"redirect_dir=nofollow\" on non-upper mount, falling back to nfs_export=off.\n");
                ofs->config.nfs_export = false;
        }
 
@@ -1459,11 +1480,11 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
        err = -EINVAL;
        sb->s_stack_depth++;
        if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
-               pr_err("overlayfs: maximum fs stacking depth exceeded\n");
+               pr_err("maximum fs stacking depth exceeded\n");
                goto out_err;
        }
 
-       err = ovl_get_lower_layers(sb, ofs, stack, numlower);
+       err = ovl_get_layers(sb, ofs, stack, numlower);
        if (err)
                goto out_err;
 
@@ -1474,7 +1495,7 @@ static struct ovl_entry *ovl_get_lowerstack(struct super_block *sb,
 
        for (i = 0; i < numlower; i++) {
                oe->lowerstack[i].dentry = dget(stack[i].dentry);
-               oe->lowerstack[i].layer = &ofs->lower_layers[i];
+               oe->lowerstack[i].layer = &ofs->layers[i+1];
        }
 
        if (remote)
@@ -1515,7 +1536,7 @@ static int ovl_check_layer(struct super_block *sb, struct ovl_fs *ofs,
        while (!err && parent != next) {
                if (ovl_lookup_trap_inode(sb, parent)) {
                        err = -ELOOP;
-                       pr_err("overlayfs: overlapping %s path\n", name);
+                       pr_err("overlapping %s path\n", name);
                } else if (ovl_is_inuse(parent)) {
                        err = ovl_report_in_use(ofs, name);
                }
@@ -1555,9 +1576,9 @@ static int ovl_check_overlapping_layers(struct super_block *sb,
                        return err;
        }
 
-       for (i = 0; i < ofs->numlower; i++) {
+       for (i = 1; i < ofs->numlayer; i++) {
                err = ovl_check_layer(sb, ofs,
-                                     ofs->lower_layers[i].mnt->mnt_root,
+                                     ofs->layers[i].mnt->mnt_root,
                                      "lowerdir");
                if (err)
                        return err;
@@ -1595,7 +1616,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        err = -EINVAL;
        if (!ofs->config.lowerdir) {
                if (!silent)
-                       pr_err("overlayfs: missing 'lowerdir'\n");
+                       pr_err("missing 'lowerdir'\n");
                goto out_err;
        }
 
@@ -1603,14 +1624,14 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        sb->s_maxbytes = MAX_LFS_FILESIZE;
        /* Assume underlaying fs uses 32bit inodes unless proven otherwise */
        if (ofs->config.xino != OVL_XINO_OFF)
-               ofs->xino_bits = BITS_PER_LONG - 32;
+               ofs->xino_mode = BITS_PER_LONG - 32;
 
        /* alloc/destroy_inode needed for setting up traps in inode cache */
        sb->s_op = &ovl_super_operations;
 
        if (ofs->config.upperdir) {
                if (!ofs->config.workdir) {
-                       pr_err("overlayfs: missing 'workdir'\n");
+                       pr_err("missing 'workdir'\n");
                        goto out_err;
                }
 
@@ -1660,13 +1681,13 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
        if (!ofs->indexdir) {
                ofs->config.index = false;
                if (ofs->upper_mnt && ofs->config.nfs_export) {
-                       pr_warn("overlayfs: NFS export requires an index dir, falling back to nfs_export=off.\n");
+                       pr_warn("NFS export requires an index dir, falling back to nfs_export=off.\n");
                        ofs->config.nfs_export = false;
                }
        }
 
        if (ofs->config.metacopy && ofs->config.nfs_export) {
-               pr_warn("overlayfs: NFS export is not supported with metadata only copy up, falling back to nfs_export=off.\n");
+               pr_warn("NFS export is not supported with metadata only copy up, falling back to nfs_export=off.\n");
                ofs->config.nfs_export = false;
        }
 
@@ -1749,9 +1770,15 @@ static int __init ovl_init(void)
        if (ovl_inode_cachep == NULL)
                return -ENOMEM;
 
-       err = register_filesystem(&ovl_fs_type);
-       if (err)
-               kmem_cache_destroy(ovl_inode_cachep);
+       err = ovl_aio_request_cache_init();
+       if (!err) {
+               err = register_filesystem(&ovl_fs_type);
+               if (!err)
+                       return 0;
+
+               ovl_aio_request_cache_destroy();
+       }
+       kmem_cache_destroy(ovl_inode_cachep);
 
        return err;
 }
@@ -1766,7 +1793,7 @@ static void __exit ovl_exit(void)
         */
        rcu_barrier();
        kmem_cache_destroy(ovl_inode_cachep);
-
+       ovl_aio_request_cache_destroy();
 }
 
 module_init(ovl_init);
index f5678a3..ea00508 100644 (file)
@@ -40,18 +40,6 @@ const struct cred *ovl_override_creds(struct super_block *sb)
        return override_creds(ofs->creator_cred);
 }
 
-struct super_block *ovl_same_sb(struct super_block *sb)
-{
-       struct ovl_fs *ofs = sb->s_fs_info;
-
-       if (!ofs->numlowerfs)
-               return ofs->upper_mnt->mnt_sb;
-       else if (ofs->numlowerfs == 1 && !ofs->upper_mnt)
-               return ofs->lower_fs[0].sb;
-       else
-               return NULL;
-}
-
 /*
  * Check if underlying fs supports file handles and try to determine encoding
  * type, in order to deduce maximum inode number used by fs.
@@ -198,7 +186,7 @@ struct dentry *ovl_dentry_lower(struct dentry *dentry)
        return oe->numlower ? oe->lowerstack[0].dentry : NULL;
 }
 
-struct ovl_layer *ovl_layer_lower(struct dentry *dentry)
+const struct ovl_layer *ovl_layer_lower(struct dentry *dentry)
 {
        struct ovl_entry *oe = dentry->d_fsdata;
 
@@ -576,7 +564,7 @@ int ovl_check_setxattr(struct dentry *dentry, struct dentry *upperdentry,
        err = ovl_do_setxattr(upperdentry, name, value, size, 0);
 
        if (err == -EOPNOTSUPP) {
-               pr_warn("overlayfs: cannot set %s xattr on upper\n", name);
+               pr_warn("cannot set %s xattr on upper\n", name);
                ofs->noxattr = true;
                return xerr;
        }
@@ -700,7 +688,7 @@ static void ovl_cleanup_index(struct dentry *dentry)
 
        inode = d_inode(upperdentry);
        if (!S_ISDIR(inode->i_mode) && inode->i_nlink != 1) {
-               pr_warn_ratelimited("overlayfs: cleanup linked index (%pd2, ino=%lu, nlink=%u)\n",
+               pr_warn_ratelimited("cleanup linked index (%pd2, ino=%lu, nlink=%u)\n",
                                    upperdentry, inode->i_ino, inode->i_nlink);
                /*
                 * We either have a bug with persistent union nlink or a lower
@@ -739,7 +727,7 @@ out:
        return;
 
 fail:
-       pr_err("overlayfs: cleanup index of '%pd2' failed (%i)\n", dentry, err);
+       pr_err("cleanup index of '%pd2' failed (%i)\n", dentry, err);
        goto out;
 }
 
@@ -830,7 +818,7 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir)
 err_unlock:
        unlock_rename(workdir, upperdir);
 err:
-       pr_err("overlayfs: failed to lock workdir+upperdir\n");
+       pr_err("failed to lock workdir+upperdir\n");
        return -EIO;
 }
 
@@ -852,7 +840,7 @@ int ovl_check_metacopy_xattr(struct dentry *dentry)
 
        return 1;
 out:
-       pr_warn_ratelimited("overlayfs: failed to get metacopy (%i)\n", res);
+       pr_warn_ratelimited("failed to get metacopy (%i)\n", res);
        return res;
 }
 
@@ -899,7 +887,7 @@ ssize_t ovl_getxattr(struct dentry *dentry, char *name, char **value,
        return res;
 
 fail:
-       pr_warn_ratelimited("overlayfs: failed to get xattr %s: err=%zi)\n",
+       pr_warn_ratelimited("failed to get xattr %s: err=%zi)\n",
                            name, res);
        kfree(buf);
        return res;
@@ -931,7 +919,7 @@ char *ovl_get_redirect_xattr(struct dentry *dentry, int padding)
 
        return buf;
 invalid:
-       pr_warn_ratelimited("overlayfs: invalid redirect (%s)\n", buf);
+       pr_warn_ratelimited("invalid redirect (%s)\n", buf);
        res = -EINVAL;
        kfree(buf);
        return ERR_PTR(res);
index 57502c3..5a34d6c 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -108,16 +108,19 @@ void pipe_double_lock(struct pipe_inode_info *pipe1,
 /* Drop the inode semaphore and wait for a pipe event, atomically */
 void pipe_wait(struct pipe_inode_info *pipe)
 {
-       DEFINE_WAIT(wait);
+       DEFINE_WAIT(rdwait);
+       DEFINE_WAIT(wrwait);
 
        /*
         * Pipes are system-local resources, so sleeping on them
         * is considered a noninteractive wait:
         */
-       prepare_to_wait(&pipe->wait, &wait, TASK_INTERRUPTIBLE);
+       prepare_to_wait(&pipe->rd_wait, &rdwait, TASK_INTERRUPTIBLE);
+       prepare_to_wait(&pipe->wr_wait, &wrwait, TASK_INTERRUPTIBLE);
        pipe_unlock(pipe);
        schedule();
-       finish_wait(&pipe->wait, &wait);
+       finish_wait(&pipe->rd_wait, &rdwait);
+       finish_wait(&pipe->wr_wait, &wrwait);
        pipe_lock(pipe);
 }
 
@@ -286,7 +289,7 @@ 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;
-       bool was_full;
+       bool was_full, wake_next_reader = false;
        ssize_t ret;
 
        /* Null read succeeds. */
@@ -344,10 +347,10 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
 
                        if (!buf->len) {
                                pipe_buf_release(pipe, buf);
-                               spin_lock_irq(&pipe->wait.lock);
+                               spin_lock_irq(&pipe->rd_wait.lock);
                                tail++;
                                pipe->tail = tail;
-                               spin_unlock_irq(&pipe->wait.lock);
+                               spin_unlock_irq(&pipe->rd_wait.lock);
                        }
                        total_len -= chars;
                        if (!total_len)
@@ -384,7 +387,7 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
                 * no data.
                 */
                if (unlikely(was_full)) {
-                       wake_up_interruptible_sync_poll(&pipe->wait, EPOLLOUT | EPOLLWRNORM);
+                       wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
                        kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
                }
 
@@ -394,18 +397,23 @@ pipe_read(struct kiocb *iocb, struct iov_iter *to)
                 * 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)
+               if (wait_event_interruptible_exclusive(pipe->rd_wait, pipe_readable(pipe)) < 0)
                        return -ERESTARTSYS;
 
                __pipe_lock(pipe);
                was_full = pipe_full(pipe->head, pipe->tail, pipe->max_usage);
+               wake_next_reader = true;
        }
+       if (pipe_empty(pipe->head, pipe->tail))
+               wake_next_reader = false;
        __pipe_unlock(pipe);
 
        if (was_full) {
-               wake_up_interruptible_sync_poll(&pipe->wait, EPOLLOUT | EPOLLWRNORM);
+               wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
                kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
        }
+       if (wake_next_reader)
+               wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
        if (ret > 0)
                file_accessed(filp);
        return ret;
@@ -437,6 +445,7 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
        size_t total_len = iov_iter_count(from);
        ssize_t chars;
        bool was_empty = false;
+       bool wake_next_writer = false;
 
        /* Null write succeeds. */
        if (unlikely(total_len == 0))
@@ -515,16 +524,16 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                         * it, either the reader will consume it or it'll still
                         * be there for the next write.
                         */
-                       spin_lock_irq(&pipe->wait.lock);
+                       spin_lock_irq(&pipe->rd_wait.lock);
 
                        head = pipe->head;
                        if (pipe_full(head, pipe->tail, pipe->max_usage)) {
-                               spin_unlock_irq(&pipe->wait.lock);
+                               spin_unlock_irq(&pipe->rd_wait.lock);
                                continue;
                        }
 
                        pipe->head = head + 1;
-                       spin_unlock_irq(&pipe->wait.lock);
+                       spin_unlock_irq(&pipe->rd_wait.lock);
 
                        /* Insert it into the buffer array */
                        buf = &pipe->bufs[head & mask];
@@ -576,14 +585,17 @@ pipe_write(struct kiocb *iocb, struct iov_iter *from)
                 */
                __pipe_unlock(pipe);
                if (was_empty) {
-                       wake_up_interruptible_sync_poll(&pipe->wait, EPOLLIN | EPOLLRDNORM);
+                       wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
                        kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
                }
-               wait_event_interruptible(pipe->wait, pipe_writable(pipe));
+               wait_event_interruptible_exclusive(pipe->wr_wait, pipe_writable(pipe));
                __pipe_lock(pipe);
                was_empty = pipe_empty(pipe->head, pipe->tail);
+               wake_next_writer = true;
        }
 out:
+       if (pipe_full(pipe->head, pipe->tail, pipe->max_usage))
+               wake_next_writer = false;
        __pipe_unlock(pipe);
 
        /*
@@ -596,9 +608,11 @@ out:
         * wake up pending jobs
         */
        if (was_empty) {
-               wake_up_interruptible_sync_poll(&pipe->wait, EPOLLIN | EPOLLRDNORM);
+               wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM);
                kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
        }
+       if (wake_next_writer)
+               wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM);
        if (ret > 0 && sb_start_write_trylock(file_inode(filp)->i_sb)) {
                int err = file_update_time(filp);
                if (err)
@@ -642,12 +656,15 @@ pipe_poll(struct file *filp, poll_table *wait)
        unsigned int head, tail;
 
        /*
-        * Reading only -- no need for acquiring the semaphore.
+        * Reading pipe state 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);
+       if (filp->f_mode & FMODE_READ)
+               poll_wait(filp, &pipe->rd_wait, wait);
+       if (filp->f_mode & FMODE_WRITE)
+               poll_wait(filp, &pipe->wr_wait, wait);
 
        /*
         * .. and only then can you do the racy tests. That way,
@@ -706,7 +723,8 @@ pipe_release(struct inode *inode, struct file *file)
                pipe->writers--;
 
        if (pipe->readers || pipe->writers) {
-               wake_up_interruptible_sync_poll(&pipe->wait, EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM | EPOLLERR | EPOLLHUP);
+               wake_up_interruptible_sync_poll(&pipe->rd_wait, EPOLLIN | EPOLLRDNORM | EPOLLERR | EPOLLHUP);
+               wake_up_interruptible_sync_poll(&pipe->wr_wait, EPOLLOUT | EPOLLWRNORM | EPOLLERR | EPOLLHUP);
                kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
                kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
        }
@@ -789,7 +807,8 @@ struct pipe_inode_info *alloc_pipe_info(void)
                             GFP_KERNEL_ACCOUNT);
 
        if (pipe->bufs) {
-               init_waitqueue_head(&pipe->wait);
+               init_waitqueue_head(&pipe->rd_wait);
+               init_waitqueue_head(&pipe->wr_wait);
                pipe->r_counter = pipe->w_counter = 1;
                pipe->max_usage = pipe_bufs;
                pipe->ring_size = pipe_bufs;
@@ -1007,7 +1026,8 @@ static int wait_for_partner(struct pipe_inode_info *pipe, unsigned int *cnt)
 
 static void wake_up_partner(struct pipe_inode_info *pipe)
 {
-       wake_up_interruptible(&pipe->wait);
+       wake_up_interruptible(&pipe->rd_wait);
+       wake_up_interruptible(&pipe->wr_wait);
 }
 
 static int fifo_open(struct inode *inode, struct file *filp)
@@ -1118,13 +1138,13 @@ static int fifo_open(struct inode *inode, struct file *filp)
 
 err_rd:
        if (!--pipe->readers)
-               wake_up_interruptible(&pipe->wait);
+               wake_up_interruptible(&pipe->wr_wait);
        ret = -ERESTARTSYS;
        goto err;
 
 err_wr:
        if (!--pipe->writers)
-               wake_up_interruptible(&pipe->wait);
+               wake_up_interruptible(&pipe->rd_wait);
        ret = -ERESTARTSYS;
        goto err;
 
@@ -1251,7 +1271,8 @@ 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);
+       wake_up_interruptible_all(&pipe->rd_wait);
+       wake_up_interruptible_all(&pipe->wr_wait);
        return pipe->max_usage * PAGE_SIZE;
 
 out_revert_acct:
index ead487e..bd08616 100644 (file)
@@ -33,3 +33,4 @@ proc-$(CONFIG_PROC_KCORE)     += kcore.o
 proc-$(CONFIG_PROC_VMCORE)     += vmcore.o
 proc-$(CONFIG_PRINTK)  += kmsg.o
 proc-$(CONFIG_PROC_PAGE_MONITOR)       += page.o
+proc-$(CONFIG_BOOT_CONFIG)     += bootconfig.o
diff --git a/fs/proc/bootconfig.c b/fs/proc/bootconfig.c
new file mode 100644 (file)
index 0000000..9955d75
--- /dev/null
@@ -0,0 +1,89 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * /proc/bootconfig - Extra boot configuration
+ */
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/printk.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
+#include <linux/bootconfig.h>
+#include <linux/slab.h>
+
+static char *saved_boot_config;
+
+static int boot_config_proc_show(struct seq_file *m, void *v)
+{
+       if (saved_boot_config)
+               seq_puts(m, saved_boot_config);
+       return 0;
+}
+
+/* Rest size of buffer */
+#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)
+
+/* Return the needed total length if @size is 0 */
+static int __init copy_xbc_key_value_list(char *dst, size_t size)
+{
+       struct xbc_node *leaf, *vnode;
+       const char *val;
+       char *key, *end = dst + size;
+       int ret = 0;
+
+       key = kzalloc(XBC_KEYLEN_MAX, GFP_KERNEL);
+
+       xbc_for_each_key_value(leaf, val) {
+               ret = xbc_node_compose_key(leaf, key, XBC_KEYLEN_MAX);
+               if (ret < 0)
+                       break;
+               ret = snprintf(dst, rest(dst, end), "%s = ", key);
+               if (ret < 0)
+                       break;
+               dst += ret;
+               vnode = xbc_node_get_child(leaf);
+               if (vnode && xbc_node_is_array(vnode)) {
+                       xbc_array_for_each_value(vnode, val) {
+                               ret = snprintf(dst, rest(dst, end), "\"%s\"%s",
+                                       val, vnode->next ? ", " : "\n");
+                               if (ret < 0)
+                                       goto out;
+                               dst += ret;
+                       }
+               } else {
+                       ret = snprintf(dst, rest(dst, end), "\"%s\"\n", val);
+                       if (ret < 0)
+                               break;
+                       dst += ret;
+               }
+       }
+out:
+       kfree(key);
+
+       return ret < 0 ? ret : dst - (end - size);
+}
+
+static int __init proc_boot_config_init(void)
+{
+       int len;
+
+       len = copy_xbc_key_value_list(NULL, 0);
+       if (len < 0)
+               return len;
+
+       if (len > 0) {
+               saved_boot_config = kzalloc(len + 1, GFP_KERNEL);
+               if (!saved_boot_config)
+                       return -ENOMEM;
+
+               len = copy_xbc_key_value_list(saved_boot_config, len + 1);
+               if (len < 0) {
+                       kfree(saved_boot_config);
+                       return len;
+               }
+       }
+
+       proc_create_single("bootconfig", 0, NULL, boot_config_proc_show);
+
+       return 0;
+}
+fs_initcall(proc_boot_config_init);
index 96f1087..c1dea9b 100644 (file)
@@ -16,16 +16,16 @@ static int cpuinfo_open(struct inode *inode, struct file *file)
        return seq_open(file, &cpuinfo_op);
 }
 
-static const struct file_operations proc_cpuinfo_operations = {
-       .open           = cpuinfo_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops cpuinfo_proc_ops = {
+       .proc_open      = cpuinfo_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 static int __init proc_cpuinfo_init(void)
 {
-       proc_create("cpuinfo", 0, NULL, &proc_cpuinfo_operations);
+       proc_create("cpuinfo", 0, NULL, &cpuinfo_proc_ops);
        return 0;
 }
 fs_initcall(proc_cpuinfo_init);
index 074e958..3faed94 100644 (file)
@@ -473,7 +473,7 @@ struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
        ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
        if (ent) {
                ent->data = data;
-               ent->proc_fops = &proc_dir_operations;
+               ent->proc_dir_ops = &proc_dir_operations;
                ent->proc_iops = &proc_dir_inode_operations;
                ent = proc_register(parent, ent);
        }
@@ -503,7 +503,7 @@ struct proc_dir_entry *proc_create_mount_point(const char *name)
        ent = __proc_create(&parent, name, mode, 2);
        if (ent) {
                ent->data = NULL;
-               ent->proc_fops = NULL;
+               ent->proc_dir_ops = NULL;
                ent->proc_iops = NULL;
                ent = proc_register(parent, ent);
        }
@@ -533,25 +533,23 @@ struct proc_dir_entry *proc_create_reg(const char *name, umode_t mode,
 
 struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
                struct proc_dir_entry *parent,
-               const struct file_operations *proc_fops, void *data)
+               const struct proc_ops *proc_ops, void *data)
 {
        struct proc_dir_entry *p;
 
-       BUG_ON(proc_fops == NULL);
-
        p = proc_create_reg(name, mode, &parent, data);
        if (!p)
                return NULL;
-       p->proc_fops = proc_fops;
+       p->proc_ops = proc_ops;
        return proc_register(parent, p);
 }
 EXPORT_SYMBOL(proc_create_data);
  
 struct proc_dir_entry *proc_create(const char *name, umode_t mode,
                                   struct proc_dir_entry *parent,
-                                  const struct file_operations *proc_fops)
+                                  const struct proc_ops *proc_ops)
 {
-       return proc_create_data(name, mode, parent, proc_fops, NULL);
+       return proc_create_data(name, mode, parent, proc_ops, NULL);
 }
 EXPORT_SYMBOL(proc_create);
 
@@ -573,11 +571,11 @@ static int proc_seq_release(struct inode *inode, struct file *file)
        return seq_release(inode, file);
 }
 
-static const struct file_operations proc_seq_fops = {
-       .open           = proc_seq_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = proc_seq_release,
+static const struct proc_ops proc_seq_ops = {
+       .proc_open      = proc_seq_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = proc_seq_release,
 };
 
 struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
@@ -589,7 +587,7 @@ struct proc_dir_entry *proc_create_seq_private(const char *name, umode_t mode,
        p = proc_create_reg(name, mode, &parent, data);
        if (!p)
                return NULL;
-       p->proc_fops = &proc_seq_fops;
+       p->proc_ops = &proc_seq_ops;
        p->seq_ops = ops;
        p->state_size = state_size;
        return proc_register(parent, p);
@@ -603,11 +601,11 @@ static int proc_single_open(struct inode *inode, struct file *file)
        return single_open(file, de->single_show, de->data);
 }
 
-static const struct file_operations proc_single_fops = {
-       .open           = proc_single_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops proc_single_ops = {
+       .proc_open      = proc_single_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
@@ -619,7 +617,7 @@ struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
        p = proc_create_reg(name, mode, &parent, data);
        if (!p)
                return NULL;
-       p->proc_fops = &proc_single_fops;
+       p->proc_ops = &proc_single_ops;
        p->single_show = show;
        return proc_register(parent, p);
 }
index dbe43a5..6da1831 100644 (file)
@@ -163,7 +163,7 @@ static void close_pdeo(struct proc_dir_entry *pde, struct pde_opener *pdeo)
                pdeo->closing = true;
                spin_unlock(&pde->pde_unload_lock);
                file = pdeo->file;
-               pde->proc_fops->release(file_inode(file), file);
+               pde->proc_ops->proc_release(file_inode(file), file);
                spin_lock(&pde->pde_unload_lock);
                /* After ->release. */
                list_del(&pdeo->lh);
@@ -200,12 +200,12 @@ static loff_t proc_reg_llseek(struct file *file, loff_t offset, int whence)
        struct proc_dir_entry *pde = PDE(file_inode(file));
        loff_t rv = -EINVAL;
        if (use_pde(pde)) {
-               typeof_member(struct file_operations, llseek) llseek;
+               typeof_member(struct proc_ops, proc_lseek) lseek;
 
-               llseek = pde->proc_fops->llseek;
-               if (!llseek)
-                       llseek = default_llseek;
-               rv = llseek(file, offset, whence);
+               lseek = pde->proc_ops->proc_lseek;
+               if (!lseek)
+                       lseek = default_llseek;
+               rv = lseek(file, offset, whence);
                unuse_pde(pde);
        }
        return rv;
@@ -216,9 +216,9 @@ static ssize_t proc_reg_read(struct file *file, char __user *buf, size_t count,
        struct proc_dir_entry *pde = PDE(file_inode(file));
        ssize_t rv = -EIO;
        if (use_pde(pde)) {
-               typeof_member(struct file_operations, read) read;
+               typeof_member(struct proc_ops, proc_read) read;
 
-               read = pde->proc_fops->read;
+               read = pde->proc_ops->proc_read;
                if (read)
                        rv = read(file, buf, count, ppos);
                unuse_pde(pde);
@@ -231,9 +231,9 @@ static ssize_t proc_reg_write(struct file *file, const char __user *buf, size_t
        struct proc_dir_entry *pde = PDE(file_inode(file));
        ssize_t rv = -EIO;
        if (use_pde(pde)) {
-               typeof_member(struct file_operations, write) write;
+               typeof_member(struct proc_ops, proc_write) write;
 
-               write = pde->proc_fops->write;
+               write = pde->proc_ops->proc_write;
                if (write)
                        rv = write(file, buf, count, ppos);
                unuse_pde(pde);
@@ -246,9 +246,9 @@ static __poll_t proc_reg_poll(struct file *file, struct poll_table_struct *pts)
        struct proc_dir_entry *pde = PDE(file_inode(file));
        __poll_t rv = DEFAULT_POLLMASK;
        if (use_pde(pde)) {
-               typeof_member(struct file_operations, poll) poll;
+               typeof_member(struct proc_ops, proc_poll) poll;
 
-               poll = pde->proc_fops->poll;
+               poll = pde->proc_ops->proc_poll;
                if (poll)
                        rv = poll(file, pts);
                unuse_pde(pde);
@@ -261,9 +261,9 @@ static long proc_reg_unlocked_ioctl(struct file *file, unsigned int cmd, unsigne
        struct proc_dir_entry *pde = PDE(file_inode(file));
        long rv = -ENOTTY;
        if (use_pde(pde)) {
-               typeof_member(struct file_operations, unlocked_ioctl) ioctl;
+               typeof_member(struct proc_ops, proc_ioctl) ioctl;
 
-               ioctl = pde->proc_fops->unlocked_ioctl;
+               ioctl = pde->proc_ops->proc_ioctl;
                if (ioctl)
                        rv = ioctl(file, cmd, arg);
                unuse_pde(pde);
@@ -277,9 +277,9 @@ static long proc_reg_compat_ioctl(struct file *file, unsigned int cmd, unsigned
        struct proc_dir_entry *pde = PDE(file_inode(file));
        long rv = -ENOTTY;
        if (use_pde(pde)) {
-               typeof_member(struct file_operations, compat_ioctl) compat_ioctl;
+               typeof_member(struct proc_ops, proc_compat_ioctl) compat_ioctl;
 
-               compat_ioctl = pde->proc_fops->compat_ioctl;
+               compat_ioctl = pde->proc_ops->proc_compat_ioctl;
                if (compat_ioctl)
                        rv = compat_ioctl(file, cmd, arg);
                unuse_pde(pde);
@@ -293,9 +293,9 @@ static int proc_reg_mmap(struct file *file, struct vm_area_struct *vma)
        struct proc_dir_entry *pde = PDE(file_inode(file));
        int rv = -EIO;
        if (use_pde(pde)) {
-               typeof_member(struct file_operations, mmap) mmap;
+               typeof_member(struct proc_ops, proc_mmap) mmap;
 
-               mmap = pde->proc_fops->mmap;
+               mmap = pde->proc_ops->proc_mmap;
                if (mmap)
                        rv = mmap(file, vma);
                unuse_pde(pde);
@@ -312,9 +312,9 @@ proc_reg_get_unmapped_area(struct file *file, unsigned long orig_addr,
        unsigned long rv = -EIO;
 
        if (use_pde(pde)) {
-               typeof_member(struct file_operations, get_unmapped_area) get_area;
+               typeof_member(struct proc_ops, proc_get_unmapped_area) get_area;
 
-               get_area = pde->proc_fops->get_unmapped_area;
+               get_area = pde->proc_ops->proc_get_unmapped_area;
 #ifdef CONFIG_MMU
                if (!get_area)
                        get_area = current->mm->get_unmapped_area;
@@ -333,8 +333,8 @@ static int proc_reg_open(struct inode *inode, struct file *file)
 {
        struct proc_dir_entry *pde = PDE(inode);
        int rv = 0;
-       typeof_member(struct file_operations, open) open;
-       typeof_member(struct file_operations, release) release;
+       typeof_member(struct proc_ops, proc_open) open;
+       typeof_member(struct proc_ops, proc_release) release;
        struct pde_opener *pdeo;
 
        /*
@@ -351,7 +351,7 @@ static int proc_reg_open(struct inode *inode, struct file *file)
        if (!use_pde(pde))
                return -ENOENT;
 
-       release = pde->proc_fops->release;
+       release = pde->proc_ops->proc_release;
        if (release) {
                pdeo = kmem_cache_alloc(pde_opener_cache, GFP_KERNEL);
                if (!pdeo) {
@@ -360,7 +360,7 @@ static int proc_reg_open(struct inode *inode, struct file *file)
                }
        }
 
-       open = pde->proc_fops->open;
+       open = pde->proc_ops->proc_open;
        if (open)
                rv = open(inode, file);
 
@@ -468,21 +468,23 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
                        inode->i_size = de->size;
                if (de->nlink)
                        set_nlink(inode, de->nlink);
-               WARN_ON(!de->proc_iops);
-               inode->i_op = de->proc_iops;
-               if (de->proc_fops) {
-                       if (S_ISREG(inode->i_mode)) {
+
+               if (S_ISREG(inode->i_mode)) {
+                       inode->i_op = de->proc_iops;
+                       inode->i_fop = &proc_reg_file_ops;
 #ifdef CONFIG_COMPAT
-                               if (!de->proc_fops->compat_ioctl)
-                                       inode->i_fop =
-                                               &proc_reg_file_ops_no_compat;
-                               else
-#endif
-                                       inode->i_fop = &proc_reg_file_ops;
-                       } else {
-                               inode->i_fop = de->proc_fops;
+                       if (!de->proc_ops->proc_compat_ioctl) {
+                               inode->i_fop = &proc_reg_file_ops_no_compat;
                        }
-               }
+#endif
+               } else if (S_ISDIR(inode->i_mode)) {
+                       inode->i_op = de->proc_iops;
+                       inode->i_fop = de->proc_dir_ops;
+               } else if (S_ISLNK(inode->i_mode)) {
+                       inode->i_op = de->proc_iops;
+                       inode->i_fop = NULL;
+               } else
+                       BUG();
        } else
               pde_put(de);
        return inode;
index 0f3b557..4158727 100644 (file)
@@ -39,7 +39,10 @@ struct proc_dir_entry {
        spinlock_t pde_unload_lock;
        struct completion *pde_unload_completion;
        const struct inode_operations *proc_iops;
-       const struct file_operations *proc_fops;
+       union {
+               const struct proc_ops *proc_ops;
+               const struct file_operations *proc_dir_ops;
+       };
        const struct dentry_operations *proc_dops;
        union {
                const struct seq_operations *seq_ops;
index e2ed8e0..8ba492d 100644 (file)
@@ -574,11 +574,11 @@ static int release_kcore(struct inode *inode, struct file *file)
        return 0;
 }
 
-static const struct file_operations proc_kcore_operations = {
-       .read           = read_kcore,
-       .open           = open_kcore,
-       .release        = release_kcore,
-       .llseek         = default_llseek,
+static const struct proc_ops kcore_proc_ops = {
+       .proc_read      = read_kcore,
+       .proc_open      = open_kcore,
+       .proc_release   = release_kcore,
+       .proc_lseek     = default_llseek,
 };
 
 /* just remember that we have to update kcore */
@@ -637,8 +637,7 @@ static void __init add_modules_range(void)
 
 static int __init proc_kcore_init(void)
 {
-       proc_root_kcore = proc_create("kcore", S_IRUSR, NULL,
-                                     &proc_kcore_operations);
+       proc_root_kcore = proc_create("kcore", S_IRUSR, NULL, &kcore_proc_ops);
        if (!proc_root_kcore) {
                pr_err("couldn't create /proc/kcore\n");
                return 0; /* Always returns 0. */
index 4f4a2ab..ec1b7d2 100644 (file)
@@ -49,17 +49,17 @@ static __poll_t kmsg_poll(struct file *file, poll_table *wait)
 }
 
 
-static const struct file_operations proc_kmsg_operations = {
-       .read           = kmsg_read,
-       .poll           = kmsg_poll,
-       .open           = kmsg_open,
-       .release        = kmsg_release,
-       .llseek         = generic_file_llseek,
+static const struct proc_ops kmsg_proc_ops = {
+       .proc_read      = kmsg_read,
+       .proc_poll      = kmsg_poll,
+       .proc_open      = kmsg_open,
+       .proc_release   = kmsg_release,
+       .proc_lseek     = generic_file_llseek,
 };
 
 static int __init proc_kmsg_init(void)
 {
-       proc_create("kmsg", S_IRUSR, NULL, &proc_kmsg_operations);
+       proc_create("kmsg", S_IRUSR, NULL, &kmsg_proc_ops);
        return 0;
 }
 fs_initcall(proc_kmsg_init);
index 7c952ee..f909243 100644 (file)
 #define KPMMASK (KPMSIZE - 1)
 #define KPMBITS (KPMSIZE * BITS_PER_BYTE)
 
+static inline unsigned long get_max_dump_pfn(void)
+{
+#ifdef CONFIG_SPARSEMEM
+       /*
+        * The memmap of early sections is completely populated and marked
+        * online even if max_pfn does not fall on a section boundary -
+        * pfn_to_online_page() will succeed on all pages. Allow inspecting
+        * these memmaps.
+        */
+       return round_up(max_pfn, PAGES_PER_SECTION);
+#else
+       return max_pfn;
+#endif
+}
+
 /* /proc/kpagecount - an array exposing page counts
  *
  * Each entry is a u64 representing the corresponding
@@ -29,6 +44,7 @@
 static ssize_t kpagecount_read(struct file *file, char __user *buf,
                             size_t count, loff_t *ppos)
 {
+       const unsigned long max_dump_pfn = get_max_dump_pfn();
        u64 __user *out = (u64 __user *)buf;
        struct page *ppage;
        unsigned long src = *ppos;
@@ -37,9 +53,11 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
        u64 pcount;
 
        pfn = src / KPMSIZE;
-       count = min_t(size_t, count, (max_pfn * KPMSIZE) - src);
        if (src & KPMMASK || count & KPMMASK)
                return -EINVAL;
+       if (src >= max_dump_pfn * KPMSIZE)
+               return 0;
+       count = min_t(unsigned long, count, (max_dump_pfn * KPMSIZE) - src);
 
        while (count > 0) {
                /*
@@ -71,9 +89,9 @@ static ssize_t kpagecount_read(struct file *file, char __user *buf,
        return ret;
 }
 
-static const struct file_operations proc_kpagecount_operations = {
-       .llseek = mem_lseek,
-       .read = kpagecount_read,
+static const struct proc_ops kpagecount_proc_ops = {
+       .proc_lseek     = mem_lseek,
+       .proc_read      = kpagecount_read,
 };
 
 /* /proc/kpageflags - an array exposing page flags
@@ -206,6 +224,7 @@ u64 stable_page_flags(struct page *page)
 static ssize_t kpageflags_read(struct file *file, char __user *buf,
                             size_t count, loff_t *ppos)
 {
+       const unsigned long max_dump_pfn = get_max_dump_pfn();
        u64 __user *out = (u64 __user *)buf;
        struct page *ppage;
        unsigned long src = *ppos;
@@ -213,9 +232,11 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
        ssize_t ret = 0;
 
        pfn = src / KPMSIZE;
-       count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
        if (src & KPMMASK || count & KPMMASK)
                return -EINVAL;
+       if (src >= max_dump_pfn * KPMSIZE)
+               return 0;
+       count = min_t(unsigned long, count, (max_dump_pfn * KPMSIZE) - src);
 
        while (count > 0) {
                /*
@@ -242,15 +263,16 @@ static ssize_t kpageflags_read(struct file *file, char __user *buf,
        return ret;
 }
 
-static const struct file_operations proc_kpageflags_operations = {
-       .llseek = mem_lseek,
-       .read = kpageflags_read,
+static const struct proc_ops kpageflags_proc_ops = {
+       .proc_lseek     = mem_lseek,
+       .proc_read      = kpageflags_read,
 };
 
 #ifdef CONFIG_MEMCG
 static ssize_t kpagecgroup_read(struct file *file, char __user *buf,
                                size_t count, loff_t *ppos)
 {
+       const unsigned long max_dump_pfn = get_max_dump_pfn();
        u64 __user *out = (u64 __user *)buf;
        struct page *ppage;
        unsigned long src = *ppos;
@@ -259,9 +281,11 @@ static ssize_t kpagecgroup_read(struct file *file, char __user *buf,
        u64 ino;
 
        pfn = src / KPMSIZE;
-       count = min_t(unsigned long, count, (max_pfn * KPMSIZE) - src);
        if (src & KPMMASK || count & KPMMASK)
                return -EINVAL;
+       if (src >= max_dump_pfn * KPMSIZE)
+               return 0;
+       count = min_t(unsigned long, count, (max_dump_pfn * KPMSIZE) - src);
 
        while (count > 0) {
                /*
@@ -293,18 +317,18 @@ static ssize_t kpagecgroup_read(struct file *file, char __user *buf,
        return ret;
 }
 
-static const struct file_operations proc_kpagecgroup_operations = {
-       .llseek = mem_lseek,
-       .read = kpagecgroup_read,
+static const struct proc_ops kpagecgroup_proc_ops = {
+       .proc_lseek     = mem_lseek,
+       .proc_read      = kpagecgroup_read,
 };
 #endif /* CONFIG_MEMCG */
 
 static int __init proc_page_init(void)
 {
-       proc_create("kpagecount", S_IRUSR, NULL, &proc_kpagecount_operations);
-       proc_create("kpageflags", S_IRUSR, NULL, &proc_kpageflags_operations);
+       proc_create("kpagecount", S_IRUSR, NULL, &kpagecount_proc_ops);
+       proc_create("kpageflags", S_IRUSR, NULL, &kpageflags_proc_ops);
 #ifdef CONFIG_MEMCG
-       proc_create("kpagecgroup", S_IRUSR, NULL, &proc_kpagecgroup_operations);
+       proc_create("kpagecgroup", S_IRUSR, NULL, &kpagecgroup_proc_ops);
 #endif
        return 0;
 }
index 76ae278..4888c52 100644 (file)
@@ -90,12 +90,12 @@ static int seq_release_net(struct inode *ino, struct file *f)
        return 0;
 }
 
-static const struct file_operations proc_net_seq_fops = {
-       .open           = seq_open_net,
-       .read           = seq_read,
-       .write          = proc_simple_write,
-       .llseek         = seq_lseek,
-       .release        = seq_release_net,
+static const struct proc_ops proc_net_seq_ops = {
+       .proc_open      = seq_open_net,
+       .proc_read      = seq_read,
+       .proc_write     = proc_simple_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release_net,
 };
 
 struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
@@ -108,7 +108,7 @@ struct proc_dir_entry *proc_create_net_data(const char *name, umode_t mode,
        if (!p)
                return NULL;
        pde_force_lookup(p);
-       p->proc_fops = &proc_net_seq_fops;
+       p->proc_ops = &proc_net_seq_ops;
        p->seq_ops = ops;
        p->state_size = state_size;
        return proc_register(parent, p);
@@ -152,7 +152,7 @@ struct proc_dir_entry *proc_create_net_data_write(const char *name, umode_t mode
        if (!p)
                return NULL;
        pde_force_lookup(p);
-       p->proc_fops = &proc_net_seq_fops;
+       p->proc_ops = &proc_net_seq_ops;
        p->seq_ops = ops;
        p->state_size = state_size;
        p->write = write;
@@ -183,12 +183,12 @@ static int single_release_net(struct inode *ino, struct file *f)
        return single_release(ino, f);
 }
 
-static const struct file_operations proc_net_single_fops = {
-       .open           = single_open_net,
-       .read           = seq_read,
-       .write          = proc_simple_write,
-       .llseek         = seq_lseek,
-       .release        = single_release_net,
+static const struct proc_ops proc_net_single_ops = {
+       .proc_open      = single_open_net,
+       .proc_read      = seq_read,
+       .proc_write     = proc_simple_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release_net,
 };
 
 struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
@@ -201,7 +201,7 @@ struct proc_dir_entry *proc_create_net_single(const char *name, umode_t mode,
        if (!p)
                return NULL;
        pde_force_lookup(p);
-       p->proc_fops = &proc_net_single_fops;
+       p->proc_ops = &proc_net_single_ops;
        p->single_show = show;
        return proc_register(parent, p);
 }
@@ -244,7 +244,7 @@ struct proc_dir_entry *proc_create_net_single_write(const char *name, umode_t mo
        if (!p)
                return NULL;
        pde_force_lookup(p);
-       p->proc_fops = &proc_net_single_fops;
+       p->proc_ops = &proc_net_single_ops;
        p->single_show = show;
        p->write = write;
        return proc_register(parent, p);
index d80989b..c75bb46 100644 (file)
@@ -1720,7 +1720,7 @@ int __init proc_sys_init(void)
 
        proc_sys_root = proc_mkdir("sys", NULL);
        proc_sys_root->proc_iops = &proc_sys_dir_operations;
-       proc_sys_root->proc_fops = &proc_sys_dir_file_operations;
+       proc_sys_root->proc_dir_ops = &proc_sys_dir_file_operations;
        proc_sys_root->nlink = 0;
 
        return sysctl_init();
index 0b7c8df..608233d 100644 (file)
@@ -41,24 +41,19 @@ enum proc_param {
        Opt_hidepid,
 };
 
-static const struct fs_parameter_spec proc_param_specs[] = {
+static const struct fs_parameter_spec proc_fs_parameters[] = {
        fsparam_u32("gid",      Opt_gid),
        fsparam_u32("hidepid",  Opt_hidepid),
        {}
 };
 
-static const struct fs_parameter_description proc_fs_parameters = {
-       .name           = "proc",
-       .specs          = proc_param_specs,
-};
-
 static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct proc_fs_context *ctx = fc->fs_private;
        struct fs_parse_result result;
        int opt;
 
-       opt = fs_parse(fc, &proc_fs_parameters, param, &result);
+       opt = fs_parse(fc, proc_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -71,7 +66,7 @@ static int proc_parse_param(struct fs_context *fc, struct fs_parameter *param)
                ctx->hidepid = result.uint_32;
                if (ctx->hidepid < HIDEPID_OFF ||
                    ctx->hidepid > HIDEPID_INVISIBLE)
-                       return invalf(fc, "proc: hidepid value must be between 0 and 2.\n");
+                       return invalfc(fc, "hidepid value must be between 0 and 2.\n");
                break;
 
        default:
@@ -207,7 +202,7 @@ static void proc_kill_sb(struct super_block *sb)
 static struct file_system_type proc_fs_type = {
        .name                   = "proc",
        .init_fs_context        = proc_init_fs_context,
-       .parameters             = &proc_fs_parameters,
+       .parameters             = proc_fs_parameters,
        .kill_sb                = proc_kill_sb,
        .fs_flags               = FS_USERNS_MOUNT | FS_DISALLOW_NOTIFY_PERM,
 };
@@ -292,7 +287,7 @@ struct proc_dir_entry proc_root = {
        .nlink          = 2, 
        .refcnt         = REFCOUNT_INIT(1),
        .proc_iops      = &proc_root_inode_operations, 
-       .proc_fops      = &proc_root_operations,
+       .proc_dir_ops   = &proc_root_operations,
        .parent         = &proc_root,
        .subdir         = RB_ROOT,
        .name           = "/proc",
index fd931d3..0449edf 100644 (file)
@@ -223,16 +223,16 @@ static int stat_open(struct inode *inode, struct file *file)
        return single_open_size(file, show_stat, NULL, size);
 }
 
-static const struct file_operations proc_stat_operations = {
-       .open           = stat_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops stat_proc_ops = {
+       .proc_open      = stat_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 static int __init proc_stat_init(void)
 {
-       proc_create("stat", 0, NULL, &proc_stat_operations);
+       proc_create("stat", 0, NULL, &stat_proc_ops);
        return 0;
 }
 fs_initcall(proc_stat_init);
index 9442631..3ba9ae8 100644 (file)
@@ -505,7 +505,7 @@ static void smaps_account(struct mem_size_stats *mss, struct page *page,
 
 #ifdef CONFIG_SHMEM
 static int smaps_pte_hole(unsigned long addr, unsigned long end,
-               struct mm_walk *walk)
+                         __always_unused int depth, struct mm_walk *walk)
 {
        struct mem_size_stats *mss = walk->private;
 
@@ -1282,7 +1282,7 @@ static int add_to_pagemap(unsigned long addr, pagemap_entry_t *pme,
 }
 
 static int pagemap_pte_hole(unsigned long start, unsigned long end,
-                               struct mm_walk *walk)
+                           __always_unused int depth, struct mm_walk *walk)
 {
        struct pagemapread *pm = walk->private;
        unsigned long addr = start;
index 7b13988..7dc800c 100644 (file)
@@ -667,10 +667,10 @@ static int mmap_vmcore(struct file *file, struct vm_area_struct *vma)
 }
 #endif
 
-static const struct file_operations proc_vmcore_operations = {
-       .read           = read_vmcore,
-       .llseek         = default_llseek,
-       .mmap           = mmap_vmcore,
+static const struct proc_ops vmcore_proc_ops = {
+       .proc_read      = read_vmcore,
+       .proc_lseek     = default_llseek,
+       .proc_mmap      = mmap_vmcore,
 };
 
 static struct vmcore* __init get_new_element(void)
@@ -1555,7 +1555,7 @@ static int __init vmcore_init(void)
        elfcorehdr_free(elfcorehdr_addr);
        elfcorehdr_addr = ELFCORE_ADDR_ERR;
 
-       proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &proc_vmcore_operations);
+       proc_vmcore = proc_create("vmcore", S_IRUSR, NULL, &vmcore_proc_ops);
        if (proc_vmcore)
                proc_vmcore->size = vmcore_size;
        return 0;
index d82636e..ee179a8 100644 (file)
@@ -181,23 +181,18 @@ enum ramfs_param {
        Opt_mode,
 };
 
-static const struct fs_parameter_spec ramfs_param_specs[] = {
+const struct fs_parameter_spec ramfs_fs_parameters[] = {
        fsparam_u32oct("mode",  Opt_mode),
        {}
 };
 
-const struct fs_parameter_description ramfs_fs_parameters = {
-       .name           = "ramfs",
-       .specs          = ramfs_param_specs,
-};
-
 static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct fs_parse_result result;
        struct ramfs_fs_info *fsi = fc->s_fs_info;
        int opt;
 
-       opt = fs_parse(fc, &ramfs_fs_parameters, param, &result);
+       opt = fs_parse(fc, ramfs_fs_parameters, param, &result);
        if (opt < 0) {
                /*
                 * We might like to report bad mount options here;
@@ -278,7 +273,7 @@ static void ramfs_kill_sb(struct super_block *sb)
 static struct file_system_type ramfs_fs_type = {
        .name           = "ramfs",
        .init_fs_context = ramfs_init_fs_context,
-       .parameters     = &ramfs_fs_parameters,
+       .parameters     = ramfs_fs_parameters,
        .kill_sb        = ramfs_kill_sb,
        .fs_flags       = FS_USERNS_MOUNT,
 };
index 7458fcc..59d819c 100644 (file)
@@ -939,6 +939,34 @@ out:
        return ret;
 }
 
+ssize_t vfs_iocb_iter_read(struct file *file, struct kiocb *iocb,
+                          struct iov_iter *iter)
+{
+       size_t tot_len;
+       ssize_t ret = 0;
+
+       if (!file->f_op->read_iter)
+               return -EINVAL;
+       if (!(file->f_mode & FMODE_READ))
+               return -EBADF;
+       if (!(file->f_mode & FMODE_CAN_READ))
+               return -EINVAL;
+
+       tot_len = iov_iter_count(iter);
+       if (!tot_len)
+               goto out;
+       ret = rw_verify_area(READ, file, &iocb->ki_pos, tot_len);
+       if (ret < 0)
+               return ret;
+
+       ret = call_read_iter(file, iocb, iter);
+out:
+       if (ret >= 0)
+               fsnotify_access(file);
+       return ret;
+}
+EXPORT_SYMBOL(vfs_iocb_iter_read);
+
 ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos,
                rwf_t flags)
 {
@@ -975,6 +1003,34 @@ static ssize_t do_iter_write(struct file *file, struct iov_iter *iter,
        return ret;
 }
 
+ssize_t vfs_iocb_iter_write(struct file *file, struct kiocb *iocb,
+                           struct iov_iter *iter)
+{
+       size_t tot_len;
+       ssize_t ret = 0;
+
+       if (!file->f_op->write_iter)
+               return -EINVAL;
+       if (!(file->f_mode & FMODE_WRITE))
+               return -EBADF;
+       if (!(file->f_mode & FMODE_CAN_WRITE))
+               return -EINVAL;
+
+       tot_len = iov_iter_count(iter);
+       if (!tot_len)
+               return 0;
+       ret = rw_verify_area(WRITE, file, &iocb->ki_pos, tot_len);
+       if (ret < 0)
+               return ret;
+
+       ret = call_write_iter(file, iocb, iter);
+       if (ret > 0)
+               fsnotify_modify(file);
+
+       return ret;
+}
+EXPORT_SYMBOL(vfs_iocb_iter_write);
+
 ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos,
                rwf_t flags)
 {
index 3009652..d671936 100644 (file)
@@ -165,8 +165,8 @@ static const struct pipe_buf_operations user_page_pipe_buf_ops = {
 static void wakeup_pipe_readers(struct pipe_inode_info *pipe)
 {
        smp_mb();
-       if (waitqueue_active(&pipe->wait))
-               wake_up_interruptible(&pipe->wait);
+       if (waitqueue_active(&pipe->rd_wait))
+               wake_up_interruptible(&pipe->rd_wait);
        kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN);
 }
 
@@ -462,8 +462,8 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe,
 static void wakeup_pipe_writers(struct pipe_inode_info *pipe)
 {
        smp_mb();
-       if (waitqueue_active(&pipe->wait))
-               wake_up_interruptible(&pipe->wait);
+       if (waitqueue_active(&pipe->wr_wait))
+               wake_up_interruptible(&pipe->wr_wait);
        kill_fasync(&pipe->fasync_writers, SIGIO, POLL_OUT);
 }
 
index d41c21f..c4ab045 100644 (file)
@@ -449,7 +449,7 @@ int __compat_only_sysfs_link_entry_to_kobj(struct kobject *kobj,
        }
 
        link = kernfs_create_link(kobj->sd, target_name, entry);
-       if (IS_ERR(link) && PTR_ERR(link) == -EEXIST)
+       if (PTR_ERR(link) == -EEXIST)
                sysfs_warn_dup(kobj->sd, target_name);
 
        kernfs_put(entry);
index 0caa151..0ee8c6d 100644 (file)
@@ -330,7 +330,10 @@ static struct dentry *start_creating(const char *name, struct dentry *parent)
                parent = tracefs_mount->mnt_root;
 
        inode_lock(parent->d_inode);
-       dentry = lookup_one_len(name, parent, strlen(name));
+       if (unlikely(IS_DEADDIR(parent->d_inode)))
+               dentry = ERR_PTR(-ENOENT);
+       else
+               dentry = lookup_one_len(name, parent, strlen(name));
        if (!IS_ERR(dentry) && dentry->d_inode) {
                dput(dentry);
                dentry = ERR_PTR(-EEXIST);
@@ -499,122 +502,27 @@ __init struct dentry *tracefs_create_instance_dir(const char *name,
        return dentry;
 }
 
-static int __tracefs_remove(struct dentry *dentry, struct dentry *parent)
+static void remove_one(struct dentry *victim)
 {
-       int ret = 0;
-
-       if (simple_positive(dentry)) {
-               if (dentry->d_inode) {
-                       dget(dentry);
-                       switch (dentry->d_inode->i_mode & S_IFMT) {
-                       case S_IFDIR:
-                               ret = simple_rmdir(parent->d_inode, dentry);
-                               if (!ret)
-                                       fsnotify_rmdir(parent->d_inode, dentry);
-                               break;
-                       default:
-                               simple_unlink(parent->d_inode, dentry);
-                               fsnotify_unlink(parent->d_inode, dentry);
-                               break;
-                       }
-                       if (!ret)
-                               d_delete(dentry);
-                       dput(dentry);
-               }
-       }
-       return ret;
-}
-
-/**
- * tracefs_remove - removes a file or directory from the tracefs filesystem
- * @dentry: a pointer to a the dentry of the file or directory to be
- *          removed.
- *
- * This function removes a file or directory in tracefs that was previously
- * created with a call to another tracefs function (like
- * tracefs_create_file() or variants thereof.)
- */
-void tracefs_remove(struct dentry *dentry)
-{
-       struct dentry *parent;
-       int ret;
-
-       if (IS_ERR_OR_NULL(dentry))
-               return;
-
-       parent = dentry->d_parent;
-       inode_lock(parent->d_inode);
-       ret = __tracefs_remove(dentry, parent);
-       inode_unlock(parent->d_inode);
-       if (!ret)
-               simple_release_fs(&tracefs_mount, &tracefs_mount_count);
+       simple_release_fs(&tracefs_mount, &tracefs_mount_count);
 }
 
 /**
- * tracefs_remove_recursive - recursively removes a directory
+ * tracefs_remove - recursively removes a directory
  * @dentry: a pointer to a the dentry of the directory to be removed.
  *
  * This function recursively removes a directory tree in tracefs that
  * was previously created with a call to another tracefs function
  * (like tracefs_create_file() or variants thereof.)
  */
-void tracefs_remove_recursive(struct dentry *dentry)
+void tracefs_remove(struct dentry *dentry)
 {
-       struct dentry *child, *parent;
-
        if (IS_ERR_OR_NULL(dentry))
                return;
 
-       parent = dentry;
- down:
-       inode_lock(parent->d_inode);
- loop:
-       /*
-        * The parent->d_subdirs is protected by the d_lock. Outside that
-        * lock, the child can be unlinked and set to be freed which can
-        * use the d_u.d_child as the rcu head and corrupt this list.
-        */
-       spin_lock(&parent->d_lock);
-       list_for_each_entry(child, &parent->d_subdirs, d_child) {
-               if (!simple_positive(child))
-                       continue;
-
-               /* perhaps simple_empty(child) makes more sense */
-               if (!list_empty(&child->d_subdirs)) {
-                       spin_unlock(&parent->d_lock);
-                       inode_unlock(parent->d_inode);
-                       parent = child;
-                       goto down;
-               }
-
-               spin_unlock(&parent->d_lock);
-
-               if (!__tracefs_remove(child, parent))
-                       simple_release_fs(&tracefs_mount, &tracefs_mount_count);
-
-               /*
-                * The parent->d_lock protects agaist child from unlinking
-                * from d_subdirs. When releasing the parent->d_lock we can
-                * no longer trust that the next pointer is valid.
-                * Restart the loop. We'll skip this one with the
-                * simple_positive() check.
-                */
-               goto loop;
-       }
-       spin_unlock(&parent->d_lock);
-
-       inode_unlock(parent->d_inode);
-       child = parent;
-       parent = parent->d_parent;
-       inode_lock(parent->d_inode);
-
-       if (child != dentry)
-               /* go up */
-               goto loop;
-
-       if (!__tracefs_remove(child, parent))
-               simple_release_fs(&tracefs_mount, &tracefs_mount_count);
-       inode_unlock(parent->d_inode);
+       simple_pin_fs(&trace_fs_type, &tracefs_mount, &tracefs_mount_count);
+       simple_recursive_removal(dentry, remove_one);
+       simple_release_fs(&tracefs_mount, &tracefs_mount_count);
 }
 
 /**
index bc4dec5..743928e 100644 (file)
@@ -1080,18 +1080,12 @@ static void do_attr_changes(struct inode *inode, const struct iattr *attr)
                inode->i_uid = attr->ia_uid;
        if (attr->ia_valid & ATTR_GID)
                inode->i_gid = attr->ia_gid;
-       if (attr->ia_valid & ATTR_ATIME) {
-               inode->i_atime = timestamp_truncate(attr->ia_atime,
-                                                 inode);
-       }
-       if (attr->ia_valid & ATTR_MTIME) {
-               inode->i_mtime = timestamp_truncate(attr->ia_mtime,
-                                                 inode);
-       }
-       if (attr->ia_valid & ATTR_CTIME) {
-               inode->i_ctime = timestamp_truncate(attr->ia_ctime,
-                                                 inode);
-       }
+       if (attr->ia_valid & ATTR_ATIME)
+               inode->i_atime = attr->ia_atime;
+       if (attr->ia_valid & ATTR_MTIME)
+               inode->i_mtime = attr->ia_mtime;
+       if (attr->ia_valid & ATTR_CTIME)
+               inode->i_ctime = attr->ia_ctime;
        if (attr->ia_valid & ATTR_MODE) {
                umode_t mode = attr->ia_mode;
 
index 17c90df..4b4b65b 100644 (file)
@@ -84,7 +84,6 @@ static int create_default_filesystem(struct ubifs_info *c)
        int idx_node_size;
        long long tmp64, main_bytes;
        __le64 tmp_le64;
-       __le32 tmp_le32;
        struct timespec64 ts;
        u8 hash[UBIFS_HASH_ARR_SZ];
        u8 hash_lpt[UBIFS_HASH_ARR_SZ];
@@ -291,16 +290,14 @@ static int create_default_filesystem(struct ubifs_info *c)
        ino->creat_sqnum = cpu_to_le64(++c->max_sqnum);
        ino->nlink = cpu_to_le32(2);
 
-       ktime_get_real_ts64(&ts);
-       ts = timespec64_trunc(ts, DEFAULT_TIME_GRAN);
+       ktime_get_coarse_real_ts64(&ts);
        tmp_le64 = cpu_to_le64(ts.tv_sec);
        ino->atime_sec   = tmp_le64;
        ino->ctime_sec   = tmp_le64;
        ino->mtime_sec   = tmp_le64;
-       tmp_le32 = cpu_to_le32(ts.tv_nsec);
-       ino->atime_nsec  = tmp_le32;
-       ino->ctime_nsec  = tmp_le32;
-       ino->mtime_nsec  = tmp_le32;
+       ino->atime_nsec  = 0;
+       ino->ctime_nsec  = 0;
+       ino->mtime_nsec  = 0;
        ino->mode = cpu_to_le32(S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO);
        ino->size = cpu_to_le64(UBIFS_INO_NODE_SZ);
 
index c952b6b..1d17ce9 100644 (file)
@@ -36,14 +36,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
                if (times[0].tv_nsec == UTIME_OMIT)
                        newattrs.ia_valid &= ~ATTR_ATIME;
                else if (times[0].tv_nsec != UTIME_NOW) {
-                       newattrs.ia_atime = timestamp_truncate(times[0], inode);
+                       newattrs.ia_atime = times[0];
                        newattrs.ia_valid |= ATTR_ATIME_SET;
                }
 
                if (times[1].tv_nsec == UTIME_OMIT)
                        newattrs.ia_valid &= ~ATTR_MTIME;
                else if (times[1].tv_nsec != UTIME_NOW) {
-                       newattrs.ia_mtime = timestamp_truncate(times[1], inode);
+                       newattrs.ia_mtime = times[1];
                        newattrs.ia_valid |= ATTR_MTIME_SET;
                }
                /*
diff --git a/fs/vboxsf/Kconfig b/fs/vboxsf/Kconfig
new file mode 100644 (file)
index 0000000..b84586a
--- /dev/null
@@ -0,0 +1,10 @@
+config VBOXSF_FS
+       tristate "VirtualBox guest shared folder (vboxsf) support"
+       depends on X86 && VBOXGUEST
+       select NLS
+       help
+         VirtualBox hosts can share folders with guests, this driver
+         implements the Linux-guest side of this allowing folders exported
+         by the host to be mounted under Linux.
+
+         If you want to use shared folders in VirtualBox guests, answer Y or M.
diff --git a/fs/vboxsf/Makefile b/fs/vboxsf/Makefile
new file mode 100644 (file)
index 0000000..9e4328e
--- /dev/null
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: MIT
+
+obj-$(CONFIG_VBOXSF_FS) += vboxsf.o
+
+vboxsf-y := dir.o file.o utils.o vboxsf_wrappers.o super.o
diff --git a/fs/vboxsf/dir.c b/fs/vboxsf/dir.c
new file mode 100644 (file)
index 0000000..dd147b4
--- /dev/null
@@ -0,0 +1,427 @@
+// SPDX-License-Identifier: MIT
+/*
+ * VirtualBox Guest Shared Folders support: Directory inode and file operations
+ *
+ * Copyright (C) 2006-2018 Oracle Corporation
+ */
+
+#include <linux/namei.h>
+#include <linux/vbox_utils.h>
+#include "vfsmod.h"
+
+static int vboxsf_dir_open(struct inode *inode, struct file *file)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
+       struct shfl_createparms params = {};
+       struct vboxsf_dir_info *sf_d;
+       int err;
+
+       sf_d = vboxsf_dir_info_alloc();
+       if (!sf_d)
+               return -ENOMEM;
+
+       params.handle = SHFL_HANDLE_NIL;
+       params.create_flags = SHFL_CF_DIRECTORY | SHFL_CF_ACT_OPEN_IF_EXISTS |
+                             SHFL_CF_ACT_FAIL_IF_NEW | SHFL_CF_ACCESS_READ;
+
+       err = vboxsf_create_at_dentry(file_dentry(file), &params);
+       if (err)
+               goto err_free_dir_info;
+
+       if (params.result != SHFL_FILE_EXISTS) {
+               err = -ENOENT;
+               goto err_close;
+       }
+
+       err = vboxsf_dir_read_all(sbi, sf_d, params.handle);
+       if (err)
+               goto err_close;
+
+       vboxsf_close(sbi->root, params.handle);
+       file->private_data = sf_d;
+       return 0;
+
+err_close:
+       vboxsf_close(sbi->root, params.handle);
+err_free_dir_info:
+       vboxsf_dir_info_free(sf_d);
+       return err;
+}
+
+static int vboxsf_dir_release(struct inode *inode, struct file *file)
+{
+       if (file->private_data)
+               vboxsf_dir_info_free(file->private_data);
+
+       return 0;
+}
+
+static unsigned int vboxsf_get_d_type(u32 mode)
+{
+       unsigned int d_type;
+
+       switch (mode & SHFL_TYPE_MASK) {
+       case SHFL_TYPE_FIFO:
+               d_type = DT_FIFO;
+               break;
+       case SHFL_TYPE_DEV_CHAR:
+               d_type = DT_CHR;
+               break;
+       case SHFL_TYPE_DIRECTORY:
+               d_type = DT_DIR;
+               break;
+       case SHFL_TYPE_DEV_BLOCK:
+               d_type = DT_BLK;
+               break;
+       case SHFL_TYPE_FILE:
+               d_type = DT_REG;
+               break;
+       case SHFL_TYPE_SYMLINK:
+               d_type = DT_LNK;
+               break;
+       case SHFL_TYPE_SOCKET:
+               d_type = DT_SOCK;
+               break;
+       case SHFL_TYPE_WHITEOUT:
+               d_type = DT_WHT;
+               break;
+       default:
+               d_type = DT_UNKNOWN;
+               break;
+       }
+       return d_type;
+}
+
+static bool vboxsf_dir_emit(struct file *dir, struct dir_context *ctx)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(file_inode(dir)->i_sb);
+       struct vboxsf_dir_info *sf_d = dir->private_data;
+       struct shfl_dirinfo *info;
+       struct vboxsf_dir_buf *b;
+       unsigned int d_type;
+       loff_t i, cur = 0;
+       ino_t fake_ino;
+       void *end;
+       int err;
+
+       list_for_each_entry(b, &sf_d->info_list, head) {
+try_next_entry:
+               if (ctx->pos >= cur + b->entries) {
+                       cur += b->entries;
+                       continue;
+               }
+
+               /*
+                * Note the vboxsf_dir_info objects we are iterating over here
+                * are variable sized, so the info pointer may end up being
+                * unaligned. This is how we get the data from the host.
+                * Since vboxsf is only supported on x86 machines this is not
+                * a problem.
+                */
+               for (i = 0, info = b->buf; i < ctx->pos - cur; i++) {
+                       end = &info->name.string.utf8[info->name.size];
+                       /* Only happens if the host gives us corrupt data */
+                       if (WARN_ON(end > (b->buf + b->used)))
+                               return false;
+                       info = end;
+               }
+
+               end = &info->name.string.utf8[info->name.size];
+               if (WARN_ON(end > (b->buf + b->used)))
+                       return false;
+
+               /* Info now points to the right entry, emit it. */
+               d_type = vboxsf_get_d_type(info->info.attr.mode);
+
+               /*
+                * On 32 bit systems pos is 64 signed, while ino is 32 bit
+                * unsigned so fake_ino may overflow, check for this.
+                */
+               if ((ino_t)(ctx->pos + 1) != (u64)(ctx->pos + 1)) {
+                       vbg_err("vboxsf: fake ino overflow, truncating dir\n");
+                       return false;
+               }
+               fake_ino = ctx->pos + 1;
+
+               if (sbi->nls) {
+                       char d_name[NAME_MAX];
+
+                       err = vboxsf_nlscpy(sbi, d_name, NAME_MAX,
+                                           info->name.string.utf8,
+                                           info->name.length);
+                       if (err) {
+                               /* skip erroneous entry and proceed */
+                               ctx->pos += 1;
+                               goto try_next_entry;
+                       }
+
+                       return dir_emit(ctx, d_name, strlen(d_name),
+                                       fake_ino, d_type);
+               }
+
+               return dir_emit(ctx, info->name.string.utf8, info->name.length,
+                               fake_ino, d_type);
+       }
+
+       return false;
+}
+
+static int vboxsf_dir_iterate(struct file *dir, struct dir_context *ctx)
+{
+       bool emitted;
+
+       do {
+               emitted = vboxsf_dir_emit(dir, ctx);
+               if (emitted)
+                       ctx->pos += 1;
+       } while (emitted);
+
+       return 0;
+}
+
+const struct file_operations vboxsf_dir_fops = {
+       .open = vboxsf_dir_open,
+       .iterate = vboxsf_dir_iterate,
+       .release = vboxsf_dir_release,
+       .read = generic_read_dir,
+       .llseek = generic_file_llseek,
+};
+
+/*
+ * This is called during name resolution/lookup to check if the @dentry in
+ * the cache is still valid. the job is handled by vboxsf_inode_revalidate.
+ */
+static int vboxsf_dentry_revalidate(struct dentry *dentry, unsigned int flags)
+{
+       if (flags & LOOKUP_RCU)
+               return -ECHILD;
+
+       if (d_really_is_positive(dentry))
+               return vboxsf_inode_revalidate(dentry) == 0;
+       else
+               return vboxsf_stat_dentry(dentry, NULL) == -ENOENT;
+}
+
+const struct dentry_operations vboxsf_dentry_ops = {
+       .d_revalidate = vboxsf_dentry_revalidate
+};
+
+/* iops */
+
+static struct dentry *vboxsf_dir_lookup(struct inode *parent,
+                                       struct dentry *dentry,
+                                       unsigned int flags)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
+       struct shfl_fsobjinfo fsinfo;
+       struct inode *inode;
+       int err;
+
+       dentry->d_time = jiffies;
+
+       err = vboxsf_stat_dentry(dentry, &fsinfo);
+       if (err) {
+               inode = (err == -ENOENT) ? NULL : ERR_PTR(err);
+       } else {
+               inode = vboxsf_new_inode(parent->i_sb);
+               if (!IS_ERR(inode))
+                       vboxsf_init_inode(sbi, inode, &fsinfo);
+       }
+
+       return d_splice_alias(inode, dentry);
+}
+
+static int vboxsf_dir_instantiate(struct inode *parent, struct dentry *dentry,
+                                 struct shfl_fsobjinfo *info)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
+       struct vboxsf_inode *sf_i;
+       struct inode *inode;
+
+       inode = vboxsf_new_inode(parent->i_sb);
+       if (IS_ERR(inode))
+               return PTR_ERR(inode);
+
+       sf_i = VBOXSF_I(inode);
+       /* The host may have given us different attr then requested */
+       sf_i->force_restat = 1;
+       vboxsf_init_inode(sbi, inode, info);
+
+       d_instantiate(dentry, inode);
+
+       return 0;
+}
+
+static int vboxsf_dir_create(struct inode *parent, struct dentry *dentry,
+                            umode_t mode, int is_dir)
+{
+       struct vboxsf_inode *sf_parent_i = VBOXSF_I(parent);
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
+       struct shfl_createparms params = {};
+       int err;
+
+       params.handle = SHFL_HANDLE_NIL;
+       params.create_flags = SHFL_CF_ACT_CREATE_IF_NEW |
+                             SHFL_CF_ACT_FAIL_IF_EXISTS |
+                             SHFL_CF_ACCESS_READWRITE |
+                             (is_dir ? SHFL_CF_DIRECTORY : 0);
+       params.info.attr.mode = (mode & 0777) |
+                               (is_dir ? SHFL_TYPE_DIRECTORY : SHFL_TYPE_FILE);
+       params.info.attr.additional = SHFLFSOBJATTRADD_NOTHING;
+
+       err = vboxsf_create_at_dentry(dentry, &params);
+       if (err)
+               return err;
+
+       if (params.result != SHFL_FILE_CREATED)
+               return -EPERM;
+
+       vboxsf_close(sbi->root, params.handle);
+
+       err = vboxsf_dir_instantiate(parent, dentry, &params.info);
+       if (err)
+               return err;
+
+       /* parent directory access/change time changed */
+       sf_parent_i->force_restat = 1;
+
+       return 0;
+}
+
+static int vboxsf_dir_mkfile(struct inode *parent, struct dentry *dentry,
+                            umode_t mode, bool excl)
+{
+       return vboxsf_dir_create(parent, dentry, mode, 0);
+}
+
+static int vboxsf_dir_mkdir(struct inode *parent, struct dentry *dentry,
+                           umode_t mode)
+{
+       return vboxsf_dir_create(parent, dentry, mode, 1);
+}
+
+static int vboxsf_dir_unlink(struct inode *parent, struct dentry *dentry)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
+       struct vboxsf_inode *sf_parent_i = VBOXSF_I(parent);
+       struct inode *inode = d_inode(dentry);
+       struct shfl_string *path;
+       u32 flags;
+       int err;
+
+       if (S_ISDIR(inode->i_mode))
+               flags = SHFL_REMOVE_DIR;
+       else
+               flags = SHFL_REMOVE_FILE;
+
+       if (S_ISLNK(inode->i_mode))
+               flags |= SHFL_REMOVE_SYMLINK;
+
+       path = vboxsf_path_from_dentry(sbi, dentry);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+
+       err = vboxsf_remove(sbi->root, path, flags);
+       __putname(path);
+       if (err)
+               return err;
+
+       /* parent directory access/change time changed */
+       sf_parent_i->force_restat = 1;
+
+       return 0;
+}
+
+static int vboxsf_dir_rename(struct inode *old_parent,
+                            struct dentry *old_dentry,
+                            struct inode *new_parent,
+                            struct dentry *new_dentry,
+                            unsigned int flags)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(old_parent->i_sb);
+       struct vboxsf_inode *sf_old_parent_i = VBOXSF_I(old_parent);
+       struct vboxsf_inode *sf_new_parent_i = VBOXSF_I(new_parent);
+       u32 shfl_flags = SHFL_RENAME_FILE | SHFL_RENAME_REPLACE_IF_EXISTS;
+       struct shfl_string *old_path, *new_path;
+       int err;
+
+       if (flags)
+               return -EINVAL;
+
+       old_path = vboxsf_path_from_dentry(sbi, old_dentry);
+       if (IS_ERR(old_path))
+               return PTR_ERR(old_path);
+
+       new_path = vboxsf_path_from_dentry(sbi, new_dentry);
+       if (IS_ERR(new_path)) {
+               err = PTR_ERR(new_path);
+               goto err_put_old_path;
+       }
+
+       if (d_inode(old_dentry)->i_mode & S_IFDIR)
+               shfl_flags = 0;
+
+       err = vboxsf_rename(sbi->root, old_path, new_path, shfl_flags);
+       if (err == 0) {
+               /* parent directories access/change time changed */
+               sf_new_parent_i->force_restat = 1;
+               sf_old_parent_i->force_restat = 1;
+       }
+
+       __putname(new_path);
+err_put_old_path:
+       __putname(old_path);
+       return err;
+}
+
+static int vboxsf_dir_symlink(struct inode *parent, struct dentry *dentry,
+                             const char *symname)
+{
+       struct vboxsf_inode *sf_parent_i = VBOXSF_I(parent);
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(parent->i_sb);
+       int symname_size = strlen(symname) + 1;
+       struct shfl_string *path, *ssymname;
+       struct shfl_fsobjinfo info;
+       int err;
+
+       path = vboxsf_path_from_dentry(sbi, dentry);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+
+       ssymname = kmalloc(SHFLSTRING_HEADER_SIZE + symname_size, GFP_KERNEL);
+       if (!ssymname) {
+               __putname(path);
+               return -ENOMEM;
+       }
+       ssymname->length = symname_size - 1;
+       ssymname->size = symname_size;
+       memcpy(ssymname->string.utf8, symname, symname_size);
+
+       err = vboxsf_symlink(sbi->root, path, ssymname, &info);
+       kfree(ssymname);
+       __putname(path);
+       if (err) {
+               /* -EROFS means symlinks are note support -> -EPERM */
+               return (err == -EROFS) ? -EPERM : err;
+       }
+
+       err = vboxsf_dir_instantiate(parent, dentry, &info);
+       if (err)
+               return err;
+
+       /* parent directory access/change time changed */
+       sf_parent_i->force_restat = 1;
+       return 0;
+}
+
+const struct inode_operations vboxsf_dir_iops = {
+       .lookup  = vboxsf_dir_lookup,
+       .create  = vboxsf_dir_mkfile,
+       .mkdir   = vboxsf_dir_mkdir,
+       .rmdir   = vboxsf_dir_unlink,
+       .unlink  = vboxsf_dir_unlink,
+       .rename  = vboxsf_dir_rename,
+       .symlink = vboxsf_dir_symlink,
+       .getattr = vboxsf_getattr,
+       .setattr = vboxsf_setattr,
+};
diff --git a/fs/vboxsf/file.c b/fs/vboxsf/file.c
new file mode 100644 (file)
index 0000000..c4ab599
--- /dev/null
@@ -0,0 +1,379 @@
+// SPDX-License-Identifier: MIT
+/*
+ * VirtualBox Guest Shared Folders support: Regular file inode and file ops.
+ *
+ * Copyright (C) 2006-2018 Oracle Corporation
+ */
+
+#include <linux/mm.h>
+#include <linux/page-flags.h>
+#include <linux/pagemap.h>
+#include <linux/highmem.h>
+#include <linux/sizes.h>
+#include "vfsmod.h"
+
+struct vboxsf_handle {
+       u64 handle;
+       u32 root;
+       u32 access_flags;
+       struct kref refcount;
+       struct list_head head;
+};
+
+static int vboxsf_file_open(struct inode *inode, struct file *file)
+{
+       struct vboxsf_inode *sf_i = VBOXSF_I(inode);
+       struct shfl_createparms params = {};
+       struct vboxsf_handle *sf_handle;
+       u32 access_flags = 0;
+       int err;
+
+       sf_handle = kmalloc(sizeof(*sf_handle), GFP_KERNEL);
+       if (!sf_handle)
+               return -ENOMEM;
+
+       /*
+        * We check the value of params.handle afterwards to find out if
+        * the call succeeded or failed, as the API does not seem to cleanly
+        * distinguish error and informational messages.
+        *
+        * Furthermore, we must set params.handle to SHFL_HANDLE_NIL to
+        * make the shared folders host service use our mode parameter.
+        */
+       params.handle = SHFL_HANDLE_NIL;
+       if (file->f_flags & O_CREAT) {
+               params.create_flags |= SHFL_CF_ACT_CREATE_IF_NEW;
+               /*
+                * We ignore O_EXCL, as the Linux kernel seems to call create
+                * beforehand itself, so O_EXCL should always fail.
+                */
+               if (file->f_flags & O_TRUNC)
+                       params.create_flags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
+               else
+                       params.create_flags |= SHFL_CF_ACT_OPEN_IF_EXISTS;
+       } else {
+               params.create_flags |= SHFL_CF_ACT_FAIL_IF_NEW;
+               if (file->f_flags & O_TRUNC)
+                       params.create_flags |= SHFL_CF_ACT_OVERWRITE_IF_EXISTS;
+       }
+
+       switch (file->f_flags & O_ACCMODE) {
+       case O_RDONLY:
+               access_flags |= SHFL_CF_ACCESS_READ;
+               break;
+
+       case O_WRONLY:
+               access_flags |= SHFL_CF_ACCESS_WRITE;
+               break;
+
+       case O_RDWR:
+               access_flags |= SHFL_CF_ACCESS_READWRITE;
+               break;
+
+       default:
+               WARN_ON(1);
+       }
+
+       if (file->f_flags & O_APPEND)
+               access_flags |= SHFL_CF_ACCESS_APPEND;
+
+       params.create_flags |= access_flags;
+       params.info.attr.mode = inode->i_mode;
+
+       err = vboxsf_create_at_dentry(file_dentry(file), &params);
+       if (err == 0 && params.handle == SHFL_HANDLE_NIL)
+               err = (params.result == SHFL_FILE_EXISTS) ? -EEXIST : -ENOENT;
+       if (err) {
+               kfree(sf_handle);
+               return err;
+       }
+
+       /* the host may have given us different attr then requested */
+       sf_i->force_restat = 1;
+
+       /* init our handle struct and add it to the inode's handles list */
+       sf_handle->handle = params.handle;
+       sf_handle->root = VBOXSF_SBI(inode->i_sb)->root;
+       sf_handle->access_flags = access_flags;
+       kref_init(&sf_handle->refcount);
+
+       mutex_lock(&sf_i->handle_list_mutex);
+       list_add(&sf_handle->head, &sf_i->handle_list);
+       mutex_unlock(&sf_i->handle_list_mutex);
+
+       file->private_data = sf_handle;
+       return 0;
+}
+
+static void vboxsf_handle_release(struct kref *refcount)
+{
+       struct vboxsf_handle *sf_handle =
+               container_of(refcount, struct vboxsf_handle, refcount);
+
+       vboxsf_close(sf_handle->root, sf_handle->handle);
+       kfree(sf_handle);
+}
+
+static int vboxsf_file_release(struct inode *inode, struct file *file)
+{
+       struct vboxsf_inode *sf_i = VBOXSF_I(inode);
+       struct vboxsf_handle *sf_handle = file->private_data;
+
+       /*
+        * When a file is closed on our (the guest) side, we want any subsequent
+        * accesses done on the host side to see all changes done from our side.
+        */
+       filemap_write_and_wait(inode->i_mapping);
+
+       mutex_lock(&sf_i->handle_list_mutex);
+       list_del(&sf_handle->head);
+       mutex_unlock(&sf_i->handle_list_mutex);
+
+       kref_put(&sf_handle->refcount, vboxsf_handle_release);
+       return 0;
+}
+
+/*
+ * Write back dirty pages now, because there may not be any suitable
+ * open files later
+ */
+static void vboxsf_vma_close(struct vm_area_struct *vma)
+{
+       filemap_write_and_wait(vma->vm_file->f_mapping);
+}
+
+static const struct vm_operations_struct vboxsf_file_vm_ops = {
+       .close          = vboxsf_vma_close,
+       .fault          = filemap_fault,
+       .map_pages      = filemap_map_pages,
+};
+
+static int vboxsf_file_mmap(struct file *file, struct vm_area_struct *vma)
+{
+       int err;
+
+       err = generic_file_mmap(file, vma);
+       if (!err)
+               vma->vm_ops = &vboxsf_file_vm_ops;
+
+       return err;
+}
+
+/*
+ * Note that since we are accessing files on the host's filesystem, files
+ * may always be changed underneath us by the host!
+ *
+ * The vboxsf API between the guest and the host does not offer any functions
+ * to deal with this. There is no inode-generation to check for changes, no
+ * events / callback on changes and no way to lock files.
+ *
+ * To avoid returning stale data when a file gets *opened* on our (the guest)
+ * side, we do a "stat" on the host side, then compare the mtime with the
+ * last known mtime and invalidate the page-cache if they differ.
+ * This is done from vboxsf_inode_revalidate().
+ *
+ * When reads are done through the read_iter fop, it is possible to do
+ * further cache revalidation then, there are 3 options to deal with this:
+ *
+ * 1)  Rely solely on the revalidation done at open time
+ * 2)  Do another "stat" and compare mtime again. Unfortunately the vboxsf
+ *     host API does not allow stat on handles, so we would need to use
+ *     file->f_path.dentry and the stat will then fail if the file was unlinked
+ *     or renamed (and there is no thing like NFS' silly-rename). So we get:
+ * 2a) "stat" and compare mtime, on stat failure invalidate the cache
+ * 2b) "stat" and compare mtime, on stat failure do nothing
+ * 3)  Simply always call invalidate_inode_pages2_range on the range of the read
+ *
+ * Currently we are keeping things KISS and using option 1. this allows
+ * directly using generic_file_read_iter without wrapping it.
+ *
+ * This means that only data written on the host side before open() on
+ * the guest side is guaranteed to be seen by the guest. If necessary
+ * we may provide other read-cache strategies in the future and make this
+ * configurable through a mount option.
+ */
+const struct file_operations vboxsf_reg_fops = {
+       .llseek = generic_file_llseek,
+       .read_iter = generic_file_read_iter,
+       .write_iter = generic_file_write_iter,
+       .mmap = vboxsf_file_mmap,
+       .open = vboxsf_file_open,
+       .release = vboxsf_file_release,
+       .fsync = noop_fsync,
+       .splice_read = generic_file_splice_read,
+};
+
+const struct inode_operations vboxsf_reg_iops = {
+       .getattr = vboxsf_getattr,
+       .setattr = vboxsf_setattr
+};
+
+static int vboxsf_readpage(struct file *file, struct page *page)
+{
+       struct vboxsf_handle *sf_handle = file->private_data;
+       loff_t off = page_offset(page);
+       u32 nread = PAGE_SIZE;
+       u8 *buf;
+       int err;
+
+       buf = kmap(page);
+
+       err = vboxsf_read(sf_handle->root, sf_handle->handle, off, &nread, buf);
+       if (err == 0) {
+               memset(&buf[nread], 0, PAGE_SIZE - nread);
+               flush_dcache_page(page);
+               SetPageUptodate(page);
+       } else {
+               SetPageError(page);
+       }
+
+       kunmap(page);
+       unlock_page(page);
+       return err;
+}
+
+static struct vboxsf_handle *vboxsf_get_write_handle(struct vboxsf_inode *sf_i)
+{
+       struct vboxsf_handle *h, *sf_handle = NULL;
+
+       mutex_lock(&sf_i->handle_list_mutex);
+       list_for_each_entry(h, &sf_i->handle_list, head) {
+               if (h->access_flags == SHFL_CF_ACCESS_WRITE ||
+                   h->access_flags == SHFL_CF_ACCESS_READWRITE) {
+                       kref_get(&h->refcount);
+                       sf_handle = h;
+                       break;
+               }
+       }
+       mutex_unlock(&sf_i->handle_list_mutex);
+
+       return sf_handle;
+}
+
+static int vboxsf_writepage(struct page *page, struct writeback_control *wbc)
+{
+       struct inode *inode = page->mapping->host;
+       struct vboxsf_inode *sf_i = VBOXSF_I(inode);
+       struct vboxsf_handle *sf_handle;
+       loff_t off = page_offset(page);
+       loff_t size = i_size_read(inode);
+       u32 nwrite = PAGE_SIZE;
+       u8 *buf;
+       int err;
+
+       if (off + PAGE_SIZE > size)
+               nwrite = size & ~PAGE_MASK;
+
+       sf_handle = vboxsf_get_write_handle(sf_i);
+       if (!sf_handle)
+               return -EBADF;
+
+       buf = kmap(page);
+       err = vboxsf_write(sf_handle->root, sf_handle->handle,
+                          off, &nwrite, buf);
+       kunmap(page);
+
+       kref_put(&sf_handle->refcount, vboxsf_handle_release);
+
+       if (err == 0) {
+               ClearPageError(page);
+               /* mtime changed */
+               sf_i->force_restat = 1;
+       } else {
+               ClearPageUptodate(page);
+       }
+
+       unlock_page(page);
+       return err;
+}
+
+static int vboxsf_write_end(struct file *file, struct address_space *mapping,
+                           loff_t pos, unsigned int len, unsigned int copied,
+                           struct page *page, void *fsdata)
+{
+       struct inode *inode = mapping->host;
+       struct vboxsf_handle *sf_handle = file->private_data;
+       unsigned int from = pos & ~PAGE_MASK;
+       u32 nwritten = len;
+       u8 *buf;
+       int err;
+
+       /* zero the stale part of the page if we did a short copy */
+       if (!PageUptodate(page) && copied < len)
+               zero_user(page, from + copied, len - copied);
+
+       buf = kmap(page);
+       err = vboxsf_write(sf_handle->root, sf_handle->handle,
+                          pos, &nwritten, buf + from);
+       kunmap(page);
+
+       if (err) {
+               nwritten = 0;
+               goto out;
+       }
+
+       /* mtime changed */
+       VBOXSF_I(inode)->force_restat = 1;
+
+       if (!PageUptodate(page) && nwritten == PAGE_SIZE)
+               SetPageUptodate(page);
+
+       pos += nwritten;
+       if (pos > inode->i_size)
+               i_size_write(inode, pos);
+
+out:
+       unlock_page(page);
+       put_page(page);
+
+       return nwritten;
+}
+
+/*
+ * Note simple_write_begin does not read the page from disk on partial writes
+ * this is ok since vboxsf_write_end only writes the written parts of the
+ * page and it does not call SetPageUptodate for partial writes.
+ */
+const struct address_space_operations vboxsf_reg_aops = {
+       .readpage = vboxsf_readpage,
+       .writepage = vboxsf_writepage,
+       .set_page_dirty = __set_page_dirty_nobuffers,
+       .write_begin = simple_write_begin,
+       .write_end = vboxsf_write_end,
+};
+
+static const char *vboxsf_get_link(struct dentry *dentry, struct inode *inode,
+                                  struct delayed_call *done)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
+       struct shfl_string *path;
+       char *link;
+       int err;
+
+       if (!dentry)
+               return ERR_PTR(-ECHILD);
+
+       path = vboxsf_path_from_dentry(sbi, dentry);
+       if (IS_ERR(path))
+               return ERR_CAST(path);
+
+       link = kzalloc(PATH_MAX, GFP_KERNEL);
+       if (!link) {
+               __putname(path);
+               return ERR_PTR(-ENOMEM);
+       }
+
+       err = vboxsf_readlink(sbi->root, path, PATH_MAX, link);
+       __putname(path);
+       if (err) {
+               kfree(link);
+               return ERR_PTR(err);
+       }
+
+       set_delayed_call(done, kfree_link, link);
+       return link;
+}
+
+const struct inode_operations vboxsf_lnk_iops = {
+       .get_link = vboxsf_get_link
+};
diff --git a/fs/vboxsf/shfl_hostintf.h b/fs/vboxsf/shfl_hostintf.h
new file mode 100644 (file)
index 0000000..aca8290
--- /dev/null
@@ -0,0 +1,901 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * VirtualBox Shared Folders: host interface definition.
+ *
+ * Copyright (C) 2006-2018 Oracle Corporation
+ */
+
+#ifndef SHFL_HOSTINTF_H
+#define SHFL_HOSTINTF_H
+
+#include <linux/vbox_vmmdev_types.h>
+
+/* The max in/out buffer size for a FN_READ or FN_WRITE call */
+#define SHFL_MAX_RW_COUNT           (16 * SZ_1M)
+
+/*
+ * Structures shared between guest and the service
+ * can be relocated and use offsets to point to variable
+ * length parts.
+ *
+ * Shared folders protocol works with handles.
+ * Before doing any action on a file system object,
+ * one have to obtain the object handle via a SHFL_FN_CREATE
+ * request. A handle must be closed with SHFL_FN_CLOSE.
+ */
+
+enum {
+       SHFL_FN_QUERY_MAPPINGS = 1,     /* Query mappings changes. */
+       SHFL_FN_QUERY_MAP_NAME = 2,     /* Query map name. */
+       SHFL_FN_CREATE = 3,             /* Open/create object. */
+       SHFL_FN_CLOSE = 4,              /* Close object handle. */
+       SHFL_FN_READ = 5,               /* Read object content. */
+       SHFL_FN_WRITE = 6,              /* Write new object content. */
+       SHFL_FN_LOCK = 7,               /* Lock/unlock a range in the object. */
+       SHFL_FN_LIST = 8,               /* List object content. */
+       SHFL_FN_INFORMATION = 9,        /* Query/set object information. */
+       /* Note function number 10 is not used! */
+       SHFL_FN_REMOVE = 11,            /* Remove object */
+       SHFL_FN_MAP_FOLDER_OLD = 12,    /* Map folder (legacy) */
+       SHFL_FN_UNMAP_FOLDER = 13,      /* Unmap folder */
+       SHFL_FN_RENAME = 14,            /* Rename object */
+       SHFL_FN_FLUSH = 15,             /* Flush file */
+       SHFL_FN_SET_UTF8 = 16,          /* Select UTF8 filename encoding */
+       SHFL_FN_MAP_FOLDER = 17,        /* Map folder */
+       SHFL_FN_READLINK = 18,          /* Read symlink dest (as of VBox 4.0) */
+       SHFL_FN_SYMLINK = 19,           /* Create symlink (as of VBox 4.0) */
+       SHFL_FN_SET_SYMLINKS = 20,      /* Ask host to show symlinks (4.0+) */
+};
+
+/* Root handles for a mapping are of type u32, Root handles are unique. */
+#define SHFL_ROOT_NIL          UINT_MAX
+
+/* Shared folders handle for an opened object are of type u64. */
+#define SHFL_HANDLE_NIL                ULLONG_MAX
+
+/* Hardcoded maximum length (in chars) of a shared folder name. */
+#define SHFL_MAX_LEN         (256)
+/* Hardcoded maximum number of shared folder mapping available to the guest. */
+#define SHFL_MAX_MAPPINGS    (64)
+
+/** Shared folder string buffer structure. */
+struct shfl_string {
+       /** Allocated size of the string member in bytes. */
+       u16 size;
+
+       /** Length of string without trailing nul in bytes. */
+       u16 length;
+
+       /** UTF-8 or UTF-16 string. Nul terminated. */
+       union {
+               u8 utf8[2];
+               u16 utf16[1];
+               u16 ucs2[1]; /* misnomer, use utf16. */
+       } string;
+};
+VMMDEV_ASSERT_SIZE(shfl_string, 6);
+
+/* The size of shfl_string w/o the string part. */
+#define SHFLSTRING_HEADER_SIZE  4
+
+/* Calculate size of the string. */
+static inline u32 shfl_string_buf_size(const struct shfl_string *string)
+{
+       return string ? SHFLSTRING_HEADER_SIZE + string->size : 0;
+}
+
+/* Set user id on execution (S_ISUID). */
+#define SHFL_UNIX_ISUID             0004000U
+/* Set group id on execution (S_ISGID). */
+#define SHFL_UNIX_ISGID             0002000U
+/* Sticky bit (S_ISVTX / S_ISTXT). */
+#define SHFL_UNIX_ISTXT             0001000U
+
+/* Owner readable (S_IRUSR). */
+#define SHFL_UNIX_IRUSR             0000400U
+/* Owner writable (S_IWUSR). */
+#define SHFL_UNIX_IWUSR             0000200U
+/* Owner executable (S_IXUSR). */
+#define SHFL_UNIX_IXUSR             0000100U
+
+/* Group readable (S_IRGRP). */
+#define SHFL_UNIX_IRGRP             0000040U
+/* Group writable (S_IWGRP). */
+#define SHFL_UNIX_IWGRP             0000020U
+/* Group executable (S_IXGRP). */
+#define SHFL_UNIX_IXGRP             0000010U
+
+/* Other readable (S_IROTH). */
+#define SHFL_UNIX_IROTH             0000004U
+/* Other writable (S_IWOTH). */
+#define SHFL_UNIX_IWOTH             0000002U
+/* Other executable (S_IXOTH). */
+#define SHFL_UNIX_IXOTH             0000001U
+
+/* Named pipe (fifo) (S_IFIFO). */
+#define SHFL_TYPE_FIFO              0010000U
+/* Character device (S_IFCHR). */
+#define SHFL_TYPE_DEV_CHAR          0020000U
+/* Directory (S_IFDIR). */
+#define SHFL_TYPE_DIRECTORY         0040000U
+/* Block device (S_IFBLK). */
+#define SHFL_TYPE_DEV_BLOCK         0060000U
+/* Regular file (S_IFREG). */
+#define SHFL_TYPE_FILE              0100000U
+/* Symbolic link (S_IFLNK). */
+#define SHFL_TYPE_SYMLINK           0120000U
+/* Socket (S_IFSOCK). */
+#define SHFL_TYPE_SOCKET            0140000U
+/* Whiteout (S_IFWHT). */
+#define SHFL_TYPE_WHITEOUT          0160000U
+/* Type mask (S_IFMT). */
+#define SHFL_TYPE_MASK              0170000U
+
+/* Checks the mode flags indicate a directory (S_ISDIR). */
+#define SHFL_IS_DIRECTORY(m)   (((m) & SHFL_TYPE_MASK) == SHFL_TYPE_DIRECTORY)
+/* Checks the mode flags indicate a symbolic link (S_ISLNK). */
+#define SHFL_IS_SYMLINK(m)     (((m) & SHFL_TYPE_MASK) == SHFL_TYPE_SYMLINK)
+
+/** The available additional information in a shfl_fsobjattr object. */
+enum shfl_fsobjattr_add {
+       /** No additional information is available / requested. */
+       SHFLFSOBJATTRADD_NOTHING = 1,
+       /**
+        * The additional unix attributes (shfl_fsobjattr::u::unix_attr) are
+        *  available / requested.
+        */
+       SHFLFSOBJATTRADD_UNIX,
+       /**
+        * The additional extended attribute size (shfl_fsobjattr::u::size) is
+        *  available / requested.
+        */
+       SHFLFSOBJATTRADD_EASIZE,
+       /**
+        * The last valid item (inclusive).
+        * The valid range is SHFLFSOBJATTRADD_NOTHING thru
+        * SHFLFSOBJATTRADD_LAST.
+        */
+       SHFLFSOBJATTRADD_LAST = SHFLFSOBJATTRADD_EASIZE,
+
+       /** The usual 32-bit hack. */
+       SHFLFSOBJATTRADD_32BIT_SIZE_HACK = 0x7fffffff
+};
+
+/**
+ * Additional unix Attributes, these are available when
+ * shfl_fsobjattr.additional == SHFLFSOBJATTRADD_UNIX.
+ */
+struct shfl_fsobjattr_unix {
+       /**
+        * The user owning the filesystem object (st_uid).
+        * This field is ~0U if not supported.
+        */
+       u32 uid;
+
+       /**
+        * The group the filesystem object is assigned (st_gid).
+        * This field is ~0U if not supported.
+        */
+       u32 gid;
+
+       /**
+        * Number of hard links to this filesystem object (st_nlink).
+        * This field is 1 if the filesystem doesn't support hardlinking or
+        * the information isn't available.
+        */
+       u32 hardlinks;
+
+       /**
+        * The device number of the device which this filesystem object resides
+        * on (st_dev). This field is 0 if this information is not available.
+        */
+       u32 inode_id_device;
+
+       /**
+        * The unique identifier (within the filesystem) of this filesystem
+        * object (st_ino). Together with inode_id_device, this field can be
+        * used as a OS wide unique id, when both their values are not 0.
+        * This field is 0 if the information is not available.
+        */
+       u64 inode_id;
+
+       /**
+        * User flags (st_flags).
+        * This field is 0 if this information is not available.
+        */
+       u32 flags;
+
+       /**
+        * The current generation number (st_gen).
+        * This field is 0 if this information is not available.
+        */
+       u32 generation_id;
+
+       /**
+        * The device number of a char. or block device type object (st_rdev).
+        * This field is 0 if the file isn't a char. or block device or when
+        * the OS doesn't use the major+minor device idenfication scheme.
+        */
+       u32 device;
+} __packed;
+
+/** Extended attribute size. */
+struct shfl_fsobjattr_easize {
+       /** Size of EAs. */
+       s64 cb;
+} __packed;
+
+/** Shared folder filesystem object attributes. */
+struct shfl_fsobjattr {
+       /** Mode flags (st_mode). SHFL_UNIX_*, SHFL_TYPE_*, and SHFL_DOS_*. */
+       u32 mode;
+
+       /** The additional attributes available. */
+       enum shfl_fsobjattr_add additional;
+
+       /**
+        * Additional attributes.
+        *
+        * Unless explicitly specified to an API, the API can provide additional
+        * data as it is provided by the underlying OS.
+        */
+       union {
+               struct shfl_fsobjattr_unix unix_attr;
+               struct shfl_fsobjattr_easize size;
+       } __packed u;
+} __packed;
+VMMDEV_ASSERT_SIZE(shfl_fsobjattr, 44);
+
+struct shfl_timespec {
+       s64 ns_relative_to_unix_epoch;
+};
+
+/** Filesystem object information structure. */
+struct shfl_fsobjinfo {
+       /**
+        * Logical size (st_size).
+        * For normal files this is the size of the file.
+        * For symbolic links, this is the length of the path name contained
+        * in the symbolic link.
+        * For other objects this fields needs to be specified.
+        */
+       s64 size;
+
+       /** Disk allocation size (st_blocks * DEV_BSIZE). */
+       s64 allocated;
+
+       /** Time of last access (st_atime). */
+       struct shfl_timespec access_time;
+
+       /** Time of last data modification (st_mtime). */
+       struct shfl_timespec modification_time;
+
+       /**
+        * Time of last status change (st_ctime).
+        * If not available this is set to modification_time.
+        */
+       struct shfl_timespec change_time;
+
+       /**
+        * Time of file birth (st_birthtime).
+        * If not available this is set to change_time.
+        */
+       struct shfl_timespec birth_time;
+
+       /** Attributes. */
+       struct shfl_fsobjattr attr;
+
+} __packed;
+VMMDEV_ASSERT_SIZE(shfl_fsobjinfo, 92);
+
+/**
+ * result of an open/create request.
+ * Along with handle value the result code
+ * identifies what has happened while
+ * trying to open the object.
+ */
+enum shfl_create_result {
+       SHFL_NO_RESULT,
+       /** Specified path does not exist. */
+       SHFL_PATH_NOT_FOUND,
+       /** Path to file exists, but the last component does not. */
+       SHFL_FILE_NOT_FOUND,
+       /** File already exists and either has been opened or not. */
+       SHFL_FILE_EXISTS,
+       /** New file was created. */
+       SHFL_FILE_CREATED,
+       /** Existing file was replaced or overwritten. */
+       SHFL_FILE_REPLACED
+};
+
+/* No flags. Initialization value. */
+#define SHFL_CF_NONE                  (0x00000000)
+
+/*
+ * Only lookup the object, do not return a handle. When this is set all other
+ * flags are ignored.
+ */
+#define SHFL_CF_LOOKUP                (0x00000001)
+
+/*
+ * Open parent directory of specified object.
+ * Useful for the corresponding Windows FSD flag
+ * and for opening paths like \\dir\\*.* to search the 'dir'.
+ */
+#define SHFL_CF_OPEN_TARGET_DIRECTORY (0x00000002)
+
+/* Create/open a directory. */
+#define SHFL_CF_DIRECTORY             (0x00000004)
+
+/*
+ *  Open/create action to do if object exists
+ *  and if the object does not exists.
+ *  REPLACE file means atomically DELETE and CREATE.
+ *  OVERWRITE file means truncating the file to 0 and
+ *  setting new size.
+ *  When opening an existing directory REPLACE and OVERWRITE
+ *  actions are considered invalid, and cause returning
+ *  FILE_EXISTS with NIL handle.
+ */
+#define SHFL_CF_ACT_MASK_IF_EXISTS      (0x000000f0)
+#define SHFL_CF_ACT_MASK_IF_NEW         (0x00000f00)
+
+/* What to do if object exists. */
+#define SHFL_CF_ACT_OPEN_IF_EXISTS      (0x00000000)
+#define SHFL_CF_ACT_FAIL_IF_EXISTS      (0x00000010)
+#define SHFL_CF_ACT_REPLACE_IF_EXISTS   (0x00000020)
+#define SHFL_CF_ACT_OVERWRITE_IF_EXISTS (0x00000030)
+
+/* What to do if object does not exist. */
+#define SHFL_CF_ACT_CREATE_IF_NEW       (0x00000000)
+#define SHFL_CF_ACT_FAIL_IF_NEW         (0x00000100)
+
+/* Read/write requested access for the object. */
+#define SHFL_CF_ACCESS_MASK_RW          (0x00003000)
+
+/* No access requested. */
+#define SHFL_CF_ACCESS_NONE             (0x00000000)
+/* Read access requested. */
+#define SHFL_CF_ACCESS_READ             (0x00001000)
+/* Write access requested. */
+#define SHFL_CF_ACCESS_WRITE            (0x00002000)
+/* Read/Write access requested. */
+#define SHFL_CF_ACCESS_READWRITE       (0x00003000)
+
+/* Requested share access for the object. */
+#define SHFL_CF_ACCESS_MASK_DENY        (0x0000c000)
+
+/* Allow any access. */
+#define SHFL_CF_ACCESS_DENYNONE         (0x00000000)
+/* Do not allow read. */
+#define SHFL_CF_ACCESS_DENYREAD         (0x00004000)
+/* Do not allow write. */
+#define SHFL_CF_ACCESS_DENYWRITE        (0x00008000)
+/* Do not allow access. */
+#define SHFL_CF_ACCESS_DENYALL          (0x0000c000)
+
+/* Requested access to attributes of the object. */
+#define SHFL_CF_ACCESS_MASK_ATTR        (0x00030000)
+
+/* No access requested. */
+#define SHFL_CF_ACCESS_ATTR_NONE        (0x00000000)
+/* Read access requested. */
+#define SHFL_CF_ACCESS_ATTR_READ        (0x00010000)
+/* Write access requested. */
+#define SHFL_CF_ACCESS_ATTR_WRITE       (0x00020000)
+/* Read/Write access requested. */
+#define SHFL_CF_ACCESS_ATTR_READWRITE   (0x00030000)
+
+/*
+ * The file is opened in append mode.
+ * Ignored if SHFL_CF_ACCESS_WRITE is not set.
+ */
+#define SHFL_CF_ACCESS_APPEND           (0x00040000)
+
+/** Create parameters buffer struct for SHFL_FN_CREATE call */
+struct shfl_createparms {
+       /** Returned handle of opened object. */
+       u64 handle;
+
+       /** Returned result of the operation */
+       enum shfl_create_result result;
+
+       /** SHFL_CF_* */
+       u32 create_flags;
+
+       /**
+        * Attributes of object to create and
+        * returned actual attributes of opened/created object.
+        */
+       struct shfl_fsobjinfo info;
+} __packed;
+
+/** Shared Folder directory information */
+struct shfl_dirinfo {
+       /** Full information about the object. */
+       struct shfl_fsobjinfo info;
+       /**
+        * The length of the short field (number of UTF16 chars).
+        * It is 16-bit for reasons of alignment.
+        */
+       u16 short_name_len;
+       /**
+        * The short name for 8.3 compatibility.
+        * Empty string if not available.
+        */
+       u16 short_name[14];
+       struct shfl_string name;
+};
+
+/** Shared folder filesystem properties. */
+struct shfl_fsproperties {
+       /**
+        * The maximum size of a filesystem object name.
+        * This does not include the '\\0'.
+        */
+       u32 max_component_len;
+
+       /**
+        * True if the filesystem is remote.
+        * False if the filesystem is local.
+        */
+       bool remote;
+
+       /**
+        * True if the filesystem is case sensitive.
+        * False if the filesystem is case insensitive.
+        */
+       bool case_sensitive;
+
+       /**
+        * True if the filesystem is mounted read only.
+        * False if the filesystem is mounted read write.
+        */
+       bool read_only;
+
+       /**
+        * True if the filesystem can encode unicode object names.
+        * False if it can't.
+        */
+       bool supports_unicode;
+
+       /**
+        * True if the filesystem is compresses.
+        * False if it isn't or we don't know.
+        */
+       bool compressed;
+
+       /**
+        * True if the filesystem compresses of individual files.
+        * False if it doesn't or we don't know.
+        */
+       bool file_compression;
+};
+VMMDEV_ASSERT_SIZE(shfl_fsproperties, 12);
+
+struct shfl_volinfo {
+       s64 total_allocation_bytes;
+       s64 available_allocation_bytes;
+       u32 bytes_per_allocation_unit;
+       u32 bytes_per_sector;
+       u32 serial;
+       struct shfl_fsproperties properties;
+};
+
+
+/** SHFL_FN_MAP_FOLDER Parameters structure. */
+struct shfl_map_folder {
+       /**
+        * pointer, in:
+        * Points to struct shfl_string buffer.
+        */
+       struct vmmdev_hgcm_function_parameter path;
+
+       /**
+        * pointer, out: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * pointer, in: UTF16
+        * Path delimiter
+        */
+       struct vmmdev_hgcm_function_parameter delimiter;
+
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Case senstive flag
+        */
+       struct vmmdev_hgcm_function_parameter case_sensitive;
+
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_MAP_FOLDER (4)
+
+
+/** SHFL_FN_UNMAP_FOLDER Parameters structure. */
+struct shfl_unmap_folder {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_UNMAP_FOLDER (1)
+
+
+/** SHFL_FN_CREATE Parameters structure. */
+struct shfl_create {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * pointer, in:
+        * Points to struct shfl_string buffer.
+        */
+       struct vmmdev_hgcm_function_parameter path;
+
+       /**
+        * pointer, in/out:
+        * Points to struct shfl_createparms buffer.
+        */
+       struct vmmdev_hgcm_function_parameter parms;
+
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_CREATE (3)
+
+
+/** SHFL_FN_CLOSE Parameters structure. */
+struct shfl_close {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * value64, in:
+        * SHFLHANDLE (u64) of object to close.
+        */
+       struct vmmdev_hgcm_function_parameter handle;
+
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_CLOSE (2)
+
+
+/** SHFL_FN_READ Parameters structure. */
+struct shfl_read {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * value64, in:
+        * SHFLHANDLE (u64) of object to read from.
+        */
+       struct vmmdev_hgcm_function_parameter handle;
+
+       /**
+        * value64, in:
+        * Offset to read from.
+        */
+       struct vmmdev_hgcm_function_parameter offset;
+
+       /**
+        * value64, in/out:
+        * Bytes to read/How many were read.
+        */
+       struct vmmdev_hgcm_function_parameter cb;
+
+       /**
+        * pointer, out:
+        * Buffer to place data to.
+        */
+       struct vmmdev_hgcm_function_parameter buffer;
+
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_READ (5)
+
+
+/** SHFL_FN_WRITE Parameters structure. */
+struct shfl_write {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * value64, in:
+        * SHFLHANDLE (u64) of object to write to.
+        */
+       struct vmmdev_hgcm_function_parameter handle;
+
+       /**
+        * value64, in:
+        * Offset to write to.
+        */
+       struct vmmdev_hgcm_function_parameter offset;
+
+       /**
+        * value64, in/out:
+        * Bytes to write/How many were written.
+        */
+       struct vmmdev_hgcm_function_parameter cb;
+
+       /**
+        * pointer, in:
+        * Data to write.
+        */
+       struct vmmdev_hgcm_function_parameter buffer;
+
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_WRITE (5)
+
+
+/*
+ * SHFL_FN_LIST
+ * Listing information includes variable length RTDIRENTRY[EX] structures.
+ */
+
+#define SHFL_LIST_NONE                 0
+#define SHFL_LIST_RETURN_ONE           1
+
+/** SHFL_FN_LIST Parameters structure. */
+struct shfl_list {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * value64, in:
+        * SHFLHANDLE (u64) of object to be listed.
+        */
+       struct vmmdev_hgcm_function_parameter handle;
+
+       /**
+        * value32, in:
+        * List flags SHFL_LIST_*.
+        */
+       struct vmmdev_hgcm_function_parameter flags;
+
+       /**
+        * value32, in/out:
+        * Bytes to be used for listing information/How many bytes were used.
+        */
+       struct vmmdev_hgcm_function_parameter cb;
+
+       /**
+        * pointer, in/optional
+        * Points to struct shfl_string buffer that specifies a search path.
+        */
+       struct vmmdev_hgcm_function_parameter path;
+
+       /**
+        * pointer, out:
+        * Buffer to place listing information to. (struct shfl_dirinfo)
+        */
+       struct vmmdev_hgcm_function_parameter buffer;
+
+       /**
+        * value32, in/out:
+        * Indicates a key where the listing must be resumed.
+        * in: 0 means start from begin of object.
+        * out: 0 means listing completed.
+        */
+       struct vmmdev_hgcm_function_parameter resume_point;
+
+       /**
+        * pointer, out:
+        * Number of files returned
+        */
+       struct vmmdev_hgcm_function_parameter file_count;
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_LIST (8)
+
+
+/** SHFL_FN_READLINK Parameters structure. */
+struct shfl_readLink {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * pointer, in:
+        * Points to struct shfl_string buffer.
+        */
+       struct vmmdev_hgcm_function_parameter path;
+
+       /**
+        * pointer, out:
+        * Buffer to place data to.
+        */
+       struct vmmdev_hgcm_function_parameter buffer;
+
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_READLINK (3)
+
+
+/* SHFL_FN_INFORMATION */
+
+/* Mask of Set/Get bit. */
+#define SHFL_INFO_MODE_MASK    (0x1)
+/* Get information */
+#define SHFL_INFO_GET          (0x0)
+/* Set information */
+#define SHFL_INFO_SET          (0x1)
+
+/* Get name of the object. */
+#define SHFL_INFO_NAME         (0x2)
+/* Set size of object (extend/trucate); only applies to file objects */
+#define SHFL_INFO_SIZE         (0x4)
+/* Get/Set file object info. */
+#define SHFL_INFO_FILE         (0x8)
+/* Get volume information. */
+#define SHFL_INFO_VOLUME       (0x10)
+
+/** SHFL_FN_INFORMATION Parameters structure. */
+struct shfl_information {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * value64, in:
+        * SHFLHANDLE (u64) of object to be listed.
+        */
+       struct vmmdev_hgcm_function_parameter handle;
+
+       /**
+        * value32, in:
+        * SHFL_INFO_*
+        */
+       struct vmmdev_hgcm_function_parameter flags;
+
+       /**
+        * value32, in/out:
+        * Bytes to be used for information/How many bytes were used.
+        */
+       struct vmmdev_hgcm_function_parameter cb;
+
+       /**
+        * pointer, in/out:
+        * Information to be set/get (shfl_fsobjinfo or shfl_string). Do not
+        * forget to set the shfl_fsobjinfo::attr::additional for a get
+        * operation as well.
+        */
+       struct vmmdev_hgcm_function_parameter info;
+
+};
+
+/* Number of parameters */
+#define SHFL_CPARMS_INFORMATION (5)
+
+
+/* SHFL_FN_REMOVE */
+
+#define SHFL_REMOVE_FILE        (0x1)
+#define SHFL_REMOVE_DIR         (0x2)
+#define SHFL_REMOVE_SYMLINK     (0x4)
+
+/** SHFL_FN_REMOVE Parameters structure. */
+struct shfl_remove {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * pointer, in:
+        * Points to struct shfl_string buffer.
+        */
+       struct vmmdev_hgcm_function_parameter path;
+
+       /**
+        * value32, in:
+        * remove flags (file/directory)
+        */
+       struct vmmdev_hgcm_function_parameter flags;
+
+};
+
+#define SHFL_CPARMS_REMOVE  (3)
+
+
+/* SHFL_FN_RENAME */
+
+#define SHFL_RENAME_FILE                (0x1)
+#define SHFL_RENAME_DIR                 (0x2)
+#define SHFL_RENAME_REPLACE_IF_EXISTS   (0x4)
+
+/** SHFL_FN_RENAME Parameters structure. */
+struct shfl_rename {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * pointer, in:
+        * Points to struct shfl_string src.
+        */
+       struct vmmdev_hgcm_function_parameter src;
+
+       /**
+        * pointer, in:
+        * Points to struct shfl_string dest.
+        */
+       struct vmmdev_hgcm_function_parameter dest;
+
+       /**
+        * value32, in:
+        * rename flags (file/directory)
+        */
+       struct vmmdev_hgcm_function_parameter flags;
+
+};
+
+#define SHFL_CPARMS_RENAME  (4)
+
+
+/** SHFL_FN_SYMLINK Parameters structure. */
+struct shfl_symlink {
+       /**
+        * pointer, in: SHFLROOT (u32)
+        * Root handle of the mapping which name is queried.
+        */
+       struct vmmdev_hgcm_function_parameter root;
+
+       /**
+        * pointer, in:
+        * Points to struct shfl_string of path for the new symlink.
+        */
+       struct vmmdev_hgcm_function_parameter new_path;
+
+       /**
+        * pointer, in:
+        * Points to struct shfl_string of destination for symlink.
+        */
+       struct vmmdev_hgcm_function_parameter old_path;
+
+       /**
+        * pointer, out:
+        * Information about created symlink.
+        */
+       struct vmmdev_hgcm_function_parameter info;
+
+};
+
+#define SHFL_CPARMS_SYMLINK  (4)
+
+#endif
diff --git a/fs/vboxsf/super.c b/fs/vboxsf/super.c
new file mode 100644 (file)
index 0000000..675e269
--- /dev/null
@@ -0,0 +1,491 @@
+// SPDX-License-Identifier: MIT
+/*
+ * VirtualBox Guest Shared Folders support: Virtual File System.
+ *
+ * Module initialization/finalization
+ * File system registration/deregistration
+ * Superblock reading
+ * Few utility functions
+ *
+ * Copyright (C) 2006-2018 Oracle Corporation
+ */
+
+#include <linux/idr.h>
+#include <linux/fs_parser.h>
+#include <linux/magic.h>
+#include <linux/module.h>
+#include <linux/nls.h>
+#include <linux/statfs.h>
+#include <linux/vbox_utils.h>
+#include "vfsmod.h"
+
+#define VBOXSF_SUPER_MAGIC 0x786f4256 /* 'VBox' little endian */
+
+#define VBSF_MOUNT_SIGNATURE_BYTE_0 ('\000')
+#define VBSF_MOUNT_SIGNATURE_BYTE_1 ('\377')
+#define VBSF_MOUNT_SIGNATURE_BYTE_2 ('\376')
+#define VBSF_MOUNT_SIGNATURE_BYTE_3 ('\375')
+
+static int follow_symlinks;
+module_param(follow_symlinks, int, 0444);
+MODULE_PARM_DESC(follow_symlinks,
+                "Let host resolve symlinks rather than showing them");
+
+static DEFINE_IDA(vboxsf_bdi_ida);
+static DEFINE_MUTEX(vboxsf_setup_mutex);
+static bool vboxsf_setup_done;
+static struct super_operations vboxsf_super_ops; /* forward declaration */
+static struct kmem_cache *vboxsf_inode_cachep;
+
+static char * const vboxsf_default_nls = CONFIG_NLS_DEFAULT;
+
+enum  { opt_nls, opt_uid, opt_gid, opt_ttl, opt_dmode, opt_fmode,
+       opt_dmask, opt_fmask };
+
+static const struct fs_parameter_spec vboxsf_fs_parameters[] = {
+       fsparam_string  ("nls",         opt_nls),
+       fsparam_u32     ("uid",         opt_uid),
+       fsparam_u32     ("gid",         opt_gid),
+       fsparam_u32     ("ttl",         opt_ttl),
+       fsparam_u32oct  ("dmode",       opt_dmode),
+       fsparam_u32oct  ("fmode",       opt_fmode),
+       fsparam_u32oct  ("dmask",       opt_dmask),
+       fsparam_u32oct  ("fmask",       opt_fmask),
+       {}
+};
+
+static int vboxsf_parse_param(struct fs_context *fc, struct fs_parameter *param)
+{
+       struct vboxsf_fs_context *ctx = fc->fs_private;
+       struct fs_parse_result result;
+       kuid_t uid;
+       kgid_t gid;
+       int opt;
+
+       opt = fs_parse(fc, vboxsf_fs_parameters, param, &result);
+       if (opt < 0)
+               return opt;
+
+       switch (opt) {
+       case opt_nls:
+               if (ctx->nls_name || fc->purpose != FS_CONTEXT_FOR_MOUNT) {
+                       vbg_err("vboxsf: Cannot reconfigure nls option\n");
+                       return -EINVAL;
+               }
+               ctx->nls_name = param->string;
+               param->string = NULL;
+               break;
+       case opt_uid:
+               uid = make_kuid(current_user_ns(), result.uint_32);
+               if (!uid_valid(uid))
+                       return -EINVAL;
+               ctx->o.uid = uid;
+               break;
+       case opt_gid:
+               gid = make_kgid(current_user_ns(), result.uint_32);
+               if (!gid_valid(gid))
+                       return -EINVAL;
+               ctx->o.gid = gid;
+               break;
+       case opt_ttl:
+               ctx->o.ttl = msecs_to_jiffies(result.uint_32);
+               break;
+       case opt_dmode:
+               if (result.uint_32 & ~0777)
+                       return -EINVAL;
+               ctx->o.dmode = result.uint_32;
+               ctx->o.dmode_set = true;
+               break;
+       case opt_fmode:
+               if (result.uint_32 & ~0777)
+                       return -EINVAL;
+               ctx->o.fmode = result.uint_32;
+               ctx->o.fmode_set = true;
+               break;
+       case opt_dmask:
+               if (result.uint_32 & ~07777)
+                       return -EINVAL;
+               ctx->o.dmask = result.uint_32;
+               break;
+       case opt_fmask:
+               if (result.uint_32 & ~07777)
+                       return -EINVAL;
+               ctx->o.fmask = result.uint_32;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int vboxsf_fill_super(struct super_block *sb, struct fs_context *fc)
+{
+       struct vboxsf_fs_context *ctx = fc->fs_private;
+       struct shfl_string *folder_name, root_path;
+       struct vboxsf_sbi *sbi;
+       struct dentry *droot;
+       struct inode *iroot;
+       char *nls_name;
+       size_t size;
+       int err;
+
+       if (!fc->source)
+               return -EINVAL;
+
+       sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
+       if (!sbi)
+               return -ENOMEM;
+
+       sbi->o = ctx->o;
+       idr_init(&sbi->ino_idr);
+       spin_lock_init(&sbi->ino_idr_lock);
+       sbi->next_generation = 1;
+       sbi->bdi_id = -1;
+
+       /* Load nls if not utf8 */
+       nls_name = ctx->nls_name ? ctx->nls_name : vboxsf_default_nls;
+       if (strcmp(nls_name, "utf8") != 0) {
+               if (nls_name == vboxsf_default_nls)
+                       sbi->nls = load_nls_default();
+               else
+                       sbi->nls = load_nls(nls_name);
+
+               if (!sbi->nls) {
+                       vbg_err("vboxsf: Count not load '%s' nls\n", nls_name);
+                       err = -EINVAL;
+                       goto fail_free;
+               }
+       }
+
+       sbi->bdi_id = ida_simple_get(&vboxsf_bdi_ida, 0, 0, GFP_KERNEL);
+       if (sbi->bdi_id < 0) {
+               err = sbi->bdi_id;
+               goto fail_free;
+       }
+
+       err = super_setup_bdi_name(sb, "vboxsf-%s.%d", fc->source, sbi->bdi_id);
+       if (err)
+               goto fail_free;
+
+       /* Turn source into a shfl_string and map the folder */
+       size = strlen(fc->source) + 1;
+       folder_name = kmalloc(SHFLSTRING_HEADER_SIZE + size, GFP_KERNEL);
+       if (!folder_name) {
+               err = -ENOMEM;
+               goto fail_free;
+       }
+       folder_name->size = size;
+       folder_name->length = size - 1;
+       strlcpy(folder_name->string.utf8, fc->source, size);
+       err = vboxsf_map_folder(folder_name, &sbi->root);
+       kfree(folder_name);
+       if (err) {
+               vbg_err("vboxsf: Host rejected mount of '%s' with error %d\n",
+                       fc->source, err);
+               goto fail_free;
+       }
+
+       root_path.length = 1;
+       root_path.size = 2;
+       root_path.string.utf8[0] = '/';
+       root_path.string.utf8[1] = 0;
+       err = vboxsf_stat(sbi, &root_path, &sbi->root_info);
+       if (err)
+               goto fail_unmap;
+
+       sb->s_magic = VBOXSF_SUPER_MAGIC;
+       sb->s_blocksize = 1024;
+       sb->s_maxbytes = MAX_LFS_FILESIZE;
+       sb->s_op = &vboxsf_super_ops;
+       sb->s_d_op = &vboxsf_dentry_ops;
+
+       iroot = iget_locked(sb, 0);
+       if (!iroot) {
+               err = -ENOMEM;
+               goto fail_unmap;
+       }
+       vboxsf_init_inode(sbi, iroot, &sbi->root_info);
+       unlock_new_inode(iroot);
+
+       droot = d_make_root(iroot);
+       if (!droot) {
+               err = -ENOMEM;
+               goto fail_unmap;
+       }
+
+       sb->s_root = droot;
+       sb->s_fs_info = sbi;
+       return 0;
+
+fail_unmap:
+       vboxsf_unmap_folder(sbi->root);
+fail_free:
+       if (sbi->bdi_id >= 0)
+               ida_simple_remove(&vboxsf_bdi_ida, sbi->bdi_id);
+       if (sbi->nls)
+               unload_nls(sbi->nls);
+       idr_destroy(&sbi->ino_idr);
+       kfree(sbi);
+       return err;
+}
+
+static void vboxsf_inode_init_once(void *data)
+{
+       struct vboxsf_inode *sf_i = data;
+
+       mutex_init(&sf_i->handle_list_mutex);
+       inode_init_once(&sf_i->vfs_inode);
+}
+
+static struct inode *vboxsf_alloc_inode(struct super_block *sb)
+{
+       struct vboxsf_inode *sf_i;
+
+       sf_i = kmem_cache_alloc(vboxsf_inode_cachep, GFP_NOFS);
+       if (!sf_i)
+               return NULL;
+
+       sf_i->force_restat = 0;
+       INIT_LIST_HEAD(&sf_i->handle_list);
+
+       return &sf_i->vfs_inode;
+}
+
+static void vboxsf_free_inode(struct inode *inode)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(inode->i_sb);
+       unsigned long flags;
+
+       spin_lock_irqsave(&sbi->ino_idr_lock, flags);
+       idr_remove(&sbi->ino_idr, inode->i_ino);
+       spin_unlock_irqrestore(&sbi->ino_idr_lock, flags);
+       kmem_cache_free(vboxsf_inode_cachep, VBOXSF_I(inode));
+}
+
+static void vboxsf_put_super(struct super_block *sb)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(sb);
+
+       vboxsf_unmap_folder(sbi->root);
+       if (sbi->bdi_id >= 0)
+               ida_simple_remove(&vboxsf_bdi_ida, sbi->bdi_id);
+       if (sbi->nls)
+               unload_nls(sbi->nls);
+
+       /*
+        * vboxsf_free_inode uses the idr, make sure all delayed rcu free
+        * inodes are flushed.
+        */
+       rcu_barrier();
+       idr_destroy(&sbi->ino_idr);
+       kfree(sbi);
+}
+
+static int vboxsf_statfs(struct dentry *dentry, struct kstatfs *stat)
+{
+       struct super_block *sb = dentry->d_sb;
+       struct shfl_volinfo shfl_volinfo;
+       struct vboxsf_sbi *sbi;
+       u32 buf_len;
+       int err;
+
+       sbi = VBOXSF_SBI(sb);
+       buf_len = sizeof(shfl_volinfo);
+       err = vboxsf_fsinfo(sbi->root, 0, SHFL_INFO_GET | SHFL_INFO_VOLUME,
+                           &buf_len, &shfl_volinfo);
+       if (err)
+               return err;
+
+       stat->f_type = VBOXSF_SUPER_MAGIC;
+       stat->f_bsize = shfl_volinfo.bytes_per_allocation_unit;
+
+       do_div(shfl_volinfo.total_allocation_bytes,
+              shfl_volinfo.bytes_per_allocation_unit);
+       stat->f_blocks = shfl_volinfo.total_allocation_bytes;
+
+       do_div(shfl_volinfo.available_allocation_bytes,
+              shfl_volinfo.bytes_per_allocation_unit);
+       stat->f_bfree  = shfl_volinfo.available_allocation_bytes;
+       stat->f_bavail = shfl_volinfo.available_allocation_bytes;
+
+       stat->f_files = 1000;
+       /*
+        * Don't return 0 here since the guest may then think that it is not
+        * possible to create any more files.
+        */
+       stat->f_ffree = 1000000;
+       stat->f_fsid.val[0] = 0;
+       stat->f_fsid.val[1] = 0;
+       stat->f_namelen = 255;
+       return 0;
+}
+
+static struct super_operations vboxsf_super_ops = {
+       .alloc_inode    = vboxsf_alloc_inode,
+       .free_inode     = vboxsf_free_inode,
+       .put_super      = vboxsf_put_super,
+       .statfs         = vboxsf_statfs,
+};
+
+static int vboxsf_setup(void)
+{
+       int err;
+
+       mutex_lock(&vboxsf_setup_mutex);
+
+       if (vboxsf_setup_done)
+               goto success;
+
+       vboxsf_inode_cachep =
+               kmem_cache_create("vboxsf_inode_cache",
+                                 sizeof(struct vboxsf_inode), 0,
+                                 (SLAB_RECLAIM_ACCOUNT | SLAB_MEM_SPREAD |
+                                  SLAB_ACCOUNT),
+                                 vboxsf_inode_init_once);
+       if (!vboxsf_inode_cachep) {
+               err = -ENOMEM;
+               goto fail_nomem;
+       }
+
+       err = vboxsf_connect();
+       if (err) {
+               vbg_err("vboxsf: err %d connecting to guest PCI-device\n", err);
+               vbg_err("vboxsf: make sure you are inside a VirtualBox VM\n");
+               vbg_err("vboxsf: and check dmesg for vboxguest errors\n");
+               goto fail_free_cache;
+       }
+
+       err = vboxsf_set_utf8();
+       if (err) {
+               vbg_err("vboxsf_setutf8 error %d\n", err);
+               goto fail_disconnect;
+       }
+
+       if (!follow_symlinks) {
+               err = vboxsf_set_symlinks();
+               if (err)
+                       vbg_warn("vboxsf: Unable to show symlinks: %d\n", err);
+       }
+
+       vboxsf_setup_done = true;
+success:
+       mutex_unlock(&vboxsf_setup_mutex);
+       return 0;
+
+fail_disconnect:
+       vboxsf_disconnect();
+fail_free_cache:
+       kmem_cache_destroy(vboxsf_inode_cachep);
+fail_nomem:
+       mutex_unlock(&vboxsf_setup_mutex);
+       return err;
+}
+
+static int vboxsf_parse_monolithic(struct fs_context *fc, void *data)
+{
+       char *options = data;
+
+       if (options && options[0] == VBSF_MOUNT_SIGNATURE_BYTE_0 &&
+                      options[1] == VBSF_MOUNT_SIGNATURE_BYTE_1 &&
+                      options[2] == VBSF_MOUNT_SIGNATURE_BYTE_2 &&
+                      options[3] == VBSF_MOUNT_SIGNATURE_BYTE_3) {
+               vbg_err("vboxsf: Old binary mount data not supported, remove obsolete mount.vboxsf and/or update your VBoxService.\n");
+               return -EINVAL;
+       }
+
+       return generic_parse_monolithic(fc, data);
+}
+
+static int vboxsf_get_tree(struct fs_context *fc)
+{
+       int err;
+
+       err = vboxsf_setup();
+       if (err)
+               return err;
+
+       return get_tree_nodev(fc, vboxsf_fill_super);
+}
+
+static int vboxsf_reconfigure(struct fs_context *fc)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(fc->root->d_sb);
+       struct vboxsf_fs_context *ctx = fc->fs_private;
+       struct inode *iroot = fc->root->d_sb->s_root->d_inode;
+
+       /* Apply changed options to the root inode */
+       sbi->o = ctx->o;
+       vboxsf_init_inode(sbi, iroot, &sbi->root_info);
+
+       return 0;
+}
+
+static void vboxsf_free_fc(struct fs_context *fc)
+{
+       struct vboxsf_fs_context *ctx = fc->fs_private;
+
+       kfree(ctx->nls_name);
+       kfree(ctx);
+}
+
+static const struct fs_context_operations vboxsf_context_ops = {
+       .free                   = vboxsf_free_fc,
+       .parse_param            = vboxsf_parse_param,
+       .parse_monolithic       = vboxsf_parse_monolithic,
+       .get_tree               = vboxsf_get_tree,
+       .reconfigure            = vboxsf_reconfigure,
+};
+
+static int vboxsf_init_fs_context(struct fs_context *fc)
+{
+       struct vboxsf_fs_context *ctx;
+
+       ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
+       if (!ctx)
+               return -ENOMEM;
+
+       current_uid_gid(&ctx->o.uid, &ctx->o.gid);
+
+       fc->fs_private = ctx;
+       fc->ops = &vboxsf_context_ops;
+       return 0;
+}
+
+static struct file_system_type vboxsf_fs_type = {
+       .owner                  = THIS_MODULE,
+       .name                   = "vboxsf",
+       .init_fs_context        = vboxsf_init_fs_context,
+       .kill_sb                = kill_anon_super
+};
+
+/* Module initialization/finalization handlers */
+static int __init vboxsf_init(void)
+{
+       return register_filesystem(&vboxsf_fs_type);
+}
+
+static void __exit vboxsf_fini(void)
+{
+       unregister_filesystem(&vboxsf_fs_type);
+
+       mutex_lock(&vboxsf_setup_mutex);
+       if (vboxsf_setup_done) {
+               vboxsf_disconnect();
+               /*
+                * Make sure all delayed rcu free inodes are flushed
+                * before we destroy the cache.
+                */
+               rcu_barrier();
+               kmem_cache_destroy(vboxsf_inode_cachep);
+       }
+       mutex_unlock(&vboxsf_setup_mutex);
+}
+
+module_init(vboxsf_init);
+module_exit(vboxsf_fini);
+
+MODULE_DESCRIPTION("Oracle VM VirtualBox Module for Host File System Access");
+MODULE_AUTHOR("Oracle Corporation");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS_FS("vboxsf");
diff --git a/fs/vboxsf/utils.c b/fs/vboxsf/utils.c
new file mode 100644 (file)
index 0000000..96bd160
--- /dev/null
@@ -0,0 +1,551 @@
+// SPDX-License-Identifier: MIT
+/*
+ * VirtualBox Guest Shared Folders support: Utility functions.
+ * Mainly conversion from/to VirtualBox/Linux data structures.
+ *
+ * Copyright (C) 2006-2018 Oracle Corporation
+ */
+
+#include <linux/namei.h>
+#include <linux/nls.h>
+#include <linux/sizes.h>
+#include <linux/vfs.h>
+#include "vfsmod.h"
+
+struct inode *vboxsf_new_inode(struct super_block *sb)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(sb);
+       struct inode *inode;
+       unsigned long flags;
+       int cursor, ret;
+       u32 gen;
+
+       inode = new_inode(sb);
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+
+       idr_preload(GFP_KERNEL);
+       spin_lock_irqsave(&sbi->ino_idr_lock, flags);
+       cursor = idr_get_cursor(&sbi->ino_idr);
+       ret = idr_alloc_cyclic(&sbi->ino_idr, inode, 1, 0, GFP_ATOMIC);
+       if (ret >= 0 && ret < cursor)
+               sbi->next_generation++;
+       gen = sbi->next_generation;
+       spin_unlock_irqrestore(&sbi->ino_idr_lock, flags);
+       idr_preload_end();
+
+       if (ret < 0) {
+               iput(inode);
+               return ERR_PTR(ret);
+       }
+
+       inode->i_ino = ret;
+       inode->i_generation = gen;
+       return inode;
+}
+
+/* set [inode] attributes based on [info], uid/gid based on [sbi] */
+void vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
+                      const struct shfl_fsobjinfo *info)
+{
+       const struct shfl_fsobjattr *attr;
+       s64 allocated;
+       int mode;
+
+       attr = &info->attr;
+
+#define mode_set(r) ((attr->mode & (SHFL_UNIX_##r)) ? (S_##r) : 0)
+
+       mode = mode_set(IRUSR);
+       mode |= mode_set(IWUSR);
+       mode |= mode_set(IXUSR);
+
+       mode |= mode_set(IRGRP);
+       mode |= mode_set(IWGRP);
+       mode |= mode_set(IXGRP);
+
+       mode |= mode_set(IROTH);
+       mode |= mode_set(IWOTH);
+       mode |= mode_set(IXOTH);
+
+#undef mode_set
+
+       /* We use the host-side values for these */
+       inode->i_flags |= S_NOATIME | S_NOCMTIME;
+       inode->i_mapping->a_ops = &vboxsf_reg_aops;
+
+       if (SHFL_IS_DIRECTORY(attr->mode)) {
+               inode->i_mode = sbi->o.dmode_set ? sbi->o.dmode : mode;
+               inode->i_mode &= ~sbi->o.dmask;
+               inode->i_mode |= S_IFDIR;
+               inode->i_op = &vboxsf_dir_iops;
+               inode->i_fop = &vboxsf_dir_fops;
+               /*
+                * XXX: this probably should be set to the number of entries
+                * in the directory plus two (. ..)
+                */
+               set_nlink(inode, 1);
+       } else if (SHFL_IS_SYMLINK(attr->mode)) {
+               inode->i_mode = sbi->o.fmode_set ? sbi->o.fmode : mode;
+               inode->i_mode &= ~sbi->o.fmask;
+               inode->i_mode |= S_IFLNK;
+               inode->i_op = &vboxsf_lnk_iops;
+               set_nlink(inode, 1);
+       } else {
+               inode->i_mode = sbi->o.fmode_set ? sbi->o.fmode : mode;
+               inode->i_mode &= ~sbi->o.fmask;
+               inode->i_mode |= S_IFREG;
+               inode->i_op = &vboxsf_reg_iops;
+               inode->i_fop = &vboxsf_reg_fops;
+               set_nlink(inode, 1);
+       }
+
+       inode->i_uid = sbi->o.uid;
+       inode->i_gid = sbi->o.gid;
+
+       inode->i_size = info->size;
+       inode->i_blkbits = 12;
+       /* i_blocks always in units of 512 bytes! */
+       allocated = info->allocated + 511;
+       do_div(allocated, 512);
+       inode->i_blocks = allocated;
+
+       inode->i_atime = ns_to_timespec64(
+                                info->access_time.ns_relative_to_unix_epoch);
+       inode->i_ctime = ns_to_timespec64(
+                                info->change_time.ns_relative_to_unix_epoch);
+       inode->i_mtime = ns_to_timespec64(
+                          info->modification_time.ns_relative_to_unix_epoch);
+}
+
+int vboxsf_create_at_dentry(struct dentry *dentry,
+                           struct shfl_createparms *params)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
+       struct shfl_string *path;
+       int err;
+
+       path = vboxsf_path_from_dentry(sbi, dentry);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+
+       err = vboxsf_create(sbi->root, path, params);
+       __putname(path);
+
+       return err;
+}
+
+int vboxsf_stat(struct vboxsf_sbi *sbi, struct shfl_string *path,
+               struct shfl_fsobjinfo *info)
+{
+       struct shfl_createparms params = {};
+       int err;
+
+       params.handle = SHFL_HANDLE_NIL;
+       params.create_flags = SHFL_CF_LOOKUP | SHFL_CF_ACT_FAIL_IF_NEW;
+
+       err = vboxsf_create(sbi->root, path, &params);
+       if (err)
+               return err;
+
+       if (params.result != SHFL_FILE_EXISTS)
+               return -ENOENT;
+
+       if (info)
+               *info = params.info;
+
+       return 0;
+}
+
+int vboxsf_stat_dentry(struct dentry *dentry, struct shfl_fsobjinfo *info)
+{
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
+       struct shfl_string *path;
+       int err;
+
+       path = vboxsf_path_from_dentry(sbi, dentry);
+       if (IS_ERR(path))
+               return PTR_ERR(path);
+
+       err = vboxsf_stat(sbi, path, info);
+       __putname(path);
+       return err;
+}
+
+int vboxsf_inode_revalidate(struct dentry *dentry)
+{
+       struct vboxsf_sbi *sbi;
+       struct vboxsf_inode *sf_i;
+       struct shfl_fsobjinfo info;
+       struct timespec64 prev_mtime;
+       struct inode *inode;
+       int err;
+
+       if (!dentry || !d_really_is_positive(dentry))
+               return -EINVAL;
+
+       inode = d_inode(dentry);
+       prev_mtime = inode->i_mtime;
+       sf_i = VBOXSF_I(inode);
+       sbi = VBOXSF_SBI(dentry->d_sb);
+       if (!sf_i->force_restat) {
+               if (time_before(jiffies, dentry->d_time + sbi->o.ttl))
+                       return 0;
+       }
+
+       err = vboxsf_stat_dentry(dentry, &info);
+       if (err)
+               return err;
+
+       dentry->d_time = jiffies;
+       sf_i->force_restat = 0;
+       vboxsf_init_inode(sbi, inode, &info);
+
+       /*
+        * If the file was changed on the host side we need to invalidate the
+        * page-cache for it.  Note this also gets triggered by our own writes,
+        * this is unavoidable.
+        */
+       if (timespec64_compare(&inode->i_mtime, &prev_mtime) > 0)
+               invalidate_inode_pages2(inode->i_mapping);
+
+       return 0;
+}
+
+int vboxsf_getattr(const struct path *path, struct kstat *kstat,
+                  u32 request_mask, unsigned int flags)
+{
+       int err;
+       struct dentry *dentry = path->dentry;
+       struct inode *inode = d_inode(dentry);
+       struct vboxsf_inode *sf_i = VBOXSF_I(inode);
+
+       switch (flags & AT_STATX_SYNC_TYPE) {
+       case AT_STATX_DONT_SYNC:
+               err = 0;
+               break;
+       case AT_STATX_FORCE_SYNC:
+               sf_i->force_restat = 1;
+               /* fall-through */
+       default:
+               err = vboxsf_inode_revalidate(dentry);
+       }
+       if (err)
+               return err;
+
+       generic_fillattr(d_inode(dentry), kstat);
+       return 0;
+}
+
+int vboxsf_setattr(struct dentry *dentry, struct iattr *iattr)
+{
+       struct vboxsf_inode *sf_i = VBOXSF_I(d_inode(dentry));
+       struct vboxsf_sbi *sbi = VBOXSF_SBI(dentry->d_sb);
+       struct shfl_createparms params = {};
+       struct shfl_fsobjinfo info = {};
+       u32 buf_len;
+       int err;
+
+       params.handle = SHFL_HANDLE_NIL;
+       params.create_flags = SHFL_CF_ACT_OPEN_IF_EXISTS |
+                             SHFL_CF_ACT_FAIL_IF_NEW |
+                             SHFL_CF_ACCESS_ATTR_WRITE;
+
+       /* this is at least required for Posix hosts */
+       if (iattr->ia_valid & ATTR_SIZE)
+               params.create_flags |= SHFL_CF_ACCESS_WRITE;
+
+       err = vboxsf_create_at_dentry(dentry, &params);
+       if (err || params.result != SHFL_FILE_EXISTS)
+               return err ? err : -ENOENT;
+
+#define mode_set(r) ((iattr->ia_mode & (S_##r)) ? SHFL_UNIX_##r : 0)
+
+       /*
+        * Setting the file size and setting the other attributes has to
+        * be handled separately.
+        */
+       if (iattr->ia_valid & (ATTR_MODE | ATTR_ATIME | ATTR_MTIME)) {
+               if (iattr->ia_valid & ATTR_MODE) {
+                       info.attr.mode = mode_set(IRUSR);
+                       info.attr.mode |= mode_set(IWUSR);
+                       info.attr.mode |= mode_set(IXUSR);
+                       info.attr.mode |= mode_set(IRGRP);
+                       info.attr.mode |= mode_set(IWGRP);
+                       info.attr.mode |= mode_set(IXGRP);
+                       info.attr.mode |= mode_set(IROTH);
+                       info.attr.mode |= mode_set(IWOTH);
+                       info.attr.mode |= mode_set(IXOTH);
+
+                       if (iattr->ia_mode & S_IFDIR)
+                               info.attr.mode |= SHFL_TYPE_DIRECTORY;
+                       else
+                               info.attr.mode |= SHFL_TYPE_FILE;
+               }
+
+               if (iattr->ia_valid & ATTR_ATIME)
+                       info.access_time.ns_relative_to_unix_epoch =
+                                           timespec64_to_ns(&iattr->ia_atime);
+
+               if (iattr->ia_valid & ATTR_MTIME)
+                       info.modification_time.ns_relative_to_unix_epoch =
+                                           timespec64_to_ns(&iattr->ia_mtime);
+
+               /*
+                * Ignore ctime (inode change time) as it can't be set
+                * from userland anyway.
+                */
+
+               buf_len = sizeof(info);
+               err = vboxsf_fsinfo(sbi->root, params.handle,
+                                   SHFL_INFO_SET | SHFL_INFO_FILE, &buf_len,
+                                   &info);
+               if (err) {
+                       vboxsf_close(sbi->root, params.handle);
+                       return err;
+               }
+
+               /* the host may have given us different attr then requested */
+               sf_i->force_restat = 1;
+       }
+
+#undef mode_set
+
+       if (iattr->ia_valid & ATTR_SIZE) {
+               memset(&info, 0, sizeof(info));
+               info.size = iattr->ia_size;
+               buf_len = sizeof(info);
+               err = vboxsf_fsinfo(sbi->root, params.handle,
+                                   SHFL_INFO_SET | SHFL_INFO_SIZE, &buf_len,
+                                   &info);
+               if (err) {
+                       vboxsf_close(sbi->root, params.handle);
+                       return err;
+               }
+
+               /* the host may have given us different attr then requested */
+               sf_i->force_restat = 1;
+       }
+
+       vboxsf_close(sbi->root, params.handle);
+
+       /* Update the inode with what the host has actually given us. */
+       if (sf_i->force_restat)
+               vboxsf_inode_revalidate(dentry);
+
+       return 0;
+}
+
+/*
+ * [dentry] contains string encoded in coding system that corresponds
+ * to [sbi]->nls, we must convert it to UTF8 here.
+ * Returns a shfl_string allocated through __getname (must be freed using
+ * __putname), or an ERR_PTR on error.
+ */
+struct shfl_string *vboxsf_path_from_dentry(struct vboxsf_sbi *sbi,
+                                           struct dentry *dentry)
+{
+       struct shfl_string *shfl_path;
+       int path_len, out_len, nb;
+       char *buf, *path;
+       wchar_t uni;
+       u8 *out;
+
+       buf = __getname();
+       if (!buf)
+               return ERR_PTR(-ENOMEM);
+
+       path = dentry_path_raw(dentry, buf, PATH_MAX);
+       if (IS_ERR(path)) {
+               __putname(buf);
+               return ERR_CAST(path);
+       }
+       path_len = strlen(path);
+
+       if (sbi->nls) {
+               shfl_path = __getname();
+               if (!shfl_path) {
+                       __putname(buf);
+                       return ERR_PTR(-ENOMEM);
+               }
+
+               out = shfl_path->string.utf8;
+               out_len = PATH_MAX - SHFLSTRING_HEADER_SIZE - 1;
+
+               while (path_len) {
+                       nb = sbi->nls->char2uni(path, path_len, &uni);
+                       if (nb < 0) {
+                               __putname(shfl_path);
+                               __putname(buf);
+                               return ERR_PTR(-EINVAL);
+                       }
+                       path += nb;
+                       path_len -= nb;
+
+                       nb = utf32_to_utf8(uni, out, out_len);
+                       if (nb < 0) {
+                               __putname(shfl_path);
+                               __putname(buf);
+                               return ERR_PTR(-ENAMETOOLONG);
+                       }
+                       out += nb;
+                       out_len -= nb;
+               }
+               *out = 0;
+               shfl_path->length = out - shfl_path->string.utf8;
+               shfl_path->size = shfl_path->length + 1;
+               __putname(buf);
+       } else {
+               if ((SHFLSTRING_HEADER_SIZE + path_len + 1) > PATH_MAX) {
+                       __putname(buf);
+                       return ERR_PTR(-ENAMETOOLONG);
+               }
+               /*
+                * dentry_path stores the name at the end of buf, but the
+                * shfl_string string we return must be properly aligned.
+                */
+               shfl_path = (struct shfl_string *)buf;
+               memmove(shfl_path->string.utf8, path, path_len);
+               shfl_path->string.utf8[path_len] = 0;
+               shfl_path->length = path_len;
+               shfl_path->size = path_len + 1;
+       }
+
+       return shfl_path;
+}
+
+int vboxsf_nlscpy(struct vboxsf_sbi *sbi, char *name, size_t name_bound_len,
+                 const unsigned char *utf8_name, size_t utf8_len)
+{
+       const char *in;
+       char *out;
+       size_t out_len;
+       size_t out_bound_len;
+       size_t in_bound_len;
+
+       in = utf8_name;
+       in_bound_len = utf8_len;
+
+       out = name;
+       out_len = 0;
+       /* Reserve space for terminating 0 */
+       out_bound_len = name_bound_len - 1;
+
+       while (in_bound_len) {
+               int nb;
+               unicode_t uni;
+
+               nb = utf8_to_utf32(in, in_bound_len, &uni);
+               if (nb < 0)
+                       return -EINVAL;
+
+               in += nb;
+               in_bound_len -= nb;
+
+               nb = sbi->nls->uni2char(uni, out, out_bound_len);
+               if (nb < 0)
+                       return nb;
+
+               out += nb;
+               out_bound_len -= nb;
+               out_len += nb;
+       }
+
+       *out = 0;
+
+       return 0;
+}
+
+static struct vboxsf_dir_buf *vboxsf_dir_buf_alloc(struct list_head *list)
+{
+       struct vboxsf_dir_buf *b;
+
+       b = kmalloc(sizeof(*b), GFP_KERNEL);
+       if (!b)
+               return NULL;
+
+       b->buf = kmalloc(DIR_BUFFER_SIZE, GFP_KERNEL);
+       if (!b->buf) {
+               kfree(b);
+               return NULL;
+       }
+
+       b->entries = 0;
+       b->used = 0;
+       b->free = DIR_BUFFER_SIZE;
+       list_add(&b->head, list);
+
+       return b;
+}
+
+static void vboxsf_dir_buf_free(struct vboxsf_dir_buf *b)
+{
+       list_del(&b->head);
+       kfree(b->buf);
+       kfree(b);
+}
+
+struct vboxsf_dir_info *vboxsf_dir_info_alloc(void)
+{
+       struct vboxsf_dir_info *p;
+
+       p = kmalloc(sizeof(*p), GFP_KERNEL);
+       if (!p)
+               return NULL;
+
+       INIT_LIST_HEAD(&p->info_list);
+       return p;
+}
+
+void vboxsf_dir_info_free(struct vboxsf_dir_info *p)
+{
+       struct list_head *list, *pos, *tmp;
+
+       list = &p->info_list;
+       list_for_each_safe(pos, tmp, list) {
+               struct vboxsf_dir_buf *b;
+
+               b = list_entry(pos, struct vboxsf_dir_buf, head);
+               vboxsf_dir_buf_free(b);
+       }
+       kfree(p);
+}
+
+int vboxsf_dir_read_all(struct vboxsf_sbi *sbi, struct vboxsf_dir_info *sf_d,
+                       u64 handle)
+{
+       struct vboxsf_dir_buf *b;
+       u32 entries, size;
+       int err = 0;
+       void *buf;
+
+       /* vboxsf_dirinfo returns 1 on end of dir */
+       while (err == 0) {
+               b = vboxsf_dir_buf_alloc(&sf_d->info_list);
+               if (!b) {
+                       err = -ENOMEM;
+                       break;
+               }
+
+               buf = b->buf;
+               size = b->free;
+
+               err = vboxsf_dirinfo(sbi->root, handle, NULL, 0, 0,
+                                    &size, buf, &entries);
+               if (err < 0)
+                       break;
+
+               b->entries += entries;
+               b->free -= size;
+               b->used += size;
+       }
+
+       if (b && b->used == 0)
+               vboxsf_dir_buf_free(b);
+
+       /* -EILSEQ means the host could not translate a filename, ignore */
+       if (err > 0 || err == -EILSEQ)
+               err = 0;
+
+       return err;
+}
diff --git a/fs/vboxsf/vboxsf_wrappers.c b/fs/vboxsf/vboxsf_wrappers.c
new file mode 100644 (file)
index 0000000..bfc78a0
--- /dev/null
@@ -0,0 +1,371 @@
+// SPDX-License-Identifier: MIT
+/*
+ * Wrapper functions for the shfl host calls.
+ *
+ * Copyright (C) 2006-2018 Oracle Corporation
+ */
+
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/vbox_err.h>
+#include <linux/vbox_utils.h>
+#include "vfsmod.h"
+
+#define SHFL_REQUEST \
+       (VMMDEV_REQUESTOR_KERNEL | VMMDEV_REQUESTOR_USR_DRV_OTHER | \
+        VMMDEV_REQUESTOR_CON_DONT_KNOW | VMMDEV_REQUESTOR_TRUST_NOT_GIVEN)
+
+static u32 vboxsf_client_id;
+
+int vboxsf_connect(void)
+{
+       struct vbg_dev *gdev;
+       struct vmmdev_hgcm_service_location loc;
+       int err, vbox_status;
+
+       loc.type = VMMDEV_HGCM_LOC_LOCALHOST_EXISTING;
+       strcpy(loc.u.localhost.service_name, "VBoxSharedFolders");
+
+       gdev = vbg_get_gdev();
+       if (IS_ERR(gdev))
+               return -ENODEV; /* No guest-device */
+
+       err = vbg_hgcm_connect(gdev, SHFL_REQUEST, &loc,
+                              &vboxsf_client_id, &vbox_status);
+       vbg_put_gdev(gdev);
+
+       return err ? err : vbg_status_code_to_errno(vbox_status);
+}
+
+void vboxsf_disconnect(void)
+{
+       struct vbg_dev *gdev;
+       int vbox_status;
+
+       gdev = vbg_get_gdev();
+       if (IS_ERR(gdev))
+               return;   /* guest-device is gone, already disconnected */
+
+       vbg_hgcm_disconnect(gdev, SHFL_REQUEST, vboxsf_client_id, &vbox_status);
+       vbg_put_gdev(gdev);
+}
+
+static int vboxsf_call(u32 function, void *parms, u32 parm_count, int *status)
+{
+       struct vbg_dev *gdev;
+       int err, vbox_status;
+
+       gdev = vbg_get_gdev();
+       if (IS_ERR(gdev))
+               return -ESHUTDOWN; /* guest-dev removed underneath us */
+
+       err = vbg_hgcm_call(gdev, SHFL_REQUEST, vboxsf_client_id, function,
+                           U32_MAX, parms, parm_count, &vbox_status);
+       vbg_put_gdev(gdev);
+
+       if (err < 0)
+               return err;
+
+       if (status)
+               *status = vbox_status;
+
+       return vbg_status_code_to_errno(vbox_status);
+}
+
+int vboxsf_map_folder(struct shfl_string *folder_name, u32 *root)
+{
+       struct shfl_map_folder parms;
+       int err, status;
+
+       parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL;
+       parms.path.u.pointer.size = shfl_string_buf_size(folder_name);
+       parms.path.u.pointer.u.linear_addr = (uintptr_t)folder_name;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = 0;
+
+       parms.delimiter.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.delimiter.u.value32 = '/';
+
+       parms.case_sensitive.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.case_sensitive.u.value32 = 1;
+
+       err = vboxsf_call(SHFL_FN_MAP_FOLDER, &parms, SHFL_CPARMS_MAP_FOLDER,
+                         &status);
+       if (err == -ENOSYS && status == VERR_NOT_IMPLEMENTED)
+               vbg_err("%s: Error host is too old\n", __func__);
+
+       *root = parms.root.u.value32;
+       return err;
+}
+
+int vboxsf_unmap_folder(u32 root)
+{
+       struct shfl_unmap_folder parms;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       return vboxsf_call(SHFL_FN_UNMAP_FOLDER, &parms,
+                          SHFL_CPARMS_UNMAP_FOLDER, NULL);
+}
+
+/**
+ * vboxsf_create - Create a new file or folder
+ * @root:         Root of the shared folder in which to create the file
+ * @parsed_path:  The path of the file or folder relative to the shared folder
+ * @param:        create_parms Parameters for file/folder creation.
+ *
+ * Create a new file or folder or open an existing one in a shared folder.
+ * Note this function always returns 0 / success unless an exceptional condition
+ * occurs - out of memory, invalid arguments, etc. If the file or folder could
+ * not be opened or created, create_parms->handle will be set to
+ * SHFL_HANDLE_NIL on return.  In this case the value in create_parms->result
+ * provides information as to why (e.g. SHFL_FILE_EXISTS), create_parms->result
+ * is also set on success as additional information.
+ *
+ * Returns:
+ * 0 or negative errno value.
+ */
+int vboxsf_create(u32 root, struct shfl_string *parsed_path,
+                 struct shfl_createparms *create_parms)
+{
+       struct shfl_create parms;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL;
+       parms.path.u.pointer.size = shfl_string_buf_size(parsed_path);
+       parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path;
+
+       parms.parms.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL;
+       parms.parms.u.pointer.size = sizeof(struct shfl_createparms);
+       parms.parms.u.pointer.u.linear_addr = (uintptr_t)create_parms;
+
+       return vboxsf_call(SHFL_FN_CREATE, &parms, SHFL_CPARMS_CREATE, NULL);
+}
+
+int vboxsf_close(u32 root, u64 handle)
+{
+       struct shfl_close parms;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
+       parms.handle.u.value64 = handle;
+
+       return vboxsf_call(SHFL_FN_CLOSE, &parms, SHFL_CPARMS_CLOSE, NULL);
+}
+
+int vboxsf_remove(u32 root, struct shfl_string *parsed_path, u32 flags)
+{
+       struct shfl_remove parms;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
+       parms.path.u.pointer.size = shfl_string_buf_size(parsed_path);
+       parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path;
+
+       parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.flags.u.value32 = flags;
+
+       return vboxsf_call(SHFL_FN_REMOVE, &parms, SHFL_CPARMS_REMOVE, NULL);
+}
+
+int vboxsf_rename(u32 root, struct shfl_string *src_path,
+                 struct shfl_string *dest_path, u32 flags)
+{
+       struct shfl_rename parms;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.src.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
+       parms.src.u.pointer.size = shfl_string_buf_size(src_path);
+       parms.src.u.pointer.u.linear_addr = (uintptr_t)src_path;
+
+       parms.dest.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
+       parms.dest.u.pointer.size = shfl_string_buf_size(dest_path);
+       parms.dest.u.pointer.u.linear_addr = (uintptr_t)dest_path;
+
+       parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.flags.u.value32 = flags;
+
+       return vboxsf_call(SHFL_FN_RENAME, &parms, SHFL_CPARMS_RENAME, NULL);
+}
+
+int vboxsf_read(u32 root, u64 handle, u64 offset, u32 *buf_len, u8 *buf)
+{
+       struct shfl_read parms;
+       int err;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
+       parms.handle.u.value64 = handle;
+       parms.offset.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
+       parms.offset.u.value64 = offset;
+       parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.cb.u.value32 = *buf_len;
+       parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT;
+       parms.buffer.u.pointer.size = *buf_len;
+       parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf;
+
+       err = vboxsf_call(SHFL_FN_READ, &parms, SHFL_CPARMS_READ, NULL);
+
+       *buf_len = parms.cb.u.value32;
+       return err;
+}
+
+int vboxsf_write(u32 root, u64 handle, u64 offset, u32 *buf_len, u8 *buf)
+{
+       struct shfl_write parms;
+       int err;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
+       parms.handle.u.value64 = handle;
+       parms.offset.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
+       parms.offset.u.value64 = offset;
+       parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.cb.u.value32 = *buf_len;
+       parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
+       parms.buffer.u.pointer.size = *buf_len;
+       parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf;
+
+       err = vboxsf_call(SHFL_FN_WRITE, &parms, SHFL_CPARMS_WRITE, NULL);
+
+       *buf_len = parms.cb.u.value32;
+       return err;
+}
+
+/* Returns 0 on success, 1 on end-of-dir, negative errno otherwise */
+int vboxsf_dirinfo(u32 root, u64 handle,
+                  struct shfl_string *parsed_path, u32 flags, u32 index,
+                  u32 *buf_len, struct shfl_dirinfo *buf, u32 *file_count)
+{
+       struct shfl_list parms;
+       int err, status;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
+       parms.handle.u.value64 = handle;
+       parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.flags.u.value32 = flags;
+       parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.cb.u.value32 = *buf_len;
+       if (parsed_path) {
+               parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
+               parms.path.u.pointer.size = shfl_string_buf_size(parsed_path);
+               parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path;
+       } else {
+               parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_IN;
+               parms.path.u.pointer.size = 0;
+               parms.path.u.pointer.u.linear_addr = 0;
+       }
+
+       parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT;
+       parms.buffer.u.pointer.size = *buf_len;
+       parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf;
+
+       parms.resume_point.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.resume_point.u.value32 = index;
+       parms.file_count.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.file_count.u.value32 = 0; /* out parameter only */
+
+       err = vboxsf_call(SHFL_FN_LIST, &parms, SHFL_CPARMS_LIST, &status);
+       if (err == -ENODATA && status == VERR_NO_MORE_FILES)
+               err = 1;
+
+       *buf_len = parms.cb.u.value32;
+       *file_count = parms.file_count.u.value32;
+       return err;
+}
+
+int vboxsf_fsinfo(u32 root, u64 handle, u32 flags,
+                 u32 *buf_len, void *buf)
+{
+       struct shfl_information parms;
+       int err;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.handle.type = VMMDEV_HGCM_PARM_TYPE_64BIT;
+       parms.handle.u.value64 = handle;
+       parms.flags.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.flags.u.value32 = flags;
+       parms.cb.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.cb.u.value32 = *buf_len;
+       parms.info.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL;
+       parms.info.u.pointer.size = *buf_len;
+       parms.info.u.pointer.u.linear_addr = (uintptr_t)buf;
+
+       err = vboxsf_call(SHFL_FN_INFORMATION, &parms, SHFL_CPARMS_INFORMATION,
+                         NULL);
+
+       *buf_len = parms.cb.u.value32;
+       return err;
+}
+
+int vboxsf_readlink(u32 root, struct shfl_string *parsed_path,
+                   u32 buf_len, u8 *buf)
+{
+       struct shfl_readLink parms;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
+       parms.path.u.pointer.size = shfl_string_buf_size(parsed_path);
+       parms.path.u.pointer.u.linear_addr = (uintptr_t)parsed_path;
+
+       parms.buffer.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT;
+       parms.buffer.u.pointer.size = buf_len;
+       parms.buffer.u.pointer.u.linear_addr = (uintptr_t)buf;
+
+       return vboxsf_call(SHFL_FN_READLINK, &parms, SHFL_CPARMS_READLINK,
+                          NULL);
+}
+
+int vboxsf_symlink(u32 root, struct shfl_string *new_path,
+                  struct shfl_string *old_path, struct shfl_fsobjinfo *buf)
+{
+       struct shfl_symlink parms;
+
+       parms.root.type = VMMDEV_HGCM_PARM_TYPE_32BIT;
+       parms.root.u.value32 = root;
+
+       parms.new_path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
+       parms.new_path.u.pointer.size = shfl_string_buf_size(new_path);
+       parms.new_path.u.pointer.u.linear_addr = (uintptr_t)new_path;
+
+       parms.old_path.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_IN;
+       parms.old_path.u.pointer.size = shfl_string_buf_size(old_path);
+       parms.old_path.u.pointer.u.linear_addr = (uintptr_t)old_path;
+
+       parms.info.type = VMMDEV_HGCM_PARM_TYPE_LINADDR_KERNEL_OUT;
+       parms.info.u.pointer.size = sizeof(struct shfl_fsobjinfo);
+       parms.info.u.pointer.u.linear_addr = (uintptr_t)buf;
+
+       return vboxsf_call(SHFL_FN_SYMLINK, &parms, SHFL_CPARMS_SYMLINK, NULL);
+}
+
+int vboxsf_set_utf8(void)
+{
+       return vboxsf_call(SHFL_FN_SET_UTF8, NULL, 0, NULL);
+}
+
+int vboxsf_set_symlinks(void)
+{
+       return vboxsf_call(SHFL_FN_SET_SYMLINKS, NULL, 0, NULL);
+}
diff --git a/fs/vboxsf/vfsmod.h b/fs/vboxsf/vfsmod.h
new file mode 100644 (file)
index 0000000..18f95b0
--- /dev/null
@@ -0,0 +1,137 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * VirtualBox Guest Shared Folders support: module header.
+ *
+ * Copyright (C) 2006-2018 Oracle Corporation
+ */
+
+#ifndef VFSMOD_H
+#define VFSMOD_H
+
+#include <linux/backing-dev.h>
+#include <linux/idr.h>
+#include "shfl_hostintf.h"
+
+#define DIR_BUFFER_SIZE SZ_16K
+
+/* The cast is to prevent assignment of void * to pointers of arbitrary type */
+#define VBOXSF_SBI(sb) ((struct vboxsf_sbi *)(sb)->s_fs_info)
+#define VBOXSF_I(i)    container_of(i, struct vboxsf_inode, vfs_inode)
+
+struct vboxsf_options {
+       unsigned long ttl;
+       kuid_t uid;
+       kgid_t gid;
+       bool dmode_set;
+       bool fmode_set;
+       umode_t dmode;
+       umode_t fmode;
+       umode_t dmask;
+       umode_t fmask;
+};
+
+struct vboxsf_fs_context {
+       struct vboxsf_options o;
+       char *nls_name;
+};
+
+/* per-shared folder information */
+struct vboxsf_sbi {
+       struct vboxsf_options o;
+       struct shfl_fsobjinfo root_info;
+       struct idr ino_idr;
+       spinlock_t ino_idr_lock; /* This protects ino_idr */
+       struct nls_table *nls;
+       u32 next_generation;
+       u32 root;
+       int bdi_id;
+};
+
+/* per-inode information */
+struct vboxsf_inode {
+       /* some information was changed, update data on next revalidate */
+       int force_restat;
+       /* list of open handles for this inode + lock protecting it */
+       struct list_head handle_list;
+       /* This mutex protects handle_list accesses */
+       struct mutex handle_list_mutex;
+       /* The VFS inode struct */
+       struct inode vfs_inode;
+};
+
+struct vboxsf_dir_info {
+       struct list_head info_list;
+};
+
+struct vboxsf_dir_buf {
+       size_t entries;
+       size_t free;
+       size_t used;
+       void *buf;
+       struct list_head head;
+};
+
+/* globals */
+extern const struct inode_operations vboxsf_dir_iops;
+extern const struct inode_operations vboxsf_lnk_iops;
+extern const struct inode_operations vboxsf_reg_iops;
+extern const struct file_operations vboxsf_dir_fops;
+extern const struct file_operations vboxsf_reg_fops;
+extern const struct address_space_operations vboxsf_reg_aops;
+extern const struct dentry_operations vboxsf_dentry_ops;
+
+/* from utils.c */
+struct inode *vboxsf_new_inode(struct super_block *sb);
+void vboxsf_init_inode(struct vboxsf_sbi *sbi, struct inode *inode,
+                      const struct shfl_fsobjinfo *info);
+int vboxsf_create_at_dentry(struct dentry *dentry,
+                           struct shfl_createparms *params);
+int vboxsf_stat(struct vboxsf_sbi *sbi, struct shfl_string *path,
+               struct shfl_fsobjinfo *info);
+int vboxsf_stat_dentry(struct dentry *dentry, struct shfl_fsobjinfo *info);
+int vboxsf_inode_revalidate(struct dentry *dentry);
+int vboxsf_getattr(const struct path *path, struct kstat *kstat,
+                  u32 request_mask, unsigned int query_flags);
+int vboxsf_setattr(struct dentry *dentry, struct iattr *iattr);
+struct shfl_string *vboxsf_path_from_dentry(struct vboxsf_sbi *sbi,
+                                           struct dentry *dentry);
+int vboxsf_nlscpy(struct vboxsf_sbi *sbi, char *name, size_t name_bound_len,
+                 const unsigned char *utf8_name, size_t utf8_len);
+struct vboxsf_dir_info *vboxsf_dir_info_alloc(void);
+void vboxsf_dir_info_free(struct vboxsf_dir_info *p);
+int vboxsf_dir_read_all(struct vboxsf_sbi *sbi, struct vboxsf_dir_info *sf_d,
+                       u64 handle);
+
+/* from vboxsf_wrappers.c */
+int vboxsf_connect(void);
+void vboxsf_disconnect(void);
+
+int vboxsf_create(u32 root, struct shfl_string *parsed_path,
+                 struct shfl_createparms *create_parms);
+
+int vboxsf_close(u32 root, u64 handle);
+int vboxsf_remove(u32 root, struct shfl_string *parsed_path, u32 flags);
+int vboxsf_rename(u32 root, struct shfl_string *src_path,
+                 struct shfl_string *dest_path, u32 flags);
+
+int vboxsf_read(u32 root, u64 handle, u64 offset, u32 *buf_len, u8 *buf);
+int vboxsf_write(u32 root, u64 handle, u64 offset, u32 *buf_len, u8 *buf);
+
+int vboxsf_dirinfo(u32 root, u64 handle,
+                  struct shfl_string *parsed_path, u32 flags, u32 index,
+                  u32 *buf_len, struct shfl_dirinfo *buf, u32 *file_count);
+int vboxsf_fsinfo(u32 root, u64 handle, u32 flags,
+                 u32 *buf_len, void *buf);
+
+int vboxsf_map_folder(struct shfl_string *folder_name, u32 *root);
+int vboxsf_unmap_folder(u32 root);
+
+int vboxsf_readlink(u32 root, struct shfl_string *parsed_path,
+                   u32 buf_len, u8 *buf);
+int vboxsf_symlink(u32 root, struct shfl_string *new_path,
+                  struct shfl_string *old_path, struct shfl_fsobjinfo *buf);
+
+int vboxsf_set_utf8(void);
+int vboxsf_set_symlinks(void);
+
+#endif
index 14fbdf2..08d6beb 100644 (file)
 #include "xfs_ag_resv.h"
 #include "xfs_health.h"
 
-static struct xfs_buf *
+static int
 xfs_get_aghdr_buf(
        struct xfs_mount        *mp,
        xfs_daddr_t             blkno,
        size_t                  numblks,
+       struct xfs_buf          **bpp,
        const struct xfs_buf_ops *ops)
 {
        struct xfs_buf          *bp;
+       int                     error;
 
-       bp = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, 0);
-       if (!bp)
-               return NULL;
+       error = xfs_buf_get_uncached(mp->m_ddev_targp, numblks, 0, &bp);
+       if (error)
+               return error;
 
        xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
        bp->b_bn = blkno;
        bp->b_maps[0].bm_bn = blkno;
        bp->b_ops = ops;
 
-       return bp;
+       *bpp = bp;
+       return 0;
 }
 
 static inline bool is_log_ag(struct xfs_mount *mp, struct aghdr_init_data *id)
@@ -340,13 +343,13 @@ xfs_ag_init_hdr(
        struct aghdr_init_data  *id,
        aghdr_init_work_f       work,
        const struct xfs_buf_ops *ops)
-
 {
        struct xfs_buf          *bp;
+       int                     error;
 
-       bp = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, ops);
-       if (!bp)
-               return -ENOMEM;
+       error = xfs_get_aghdr_buf(mp, id->daddr, id->numblks, &bp, ops);
+       if (error)
+               return error;
 
        (*work)(mp, bp, id);
 
index fc93fd8..d8053bc 100644 (file)
@@ -1070,11 +1070,11 @@ xfs_alloc_ag_vextent_small(
        if (args->datatype & XFS_ALLOC_USERDATA) {
                struct xfs_buf  *bp;
 
-               bp = xfs_btree_get_bufs(args->mp, args->tp, args->agno, fbno);
-               if (XFS_IS_CORRUPT(args->mp, !bp)) {
-                       error = -EFSCORRUPTED;
+               error = xfs_trans_get_buf(args->tp, args->mp->m_ddev_targp,
+                               XFS_AGB_TO_DADDR(args->mp, args->agno, fbno),
+                               args->mp->m_bsize, 0, &bp);
+               if (error)
                        goto error;
-               }
                xfs_trans_binval(args->tp, bp);
        }
        *fbnop = args->agbno = fbno;
@@ -2347,9 +2347,11 @@ xfs_free_agfl_block(
        if (error)
                return error;
 
-       bp = xfs_btree_get_bufs(tp->t_mountp, tp, agno, agbno);
-       if (XFS_IS_CORRUPT(tp->t_mountp, !bp))
-               return -EFSCORRUPTED;
+       error = xfs_trans_get_buf(tp, tp->t_mountp->m_ddev_targp,
+                       XFS_AGB_TO_DADDR(tp->t_mountp, agno, agbno),
+                       tp->t_mountp->m_bsize, 0, &bp);
+       if (error)
+               return error;
        xfs_trans_binval(tp, bp);
 
        return 0;
@@ -2500,12 +2502,11 @@ xfs_alloc_fix_freelist(
 
        if (!pag->pagf_init) {
                error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
-               if (error)
+               if (error) {
+                       /* Couldn't lock the AGF so skip this AG. */
+                       if (error == -EAGAIN)
+                               error = 0;
                        goto out_no_agbp;
-               if (!pag->pagf_init) {
-                       ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
-                       ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
-                       goto out_agbp_relse;
                }
        }
 
@@ -2531,11 +2532,10 @@ xfs_alloc_fix_freelist(
         */
        if (!agbp) {
                error = xfs_alloc_read_agf(mp, tp, args->agno, flags, &agbp);
-               if (error)
-                       goto out_no_agbp;
-               if (!agbp) {
-                       ASSERT(flags & XFS_ALLOC_FLAG_TRYLOCK);
-                       ASSERT(!(flags & XFS_ALLOC_FLAG_FREEING));
+               if (error) {
+                       /* Couldn't lock the AGF so skip this AG. */
+                       if (error == -EAGAIN)
+                               error = 0;
                        goto out_no_agbp;
                }
        }
@@ -2766,11 +2766,10 @@ xfs_alloc_pagf_init(
        xfs_buf_t               *bp;
        int                     error;
 
-       if ((error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp)))
-               return error;
-       if (bp)
+       error = xfs_alloc_read_agf(mp, tp, agno, flags, &bp);
+       if (!error)
                xfs_trans_brelse(tp, bp);
-       return 0;
+       return error;
 }
 
 /*
@@ -2956,14 +2955,11 @@ xfs_read_agf(
        trace_xfs_read_agf(mp, agno);
 
        ASSERT(agno != NULLAGNUMBER);
-       error = xfs_trans_read_buf(
-                       mp, tp, mp->m_ddev_targp,
+       error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
                        XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
                        XFS_FSS_TO_BB(mp, 1), flags, bpp, &xfs_agf_buf_ops);
        if (error)
                return error;
-       if (!*bpp)
-               return 0;
 
        ASSERT(!(*bpp)->b_error);
        xfs_buf_set_ref(*bpp, XFS_AGF_REF);
@@ -2987,14 +2983,15 @@ xfs_alloc_read_agf(
 
        trace_xfs_alloc_read_agf(mp, agno);
 
+       /* We don't support trylock when freeing. */
+       ASSERT((flags & (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK)) !=
+                       (XFS_ALLOC_FLAG_FREEING | XFS_ALLOC_FLAG_TRYLOCK));
        ASSERT(agno != NULLAGNUMBER);
        error = xfs_read_agf(mp, tp, agno,
                        (flags & XFS_ALLOC_FLAG_TRYLOCK) ? XBF_TRYLOCK : 0,
                        bpp);
        if (error)
                return error;
-       if (!*bpp)
-               return 0;
        ASSERT(!(*bpp)->b_error);
 
        agf = XFS_BUF_TO_AGF(*bpp);
index a266d05..8b7f74b 100644 (file)
@@ -418,20 +418,10 @@ xfs_attr_rmtval_get(
                               (map[i].br_startblock != HOLESTARTBLOCK));
                        dblkno = XFS_FSB_TO_DADDR(mp, map[i].br_startblock);
                        dblkcnt = XFS_FSB_TO_BB(mp, map[i].br_blockcount);
-                       bp = xfs_buf_read(mp->m_ddev_targp, dblkno, dblkcnt, 0,
-                                       &xfs_attr3_rmt_buf_ops);
-                       if (!bp)
-                               return -ENOMEM;
-                       error = bp->b_error;
-                       if (error) {
-                               xfs_buf_ioerror_alert(bp, __func__);
-                               xfs_buf_relse(bp);
-
-                               /* bad CRC means corrupted metadata */
-                               if (error == -EFSBADCRC)
-                                       error = -EFSCORRUPTED;
+                       error = xfs_buf_read(mp->m_ddev_targp, dblkno, dblkcnt,
+                                       0, &bp, &xfs_attr3_rmt_buf_ops);
+                       if (error)
                                return error;
-                       }
 
                        error = xfs_attr_rmtval_copyout(mp, bp, args->dp->i_ino,
                                                        &offset, &valuelen,
@@ -555,9 +545,9 @@ xfs_attr_rmtval_set(
                dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
                dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
 
-               bp = xfs_buf_get(mp->m_ddev_targp, dblkno, dblkcnt);
-               if (!bp)
-                       return -ENOMEM;
+               error = xfs_buf_get(mp->m_ddev_targp, dblkno, dblkcnt, &bp);
+               if (error)
+                       return error;
                bp->b_ops = &xfs_attr3_rmt_buf_ops;
 
                xfs_attr_rmtval_copyin(mp, bp, args->dp->i_ino, &offset,
index 4c2e046..9a6d7a8 100644 (file)
@@ -730,11 +730,11 @@ xfs_bmap_extents_to_btree(
        cur->bc_private.b.allocated++;
        ip->i_d.di_nblocks++;
        xfs_trans_mod_dquot_byino(tp, ip, XFS_TRANS_DQ_BCOUNT, 1L);
-       abp = xfs_btree_get_bufl(mp, tp, args.fsbno);
-       if (XFS_IS_CORRUPT(mp, !abp)) {
-               error = -EFSCORRUPTED;
+       error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
+                       XFS_FSB_TO_DADDR(mp, args.fsbno),
+                       mp->m_bsize, 0, &abp);
+       if (error)
                goto out_unreserve_dquot;
-       }
 
        /*
         * Fill in the child block.
@@ -878,7 +878,11 @@ xfs_bmap_local_to_extents(
        ASSERT(args.fsbno != NULLFSBLOCK);
        ASSERT(args.len == 1);
        tp->t_firstblock = args.fsbno;
-       bp = xfs_btree_get_bufl(args.mp, tp, args.fsbno);
+       error = xfs_trans_get_buf(tp, args.mp->m_ddev_targp,
+                       XFS_FSB_TO_DADDR(args.mp, args.fsbno),
+                       args.mp->m_bsize, 0, &bp);
+       if (error)
+               goto done;
 
        /*
         * Initialize the block, copy the data and log the remote buffer.
@@ -3307,11 +3311,12 @@ xfs_bmap_longest_free_extent(
        pag = xfs_perag_get(mp, ag);
        if (!pag->pagf_init) {
                error = xfs_alloc_pagf_init(mp, tp, ag, XFS_ALLOC_FLAG_TRYLOCK);
-               if (error)
-                       goto out;
-
-               if (!pag->pagf_init) {
-                       *notinit = 1;
+               if (error) {
+                       /* Couldn't lock the AGF, so skip this AG. */
+                       if (error == -EAGAIN) {
+                               *notinit = 1;
+                               error = 0;
+                       }
                        goto out;
                }
        }
index b22c7e9..fd300dc 100644 (file)
@@ -679,42 +679,6 @@ xfs_btree_get_block(
 }
 
 /*
- * Get a buffer for the block, return it with no data read.
- * Long-form addressing.
- */
-xfs_buf_t *                            /* buffer for fsbno */
-xfs_btree_get_bufl(
-       xfs_mount_t     *mp,            /* file system mount point */
-       xfs_trans_t     *tp,            /* transaction pointer */
-       xfs_fsblock_t   fsbno)          /* file system block number */
-{
-       xfs_daddr_t             d;              /* real disk block address */
-
-       ASSERT(fsbno != NULLFSBLOCK);
-       d = XFS_FSB_TO_DADDR(mp, fsbno);
-       return xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, 0);
-}
-
-/*
- * Get a buffer for the block, return it with no data read.
- * Short-form addressing.
- */
-xfs_buf_t *                            /* buffer for agno/agbno */
-xfs_btree_get_bufs(
-       xfs_mount_t     *mp,            /* file system mount point */
-       xfs_trans_t     *tp,            /* transaction pointer */
-       xfs_agnumber_t  agno,           /* allocation group number */
-       xfs_agblock_t   agbno)          /* allocation group block number */
-{
-       xfs_daddr_t             d;              /* real disk block address */
-
-       ASSERT(agno != NULLAGNUMBER);
-       ASSERT(agbno != NULLAGBLOCK);
-       d = XFS_AGB_TO_DADDR(mp, agno, agbno);
-       return xfs_trans_get_buf(tp, mp->m_ddev_targp, d, mp->m_bsize, 0);
-}
-
-/*
  * Change the cursor to point to the first record at the given level.
  * Other levels are unaffected.
  */
@@ -1270,11 +1234,10 @@ xfs_btree_get_buf_block(
        error = xfs_btree_ptr_to_daddr(cur, ptr, &d);
        if (error)
                return error;
-       *bpp = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d,
-                                mp->m_bsize, 0);
-
-       if (!*bpp)
-               return -ENOMEM;
+       error = xfs_trans_get_buf(cur->bc_tp, mp->m_ddev_targp, d, mp->m_bsize,
+                       0, bpp);
+       if (error)
+               return error;
 
        (*bpp)->b_ops = cur->bc_ops->buf_ops;
        *block = XFS_BUF_TO_BLOCK(*bpp);
index fb9b212..3eff7c3 100644 (file)
@@ -297,27 +297,6 @@ xfs_btree_dup_cursor(
        xfs_btree_cur_t         **ncur);/* output cursor */
 
 /*
- * Get a buffer for the block, return it with no data read.
- * Long-form addressing.
- */
-struct xfs_buf *                               /* buffer for fsbno */
-xfs_btree_get_bufl(
-       struct xfs_mount        *mp,    /* file system mount point */
-       struct xfs_trans        *tp,    /* transaction pointer */
-       xfs_fsblock_t           fsbno); /* file system block number */
-
-/*
- * Get a buffer for the block, return it with no data read.
- * Short-form addressing.
- */
-struct xfs_buf *                               /* buffer for agno/agbno */
-xfs_btree_get_bufs(
-       struct xfs_mount        *mp,    /* file system mount point */
-       struct xfs_trans        *tp,    /* transaction pointer */
-       xfs_agnumber_t          agno,   /* allocation group number */
-       xfs_agblock_t           agbno); /* allocation group block number */
-
-/*
  * Compute first and last byte offsets for the fields given.
  * Interprets the offsets table, which contains struct field offsets.
  */
index 8c3eafe..875e04f 100644 (file)
@@ -2591,13 +2591,9 @@ xfs_da_get_buf(
        if (error || nmap == 0)
                goto out_free;
 
-       bp = xfs_trans_get_buf_map(tp, mp->m_ddev_targp, mapp, nmap, 0);
-       error = bp ? bp->b_error : -EIO;
-       if (error) {
-               if (bp)
-                       xfs_trans_brelse(tp, bp);
+       error = xfs_trans_get_buf_map(tp, mp->m_ddev_targp, mapp, nmap, 0, &bp);
+       if (error)
                goto out_free;
-       }
 
        *bpp = bp;
 
index 5b759af..bf161e9 100644 (file)
@@ -276,6 +276,7 @@ xfs_ialloc_inode_init(
        int                     i, j;
        xfs_daddr_t             d;
        xfs_ino_t               ino = 0;
+       int                     error;
 
        /*
         * Loop over the new block(s), filling in the inodes.  For small block
@@ -327,12 +328,11 @@ xfs_ialloc_inode_init(
                 */
                d = XFS_AGB_TO_DADDR(mp, agno, agbno +
                                (j * M_IGEO(mp)->blocks_per_cluster));
-               fbuf = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
-                                        mp->m_bsize *
-                                        M_IGEO(mp)->blocks_per_cluster,
-                                        XBF_UNMAPPED);
-               if (!fbuf)
-                       return -ENOMEM;
+               error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
+                               mp->m_bsize * M_IGEO(mp)->blocks_per_cluster,
+                               XBF_UNMAPPED, &fbuf);
+               if (error)
+                       return error;
 
                /* Initialize the inode buffers and log them appropriately. */
                fbuf->b_ops = &xfs_inode_buf_ops;
index d7d702e..6e1665f 100644 (file)
@@ -1177,8 +1177,6 @@ xfs_refcount_finish_one(
                                XFS_ALLOC_FLAG_FREEING, &agbp);
                if (error)
                        return error;
-               if (XFS_IS_CORRUPT(tp->t_mountp, !agbp))
-                       return -EFSCORRUPTED;
 
                rcur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno);
                if (!rcur) {
@@ -1718,10 +1716,6 @@ xfs_refcount_recover_cow_leftovers(
        error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
        if (error)
                goto out_trans;
-       if (!agbp) {
-               error = -ENOMEM;
-               goto out_trans;
-       }
        cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno);
 
        /* Find all the leftover CoW staging extents. */
index 0ac6975..2f60fc3 100644 (file)
@@ -985,9 +985,9 @@ xfs_update_secondary_sbs(
        for (agno = 1; agno < mp->m_sb.sb_agcount; agno++) {
                struct xfs_buf          *bp;
 
-               bp = xfs_buf_get(mp->m_ddev_targp,
+               error = xfs_buf_get(mp->m_ddev_targp,
                                 XFS_AG_DADDR(mp, agno, XFS_SB_DADDR),
-                                XFS_FSS_TO_BB(mp, 1));
+                                XFS_FSS_TO_BB(mp, 1), &bp);
                /*
                 * If we get an error reading or writing alternate superblocks,
                 * continue.  xfs_repair chooses the "best" superblock based
@@ -995,12 +995,12 @@ xfs_update_secondary_sbs(
                 * superblocks un-updated than updated, and xfs_repair may
                 * pick them over the properly-updated primary.
                 */
-               if (!bp) {
+               if (error) {
                        xfs_warn(mp,
                "error allocating secondary superblock for ag %d",
                                agno);
                        if (!saved_error)
-                               saved_error = -ENOMEM;
+                               saved_error = error;
                        continue;
                }
 
@@ -1185,13 +1185,14 @@ xfs_sb_get_secondary(
        struct xfs_buf          **bpp)
 {
        struct xfs_buf          *bp;
+       int                     error;
 
        ASSERT(agno != 0 && agno != NULLAGNUMBER);
-       bp = xfs_trans_get_buf(tp, mp->m_ddev_targp,
+       error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
                        XFS_AG_DADDR(mp, agno, XFS_SB_BLOCK(mp)),
-                       XFS_FSS_TO_BB(mp, 1), 0);
-       if (!bp)
-               return -ENOMEM;
+                       XFS_FSS_TO_BB(mp, 1), 0, &bp);
+       if (error)
+               return error;
        bp->b_ops = &xfs_sb_buf_ops;
        xfs_buf_oneshot(bp);
        *bpp = bp;
index 7a1a38b..d5e6db9 100644 (file)
@@ -659,8 +659,6 @@ xrep_agfl(
        error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.agno, 0, &agf_bp);
        if (error)
                return error;
-       if (!agf_bp)
-               return -ENOMEM;
 
        /*
         * Make sure we have the AGFL buffer, as scrub might have decided it
@@ -735,8 +733,6 @@ xrep_agi_find_btrees(
        error = xfs_alloc_read_agf(mp, sc->tp, sc->sa.agno, 0, &agf_bp);
        if (error)
                return error;
-       if (!agf_bp)
-               return -ENOMEM;
 
        /* Find the btree roots. */
        error = xrep_find_ag_btree_roots(sc, agf_bp, fab, NULL);
index 7251c66..ec2064e 100644 (file)
@@ -83,9 +83,6 @@ xchk_fscount_warmup(
                error = xfs_alloc_read_agf(mp, sc->tp, agno, 0, &agf_bp);
                if (error)
                        break;
-               error = -ENOMEM;
-               if (!agf_bp || !agi_bp)
-                       break;
 
                /*
                 * These are supposed to be initialized by the header read
index b70a88b..e489d7a 100644 (file)
@@ -341,13 +341,17 @@ xrep_init_btblock(
        struct xfs_trans                *tp = sc->tp;
        struct xfs_mount                *mp = sc->mp;
        struct xfs_buf                  *bp;
+       int                             error;
 
        trace_xrep_init_btblock(mp, XFS_FSB_TO_AGNO(mp, fsb),
                        XFS_FSB_TO_AGBNO(mp, fsb), btnum);
 
        ASSERT(XFS_FSB_TO_AGNO(mp, fsb) == sc->sa.agno);
-       bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, XFS_FSB_TO_DADDR(mp, fsb),
-                       XFS_FSB_TO_BB(mp, 1), 0);
+       error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
+                       XFS_FSB_TO_DADDR(mp, fsb), XFS_FSB_TO_BB(mp, 1), 0,
+                       &bp);
+       if (error)
+               return error;
        xfs_buf_zero(bp, 0, BBTOB(bp->b_length));
        xfs_btree_init_block(mp, bp, btnum, 0, 0, sc->sa.agno);
        xfs_trans_buf_set_type(tp, bp, XFS_BLFT_BTREE_BUF);
@@ -542,8 +546,6 @@ xrep_reap_block(
                error = xfs_alloc_read_agf(sc->mp, sc->tp, agno, 0, &agf_bp);
                if (error)
                        return error;
-               if (!agf_bp)
-                       return -ENOMEM;
        } else {
                agf_bp = sc->sa.agf_bp;
        }
index 8fbb841..bbfa6ba 100644 (file)
@@ -205,11 +205,12 @@ xfs_attr3_node_inactive(
                /*
                 * Remove the subsidiary block from the cache and from the log.
                 */
-               child_bp = xfs_trans_get_buf(*trans, mp->m_ddev_targp,
+               error = xfs_trans_get_buf(*trans, mp->m_ddev_targp,
                                child_blkno,
-                               XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0);
-               if (!child_bp)
-                       return -EIO;
+                               XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0,
+                               &child_bp);
+               if (error)
+                       return error;
                error = bp->b_error;
                if (error) {
                        xfs_trans_brelse(*trans, child_bp);
@@ -298,10 +299,10 @@ xfs_attr3_root_inactive(
        /*
         * Invalidate the incore copy of the root block.
         */
-       bp = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno,
-                       XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0);
-       if (!bp)
-               return -EIO;
+       error = xfs_trans_get_buf(*trans, mp->m_ddev_targp, blkno,
+                       XFS_FSB_TO_BB(mp, mp->m_attr_geo->fsbcount), 0, &bp);
+       if (error)
+               return error;
        error = bp->b_error;
        if (error) {
                xfs_trans_brelse(*trans, bp);
index a0229c3..217e4f8 100644 (file)
@@ -198,20 +198,22 @@ xfs_buf_free_maps(
        }
 }
 
-static struct xfs_buf *
+static int
 _xfs_buf_alloc(
        struct xfs_buftarg      *target,
        struct xfs_buf_map      *map,
        int                     nmaps,
-       xfs_buf_flags_t         flags)
+       xfs_buf_flags_t         flags,
+       struct xfs_buf          **bpp)
 {
        struct xfs_buf          *bp;
        int                     error;
        int                     i;
 
+       *bpp = NULL;
        bp = kmem_zone_zalloc(xfs_buf_zone, KM_NOFS);
        if (unlikely(!bp))
-               return NULL;
+               return -ENOMEM;
 
        /*
         * We don't want certain flags to appear in b_flags unless they are
@@ -239,7 +241,7 @@ _xfs_buf_alloc(
        error = xfs_buf_get_maps(bp, nmaps);
        if (error)  {
                kmem_cache_free(xfs_buf_zone, bp);
-               return NULL;
+               return error;
        }
 
        bp->b_bn = map[0].bm_bn;
@@ -256,7 +258,8 @@ _xfs_buf_alloc(
        XFS_STATS_INC(bp->b_mount, xb_create);
        trace_xfs_buf_init(bp, _RET_IP_);
 
-       return bp;
+       *bpp = bp;
+       return 0;
 }
 
 /*
@@ -682,53 +685,39 @@ xfs_buf_incore(
  * cache hits, as metadata intensive workloads will see 3 orders of magnitude
  * more hits than misses.
  */
-struct xfs_buf *
+int
 xfs_buf_get_map(
        struct xfs_buftarg      *target,
        struct xfs_buf_map      *map,
        int                     nmaps,
-       xfs_buf_flags_t         flags)
+       xfs_buf_flags_t         flags,
+       struct xfs_buf          **bpp)
 {
        struct xfs_buf          *bp;
        struct xfs_buf          *new_bp;
        int                     error = 0;
 
+       *bpp = NULL;
        error = xfs_buf_find(target, map, nmaps, flags, NULL, &bp);
-
-       switch (error) {
-       case 0:
-               /* cache hit */
+       if (!error)
                goto found;
-       case -EAGAIN:
-               /* cache hit, trylock failure, caller handles failure */
-               ASSERT(flags & XBF_TRYLOCK);
-               return NULL;
-       case -ENOENT:
-               /* cache miss, go for insert */
-               break;
-       case -EFSCORRUPTED:
-       default:
-               /*
-                * None of the higher layers understand failure types
-                * yet, so return NULL to signal a fatal lookup error.
-                */
-               return NULL;
-       }
+       if (error != -ENOENT)
+               return error;
 
-       new_bp = _xfs_buf_alloc(target, map, nmaps, flags);
-       if (unlikely(!new_bp))
-               return NULL;
+       error = _xfs_buf_alloc(target, map, nmaps, flags, &new_bp);
+       if (error)
+               return error;
 
        error = xfs_buf_allocate_memory(new_bp, flags);
        if (error) {
                xfs_buf_free(new_bp);
-               return NULL;
+               return error;
        }
 
        error = xfs_buf_find(target, map, nmaps, flags, new_bp, &bp);
        if (error) {
                xfs_buf_free(new_bp);
-               return NULL;
+               return error;
        }
 
        if (bp != new_bp)
@@ -741,7 +730,7 @@ found:
                        xfs_warn(target->bt_mount,
                                "%s: failed to map pagesn", __func__);
                        xfs_buf_relse(bp);
-                       return NULL;
+                       return error;
                }
        }
 
@@ -754,7 +743,8 @@ found:
 
        XFS_STATS_INC(target->bt_mount, xb_get);
        trace_xfs_buf_get(bp, flags, _RET_IP_);
-       return bp;
+       *bpp = bp;
+       return 0;
 }
 
 STATIC int
@@ -806,46 +796,77 @@ xfs_buf_reverify(
        return bp->b_error;
 }
 
-xfs_buf_t *
+int
 xfs_buf_read_map(
        struct xfs_buftarg      *target,
        struct xfs_buf_map      *map,
        int                     nmaps,
        xfs_buf_flags_t         flags,
-       const struct xfs_buf_ops *ops)
+       struct xfs_buf          **bpp,
+       const struct xfs_buf_ops *ops,
+       xfs_failaddr_t          fa)
 {
        struct xfs_buf          *bp;
+       int                     error;
 
        flags |= XBF_READ;
+       *bpp = NULL;
 
-       bp = xfs_buf_get_map(target, map, nmaps, flags);
-       if (!bp)
-               return NULL;
+       error = xfs_buf_get_map(target, map, nmaps, flags, &bp);
+       if (error)
+               return error;
 
        trace_xfs_buf_read(bp, flags, _RET_IP_);
 
        if (!(bp->b_flags & XBF_DONE)) {
+               /* Initiate the buffer read and wait. */
                XFS_STATS_INC(target->bt_mount, xb_get_read);
                bp->b_ops = ops;
-               _xfs_buf_read(bp, flags);
-               return bp;
+               error = _xfs_buf_read(bp, flags);
+
+               /* Readahead iodone already dropped the buffer, so exit. */
+               if (flags & XBF_ASYNC)
+                       return 0;
+       } else {
+               /* Buffer already read; all we need to do is check it. */
+               error = xfs_buf_reverify(bp, ops);
+
+               /* Readahead already finished; drop the buffer and exit. */
+               if (flags & XBF_ASYNC) {
+                       xfs_buf_relse(bp);
+                       return 0;
+               }
+
+               /* We do not want read in the flags */
+               bp->b_flags &= ~XBF_READ;
+               ASSERT(bp->b_ops != NULL || ops == NULL);
        }
 
-       xfs_buf_reverify(bp, ops);
+       /*
+        * If we've had a read error, then the contents of the buffer are
+        * invalid and should not be used. To ensure that a followup read tries
+        * to pull the buffer from disk again, we clear the XBF_DONE flag and
+        * mark the buffer stale. This ensures that anyone who has a current
+        * reference to the buffer will interpret it's contents correctly and
+        * future cache lookups will also treat it as an empty, uninitialised
+        * buffer.
+        */
+       if (error) {
+               if (!XFS_FORCED_SHUTDOWN(target->bt_mount))
+                       xfs_buf_ioerror_alert(bp, fa);
 
-       if (flags & XBF_ASYNC) {
-               /*
-                * Read ahead call which is already satisfied,
-                * drop the buffer
-                */
+               bp->b_flags &= ~XBF_DONE;
+               xfs_buf_stale(bp);
                xfs_buf_relse(bp);
-               return NULL;
+
+               /* bad CRC means corrupted metadata */
+               if (error == -EFSBADCRC)
+                       error = -EFSCORRUPTED;
+               return error;
        }
 
-       /* We do not want read in the flags */
-       bp->b_flags &= ~XBF_READ;
-       ASSERT(bp->b_ops != NULL || ops == NULL);
-       return bp;
+       *bpp = bp;
+       return 0;
 }
 
 /*
@@ -859,11 +880,14 @@ xfs_buf_readahead_map(
        int                     nmaps,
        const struct xfs_buf_ops *ops)
 {
+       struct xfs_buf          *bp;
+
        if (bdi_read_congested(target->bt_bdev->bd_bdi))
                return;
 
        xfs_buf_read_map(target, map, nmaps,
-                    XBF_TRYLOCK|XBF_ASYNC|XBF_READ_AHEAD, ops);
+                    XBF_TRYLOCK | XBF_ASYNC | XBF_READ_AHEAD, &bp, ops,
+                    __this_address);
 }
 
 /*
@@ -880,12 +904,13 @@ xfs_buf_read_uncached(
        const struct xfs_buf_ops *ops)
 {
        struct xfs_buf          *bp;
+       int                     error;
 
        *bpp = NULL;
 
-       bp = xfs_buf_get_uncached(target, numblks, flags);
-       if (!bp)
-               return -ENOMEM;
+       error = xfs_buf_get_uncached(target, numblks, flags, &bp);
+       if (error)
+               return error;
 
        /* set up the buffer for a read IO */
        ASSERT(bp->b_map_count == 1);
@@ -896,7 +921,7 @@ xfs_buf_read_uncached(
 
        xfs_buf_submit(bp);
        if (bp->b_error) {
-               int     error = bp->b_error;
+               error = bp->b_error;
                xfs_buf_relse(bp);
                return error;
        }
@@ -905,20 +930,23 @@ xfs_buf_read_uncached(
        return 0;
 }
 
-xfs_buf_t *
+int
 xfs_buf_get_uncached(
        struct xfs_buftarg      *target,
        size_t                  numblks,
-       int                     flags)
+       int                     flags,
+       struct xfs_buf          **bpp)
 {
        unsigned long           page_count;
        int                     error, i;
        struct xfs_buf          *bp;
        DEFINE_SINGLE_BUF_MAP(map, XFS_BUF_DADDR_NULL, numblks);
 
+       *bpp = NULL;
+
        /* flags might contain irrelevant bits, pass only what we care about */
-       bp = _xfs_buf_alloc(target, &map, 1, flags & XBF_NO_IOACCT);
-       if (unlikely(bp == NULL))
+       error = _xfs_buf_alloc(target, &map, 1, flags & XBF_NO_IOACCT, &bp);
+       if (error)
                goto fail;
 
        page_count = PAGE_ALIGN(numblks << BBSHIFT) >> PAGE_SHIFT;
@@ -928,8 +956,10 @@ xfs_buf_get_uncached(
 
        for (i = 0; i < page_count; i++) {
                bp->b_pages[i] = alloc_page(xb_to_gfp(flags));
-               if (!bp->b_pages[i])
+               if (!bp->b_pages[i]) {
+                       error = -ENOMEM;
                        goto fail_free_mem;
+               }
        }
        bp->b_flags |= _XBF_PAGES;
 
@@ -941,7 +971,8 @@ xfs_buf_get_uncached(
        }
 
        trace_xfs_buf_get_uncached(bp, _RET_IP_);
-       return bp;
+       *bpp = bp;
+       return 0;
 
  fail_free_mem:
        while (--i >= 0)
@@ -951,7 +982,7 @@ xfs_buf_get_uncached(
        xfs_buf_free_maps(bp);
        kmem_cache_free(xfs_buf_zone, bp);
  fail:
-       return NULL;
+       return error;
 }
 
 /*
@@ -1205,10 +1236,10 @@ __xfs_buf_ioerror(
 void
 xfs_buf_ioerror_alert(
        struct xfs_buf          *bp,
-       const char              *func)
+       xfs_failaddr_t          func)
 {
        xfs_alert(bp->b_mount,
-"metadata I/O error in \"%s\" at daddr 0x%llx len %d error %d",
+"metadata I/O error in \"%pS\" at daddr 0x%llx len %d error %d",
                        func, (uint64_t)XFS_BUF_ADDR(bp), bp->b_length,
                        -bp->b_error);
 }
index 56e081d..d79a1fe 100644 (file)
@@ -192,37 +192,40 @@ struct xfs_buf *xfs_buf_incore(struct xfs_buftarg *target,
                           xfs_daddr_t blkno, size_t numblks,
                           xfs_buf_flags_t flags);
 
-struct xfs_buf *xfs_buf_get_map(struct xfs_buftarg *target,
-                              struct xfs_buf_map *map, int nmaps,
-                              xfs_buf_flags_t flags);
-struct xfs_buf *xfs_buf_read_map(struct xfs_buftarg *target,
-                              struct xfs_buf_map *map, int nmaps,
-                              xfs_buf_flags_t flags,
-                              const struct xfs_buf_ops *ops);
+int xfs_buf_get_map(struct xfs_buftarg *target, struct xfs_buf_map *map,
+               int nmaps, xfs_buf_flags_t flags, struct xfs_buf **bpp);
+int xfs_buf_read_map(struct xfs_buftarg *target, struct xfs_buf_map *map,
+               int nmaps, xfs_buf_flags_t flags, struct xfs_buf **bpp,
+               const struct xfs_buf_ops *ops, xfs_failaddr_t fa);
 void xfs_buf_readahead_map(struct xfs_buftarg *target,
                               struct xfs_buf_map *map, int nmaps,
                               const struct xfs_buf_ops *ops);
 
-static inline struct xfs_buf *
+static inline int
 xfs_buf_get(
        struct xfs_buftarg      *target,
        xfs_daddr_t             blkno,
-       size_t                  numblks)
+       size_t                  numblks,
+       struct xfs_buf          **bpp)
 {
        DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
-       return xfs_buf_get_map(target, &map, 1, 0);
+
+       return xfs_buf_get_map(target, &map, 1, 0, bpp);
 }
 
-static inline struct xfs_buf *
+static inline int
 xfs_buf_read(
        struct xfs_buftarg      *target,
        xfs_daddr_t             blkno,
        size_t                  numblks,
        xfs_buf_flags_t         flags,
+       struct xfs_buf          **bpp,
        const struct xfs_buf_ops *ops)
 {
        DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
-       return xfs_buf_read_map(target, &map, 1, flags, ops);
+
+       return xfs_buf_read_map(target, &map, 1, flags, bpp, ops,
+                       __builtin_return_address(0));
 }
 
 static inline void
@@ -236,8 +239,8 @@ xfs_buf_readahead(
        return xfs_buf_readahead_map(target, &map, 1, ops);
 }
 
-struct xfs_buf *xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks,
-                               int flags);
+int xfs_buf_get_uncached(struct xfs_buftarg *target, size_t numblks, int flags,
+               struct xfs_buf **bpp);
 int xfs_buf_read_uncached(struct xfs_buftarg *target, xfs_daddr_t daddr,
                          size_t numblks, int flags, struct xfs_buf **bpp,
                          const struct xfs_buf_ops *ops);
@@ -259,7 +262,7 @@ extern void xfs_buf_ioend(struct xfs_buf *bp);
 extern void __xfs_buf_ioerror(struct xfs_buf *bp, int error,
                xfs_failaddr_t failaddr);
 #define xfs_buf_ioerror(bp, err) __xfs_buf_ioerror((bp), (err), __this_address)
-extern void xfs_buf_ioerror_alert(struct xfs_buf *, const char *func);
+extern void xfs_buf_ioerror_alert(struct xfs_buf *bp, xfs_failaddr_t fa);
 
 extern int __xfs_buf_submit(struct xfs_buf *bp, bool);
 static inline int xfs_buf_submit(struct xfs_buf *bp)
index 5be8973..663810e 100644 (file)
@@ -1113,7 +1113,7 @@ xfs_buf_iodone_callback_error(
        if (bp->b_target != lasttarg ||
            time_after(jiffies, (lasttime + 5*HZ))) {
                lasttime = jiffies;
-               xfs_buf_ioerror_alert(bp, __func__);
+               xfs_buf_ioerror_alert(bp, __this_address);
        }
        lasttarg = bp->b_target;
 
index cae6136..0b8350e 100644 (file)
@@ -45,7 +45,7 @@ xfs_trim_extents(
        xfs_log_force(mp, XFS_LOG_SYNC);
 
        error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agbp);
-       if (error || !agbp)
+       if (error)
                goto out_put_perag;
 
        cur = xfs_allocbt_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_CNT);
index 9cfd320..d223e1a 100644 (file)
@@ -320,10 +320,10 @@ xfs_dquot_disk_alloc(
        dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock);
 
        /* now we can just get the buffer (there's nothing to read yet) */
-       bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, dqp->q_blkno,
-                       mp->m_quotainfo->qi_dqchunklen, 0);
-       if (!bp)
-               return -ENOMEM;
+       error = xfs_trans_get_buf(tp, mp->m_ddev_targp, dqp->q_blkno,
+                       mp->m_quotainfo->qi_dqchunklen, 0, &bp);
+       if (error)
+               return error;
        bp->b_ops = &xfs_dquot_buf_ops;
 
        /*
index 5f12b5d..1a88025 100644 (file)
@@ -159,16 +159,15 @@ xfs_filestream_pick_ag(
 
                if (!pag->pagf_init) {
                        err = xfs_alloc_pagf_init(mp, NULL, ag, trylock);
-                       if (err && !trylock) {
+                       if (err) {
                                xfs_perag_put(pag);
-                               return err;
+                               if (err != -EAGAIN)
+                                       return err;
+                               /* Couldn't lock the AGF, skip this AG. */
+                               continue;
                        }
                }
 
-               /* Might fail sometimes during the 1st pass with trylock set. */
-               if (!pag->pagf_init)
-                       goto next_ag;
-
                /* Keep track of the AG with the most free blocks. */
                if (pag->pagf_freeblks > maxfree) {
                        maxfree = pag->pagf_freeblks;
index 1979a00..c5077e6 100644 (file)
@@ -2546,6 +2546,7 @@ xfs_ifree_cluster(
        struct xfs_perag        *pag;
        struct xfs_ino_geometry *igeo = M_IGEO(mp);
        xfs_ino_t               inum;
+       int                     error;
 
        inum = xic->first_ino;
        pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, inum));
@@ -2574,12 +2575,11 @@ xfs_ifree_cluster(
                 * complete before we get a lock on it, and hence we may fail
                 * to mark all the active inodes on the buffer stale.
                 */
-               bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
-                                       mp->m_bsize * igeo->blocks_per_cluster,
-                                       XBF_UNMAPPED);
-
-               if (!bp)
-                       return -ENOMEM;
+               error = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno,
+                               mp->m_bsize * igeo->blocks_per_cluster,
+                               XBF_UNMAPPED, &bp);
+               if (error)
+                       return error;
 
                /*
                 * This buffer may not have been correctly initialised as we
index 0d683fb..25cfc85 100644 (file)
@@ -294,7 +294,7 @@ xlog_recover_iodone(
                 * this during recovery. One strike!
                 */
                if (!XFS_FORCED_SHUTDOWN(bp->b_mount)) {
-                       xfs_buf_ioerror_alert(bp, __func__);
+                       xfs_buf_ioerror_alert(bp, __this_address);
                        xfs_force_shutdown(bp->b_mount, SHUTDOWN_META_IO_ERROR);
                }
        }
@@ -2745,15 +2745,10 @@ xlog_recover_buffer_pass2(
        if (buf_f->blf_flags & XFS_BLF_INODE_BUF)
                buf_flags |= XBF_UNMAPPED;
 
-       bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len,
-                         buf_flags, NULL);
-       if (!bp)
-               return -ENOMEM;
-       error = bp->b_error;
-       if (error) {
-               xfs_buf_ioerror_alert(bp, "xlog_recover_do..(read#1)");
-               goto out_release;
-       }
+       error = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len,
+                         buf_flags, &bp, NULL);
+       if (error)
+               return error;
 
        /*
         * Recover the buffer only if we get an LSN from it and it's less than
@@ -2950,17 +2945,10 @@ xlog_recover_inode_pass2(
        }
        trace_xfs_log_recover_inode_recover(log, in_f);
 
-       bp = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len, 0,
-                         &xfs_inode_buf_ops);
-       if (!bp) {
-               error = -ENOMEM;
+       error = xfs_buf_read(mp->m_ddev_targp, in_f->ilf_blkno, in_f->ilf_len,
+                       0, &bp, &xfs_inode_buf_ops);
+       if (error)
                goto error;
-       }
-       error = bp->b_error;
-       if (error) {
-               xfs_buf_ioerror_alert(bp, "xlog_recover_do..(read#2)");
-               goto out_release;
-       }
        ASSERT(in_f->ilf_fields & XFS_ILOG_CORE);
        dip = xfs_buf_offset(bp, in_f->ilf_boffset);
 
@@ -5639,7 +5627,7 @@ xlog_do_recover(
        error = xfs_buf_submit(bp);
        if (error) {
                if (!XFS_FORCED_SHUTDOWN(mp)) {
-                       xfs_buf_ioerror_alert(bp, __func__);
+                       xfs_buf_ioerror_alert(bp, __this_address);
                        ASSERT(0);
                }
                xfs_buf_relse(bp);
index e723b26..b0ce04f 100644 (file)
@@ -143,8 +143,6 @@ xfs_reflink_find_shared(
        error = xfs_alloc_read_agf(mp, tp, agno, 0, &agbp);
        if (error)
                return error;
-       if (!agbp)
-               return -ENOMEM;
 
        cur = xfs_refcountbt_init_cursor(mp, tp, agbp, agno);
 
index d42b5a2..6209e7b 100644 (file)
@@ -826,12 +826,10 @@ xfs_growfs_rt_alloc(
                         * Get a buffer for the block.
                         */
                        d = XFS_FSB_TO_DADDR(mp, fsbno);
-                       bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
-                               mp->m_bsize, 0);
-                       if (bp == NULL) {
-                               error = -EIO;
+                       error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
+                                       mp->m_bsize, 0, &bp);
+                       if (error)
                                goto out_trans_cancel;
-                       }
                        memset(bp->b_addr, 0, mp->m_sb.sb_blocksize);
                        xfs_trans_log_buf(tp, bp, 0, mp->m_sb.sb_blocksize - 1);
                        /*
index 7609017..2094386 100644 (file)
@@ -62,7 +62,7 @@ enum {
        Opt_discard, Opt_nodiscard, Opt_dax,
 };
 
-static const struct fs_parameter_spec xfs_param_specs[] = {
+static const struct fs_parameter_spec xfs_fs_parameters[] = {
        fsparam_u32("logbufs",          Opt_logbufs),
        fsparam_string("logbsize",      Opt_logbsize),
        fsparam_string("logdev",        Opt_logdev),
@@ -106,11 +106,6 @@ static const struct fs_parameter_spec xfs_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description xfs_fs_parameters = {
-       .name           = "xfs",
-       .specs          = xfs_param_specs,
-};
-
 struct proc_xfs_info {
        uint64_t        flag;
        char            *str;
@@ -1120,7 +1115,7 @@ xfs_fc_parse_param(
        int                     size = 0;
        int                     opt;
 
-       opt = fs_parse(fc, &xfs_fs_parameters, param, &result);
+       opt = fs_parse(fc, xfs_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -1782,7 +1777,7 @@ static struct file_system_type xfs_fs_type = {
        .owner                  = THIS_MODULE,
        .name                   = "xfs",
        .init_fs_context        = xfs_init_fs_context,
-       .parameters             = &xfs_fs_parameters,
+       .parameters             = xfs_fs_parameters,
        .kill_sb                = kill_block_super,
        .fs_flags               = FS_REQUIRES_DEV,
 };
index a25502b..d762d42 100644 (file)
@@ -53,20 +53,10 @@ xfs_readlink_bmap_ilocked(
                d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
                byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
 
-               bp = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0,
-                                 &xfs_symlink_buf_ops);
-               if (!bp)
-                       return -ENOMEM;
-               error = bp->b_error;
-               if (error) {
-                       xfs_buf_ioerror_alert(bp, __func__);
-                       xfs_buf_relse(bp);
-
-                       /* bad CRC means corrupted metadata */
-                       if (error == -EFSBADCRC)
-                               error = -EFSCORRUPTED;
-                       goto out;
-               }
+               error = xfs_buf_read(mp->m_ddev_targp, d, BTOBB(byte_cnt), 0,
+                               &bp, &xfs_symlink_buf_ops);
+               if (error)
+                       return error;
                byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
                if (pathlen < byte_cnt)
                        byte_cnt = pathlen;
@@ -290,12 +280,10 @@ xfs_symlink(
 
                        d = XFS_FSB_TO_DADDR(mp, mval[n].br_startblock);
                        byte_cnt = XFS_FSB_TO_B(mp, mval[n].br_blockcount);
-                       bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
-                                              BTOBB(byte_cnt), 0);
-                       if (!bp) {
-                               error = -ENOMEM;
+                       error = xfs_trans_get_buf(tp, mp->m_ddev_targp, d,
+                                              BTOBB(byte_cnt), 0, &bp);
+                       if (error)
                                goto out_trans_cancel;
-                       }
                        bp->b_ops = &xfs_symlink_buf_ops;
 
                        byte_cnt = XFS_SYMLINK_BUF_SPACE(mp, byte_cnt);
@@ -433,13 +421,12 @@ xfs_inactive_symlink_rmt(
         * Invalidate the block(s). No validation is done.
         */
        for (i = 0; i < nmaps; i++) {
-               bp = xfs_trans_get_buf(tp, mp->m_ddev_targp,
-                       XFS_FSB_TO_DADDR(mp, mval[i].br_startblock),
-                       XFS_FSB_TO_BB(mp, mval[i].br_blockcount), 0);
-               if (!bp) {
-                       error = -ENOMEM;
+               error = xfs_trans_get_buf(tp, mp->m_ddev_targp,
+                               XFS_FSB_TO_DADDR(mp, mval[i].br_startblock),
+                               XFS_FSB_TO_BB(mp, mval[i].br_blockcount), 0,
+                               &bp);
+               if (error)
                        goto error_trans_cancel;
-               }
                xfs_trans_binval(tp, bp);
        }
        /*
index 64d7f17..752c7fe 100644 (file)
@@ -169,21 +169,21 @@ int               xfs_trans_alloc_empty(struct xfs_mount *mp,
                        struct xfs_trans **tpp);
 void           xfs_trans_mod_sb(xfs_trans_t *, uint, int64_t);
 
-struct xfs_buf *xfs_trans_get_buf_map(struct xfs_trans *tp,
-                                      struct xfs_buftarg *target,
-                                      struct xfs_buf_map *map, int nmaps,
-                                      uint flags);
+int xfs_trans_get_buf_map(struct xfs_trans *tp, struct xfs_buftarg *target,
+               struct xfs_buf_map *map, int nmaps, xfs_buf_flags_t flags,
+               struct xfs_buf **bpp);
 
-static inline struct xfs_buf *
+static inline int
 xfs_trans_get_buf(
        struct xfs_trans        *tp,
        struct xfs_buftarg      *target,
        xfs_daddr_t             blkno,
        int                     numblks,
-       uint                    flags)
+       uint                    flags,
+       struct xfs_buf          **bpp)
 {
        DEFINE_SINGLE_BUF_MAP(map, blkno, numblks);
-       return xfs_trans_get_buf_map(tp, target, &map, 1, flags);
+       return xfs_trans_get_buf_map(tp, target, &map, 1, flags, bpp);
 }
 
 int            xfs_trans_read_buf_map(struct xfs_mount *mp,
index b5b3a78..08174ff 100644 (file)
@@ -112,19 +112,22 @@ xfs_trans_bjoin(
  * If the transaction pointer is NULL, make this just a normal
  * get_buf() call.
  */
-struct xfs_buf *
+int
 xfs_trans_get_buf_map(
        struct xfs_trans        *tp,
        struct xfs_buftarg      *target,
        struct xfs_buf_map      *map,
        int                     nmaps,
-       xfs_buf_flags_t         flags)
+       xfs_buf_flags_t         flags,
+       struct xfs_buf          **bpp)
 {
        xfs_buf_t               *bp;
        struct xfs_buf_log_item *bip;
+       int                     error;
 
+       *bpp = NULL;
        if (!tp)
-               return xfs_buf_get_map(target, map, nmaps, flags);
+               return xfs_buf_get_map(target, map, nmaps, flags, bpp);
 
        /*
         * If we find the buffer in the cache with this transaction
@@ -146,19 +149,20 @@ xfs_trans_get_buf_map(
                ASSERT(atomic_read(&bip->bli_refcount) > 0);
                bip->bli_recur++;
                trace_xfs_trans_get_buf_recur(bip);
-               return bp;
+               *bpp = bp;
+               return 0;
        }
 
-       bp = xfs_buf_get_map(target, map, nmaps, flags);
-       if (bp == NULL) {
-               return NULL;
-       }
+       error = xfs_buf_get_map(target, map, nmaps, flags, &bp);
+       if (error)
+               return error;
 
        ASSERT(!bp->b_error);
 
        _xfs_trans_bjoin(tp, bp, 1);
        trace_xfs_trans_get_buf(bp->b_log_item);
-       return bp;
+       *bpp = bp;
+       return 0;
 }
 
 /*
@@ -276,7 +280,7 @@ xfs_trans_read_buf_map(
                ASSERT(bp->b_ops != NULL);
                error = xfs_buf_reverify(bp, ops);
                if (error) {
-                       xfs_buf_ioerror_alert(bp, __func__);
+                       xfs_buf_ioerror_alert(bp, __return_address);
 
                        if (tp->t_flags & XFS_TRANS_DIRTY)
                                xfs_force_shutdown(tp->t_mountp,
@@ -298,36 +302,17 @@ xfs_trans_read_buf_map(
                return 0;
        }
 
-       bp = xfs_buf_read_map(target, map, nmaps, flags, ops);
-       if (!bp) {
-               if (!(flags & XBF_TRYLOCK))
-                       return -ENOMEM;
-               return tp ? 0 : -EAGAIN;
-       }
-
-       /*
-        * If we've had a read error, then the contents of the buffer are
-        * invalid and should not be used. To ensure that a followup read tries
-        * to pull the buffer from disk again, we clear the XBF_DONE flag and
-        * mark the buffer stale. This ensures that anyone who has a current
-        * reference to the buffer will interpret it's contents correctly and
-        * future cache lookups will also treat it as an empty, uninitialised
-        * buffer.
-        */
-       if (bp->b_error) {
-               error = bp->b_error;
-               if (!XFS_FORCED_SHUTDOWN(mp))
-                       xfs_buf_ioerror_alert(bp, __func__);
-               bp->b_flags &= ~XBF_DONE;
-               xfs_buf_stale(bp);
-
+       error = xfs_buf_read_map(target, map, nmaps, flags, &bp, ops,
+                       __return_address);
+       switch (error) {
+       case 0:
+               break;
+       default:
                if (tp && (tp->t_flags & XFS_TRANS_DIRTY))
                        xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
-               xfs_buf_relse(bp);
-
-               /* bad CRC means corrupted metadata */
-               if (error == -EFSBADCRC)
-                       error = -EFSCORRUPTED;
+               /* fall through */
+       case -ENOMEM:
+       case -EAGAIN:
                return error;
        }
 
index ddfee1b..cd17d50 100644 (file)
@@ -4,5 +4,6 @@
 # (This file is not included when SRCARCH=um since UML borrows several
 # asm headers from the host architecutre.)
 
+mandatory-y += dma-contiguous.h
 mandatory-y += msi.h
 mandatory-y += simd.h
index c2de013..35e4a53 100644 (file)
@@ -74,7 +74,7 @@ do {                                                                  \
 
 #define raw_cpu_generic_add_return(pcp, val)                           \
 ({                                                                     \
-       typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp));                       \
+       typeof(pcp) *__p = raw_cpu_ptr(&(pcp));                         \
                                                                        \
        *__p += val;                                                    \
        *__p;                                                           \
@@ -82,7 +82,7 @@ do {                                                                  \
 
 #define raw_cpu_generic_xchg(pcp, nval)                                        \
 ({                                                                     \
-       typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp));                       \
+       typeof(pcp) *__p = raw_cpu_ptr(&(pcp));                         \
        typeof(pcp) __ret;                                              \
        __ret = *__p;                                                   \
        *__p = nval;                                                    \
@@ -91,7 +91,7 @@ do {                                                                  \
 
 #define raw_cpu_generic_cmpxchg(pcp, oval, nval)                       \
 ({                                                                     \
-       typeof(&(pcp)) __p = raw_cpu_ptr(&(pcp));                       \
+       typeof(pcp) *__p = raw_cpu_ptr(&(pcp));                         \
        typeof(pcp) __ret;                                              \
        __ret = *__p;                                                   \
        if (__ret == (oval))                                            \
@@ -101,8 +101,8 @@ do {                                                                        \
 
 #define raw_cpu_generic_cmpxchg_double(pcp1, pcp2, oval1, oval2, nval1, nval2) \
 ({                                                                     \
-       typeof(&(pcp1)) __p1 = raw_cpu_ptr(&(pcp1));                    \
-       typeof(&(pcp2)) __p2 = raw_cpu_ptr(&(pcp2));                    \
+       typeof(pcp1) *__p1 = raw_cpu_ptr(&(pcp1));                      \
+       typeof(pcp2) *__p2 = raw_cpu_ptr(&(pcp2));                      \
        int __ret = 0;                                                  \
        if (*__p1 == (oval1) && *__p2  == (oval2)) {                    \
                *__p1 = nval1;                                          \
index 798ea36..e2e2bef 100644 (file)
@@ -1238,4 +1238,24 @@ static inline bool arch_has_pfn_modify_check(void)
 #define mm_pmd_folded(mm)      __is_defined(__PAGETABLE_PMD_FOLDED)
 #endif
 
+/*
+ * p?d_leaf() - true if this entry is a final mapping to a physical address.
+ * This differs from p?d_huge() by the fact that they are always available (if
+ * the architecture supports large pages at the appropriate level) even
+ * if CONFIG_HUGETLB_PAGE is not defined.
+ * Only meaningful when called on a valid entry.
+ */
+#ifndef pgd_leaf
+#define pgd_leaf(x)    0
+#endif
+#ifndef p4d_leaf
+#define p4d_leaf(x)    0
+#endif
+#ifndef pud_leaf
+#define pud_leaf(x)    0
+#endif
+#ifndef pmd_leaf
+#define pmd_leaf(x)    0
+#endif
+
 #endif /* _ASM_GENERIC_PGTABLE_H */
index 2b10036..f391f6b 100644 (file)
  *    Defaults to flushing at tlb_end_vma() to reset the range; helps when
  *    there's large holes between the VMAs.
  *
+ *  - tlb_remove_table()
+ *
+ *    tlb_remove_table() is the basic primitive to free page-table directories
+ *    (__p*_free_tlb()).  In it's most primitive form it is an alias for
+ *    tlb_remove_page() below, for when page directories are pages and have no
+ *    additional constraints.
+ *
+ *    See also MMU_GATHER_TABLE_FREE and MMU_GATHER_RCU_TABLE_FREE.
+ *
  *  - tlb_remove_page() / __tlb_remove_page()
  *  - tlb_remove_page_size() / __tlb_remove_page_size()
  *
  *
  * Additionally there are a few opt-in features:
  *
- *  HAVE_MMU_GATHER_PAGE_SIZE
+ *  MMU_GATHER_PAGE_SIZE
  *
  *  This ensures we call tlb_flush() every time tlb_change_page_size() actually
  *  changes the size and provides mmu_gather::page_size to tlb_flush().
  *
- *  HAVE_RCU_TABLE_FREE
+ *  This might be useful if your architecture has size specific TLB
+ *  invalidation instructions.
+ *
+ *  MMU_GATHER_TABLE_FREE
  *
  *  This provides tlb_remove_table(), to be used instead of tlb_remove_page()
- *  for page directores (__p*_free_tlb()). This provides separate freeing of
- *  the page-table pages themselves in a semi-RCU fashion (see comment below).
- *  Useful if your architecture doesn't use IPIs for remote TLB invalidates
- *  and therefore doesn't naturally serialize with software page-table walkers.
+ *  for page directores (__p*_free_tlb()).
+ *
+ *  Useful if your architecture has non-page page directories.
  *
  *  When used, an architecture is expected to provide __tlb_remove_table()
  *  which does the actual freeing of these pages.
  *
- *  HAVE_RCU_TABLE_NO_INVALIDATE
+ *  MMU_GATHER_RCU_TABLE_FREE
  *
- *  This makes HAVE_RCU_TABLE_FREE avoid calling tlb_flush_mmu_tlbonly() before
- *  freeing the page-table pages. This can be avoided if you use
- *  HAVE_RCU_TABLE_FREE and your architecture does _NOT_ use the Linux
- *  page-tables natively.
+ *  Like MMU_GATHER_TABLE_FREE, and adds semi-RCU semantics to the free (see
+ *  comment below).
+ *
+ *  Useful if your architecture doesn't use IPIs for remote TLB invalidates
+ *  and therefore doesn't naturally serialize with software page-table walkers.
  *
  *  MMU_GATHER_NO_RANGE
  *
  *  Use this if your architecture lacks an efficient flush_tlb_range().
- */
-
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-/*
- * Semi RCU freeing of the page directories.
- *
- * This is needed by some architectures to implement software pagetable walkers.
  *
- * gup_fast() and other software pagetable walkers do a lockless page-table
- * walk and therefore needs some synchronization with the freeing of the page
- * directories. The chosen means to accomplish that is by disabling IRQs over
- * the walk.
+ *  MMU_GATHER_NO_GATHER
  *
- * Architectures that use IPIs to flush TLBs will then automagically DTRT,
- * since we unlink the page, flush TLBs, free the page. Since the disabling of
- * IRQs delays the completion of the TLB flush we can never observe an already
- * freed page.
- *
- * Architectures that do not have this (PPC) need to delay the freeing by some
- * other means, this is that means.
- *
- * What we do is batch the freed directory pages (tables) and RCU free them.
- * We use the sched RCU variant, as that guarantees that IRQ/preempt disabling
- * holds off grace periods.
- *
- * However, in order to batch these pages we need to allocate storage, this
- * allocation is deep inside the MM code and can thus easily fail on memory
- * pressure. To guarantee progress we fall back to single table freeing, see
- * the implementation of tlb_remove_table_one().
+ *  If the option is set the mmu_gather will not track individual pages for
+ *  delayed page free anymore. A platform that enables the option needs to
+ *  provide its own implementation of the __tlb_remove_page_size() function to
+ *  free pages.
  *
+ *  This is useful if your architecture already flushes TLB entries in the
+ *  various ptep_get_and_clear() functions.
  */
+
+#ifdef CONFIG_MMU_GATHER_TABLE_FREE
+
 struct mmu_table_batch {
+#ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE
        struct rcu_head         rcu;
+#endif
        unsigned int            nr;
        void                    *tables[0];
 };
@@ -189,9 +186,35 @@ struct mmu_table_batch {
 
 extern void tlb_remove_table(struct mmu_gather *tlb, void *table);
 
+#else /* !CONFIG_MMU_GATHER_HAVE_TABLE_FREE */
+
+/*
+ * Without MMU_GATHER_TABLE_FREE the architecture is assumed to have page based
+ * page directories and we can use the normal page batching to free them.
+ */
+#define tlb_remove_table(tlb, page) tlb_remove_page((tlb), (page))
+
+#endif /* CONFIG_MMU_GATHER_TABLE_FREE */
+
+#ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE
+/*
+ * This allows an architecture that does not use the linux page-tables for
+ * hardware to skip the TLBI when freeing page tables.
+ */
+#ifndef tlb_needs_table_invalidate
+#define tlb_needs_table_invalidate() (true)
 #endif
 
-#ifndef CONFIG_HAVE_MMU_GATHER_NO_GATHER
+#else
+
+#ifdef tlb_needs_table_invalidate
+#error tlb_needs_table_invalidate() requires MMU_GATHER_RCU_TABLE_FREE
+#endif
+
+#endif /* CONFIG_MMU_GATHER_RCU_TABLE_FREE */
+
+
+#ifndef CONFIG_MMU_GATHER_NO_GATHER
 /*
  * If we can't allocate a page to make a big batch of page pointers
  * to work on, then just handle a few from the on-stack structure.
@@ -227,7 +250,7 @@ extern bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page,
 struct mmu_gather {
        struct mm_struct        *mm;
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+#ifdef CONFIG_MMU_GATHER_TABLE_FREE
        struct mmu_table_batch  *batch;
 #endif
 
@@ -266,22 +289,18 @@ struct mmu_gather {
 
        unsigned int            batch_count;
 
-#ifndef CONFIG_HAVE_MMU_GATHER_NO_GATHER
+#ifndef CONFIG_MMU_GATHER_NO_GATHER
        struct mmu_gather_batch *active;
        struct mmu_gather_batch local;
        struct page             *__pages[MMU_GATHER_BUNDLE];
 
-#ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
+#ifdef CONFIG_MMU_GATHER_PAGE_SIZE
        unsigned int page_size;
 #endif
 #endif
 };
 
-void arch_tlb_gather_mmu(struct mmu_gather *tlb,
-       struct mm_struct *mm, unsigned long start, unsigned long end);
 void tlb_flush_mmu(struct mmu_gather *tlb);
-void arch_tlb_finish_mmu(struct mmu_gather *tlb,
-                        unsigned long start, unsigned long end, bool force);
 
 static inline void __tlb_adjust_range(struct mmu_gather *tlb,
                                      unsigned long address,
@@ -394,7 +413,12 @@ tlb_update_vma_flags(struct mmu_gather *tlb, struct vm_area_struct *vma) { }
 
 static inline void tlb_flush_mmu_tlbonly(struct mmu_gather *tlb)
 {
-       if (!tlb->end)
+       /*
+        * Anything calling __tlb_adjust_range() also sets at least one of
+        * these bits.
+        */
+       if (!(tlb->freed_tables || tlb->cleared_ptes || tlb->cleared_pmds ||
+             tlb->cleared_puds || tlb->cleared_p4ds))
                return;
 
        tlb_flush(tlb);
@@ -426,7 +450,7 @@ static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page)
 static inline void tlb_change_page_size(struct mmu_gather *tlb,
                                                     unsigned int page_size)
 {
-#ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
+#ifdef CONFIG_MMU_GATHER_PAGE_SIZE
        if (tlb->page_size && tlb->page_size != page_size) {
                if (!tlb->fullmm && !tlb->need_flush_all)
                        tlb_flush_mmu(tlb);
index 9e71be1..589be85 100644 (file)
@@ -52,8 +52,9 @@ enum drm_sched_priority {
  * @list: used to append this struct to the list of entities in the
  *        runqueue.
  * @rq: runqueue on which this entity is currently scheduled.
- * @sched_list: a list of drm_gpu_schedulers on which jobs from this entity can
- *              be scheduled
+ * @sched_list: A list of schedulers (drm_gpu_schedulers).
+ *              Jobs from this entity can be scheduled on any scheduler
+ *              on this list.
  * @num_sched_list: number of drm_gpu_schedulers in the sched_list.
  * @rq_lock: lock to modify the runqueue to which this entity belongs.
  * @job_queue: the list of jobs of this entity.
index 72f2e84..8cec5a1 100644 (file)
 #define DRA7_RTC_CLKCTRL_INDEX(offset) ((offset) - DRA7_RTC_CLKCTRL_OFFSET)
 #define DRA7_RTCSS_CLKCTRL     DRA7_RTC_CLKCTRL_INDEX(0x44)
 
+/* vip clocks */
+#define DRA7_VIP1_CLKCTRL      DRA7_CLKCTRL_INDEX(0x20)
+#define DRA7_VIP2_CLKCTRL      DRA7_CLKCTRL_INDEX(0x28)
+#define DRA7_VIP3_CLKCTRL      DRA7_CLKCTRL_INDEX(0x30)
+
+/* vpe clocks */
+#define DRA7_VPE_CLKCTRL_OFFSET        0x60
+#define DRA7_VPE_CLKCTRL_INDEX(offset) ((offset) - DRA7_VPE_CLKCTRL_OFFSET)
+#define DRA7_VPE_CLKCTRL       DRA7_VPE_CLKCTRL_INDEX(0x64)
+
 /* coreaon clocks */
 #define DRA7_SMARTREFLEX_MPU_CLKCTRL   DRA7_CLKCTRL_INDEX(0x28)
 #define DRA7_SMARTREFLEX_CORE_CLKCTRL  DRA7_CLKCTRL_INDEX(0x38)
@@ -78,6 +88,9 @@
 #define DRA7_DSS_CORE_CLKCTRL  DRA7_CLKCTRL_INDEX(0x20)
 #define DRA7_BB2D_CLKCTRL      DRA7_CLKCTRL_INDEX(0x30)
 
+/* gpu clocks */
+#define DRA7_GPU_CLKCTRL       DRA7_CLKCTRL_INDEX(0x20)
+
 /* l3init clocks */
 #define DRA7_MMC1_CLKCTRL      DRA7_CLKCTRL_INDEX(0x28)
 #define DRA7_MMC2_CLKCTRL      DRA7_CLKCTRL_INDEX(0x30)
 /* rtc clocks */
 #define DRA7_RTC_RTCSS_CLKCTRL DRA7_CLKCTRL_INDEX(0x44)
 
+/* vip clocks */
+#define DRA7_CAM_VIP1_CLKCTRL  DRA7_CLKCTRL_INDEX(0x20)
+#define DRA7_CAM_VIP2_CLKCTRL  DRA7_CLKCTRL_INDEX(0x28)
+#define DRA7_CAM_VIP3_CLKCTRL  DRA7_CLKCTRL_INDEX(0x30)
+
+/* vpe clocks */
+#define DRA7_VPE_CLKCTRL_OFFSET        0x60
+#define DRA7_VPE_CLKCTRL_INDEX(offset) ((offset) - DRA7_VPE_CLKCTRL_OFFSET)
+#define DRA7_VPE_VPE_CLKCTRL   DRA7_VPE_CLKCTRL_INDEX(0x64)
+
 /* coreaon clocks */
 #define DRA7_COREAON_SMARTREFLEX_MPU_CLKCTRL   DRA7_CLKCTRL_INDEX(0x28)
 #define DRA7_COREAON_SMARTREFLEX_CORE_CLKCTRL  DRA7_CLKCTRL_INDEX(0x38)
diff --git a/include/dt-bindings/clock/imx8mp-clock.h b/include/dt-bindings/clock/imx8mp-clock.h
new file mode 100644 (file)
index 0000000..2fab631
--- /dev/null
@@ -0,0 +1,300 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2019 NXP
+ */
+
+#ifndef __DT_BINDINGS_CLOCK_IMX8MP_H
+#define __DT_BINDINGS_CLOCK_IMX8MP_H
+
+#define IMX8MP_CLK_DUMMY                       0
+#define IMX8MP_CLK_32K                         1
+#define IMX8MP_CLK_24M                         2
+#define IMX8MP_OSC_HDMI_CLK                    3
+#define IMX8MP_CLK_EXT1                                4
+#define IMX8MP_CLK_EXT2                                5
+#define IMX8MP_CLK_EXT3                                6
+#define IMX8MP_CLK_EXT4                                7
+#define IMX8MP_AUDIO_PLL1_REF_SEL              8
+#define IMX8MP_AUDIO_PLL2_REF_SEL              9
+#define IMX8MP_VIDEO_PLL1_REF_SEL              10
+#define IMX8MP_DRAM_PLL_REF_SEL                        11
+#define IMX8MP_GPU_PLL_REF_SEL                 12
+#define IMX8MP_VPU_PLL_REF_SEL                 13
+#define IMX8MP_ARM_PLL_REF_SEL                 14
+#define IMX8MP_SYS_PLL1_REF_SEL                        15
+#define IMX8MP_SYS_PLL2_REF_SEL                        16
+#define IMX8MP_SYS_PLL3_REF_SEL                        17
+#define IMX8MP_AUDIO_PLL1                      18
+#define IMX8MP_AUDIO_PLL2                      19
+#define IMX8MP_VIDEO_PLL1                      20
+#define IMX8MP_DRAM_PLL                                21
+#define IMX8MP_GPU_PLL                         22
+#define IMX8MP_VPU_PLL                         23
+#define IMX8MP_ARM_PLL                         24
+#define IMX8MP_SYS_PLL1                                25
+#define IMX8MP_SYS_PLL2                                26
+#define IMX8MP_SYS_PLL3                                27
+#define IMX8MP_AUDIO_PLL1_BYPASS               28
+#define IMX8MP_AUDIO_PLL2_BYPASS               29
+#define IMX8MP_VIDEO_PLL1_BYPASS               30
+#define IMX8MP_DRAM_PLL_BYPASS                 31
+#define IMX8MP_GPU_PLL_BYPASS                  32
+#define IMX8MP_VPU_PLL_BYPASS                  33
+#define IMX8MP_ARM_PLL_BYPASS                  34
+#define IMX8MP_SYS_PLL1_BYPASS                 35
+#define IMX8MP_SYS_PLL2_BYPASS                 36
+#define IMX8MP_SYS_PLL3_BYPASS                 37
+#define IMX8MP_AUDIO_PLL1_OUT                  38
+#define IMX8MP_AUDIO_PLL2_OUT                  39
+#define IMX8MP_VIDEO_PLL1_OUT                  40
+#define IMX8MP_DRAM_PLL_OUT                    41
+#define IMX8MP_GPU_PLL_OUT                     42
+#define IMX8MP_VPU_PLL_OUT                     43
+#define IMX8MP_ARM_PLL_OUT                     44
+#define IMX8MP_SYS_PLL1_OUT                    45
+#define IMX8MP_SYS_PLL2_OUT                    46
+#define IMX8MP_SYS_PLL3_OUT                    47
+#define IMX8MP_SYS_PLL1_40M                    48
+#define IMX8MP_SYS_PLL1_80M                    49
+#define IMX8MP_SYS_PLL1_100M                   50
+#define IMX8MP_SYS_PLL1_133M                   51
+#define IMX8MP_SYS_PLL1_160M                   52
+#define IMX8MP_SYS_PLL1_200M                   53
+#define IMX8MP_SYS_PLL1_266M                   54
+#define IMX8MP_SYS_PLL1_400M                   55
+#define IMX8MP_SYS_PLL1_800M                   56
+#define IMX8MP_SYS_PLL2_50M                    57
+#define IMX8MP_SYS_PLL2_100M                   58
+#define IMX8MP_SYS_PLL2_125M                   59
+#define IMX8MP_SYS_PLL2_166M                   60
+#define IMX8MP_SYS_PLL2_200M                   61
+#define IMX8MP_SYS_PLL2_250M                   62
+#define IMX8MP_SYS_PLL2_333M                   63
+#define IMX8MP_SYS_PLL2_500M                   64
+#define IMX8MP_SYS_PLL2_1000M                  65
+#define IMX8MP_CLK_A53_SRC                     66
+#define IMX8MP_CLK_M7_SRC                      67
+#define IMX8MP_CLK_ML_SRC                      68
+#define IMX8MP_CLK_GPU3D_CORE_SRC              69
+#define IMX8MP_CLK_GPU3D_SHADER_SRC            70
+#define IMX8MP_CLK_GPU2D_SRC                   71
+#define IMX8MP_CLK_AUDIO_AXI_SRC               72
+#define IMX8MP_CLK_HSIO_AXI_SRC                        73
+#define IMX8MP_CLK_MEDIA_ISP_SRC               74
+#define IMX8MP_CLK_A53_CG                      75
+#define IMX8MP_CLK_M4_CG                       76
+#define IMX8MP_CLK_ML_CG                       77
+#define IMX8MP_CLK_GPU3D_CORE_CG               78
+#define IMX8MP_CLK_GPU3D_SHADER_CG             79
+#define IMX8MP_CLK_GPU2D_CG                    80
+#define IMX8MP_CLK_AUDIO_AXI_CG                        81
+#define IMX8MP_CLK_HSIO_AXI_CG                 82
+#define IMX8MP_CLK_MEDIA_ISP_CG                        83
+#define IMX8MP_CLK_A53_DIV                     84
+#define IMX8MP_CLK_M7_DIV                      85
+#define IMX8MP_CLK_ML_DIV                      86
+#define IMX8MP_CLK_GPU3D_CORE_DIV              87
+#define IMX8MP_CLK_GPU3D_SHADER_DIV            88
+#define IMX8MP_CLK_GPU2D_DIV                   89
+#define IMX8MP_CLK_AUDIO_AXI_DIV               90
+#define IMX8MP_CLK_HSIO_AXI_DIV                        91
+#define IMX8MP_CLK_MEDIA_ISP_DIV               92
+#define IMX8MP_CLK_MAIN_AXI                    93
+#define IMX8MP_CLK_ENET_AXI                    94
+#define IMX8MP_CLK_NAND_USDHC_BUS              95
+#define IMX8MP_CLK_VPU_BUS                     96
+#define IMX8MP_CLK_MEDIA_AXI                   97
+#define IMX8MP_CLK_MEDIA_APB                   98
+#define IMX8MP_CLK_HDMI_APB                    99
+#define IMX8MP_CLK_HDMI_AXI                    100
+#define IMX8MP_CLK_GPU_AXI                     101
+#define IMX8MP_CLK_GPU_AHB                     102
+#define IMX8MP_CLK_NOC                         103
+#define IMX8MP_CLK_NOC_IO                      104
+#define IMX8MP_CLK_ML_AXI                      105
+#define IMX8MP_CLK_ML_AHB                      106
+#define IMX8MP_CLK_AHB                         107
+#define IMX8MP_CLK_AUDIO_AHB                   108
+#define IMX8MP_CLK_MIPI_DSI_ESC_RX             109
+#define IMX8MP_CLK_IPG_ROOT                    110
+#define IMX8MP_CLK_IPG_AUDIO_ROOT              111
+#define IMX8MP_CLK_DRAM_ALT                    112
+#define IMX8MP_CLK_DRAM_APB                    113
+#define IMX8MP_CLK_VPU_G1                      114
+#define IMX8MP_CLK_VPU_G2                      115
+#define IMX8MP_CLK_CAN1                                116
+#define IMX8MP_CLK_CAN2                                117
+#define IMX8MP_CLK_MEMREPAIR                   118
+#define IMX8MP_CLK_PCIE_PHY                    119
+#define IMX8MP_CLK_PCIE_AUX                    120
+#define IMX8MP_CLK_I2C5                                121
+#define IMX8MP_CLK_I2C6                                122
+#define IMX8MP_CLK_SAI1                                123
+#define IMX8MP_CLK_SAI2                                124
+#define IMX8MP_CLK_SAI3                                125
+#define IMX8MP_CLK_SAI4                                126
+#define IMX8MP_CLK_SAI5                                127
+#define IMX8MP_CLK_SAI6                                128
+#define IMX8MP_CLK_ENET_QOS                    129
+#define IMX8MP_CLK_ENET_QOS_TIMER              130
+#define IMX8MP_CLK_ENET_REF                    131
+#define IMX8MP_CLK_ENET_TIMER                  132
+#define IMX8MP_CLK_ENET_PHY_REF                        133
+#define IMX8MP_CLK_NAND                                134
+#define IMX8MP_CLK_QSPI                                135
+#define IMX8MP_CLK_USDHC1                      136
+#define IMX8MP_CLK_USDHC2                      137
+#define IMX8MP_CLK_I2C1                                138
+#define IMX8MP_CLK_I2C2                                139
+#define IMX8MP_CLK_I2C3                                140
+#define IMX8MP_CLK_I2C4                                141
+#define IMX8MP_CLK_UART1                       142
+#define IMX8MP_CLK_UART2                       143
+#define IMX8MP_CLK_UART3                       144
+#define IMX8MP_CLK_UART4                       145
+#define IMX8MP_CLK_USB_CORE_REF                        146
+#define IMX8MP_CLK_USB_PHY_REF                 147
+#define IMX8MP_CLK_GIC                         148
+#define IMX8MP_CLK_ECSPI1                      149
+#define IMX8MP_CLK_ECSPI2                      150
+#define IMX8MP_CLK_PWM1                                151
+#define IMX8MP_CLK_PWM2                                152
+#define IMX8MP_CLK_PWM3                                153
+#define IMX8MP_CLK_PWM4                                154
+#define IMX8MP_CLK_GPT1                                155
+#define IMX8MP_CLK_GPT2                                156
+#define IMX8MP_CLK_GPT3                                157
+#define IMX8MP_CLK_GPT4                                158
+#define IMX8MP_CLK_GPT5                                159
+#define IMX8MP_CLK_GPT6                                160
+#define IMX8MP_CLK_TRACE                       161
+#define IMX8MP_CLK_WDOG                                162
+#define IMX8MP_CLK_WRCLK                       163
+#define IMX8MP_CLK_IPP_DO_CLKO1                        164
+#define IMX8MP_CLK_IPP_DO_CLKO2                        165
+#define IMX8MP_CLK_HDMI_FDCC_TST               166
+#define IMX8MP_CLK_HDMI_27M                    167
+#define IMX8MP_CLK_HDMI_REF_266M               168
+#define IMX8MP_CLK_USDHC3                      169
+#define IMX8MP_CLK_MEDIA_CAM1_PIX              170
+#define IMX8MP_CLK_MEDIA_MIPI_PHY1_REF         171
+#define IMX8MP_CLK_MEDIA_DISP1_PIX             172
+#define IMX8MP_CLK_MEDIA_CAM2_PIX              173
+#define IMX8MP_CLK_MEDIA_MIPI_PHY2_REF         174
+#define IMX8MP_CLK_MEDIA_MIPI_CSI2_ESC         175
+#define IMX8MP_CLK_PCIE2_CTRL                  176
+#define IMX8MP_CLK_PCIE2_PHY                   177
+#define IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE                178
+#define IMX8MP_CLK_ECSPI3                      179
+#define IMX8MP_CLK_PDM                         180
+#define IMX8MP_CLK_VPU_VC8000E                 181
+#define IMX8MP_CLK_SAI7                                182
+#define IMX8MP_CLK_GPC_ROOT                    183
+#define IMX8MP_CLK_ANAMIX_ROOT                 184
+#define IMX8MP_CLK_CPU_ROOT                    185
+#define IMX8MP_CLK_CSU_ROOT                    186
+#define IMX8MP_CLK_DEBUG_ROOT                  187
+#define IMX8MP_CLK_DRAM1_ROOT                  188
+#define IMX8MP_CLK_ECSPI1_ROOT                 189
+#define IMX8MP_CLK_ECSPI2_ROOT                 190
+#define IMX8MP_CLK_ECSPI3_ROOT                 191
+#define IMX8MP_CLK_ENET1_ROOT                  192
+#define IMX8MP_CLK_GPIO1_ROOT                  193
+#define IMX8MP_CLK_GPIO2_ROOT                  194
+#define IMX8MP_CLK_GPIO3_ROOT                  195
+#define IMX8MP_CLK_GPIO4_ROOT                  196
+#define IMX8MP_CLK_GPIO5_ROOT                  197
+#define IMX8MP_CLK_GPT1_ROOT                   198
+#define IMX8MP_CLK_GPT2_ROOT                   199
+#define IMX8MP_CLK_GPT3_ROOT                   200
+#define IMX8MP_CLK_GPT4_ROOT                   201
+#define IMX8MP_CLK_GPT5_ROOT                   202
+#define IMX8MP_CLK_GPT6_ROOT                   203
+#define IMX8MP_CLK_HS_ROOT                     204
+#define IMX8MP_CLK_I2C1_ROOT                   205
+#define IMX8MP_CLK_I2C2_ROOT                   206
+#define IMX8MP_CLK_I2C3_ROOT                   207
+#define IMX8MP_CLK_I2C4_ROOT                   208
+#define IMX8MP_CLK_IOMUX_ROOT                  209
+#define IMX8MP_CLK_IPMUX1_ROOT                 210
+#define IMX8MP_CLK_IPMUX2_ROOT                 211
+#define IMX8MP_CLK_IPMUX3_ROOT                 212
+#define IMX8MP_CLK_MU_ROOT                     213
+#define IMX8MP_CLK_OCOTP_ROOT                  214
+#define IMX8MP_CLK_OCRAM_ROOT                  215
+#define IMX8MP_CLK_OCRAM_S_ROOT                        216
+#define IMX8MP_CLK_PCIE_ROOT                   217
+#define IMX8MP_CLK_PERFMON1_ROOT               218
+#define IMX8MP_CLK_PERFMON2_ROOT               219
+#define IMX8MP_CLK_PWM1_ROOT                   220
+#define IMX8MP_CLK_PWM2_ROOT                   221
+#define IMX8MP_CLK_PWM3_ROOT                   222
+#define IMX8MP_CLK_PWM4_ROOT                   223
+#define IMX8MP_CLK_QOS_ROOT                    224
+#define IMX8MP_CLK_QOS_ENET_ROOT               225
+#define IMX8MP_CLK_QSPI_ROOT                   226
+#define IMX8MP_CLK_NAND_ROOT                   227
+#define IMX8MP_CLK_NAND_USDHC_BUS_RAWNAND_CLK  228
+#define IMX8MP_CLK_RDC_ROOT                    229
+#define IMX8MP_CLK_ROM_ROOT                    230
+#define IMX8MP_CLK_I2C5_ROOT                   231
+#define IMX8MP_CLK_I2C6_ROOT                   232
+#define IMX8MP_CLK_CAN1_ROOT                   233
+#define IMX8MP_CLK_CAN2_ROOT                   234
+#define IMX8MP_CLK_SCTR_ROOT                   235
+#define IMX8MP_CLK_SDMA1_ROOT                  236
+#define IMX8MP_CLK_ENET_QOS_ROOT               237
+#define IMX8MP_CLK_SEC_DEBUG_ROOT              238
+#define IMX8MP_CLK_SEMA1_ROOT                  239
+#define IMX8MP_CLK_SEMA2_ROOT                  240
+#define IMX8MP_CLK_IRQ_STEER_ROOT              241
+#define IMX8MP_CLK_SIM_ENET_ROOT               242
+#define IMX8MP_CLK_SIM_M_ROOT                  243
+#define IMX8MP_CLK_SIM_MAIN_ROOT               244
+#define IMX8MP_CLK_SIM_S_ROOT                  245
+#define IMX8MP_CLK_SIM_WAKEUP_ROOT             246
+#define IMX8MP_CLK_GPU2D_ROOT                  247
+#define IMX8MP_CLK_GPU3D_ROOT                  248
+#define IMX8MP_CLK_SNVS_ROOT                   249
+#define IMX8MP_CLK_TRACE_ROOT                  250
+#define IMX8MP_CLK_UART1_ROOT                  251
+#define IMX8MP_CLK_UART2_ROOT                  252
+#define IMX8MP_CLK_UART3_ROOT                  253
+#define IMX8MP_CLK_UART4_ROOT                  254
+#define IMX8MP_CLK_USB_ROOT                    255
+#define IMX8MP_CLK_USB_PHY_ROOT                        256
+#define IMX8MP_CLK_USDHC1_ROOT                 257
+#define IMX8MP_CLK_USDHC2_ROOT                 258
+#define IMX8MP_CLK_WDOG1_ROOT                  259
+#define IMX8MP_CLK_WDOG2_ROOT                  260
+#define IMX8MP_CLK_WDOG3_ROOT                  261
+#define IMX8MP_CLK_VPU_G1_ROOT                 262
+#define IMX8MP_CLK_GPU_ROOT                    263
+#define IMX8MP_CLK_NOC_WRAPPER_ROOT            264
+#define IMX8MP_CLK_VPU_VC8KE_ROOT              265
+#define IMX8MP_CLK_VPU_G2_ROOT                 266
+#define IMX8MP_CLK_NPU_ROOT                    267
+#define IMX8MP_CLK_HSIO_ROOT                   268
+#define IMX8MP_CLK_MEDIA_APB_ROOT              269
+#define IMX8MP_CLK_MEDIA_AXI_ROOT              270
+#define IMX8MP_CLK_MEDIA_CAM1_PIX_ROOT         271
+#define IMX8MP_CLK_MEDIA_CAM2_PIX_ROOT         272
+#define IMX8MP_CLK_MEDIA_DISP1_PIX_ROOT                273
+#define IMX8MP_CLK_MEDIA_DISP2_PIX_ROOT                274
+#define IMX8MP_CLK_MEDIA_MIPI_PHY1_REF_ROOT    275
+#define IMX8MP_CLK_MEDIA_ISP_ROOT              276
+#define IMX8MP_CLK_USDHC3_ROOT                 277
+#define IMX8MP_CLK_HDMI_ROOT                   278
+#define IMX8MP_CLK_XTAL_ROOT                   279
+#define IMX8MP_CLK_PLL_ROOT                    280
+#define IMX8MP_CLK_TSENSOR_ROOT                        281
+#define IMX8MP_CLK_VPU_ROOT                    282
+#define IMX8MP_CLK_MRPR_ROOT                   283
+#define IMX8MP_CLK_AUDIO_ROOT                  284
+#define IMX8MP_CLK_DRAM_ALT_ROOT               285
+#define IMX8MP_CLK_DRAM_CORE                   286
+#define IMX8MP_CLK_ARM                         287
+
+#define IMX8MP_CLK_END                         288
+
+#endif
index e785c6e..4b1a772 100644 (file)
@@ -72,6 +72,8 @@
 #define MMP2_CLK_CCIC1_PHY             118
 #define MMP2_CLK_CCIC1_SPHY            119
 #define MMP2_CLK_DISP0_LCDC            120
+#define MMP2_CLK_USBHSIC0              121
+#define MMP2_CLK_USBHSIC1              122
 
 #define MMP2_NR_CLKS                   200
 #endif
diff --git a/include/dt-bindings/clock/meson8-ddr-clkc.h b/include/dt-bindings/clock/meson8-ddr-clkc.h
new file mode 100644 (file)
index 0000000..a8e0fa2
--- /dev/null
@@ -0,0 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#define DDR_CLKID_DDR_PLL_DCO                  0
+#define DDR_CLKID_DDR_PLL                      1
index 5167b2d..88d73be 100644 (file)
 #define OMAP4_UART4_CLKCTRL    OMAP4_CLKCTRL_INDEX(0x158)
 #define OMAP4_MMC5_CLKCTRL     OMAP4_CLKCTRL_INDEX(0x160)
 
+/* l4_secure clocks */
+#define OMAP4_L4_SECURE_CLKCTRL_OFFSET 0x1a0
+#define OMAP4_L4_SECURE_CLKCTRL_INDEX(offset)  ((offset) - OMAP4_L4_SECURE_CLKCTRL_OFFSET)
+#define OMAP4_AES1_CLKCTRL     OMAP4_L4_SECURE_CLKCTRL_INDEX(0x1a0)
+#define OMAP4_AES2_CLKCTRL     OMAP4_L4_SECURE_CLKCTRL_INDEX(0x1a8)
+#define OMAP4_DES3DES_CLKCTRL  OMAP4_L4_SECURE_CLKCTRL_INDEX(0x1b0)
+#define OMAP4_PKA_CLKCTRL      OMAP4_L4_SECURE_CLKCTRL_INDEX(0x1b8)
+#define OMAP4_RNG_CLKCTRL      OMAP4_L4_SECURE_CLKCTRL_INDEX(0x1c0)
+#define OMAP4_SHA2MD5_CLKCTRL  OMAP4_L4_SECURE_CLKCTRL_INDEX(0x1c8)
+#define OMAP4_CRYPTODMA_CLKCTRL        OMAP4_L4_SECURE_CLKCTRL_INDEX(0x1d8)
+
 /* l4_wkup clocks */
 #define OMAP4_L4_WKUP_CLKCTRL  OMAP4_CLKCTRL_INDEX(0x20)
 #define OMAP4_WD_TIMER2_CLKCTRL        OMAP4_CLKCTRL_INDEX(0x30)
index ba67206..4177527 100644 (file)
@@ -16,6 +16,7 @@
 
 /* abe clocks */
 #define OMAP5_L4_ABE_CLKCTRL   OMAP5_CLKCTRL_INDEX(0x20)
+#define OMAP5_AESS_CLKCTRL     OMAP5_CLKCTRL_INDEX(0x28)
 #define OMAP5_MCPDM_CLKCTRL    OMAP5_CLKCTRL_INDEX(0x30)
 #define OMAP5_DMIC_CLKCTRL     OMAP5_CLKCTRL_INDEX(0x38)
 #define OMAP5_MCBSP1_CLKCTRL   OMAP5_CLKCTRL_INDEX(0x48)
 #define OMAP5_UART5_CLKCTRL    OMAP5_CLKCTRL_INDEX(0x170)
 #define OMAP5_UART6_CLKCTRL    OMAP5_CLKCTRL_INDEX(0x178)
 
+/* l4_secure clocks */
+#define OMAP5_L4_SECURE_CLKCTRL_OFFSET 0x1a0
+#define OMAP5_L4_SECURE_CLKCTRL_INDEX(offset)  ((offset) - OMAP5_L4_SECURE_CLKCTRL_OFFSET)
+#define OMAP5_AES1_CLKCTRL     OMAP5_L4_SECURE_CLKCTRL_INDEX(0x1a0)
+#define OMAP5_AES2_CLKCTRL     OMAP5_L4_SECURE_CLKCTRL_INDEX(0x1a8)
+#define OMAP5_DES3DES_CLKCTRL  OMAP5_L4_SECURE_CLKCTRL_INDEX(0x1b0)
+#define OMAP5_FPKA_CLKCTRL     OMAP5_L4_SECURE_CLKCTRL_INDEX(0x1b8)
+#define OMAP5_RNG_CLKCTRL      OMAP5_L4_SECURE_CLKCTRL_INDEX(0x1c0)
+#define OMAP5_SHA2MD5_CLKCTRL  OMAP5_L4_SECURE_CLKCTRL_INDEX(0x1c8)
+#define OMAP5_DMA_CRYPTO_CLKCTRL       OMAP5_L4_SECURE_CLKCTRL_INDEX(0x1d8)
+
 /* iva clocks */
 #define OMAP5_IVA_CLKCTRL      OMAP5_CLKCTRL_INDEX(0x20)
 #define OMAP5_SL2IF_CLKCTRL    OMAP5_CLKCTRL_INDEX(0x28)
diff --git a/include/dt-bindings/clock/qcom,dispcc-sc7180.h b/include/dt-bindings/clock/qcom,dispcc-sc7180.h
new file mode 100644 (file)
index 0000000..b9b5161
--- /dev/null
@@ -0,0 +1,46 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_DISP_CC_SC7180_H
+#define _DT_BINDINGS_CLK_QCOM_DISP_CC_SC7180_H
+
+#define DISP_CC_PLL0                           0
+#define DISP_CC_PLL0_OUT_EVEN                  1
+#define DISP_CC_MDSS_AHB_CLK                   2
+#define DISP_CC_MDSS_AHB_CLK_SRC               3
+#define DISP_CC_MDSS_BYTE0_CLK                 4
+#define DISP_CC_MDSS_BYTE0_CLK_SRC             5
+#define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC         6
+#define DISP_CC_MDSS_BYTE0_INTF_CLK            7
+#define DISP_CC_MDSS_DP_AUX_CLK                        8
+#define DISP_CC_MDSS_DP_AUX_CLK_SRC            9
+#define DISP_CC_MDSS_DP_CRYPTO_CLK             10
+#define DISP_CC_MDSS_DP_CRYPTO_CLK_SRC         11
+#define DISP_CC_MDSS_DP_LINK_CLK               12
+#define DISP_CC_MDSS_DP_LINK_CLK_SRC           13
+#define DISP_CC_MDSS_DP_LINK_DIV_CLK_SRC       14
+#define DISP_CC_MDSS_DP_LINK_INTF_CLK          15
+#define DISP_CC_MDSS_DP_PIXEL_CLK              16
+#define DISP_CC_MDSS_DP_PIXEL_CLK_SRC          17
+#define DISP_CC_MDSS_ESC0_CLK                  18
+#define DISP_CC_MDSS_ESC0_CLK_SRC              19
+#define DISP_CC_MDSS_MDP_CLK                   20
+#define DISP_CC_MDSS_MDP_CLK_SRC               21
+#define DISP_CC_MDSS_MDP_LUT_CLK               22
+#define DISP_CC_MDSS_NON_GDSC_AHB_CLK          23
+#define DISP_CC_MDSS_PCLK0_CLK                 24
+#define DISP_CC_MDSS_PCLK0_CLK_SRC             25
+#define DISP_CC_MDSS_ROT_CLK                   26
+#define DISP_CC_MDSS_ROT_CLK_SRC               27
+#define DISP_CC_MDSS_RSCC_AHB_CLK              28
+#define DISP_CC_MDSS_RSCC_VSYNC_CLK            29
+#define DISP_CC_MDSS_VSYNC_CLK                 30
+#define DISP_CC_MDSS_VSYNC_CLK_SRC             31
+#define DISP_CC_XO_CLK                         32
+
+/* DISP_CC GDSCR */
+#define MDSS_GDSC                              0
+
+#endif
index 11eed4b..4016fd1 100644 (file)
@@ -1,6 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 /*
- * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
  */
 
 #ifndef _DT_BINDINGS_CLK_SDM_DISP_CC_SDM845_H
 #define DISP_CC_PLL0                                           25
 #define DISP_CC_MDSS_BYTE0_DIV_CLK_SRC                         26
 #define DISP_CC_MDSS_BYTE1_DIV_CLK_SRC                         27
+#define DISP_CC_MDSS_DP_AUX_CLK                                        28
+#define DISP_CC_MDSS_DP_AUX_CLK_SRC                            29
+#define DISP_CC_MDSS_DP_CRYPTO_CLK                             30
+#define DISP_CC_MDSS_DP_CRYPTO_CLK_SRC                         31
+#define DISP_CC_MDSS_DP_LINK_CLK                               32
+#define DISP_CC_MDSS_DP_LINK_CLK_SRC                           33
+#define DISP_CC_MDSS_DP_LINK_INTF_CLK                          34
+#define DISP_CC_MDSS_DP_PIXEL1_CLK                             35
+#define DISP_CC_MDSS_DP_PIXEL1_CLK_SRC                         36
+#define DISP_CC_MDSS_DP_PIXEL_CLK                              37
+#define DISP_CC_MDSS_DP_PIXEL_CLK_SRC                          38
 
 /* DISP_CC Reset */
 #define DISP_CC_MDSS_RSCC_BCR                                  0
diff --git a/include/dt-bindings/clock/qcom,gcc-ipq6018.h b/include/dt-bindings/clock/qcom,gcc-ipq6018.h
new file mode 100644 (file)
index 0000000..6f4be3a
--- /dev/null
@@ -0,0 +1,262 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLOCK_IPQ_GCC_6018_H
+#define _DT_BINDINGS_CLOCK_IPQ_GCC_6018_H
+
+#define GPLL0                                  0
+#define UBI32_PLL                              1
+#define GPLL6                                  2
+#define GPLL4                                  3
+#define PCNOC_BFDCD_CLK_SRC                    4
+#define GPLL2                                  5
+#define NSS_CRYPTO_PLL                         6
+#define NSS_PPE_CLK_SRC                                7
+#define GCC_XO_CLK_SRC                         8
+#define NSS_CE_CLK_SRC                         9
+#define GCC_SLEEP_CLK_SRC                      10
+#define APSS_AHB_CLK_SRC                       11
+#define NSS_PORT5_RX_CLK_SRC                   12
+#define NSS_PORT5_TX_CLK_SRC                   13
+#define PCIE0_AXI_CLK_SRC                      14
+#define USB0_MASTER_CLK_SRC                    15
+#define APSS_AHB_POSTDIV_CLK_SRC               16
+#define NSS_PORT1_RX_CLK_SRC                   17
+#define NSS_PORT1_TX_CLK_SRC                   18
+#define NSS_PORT2_RX_CLK_SRC                   19
+#define NSS_PORT2_TX_CLK_SRC                   20
+#define NSS_PORT3_RX_CLK_SRC                   21
+#define NSS_PORT3_TX_CLK_SRC                   22
+#define NSS_PORT4_RX_CLK_SRC                   23
+#define NSS_PORT4_TX_CLK_SRC                   24
+#define NSS_PORT5_RX_DIV_CLK_SRC               25
+#define NSS_PORT5_TX_DIV_CLK_SRC               26
+#define APSS_AXI_CLK_SRC                       27
+#define NSS_CRYPTO_CLK_SRC                     28
+#define NSS_PORT1_RX_DIV_CLK_SRC               29
+#define NSS_PORT1_TX_DIV_CLK_SRC               30
+#define NSS_PORT2_RX_DIV_CLK_SRC               31
+#define NSS_PORT2_TX_DIV_CLK_SRC               32
+#define NSS_PORT3_RX_DIV_CLK_SRC               33
+#define NSS_PORT3_TX_DIV_CLK_SRC               34
+#define NSS_PORT4_RX_DIV_CLK_SRC               35
+#define NSS_PORT4_TX_DIV_CLK_SRC               36
+#define NSS_UBI0_CLK_SRC                       37
+#define BLSP1_QUP1_I2C_APPS_CLK_SRC            38
+#define BLSP1_QUP1_SPI_APPS_CLK_SRC            39
+#define BLSP1_QUP2_I2C_APPS_CLK_SRC            40
+#define BLSP1_QUP2_SPI_APPS_CLK_SRC            41
+#define BLSP1_QUP3_I2C_APPS_CLK_SRC            42
+#define BLSP1_QUP3_SPI_APPS_CLK_SRC            43
+#define BLSP1_QUP4_I2C_APPS_CLK_SRC            44
+#define BLSP1_QUP4_SPI_APPS_CLK_SRC            45
+#define BLSP1_QUP5_I2C_APPS_CLK_SRC            46
+#define BLSP1_QUP5_SPI_APPS_CLK_SRC            47
+#define BLSP1_QUP6_I2C_APPS_CLK_SRC            48
+#define BLSP1_QUP6_SPI_APPS_CLK_SRC            49
+#define BLSP1_UART1_APPS_CLK_SRC               50
+#define BLSP1_UART2_APPS_CLK_SRC               51
+#define BLSP1_UART3_APPS_CLK_SRC               52
+#define BLSP1_UART4_APPS_CLK_SRC               53
+#define BLSP1_UART5_APPS_CLK_SRC               54
+#define BLSP1_UART6_APPS_CLK_SRC               55
+#define CRYPTO_CLK_SRC                         56
+#define NSS_UBI0_DIV_CLK_SRC                   57
+#define PCIE0_AUX_CLK_SRC                      58
+#define PCIE0_PIPE_CLK_SRC                     59
+#define SDCC1_APPS_CLK_SRC                     60
+#define USB0_AUX_CLK_SRC                       61
+#define USB0_MOCK_UTMI_CLK_SRC                 62
+#define USB0_PIPE_CLK_SRC                      63
+#define USB1_MOCK_UTMI_CLK_SRC                 64
+#define GCC_APSS_AHB_CLK                       65
+#define GCC_APSS_AXI_CLK                       66
+#define GCC_BLSP1_AHB_CLK                      67
+#define GCC_BLSP1_QUP1_I2C_APPS_CLK            68
+#define GCC_BLSP1_QUP1_SPI_APPS_CLK            69
+#define GCC_BLSP1_QUP2_I2C_APPS_CLK            70
+#define GCC_BLSP1_QUP2_SPI_APPS_CLK            71
+#define GCC_BLSP1_QUP3_I2C_APPS_CLK            72
+#define GCC_BLSP1_QUP3_SPI_APPS_CLK            73
+#define GCC_BLSP1_QUP4_I2C_APPS_CLK            74
+#define GCC_BLSP1_QUP4_SPI_APPS_CLK            75
+#define GCC_BLSP1_QUP5_I2C_APPS_CLK            76
+#define GCC_BLSP1_QUP5_SPI_APPS_CLK            77
+#define GCC_BLSP1_QUP6_I2C_APPS_CLK            78
+#define GCC_BLSP1_QUP6_SPI_APPS_CLK            79
+#define GCC_BLSP1_UART1_APPS_CLK               80
+#define GCC_BLSP1_UART2_APPS_CLK               81
+#define GCC_BLSP1_UART3_APPS_CLK               82
+#define GCC_BLSP1_UART4_APPS_CLK               83
+#define GCC_BLSP1_UART5_APPS_CLK               84
+#define GCC_BLSP1_UART6_APPS_CLK               85
+#define GCC_CRYPTO_AHB_CLK                     86
+#define GCC_CRYPTO_AXI_CLK                     87
+#define GCC_CRYPTO_CLK                         88
+#define GCC_XO_CLK                             89
+#define GCC_XO_DIV4_CLK                                90
+#define GCC_MDIO_AHB_CLK                       91
+#define GCC_CRYPTO_PPE_CLK                     92
+#define GCC_NSS_CE_APB_CLK                     93
+#define GCC_NSS_CE_AXI_CLK                     94
+#define GCC_NSS_CFG_CLK                                95
+#define GCC_NSS_CRYPTO_CLK                     96
+#define GCC_NSS_CSR_CLK                                97
+#define GCC_NSS_EDMA_CFG_CLK                   98
+#define GCC_NSS_EDMA_CLK                       99
+#define GCC_NSS_NOC_CLK                                100
+#define GCC_NSS_PORT1_RX_CLK                   101
+#define GCC_NSS_PORT1_TX_CLK                   102
+#define GCC_NSS_PORT2_RX_CLK                   103
+#define GCC_NSS_PORT2_TX_CLK                   104
+#define GCC_NSS_PORT3_RX_CLK                   105
+#define GCC_NSS_PORT3_TX_CLK                   106
+#define GCC_NSS_PORT4_RX_CLK                   107
+#define GCC_NSS_PORT4_TX_CLK                   108
+#define GCC_NSS_PORT5_RX_CLK                   109
+#define GCC_NSS_PORT5_TX_CLK                   110
+#define GCC_NSS_PPE_CFG_CLK                    111
+#define GCC_NSS_PPE_CLK                                112
+#define GCC_NSS_PPE_IPE_CLK                    113
+#define GCC_NSS_PTP_REF_CLK                    114
+#define GCC_NSSNOC_CE_APB_CLK                  115
+#define GCC_NSSNOC_CE_AXI_CLK                  116
+#define GCC_NSSNOC_CRYPTO_CLK                  117
+#define GCC_NSSNOC_PPE_CFG_CLK                 118
+#define GCC_NSSNOC_PPE_CLK                     119
+#define GCC_NSSNOC_QOSGEN_REF_CLK              120
+#define GCC_NSSNOC_TIMEOUT_REF_CLK             121
+#define GCC_NSSNOC_UBI0_AHB_CLK                        122
+#define GCC_PORT1_MAC_CLK                      123
+#define GCC_PORT2_MAC_CLK                      124
+#define GCC_PORT3_MAC_CLK                      125
+#define GCC_PORT4_MAC_CLK                      126
+#define GCC_PORT5_MAC_CLK                      127
+#define GCC_UBI0_AHB_CLK                       128
+#define GCC_UBI0_AXI_CLK                       129
+#define GCC_UBI0_CORE_CLK                      130
+#define GCC_PCIE0_AHB_CLK                      131
+#define GCC_PCIE0_AUX_CLK                      132
+#define GCC_PCIE0_AXI_M_CLK                    133
+#define GCC_PCIE0_AXI_S_CLK                    134
+#define GCC_PCIE0_PIPE_CLK                     135
+#define GCC_PRNG_AHB_CLK                       136
+#define GCC_QPIC_AHB_CLK                       137
+#define GCC_QPIC_CLK                           138
+#define GCC_SDCC1_AHB_CLK                      139
+#define GCC_SDCC1_APPS_CLK                     140
+#define GCC_UNIPHY0_AHB_CLK                    141
+#define GCC_UNIPHY0_PORT1_RX_CLK               142
+#define GCC_UNIPHY0_PORT1_TX_CLK               143
+#define GCC_UNIPHY0_PORT2_RX_CLK               144
+#define GCC_UNIPHY0_PORT2_TX_CLK               145
+#define GCC_UNIPHY0_PORT3_RX_CLK               146
+#define GCC_UNIPHY0_PORT3_TX_CLK               147
+#define GCC_UNIPHY0_PORT4_RX_CLK               148
+#define GCC_UNIPHY0_PORT4_TX_CLK               149
+#define GCC_UNIPHY0_PORT5_RX_CLK               150
+#define GCC_UNIPHY0_PORT5_TX_CLK               151
+#define GCC_UNIPHY0_SYS_CLK                    152
+#define GCC_UNIPHY1_AHB_CLK                    153
+#define GCC_UNIPHY1_PORT5_RX_CLK               154
+#define GCC_UNIPHY1_PORT5_TX_CLK               155
+#define GCC_UNIPHY1_SYS_CLK                    156
+#define GCC_USB0_AUX_CLK                       157
+#define GCC_USB0_MASTER_CLK                    158
+#define GCC_USB0_MOCK_UTMI_CLK                 159
+#define GCC_USB0_PHY_CFG_AHB_CLK               160
+#define GCC_USB0_PIPE_CLK                      161
+#define GCC_USB0_SLEEP_CLK                     162
+#define GCC_USB1_MASTER_CLK                    163
+#define GCC_USB1_MOCK_UTMI_CLK                 164
+#define GCC_USB1_PHY_CFG_AHB_CLK               165
+#define GCC_USB1_SLEEP_CLK                     166
+#define GP1_CLK_SRC                            167
+#define GP2_CLK_SRC                            168
+#define GP3_CLK_SRC                            169
+#define GCC_GP1_CLK                            170
+#define GCC_GP2_CLK                            171
+#define GCC_GP3_CLK                            172
+#define SYSTEM_NOC_BFDCD_CLK_SRC               173
+#define GCC_NSSNOC_SNOC_CLK                    174
+#define GCC_UBI0_NC_AXI_CLK                    175
+#define GCC_UBI1_NC_AXI_CLK                    176
+#define GPLL0_MAIN                             177
+#define UBI32_PLL_MAIN                         178
+#define GPLL6_MAIN                             179
+#define GPLL4_MAIN                             180
+#define GPLL2_MAIN                             181
+#define NSS_CRYPTO_PLL_MAIN                    182
+#define GCC_CMN_12GPLL_AHB_CLK                 183
+#define GCC_CMN_12GPLL_SYS_CLK                 184
+#define GCC_SNOC_BUS_TIMEOUT2_AHB_CLK          185
+#define GCC_SYS_NOC_USB0_AXI_CLK               186
+#define GCC_SYS_NOC_PCIE0_AXI_CLK              187
+#define QDSS_TSCTR_CLK_SRC                     188
+#define QDSS_AT_CLK_SRC                                189
+#define GCC_QDSS_AT_CLK                                190
+#define GCC_QDSS_DAP_CLK                       191
+#define ADSS_PWM_CLK_SRC                       192
+#define GCC_ADSS_PWM_CLK                       193
+#define SDCC1_ICE_CORE_CLK_SRC                 194
+#define GCC_SDCC1_ICE_CORE_CLK                 195
+#define GCC_DCC_CLK                            196
+#define PCIE0_RCHNG_CLK_SRC                    197
+#define GCC_PCIE0_AXI_S_BRIDGE_CLK             198
+#define PCIE0_RCHNG_CLK                                199
+#define UBI32_MEM_NOC_BFDCD_CLK_SRC            200
+#define WCSS_AHB_CLK_SRC                       201
+#define Q6_AXI_CLK_SRC                         202
+#define GCC_Q6SS_PCLKDBG_CLK                   203
+#define GCC_Q6_TSCTR_1TO2_CLK                  204
+#define GCC_WCSS_CORE_TBU_CLK                  205
+#define GCC_WCSS_AXI_M_CLK                     206
+#define GCC_SYS_NOC_WCSS_AHB_CLK               207
+#define GCC_Q6_AXIM_CLK                                208
+#define GCC_Q6SS_ATBM_CLK                      209
+#define GCC_WCSS_Q6_TBU_CLK                    210
+#define GCC_Q6_AXIM2_CLK                       211
+#define GCC_Q6_AHB_CLK                         212
+#define GCC_Q6_AHB_S_CLK                       213
+#define GCC_WCSS_DBG_IFC_APB_CLK               214
+#define GCC_WCSS_DBG_IFC_ATB_CLK               215
+#define GCC_WCSS_DBG_IFC_NTS_CLK               216
+#define GCC_WCSS_DBG_IFC_DAPBUS_CLK            217
+#define GCC_WCSS_DBG_IFC_APB_BDG_CLK           218
+#define GCC_WCSS_DBG_IFC_ATB_BDG_CLK           219
+#define GCC_WCSS_DBG_IFC_NTS_BDG_CLK           220
+#define GCC_WCSS_DBG_IFC_DAPBUS_BDG_CLK                221
+#define GCC_WCSS_ECAHB_CLK                     222
+#define GCC_WCSS_ACMT_CLK                      223
+#define GCC_WCSS_AHB_S_CLK                     224
+#define GCC_RBCPR_WCSS_CLK                     225
+#define RBCPR_WCSS_CLK_SRC                     226
+#define GCC_RBCPR_WCSS_AHB_CLK                 227
+#define GCC_LPASS_CORE_AXIM_CLK                        228
+#define GCC_LPASS_SNOC_CFG_CLK                 229
+#define GCC_LPASS_Q6_AXIM_CLK                  230
+#define GCC_LPASS_Q6_ATBM_AT_CLK               231
+#define GCC_LPASS_Q6_PCLKDBG_CLK               232
+#define GCC_LPASS_Q6SS_TSCTR_1TO2_CLK          233
+#define GCC_LPASS_Q6SS_TRIG_CLK                        234
+#define GCC_LPASS_TBU_CLK                      235
+#define LPASS_CORE_AXIM_CLK_SRC                        236
+#define LPASS_SNOC_CFG_CLK_SRC                 237
+#define LPASS_Q6_AXIM_CLK_SRC                  238
+#define GCC_PCNOC_LPASS_CLK                    239
+#define GCC_UBI0_UTCM_CLK                      240
+#define SNOC_NSSNOC_BFDCD_CLK_SRC              241
+#define GCC_SNOC_NSSNOC_CLK                    242
+#define GCC_MEM_NOC_Q6_AXI_CLK                 243
+#define GCC_MEM_NOC_UBI32_CLK                  244
+#define GCC_MEM_NOC_LPASS_CLK                  245
+#define GCC_SNOC_LPASS_CFG_CLK                 246
+#define GCC_SYS_NOC_QDSS_STM_AXI_CLK           247
+#define GCC_QDSS_STM_CLK                       248
+#define GCC_QDSS_TRACECLKIN_CLK                        249
+#define QDSS_STM_CLK_SRC                       250
+#define QDSS_TRACECLKIN_CLK_SRC                        251
+#define GCC_NSSNOC_ATB_CLK                     252
+#endif
index de1d8a1..63e02dc 100644 (file)
 #define GCC_MSS_GPLL0_DIV_CLK_SRC                              173
 #define GCC_MSS_SNOC_AXI_CLK                                   174
 #define GCC_MSS_MNOC_BIMC_AXI_CLK                              175
+#define GCC_BIMC_GFX_CLK                                       176
 
 #define PCIE_0_GDSC                                            0
 #define UFS_GDSC                                               1
diff --git a/include/dt-bindings/clock/qcom,gpucc-sc7180.h b/include/dt-bindings/clock/qcom,gpucc-sc7180.h
new file mode 100644 (file)
index 0000000..0e4643b
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_SC7180_H
+#define _DT_BINDINGS_CLK_QCOM_GPU_CC_SC7180_H
+
+#define GPU_CC_PLL1                    0
+#define GPU_CC_AHB_CLK                 1
+#define GPU_CC_CRC_AHB_CLK             2
+#define GPU_CC_CX_GMU_CLK              3
+#define GPU_CC_CX_SNOC_DVM_CLK         4
+#define GPU_CC_CXO_AON_CLK             5
+#define GPU_CC_CXO_CLK                 6
+#define GPU_CC_GMU_CLK_SRC             7
+
+/* CAM_CC GDSCRs */
+#define CX_GDSC                                0
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,mmcc-msm8998.h b/include/dt-bindings/clock/qcom,mmcc-msm8998.h
new file mode 100644 (file)
index 0000000..ecbafdb
--- /dev/null
@@ -0,0 +1,210 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_MSM_MMCC_8998_H
+#define _DT_BINDINGS_CLK_MSM_MMCC_8998_H
+
+#define MMPLL0                                         0
+#define MMPLL0_OUT_EVEN                                        1
+#define MMPLL1                                         2
+#define MMPLL1_OUT_EVEN                                        3
+#define MMPLL3                                         4
+#define MMPLL3_OUT_EVEN                                        5
+#define MMPLL4                                         6
+#define MMPLL4_OUT_EVEN                                        7
+#define MMPLL5                                         8
+#define MMPLL5_OUT_EVEN                                        9
+#define MMPLL6                                         10
+#define MMPLL6_OUT_EVEN                                        11
+#define MMPLL7                                         12
+#define MMPLL7_OUT_EVEN                                        13
+#define MMPLL10                                                14
+#define MMPLL10_OUT_EVEN                               15
+#define BYTE0_CLK_SRC                                  16
+#define BYTE1_CLK_SRC                                  17
+#define CCI_CLK_SRC                                    18
+#define CPP_CLK_SRC                                    19
+#define CSI0_CLK_SRC                                   20
+#define CSI1_CLK_SRC                                   21
+#define CSI2_CLK_SRC                                   22
+#define CSI3_CLK_SRC                                   23
+#define CSIPHY_CLK_SRC                                 24
+#define CSI0PHYTIMER_CLK_SRC                           25
+#define CSI1PHYTIMER_CLK_SRC                           26
+#define CSI2PHYTIMER_CLK_SRC                           27
+#define DP_AUX_CLK_SRC                                 28
+#define DP_CRYPTO_CLK_SRC                              29
+#define DP_LINK_CLK_SRC                                        30
+#define DP_PIXEL_CLK_SRC                               31
+#define ESC0_CLK_SRC                                   32
+#define ESC1_CLK_SRC                                   33
+#define EXTPCLK_CLK_SRC                                        34
+#define FD_CORE_CLK_SRC                                        35
+#define HDMI_CLK_SRC                                   36
+#define JPEG0_CLK_SRC                                  37
+#define MAXI_CLK_SRC                                   38
+#define MCLK0_CLK_SRC                                  39
+#define MCLK1_CLK_SRC                                  40
+#define MCLK2_CLK_SRC                                  41
+#define MCLK3_CLK_SRC                                  42
+#define MDP_CLK_SRC                                    43
+#define VSYNC_CLK_SRC                                  44
+#define AHB_CLK_SRC                                    45
+#define AXI_CLK_SRC                                    46
+#define PCLK0_CLK_SRC                                  47
+#define PCLK1_CLK_SRC                                  48
+#define ROT_CLK_SRC                                    49
+#define VIDEO_CORE_CLK_SRC                             50
+#define VIDEO_SUBCORE0_CLK_SRC                         51
+#define VIDEO_SUBCORE1_CLK_SRC                         52
+#define VFE0_CLK_SRC                                   53
+#define VFE1_CLK_SRC                                   54
+#define MISC_AHB_CLK                                   55
+#define VIDEO_CORE_CLK                                 56
+#define VIDEO_AHB_CLK                                  57
+#define VIDEO_AXI_CLK                                  58
+#define VIDEO_MAXI_CLK                                 59
+#define VIDEO_SUBCORE0_CLK                             60
+#define VIDEO_SUBCORE1_CLK                             61
+#define MDSS_AHB_CLK                                   62
+#define MDSS_HDMI_DP_AHB_CLK                           63
+#define MDSS_AXI_CLK                                   64
+#define MDSS_PCLK0_CLK                                 65
+#define MDSS_PCLK1_CLK                                 66
+#define MDSS_MDP_CLK                                   67
+#define MDSS_MDP_LUT_CLK                               68
+#define MDSS_EXTPCLK_CLK                               69
+#define MDSS_VSYNC_CLK                                 70
+#define MDSS_HDMI_CLK                                  71
+#define MDSS_BYTE0_CLK                                 72
+#define MDSS_BYTE1_CLK                                 73
+#define MDSS_ESC0_CLK                                  74
+#define MDSS_ESC1_CLK                                  75
+#define MDSS_ROT_CLK                                   76
+#define MDSS_DP_LINK_CLK                               77
+#define MDSS_DP_LINK_INTF_CLK                          78
+#define MDSS_DP_CRYPTO_CLK                             79
+#define MDSS_DP_PIXEL_CLK                              80
+#define MDSS_DP_AUX_CLK                                        81
+#define MDSS_BYTE0_INTF_CLK                            82
+#define MDSS_BYTE1_INTF_CLK                            83
+#define CAMSS_CSI0PHYTIMER_CLK                         84
+#define CAMSS_CSI1PHYTIMER_CLK                         85
+#define CAMSS_CSI2PHYTIMER_CLK                         86
+#define CAMSS_CSI0_CLK                                 87
+#define CAMSS_CSI0_AHB_CLK                             88
+#define CAMSS_CSI0RDI_CLK                              89
+#define CAMSS_CSI0PIX_CLK                              90
+#define CAMSS_CSI1_CLK                                 91
+#define CAMSS_CSI1_AHB_CLK                             92
+#define CAMSS_CSI1RDI_CLK                              93
+#define CAMSS_CSI1PIX_CLK                              94
+#define CAMSS_CSI2_CLK                                 95
+#define CAMSS_CSI2_AHB_CLK                             96
+#define CAMSS_CSI2RDI_CLK                              97
+#define CAMSS_CSI2PIX_CLK                              98
+#define CAMSS_CSI3_CLK                                 99
+#define CAMSS_CSI3_AHB_CLK                             100
+#define CAMSS_CSI3RDI_CLK                              101
+#define CAMSS_CSI3PIX_CLK                              102
+#define CAMSS_ISPIF_AHB_CLK                            103
+#define CAMSS_CCI_CLK                                  104
+#define CAMSS_CCI_AHB_CLK                              105
+#define CAMSS_MCLK0_CLK                                        106
+#define CAMSS_MCLK1_CLK                                        107
+#define CAMSS_MCLK2_CLK                                        108
+#define CAMSS_MCLK3_CLK                                        109
+#define CAMSS_TOP_AHB_CLK                              110
+#define CAMSS_AHB_CLK                                  111
+#define CAMSS_MICRO_AHB_CLK                            112
+#define CAMSS_JPEG0_CLK                                        113
+#define CAMSS_JPEG_AHB_CLK                             114
+#define CAMSS_JPEG_AXI_CLK                             115
+#define CAMSS_VFE0_AHB_CLK                             116
+#define CAMSS_VFE1_AHB_CLK                             117
+#define CAMSS_VFE0_CLK                                 118
+#define CAMSS_VFE1_CLK                                 119
+#define CAMSS_CPP_CLK                                  120
+#define CAMSS_CPP_AHB_CLK                              121
+#define CAMSS_VFE_VBIF_AHB_CLK                         122
+#define CAMSS_VFE_VBIF_AXI_CLK                         123
+#define CAMSS_CPP_AXI_CLK                              124
+#define CAMSS_CPP_VBIF_AHB_CLK                         125
+#define CAMSS_CSI_VFE0_CLK                             126
+#define CAMSS_CSI_VFE1_CLK                             127
+#define CAMSS_VFE0_STREAM_CLK                          128
+#define CAMSS_VFE1_STREAM_CLK                          129
+#define CAMSS_CPHY_CSID0_CLK                           130
+#define CAMSS_CPHY_CSID1_CLK                           131
+#define CAMSS_CPHY_CSID2_CLK                           132
+#define CAMSS_CPHY_CSID3_CLK                           133
+#define CAMSS_CSIPHY0_CLK                              134
+#define CAMSS_CSIPHY1_CLK                              135
+#define CAMSS_CSIPHY2_CLK                              136
+#define FD_CORE_CLK                                    137
+#define FD_CORE_UAR_CLK                                        138
+#define FD_AHB_CLK                                     139
+#define MNOC_AHB_CLK                                   140
+#define BIMC_SMMU_AHB_CLK                              141
+#define BIMC_SMMU_AXI_CLK                              142
+#define MNOC_MAXI_CLK                                  143
+#define VMEM_MAXI_CLK                                  144
+#define VMEM_AHB_CLK                                   145
+
+#define SPDM_BCR                                       0
+#define SPDM_RM_BCR                                    1
+#define MISC_BCR                                       2
+#define VIDEO_TOP_BCR                                  3
+#define THROTTLE_VIDEO_BCR                             4
+#define MDSS_BCR                                       5
+#define THROTTLE_MDSS_BCR                              6
+#define CAMSS_PHY0_BCR                                 7
+#define CAMSS_PHY1_BCR                                 8
+#define CAMSS_PHY2_BCR                                 9
+#define CAMSS_CSI0_BCR                                 10
+#define CAMSS_CSI0RDI_BCR                              11
+#define CAMSS_CSI0PIX_BCR                              12
+#define CAMSS_CSI1_BCR                                 13
+#define CAMSS_CSI1RDI_BCR                              14
+#define CAMSS_CSI1PIX_BCR                              15
+#define CAMSS_CSI2_BCR                                 16
+#define CAMSS_CSI2RDI_BCR                              17
+#define CAMSS_CSI2PIX_BCR                              18
+#define CAMSS_CSI3_BCR                                 19
+#define CAMSS_CSI3RDI_BCR                              20
+#define CAMSS_CSI3PIX_BCR                              21
+#define CAMSS_ISPIF_BCR                                        22
+#define CAMSS_CCI_BCR                                  23
+#define CAMSS_TOP_BCR                                  24
+#define CAMSS_AHB_BCR                                  25
+#define CAMSS_MICRO_BCR                                        26
+#define CAMSS_JPEG_BCR                                 27
+#define CAMSS_VFE0_BCR                                 28
+#define CAMSS_VFE1_BCR                                 29
+#define CAMSS_VFE_VBIF_BCR                             30
+#define CAMSS_CPP_TOP_BCR                              31
+#define CAMSS_CPP_BCR                                  32
+#define CAMSS_CSI_VFE0_BCR                             33
+#define CAMSS_CSI_VFE1_BCR                             34
+#define CAMSS_FD_BCR                                   35
+#define THROTTLE_CAMSS_BCR                             36
+#define MNOCAHB_BCR                                    37
+#define MNOCAXI_BCR                                    38
+#define BMIC_SMMU_BCR                                  39
+#define MNOC_MAXI_BCR                                  40
+#define VMEM_BCR                                       41
+#define BTO_BCR                                                42
+
+#define VIDEO_TOP_GDSC         1
+#define VIDEO_SUBCORE0_GDSC    2
+#define VIDEO_SUBCORE1_GDSC    3
+#define MDSS_GDSC              4
+#define CAMSS_TOP_GDSC         5
+#define CAMSS_VFE0_GDSC                6
+#define CAMSS_VFE1_GDSC                7
+#define CAMSS_CPP_GDSC         8
+#define BIMC_SMMU_GDSC         9
+
+#endif
diff --git a/include/dt-bindings/clock/qcom,videocc-sc7180.h b/include/dt-bindings/clock/qcom,videocc-sc7180.h
new file mode 100644 (file)
index 0000000..7acaf13
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2019, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SC7180_H
+#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SC7180_H
+
+/* VIDEO_CC clocks */
+#define VIDEO_PLL0                             0
+#define VIDEO_CC_VCODEC0_AXI_CLK               1
+#define VIDEO_CC_VCODEC0_CORE_CLK              2
+#define VIDEO_CC_VENUS_AHB_CLK                 3
+#define VIDEO_CC_VENUS_CLK_SRC                 4
+#define VIDEO_CC_VENUS_CTL_AXI_CLK             5
+#define VIDEO_CC_VENUS_CTL_CORE_CLK            6
+#define VIDEO_CC_XO_CLK                                7
+
+/* VIDEO_CC GDSCRs */
+#define VENUS_GDSC                             0
+#define VCODEC0_GDSC                           1
+
+#endif
index a8ac4cf..e512a1c 100644 (file)
@@ -46,6 +46,7 @@
 #define CLK_PLL_VIDEO0         7
 #define CLK_PLL_PERIPH0                11
 
+#define CLK_CPUX               21
 #define CLK_BUS_MIPI_DSI       28
 #define CLK_BUS_CE             29
 #define CLK_BUS_DMA            30
index c5d1334..39878d9 100644 (file)
@@ -49,6 +49,8 @@
 
 #define CLK_PLL_VIDEO1_2X      13
 
+#define CLK_PLL_MIPI           15
+
 #define CLK_CPU                        18
 
 #define CLK_AHB1_MIPIDSI       23
index f8222b6..eb524d0 100644 (file)
@@ -43,6 +43,8 @@
 #ifndef _DT_BINDINGS_CLK_SUN8I_A23_A33_H_
 #define _DT_BINDINGS_CLK_SUN8I_A23_A33_H_
 
+#define CLK_PLL_MIPI           13
+
 #define CLK_CPUX               18
 
 #define CLK_BUS_MIPI_DSI       23
index f9e15a2..d7337b5 100644 (file)
 #define CLK_AVS                        152
 #define CLK_HDMI               153
 #define CLK_HDMI_SLOW          154
-
+#define CLK_MBUS               155
 #define CLK_DSI_DPHY           156
 #define CLK_TVE0               157
 #define CLK_TVE1               158
diff --git a/include/dt-bindings/clock/xlnx-versal-clk.h b/include/dt-bindings/clock/xlnx-versal-clk.h
new file mode 100644 (file)
index 0000000..264d634
--- /dev/null
@@ -0,0 +1,123 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ *  Copyright (C) 2019 Xilinx Inc.
+ *
+ */
+
+#ifndef _DT_BINDINGS_CLK_VERSAL_H
+#define _DT_BINDINGS_CLK_VERSAL_H
+
+#define PMC_PLL                                        1
+#define APU_PLL                                        2
+#define RPU_PLL                                        3
+#define CPM_PLL                                        4
+#define NOC_PLL                                        5
+#define PLL_MAX                                        6
+#define PMC_PRESRC                             7
+#define PMC_POSTCLK                            8
+#define PMC_PLL_OUT                            9
+#define PPLL                                   10
+#define NOC_PRESRC                             11
+#define NOC_POSTCLK                            12
+#define NOC_PLL_OUT                            13
+#define NPLL                                   14
+#define APU_PRESRC                             15
+#define APU_POSTCLK                            16
+#define APU_PLL_OUT                            17
+#define APLL                                   18
+#define RPU_PRESRC                             19
+#define RPU_POSTCLK                            20
+#define RPU_PLL_OUT                            21
+#define RPLL                                   22
+#define CPM_PRESRC                             23
+#define CPM_POSTCLK                            24
+#define CPM_PLL_OUT                            25
+#define CPLL                                   26
+#define PPLL_TO_XPD                            27
+#define NPLL_TO_XPD                            28
+#define APLL_TO_XPD                            29
+#define RPLL_TO_XPD                            30
+#define EFUSE_REF                              31
+#define SYSMON_REF                             32
+#define IRO_SUSPEND_REF                                33
+#define USB_SUSPEND                            34
+#define SWITCH_TIMEOUT                         35
+#define RCLK_PMC                               36
+#define RCLK_LPD                               37
+#define WDT                                    38
+#define TTC0                                   39
+#define TTC1                                   40
+#define TTC2                                   41
+#define TTC3                                   42
+#define GEM_TSU                                        43
+#define GEM_TSU_LB                             44
+#define MUXED_IRO_DIV2                         45
+#define MUXED_IRO_DIV4                         46
+#define PSM_REF                                        47
+#define GEM0_RX                                        48
+#define GEM0_TX                                        49
+#define GEM1_RX                                        50
+#define GEM1_TX                                        51
+#define CPM_CORE_REF                           52
+#define CPM_LSBUS_REF                          53
+#define CPM_DBG_REF                            54
+#define CPM_AUX0_REF                           55
+#define CPM_AUX1_REF                           56
+#define QSPI_REF                               57
+#define OSPI_REF                               58
+#define SDIO0_REF                              59
+#define SDIO1_REF                              60
+#define PMC_LSBUS_REF                          61
+#define I2C_REF                                        62
+#define TEST_PATTERN_REF                       63
+#define DFT_OSC_REF                            64
+#define PMC_PL0_REF                            65
+#define PMC_PL1_REF                            66
+#define PMC_PL2_REF                            67
+#define PMC_PL3_REF                            68
+#define CFU_REF                                        69
+#define SPARE_REF                              70
+#define NPI_REF                                        71
+#define HSM0_REF                               72
+#define HSM1_REF                               73
+#define SD_DLL_REF                             74
+#define FPD_TOP_SWITCH                         75
+#define FPD_LSBUS                              76
+#define ACPU                                   77
+#define DBG_TRACE                              78
+#define DBG_FPD                                        79
+#define LPD_TOP_SWITCH                         80
+#define ADMA                                   81
+#define LPD_LSBUS                              82
+#define CPU_R5                                 83
+#define CPU_R5_CORE                            84
+#define CPU_R5_OCM                             85
+#define CPU_R5_OCM2                            86
+#define IOU_SWITCH                             87
+#define GEM0_REF                               88
+#define GEM1_REF                               89
+#define GEM_TSU_REF                            90
+#define USB0_BUS_REF                           91
+#define UART0_REF                              92
+#define UART1_REF                              93
+#define SPI0_REF                               94
+#define SPI1_REF                               95
+#define CAN0_REF                               96
+#define CAN1_REF                               97
+#define I2C0_REF                               98
+#define I2C1_REF                               99
+#define DBG_LPD                                        100
+#define TIMESTAMP_REF                          101
+#define DBG_TSTMP                              102
+#define CPM_TOPSW_REF                          103
+#define USB3_DUAL_REF                          104
+#define OUTCLK_MAX                             105
+#define REF_CLK                                        106
+#define PL_ALT_REF_CLK                         107
+#define MUXED_IRO                              108
+#define PL_EXT                                 109
+#define PL_LB                                  110
+#define MIO_50_OR_51                           111
+#define MIO_24_OR_25                           112
+
+#endif
index 6481353..82a1e27 100644 (file)
 #define TEGRA186_SID_SE_VM6            0x4e
 #define TEGRA186_SID_SE_VM7            0x4f
 
+/*
+ * memory client IDs
+ */
+
+/* Misses from System Memory Management Unit (SMMU) Page Table Cache (PTC) */
+#define TEGRA186_MEMORY_CLIENT_PTCR 0x00
+/* PCIE reads */
+#define TEGRA186_MEMORY_CLIENT_AFIR 0x0e
+/* High-definition audio (HDA) reads */
+#define TEGRA186_MEMORY_CLIENT_HDAR 0x15
+/* Host channel data reads */
+#define TEGRA186_MEMORY_CLIENT_HOST1XDMAR 0x16
+#define TEGRA186_MEMORY_CLIENT_NVENCSRD 0x1c
+/* SATA reads */
+#define TEGRA186_MEMORY_CLIENT_SATAR 0x1f
+/* Reads from Cortex-A9 4 CPU cores via the L2 cache */
+#define TEGRA186_MEMORY_CLIENT_MPCORER 0x27
+#define TEGRA186_MEMORY_CLIENT_NVENCSWR 0x2b
+/* PCIE writes */
+#define TEGRA186_MEMORY_CLIENT_AFIW 0x31
+/* High-definition audio (HDA) writes */
+#define TEGRA186_MEMORY_CLIENT_HDAW 0x35
+/* Writes from Cortex-A9 4 CPU cores via the L2 cache */
+#define TEGRA186_MEMORY_CLIENT_MPCOREW 0x39
+/* SATA writes */
+#define TEGRA186_MEMORY_CLIENT_SATAW 0x3d
+/* ISP Read client for Crossbar A */
+#define TEGRA186_MEMORY_CLIENT_ISPRA 0x44
+/* ISP Write client for Crossbar A */
+#define TEGRA186_MEMORY_CLIENT_ISPWA 0x46
+/* ISP Write client Crossbar B */
+#define TEGRA186_MEMORY_CLIENT_ISPWB 0x47
+/* XUSB reads */
+#define TEGRA186_MEMORY_CLIENT_XUSB_HOSTR 0x4a
+/* XUSB_HOST writes */
+#define TEGRA186_MEMORY_CLIENT_XUSB_HOSTW 0x4b
+/* XUSB reads */
+#define TEGRA186_MEMORY_CLIENT_XUSB_DEVR 0x4c
+/* XUSB_DEV writes */
+#define TEGRA186_MEMORY_CLIENT_XUSB_DEVW 0x4d
+/* TSEC Memory Return Data Client Description */
+#define TEGRA186_MEMORY_CLIENT_TSECSRD 0x54
+/* TSEC Memory Write Client Description */
+#define TEGRA186_MEMORY_CLIENT_TSECSWR 0x55
+/* 3D, ltcx reads instance 0 */
+#define TEGRA186_MEMORY_CLIENT_GPUSRD 0x58
+/* 3D, ltcx writes instance 0 */
+#define TEGRA186_MEMORY_CLIENT_GPUSWR 0x59
+/* sdmmca memory read client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCRA 0x60
+/* sdmmcbmemory read client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCRAA 0x61
+/* sdmmc memory read client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCR 0x62
+/* sdmmcd memory read client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCRAB 0x63
+/* sdmmca memory write client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCWA 0x64
+/* sdmmcb memory write client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCWAA 0x65
+/* sdmmc memory write client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCW 0x66
+/* sdmmcd memory write client */
+#define TEGRA186_MEMORY_CLIENT_SDMMCWAB 0x67
+#define TEGRA186_MEMORY_CLIENT_VICSRD 0x6c
+#define TEGRA186_MEMORY_CLIENT_VICSWR 0x6d
+/* VI Write client */
+#define TEGRA186_MEMORY_CLIENT_VIW 0x72
+#define TEGRA186_MEMORY_CLIENT_NVDECSRD 0x78
+#define TEGRA186_MEMORY_CLIENT_NVDECSWR 0x79
+/* Audio Processing (APE) engine reads */
+#define TEGRA186_MEMORY_CLIENT_APER 0x7a
+/* Audio Processing (APE) engine writes */
+#define TEGRA186_MEMORY_CLIENT_APEW 0x7b
+#define TEGRA186_MEMORY_CLIENT_NVJPGSRD 0x7e
+#define TEGRA186_MEMORY_CLIENT_NVJPGSWR 0x7f
+/* SE Memory Return Data Client Description */
+#define TEGRA186_MEMORY_CLIENT_SESRD 0x80
+/* SE Memory Write Client Description */
+#define TEGRA186_MEMORY_CLIENT_SESWR 0x81
+/* ETR reads */
+#define TEGRA186_MEMORY_CLIENT_ETRR 0x84
+/* ETR writes */
+#define TEGRA186_MEMORY_CLIENT_ETRW 0x85
+/* TSECB Memory Return Data Client Description */
+#define TEGRA186_MEMORY_CLIENT_TSECSRDB 0x86
+/* TSECB Memory Write Client Description */
+#define TEGRA186_MEMORY_CLIENT_TSECSWRB 0x87
+/* 3D, ltcx reads instance 1 */
+#define TEGRA186_MEMORY_CLIENT_GPUSRD2 0x88
+/* 3D, ltcx writes instance 1 */
+#define TEGRA186_MEMORY_CLIENT_GPUSWR2 0x89
+/* AXI Switch read client */
+#define TEGRA186_MEMORY_CLIENT_AXISR 0x8c
+/* AXI Switch write client */
+#define TEGRA186_MEMORY_CLIENT_AXISW 0x8d
+/* EQOS read client */
+#define TEGRA186_MEMORY_CLIENT_EQOSR 0x8e
+/* EQOS write client */
+#define TEGRA186_MEMORY_CLIENT_EQOSW 0x8f
+/* UFSHC read client */
+#define TEGRA186_MEMORY_CLIENT_UFSHCR 0x90
+/* UFSHC write client */
+#define TEGRA186_MEMORY_CLIENT_UFSHCW 0x91
+/* NVDISPLAY read client */
+#define TEGRA186_MEMORY_CLIENT_NVDISPLAYR 0x92
+/* BPMP read client */
+#define TEGRA186_MEMORY_CLIENT_BPMPR 0x93
+/* BPMP write client */
+#define TEGRA186_MEMORY_CLIENT_BPMPW 0x94
+/* BPMPDMA read client */
+#define TEGRA186_MEMORY_CLIENT_BPMPDMAR 0x95
+/* BPMPDMA write client */
+#define TEGRA186_MEMORY_CLIENT_BPMPDMAW 0x96
+/* AON read client */
+#define TEGRA186_MEMORY_CLIENT_AONR 0x97
+/* AON write client */
+#define TEGRA186_MEMORY_CLIENT_AONW 0x98
+/* AONDMA read client */
+#define TEGRA186_MEMORY_CLIENT_AONDMAR 0x99
+/* AONDMA write client */
+#define TEGRA186_MEMORY_CLIENT_AONDMAW 0x9a
+/* SCE read client */
+#define TEGRA186_MEMORY_CLIENT_SCER 0x9b
+/* SCE write client */
+#define TEGRA186_MEMORY_CLIENT_SCEW 0x9c
+/* SCEDMA read client */
+#define TEGRA186_MEMORY_CLIENT_SCEDMAR 0x9d
+/* SCEDMA write client */
+#define TEGRA186_MEMORY_CLIENT_SCEDMAW 0x9e
+/* APEDMA read client */
+#define TEGRA186_MEMORY_CLIENT_APEDMAR 0x9f
+/* APEDMA write client */
+#define TEGRA186_MEMORY_CLIENT_APEDMAW 0xa0
+/* NVDISPLAY read client instance 2 */
+#define TEGRA186_MEMORY_CLIENT_NVDISPLAYR1 0xa1
+#define TEGRA186_MEMORY_CLIENT_VICSRD1 0xa2
+#define TEGRA186_MEMORY_CLIENT_NVDECSRD1 0xa3
+
 #endif
diff --git a/include/dt-bindings/memory/tegra194-mc.h b/include/dt-bindings/memory/tegra194-mc.h
new file mode 100644 (file)
index 0000000..eed48b7
--- /dev/null
@@ -0,0 +1,410 @@
+#ifndef DT_BINDINGS_MEMORY_TEGRA194_MC_H
+#define DT_BINDINGS_MEMORY_TEGRA194_MC_H
+
+/* special clients */
+#define TEGRA194_SID_INVALID           0x00
+#define TEGRA194_SID_PASSTHROUGH       0x7f
+
+/* host1x clients */
+#define TEGRA194_SID_HOST1X            0x01
+#define TEGRA194_SID_CSI               0x02
+#define TEGRA194_SID_VIC               0x03
+#define TEGRA194_SID_VI                        0x04
+#define TEGRA194_SID_ISP               0x05
+#define TEGRA194_SID_NVDEC             0x06
+#define TEGRA194_SID_NVENC             0x07
+#define TEGRA194_SID_NVJPG             0x08
+#define TEGRA194_SID_NVDISPLAY         0x09
+#define TEGRA194_SID_TSEC              0x0a
+#define TEGRA194_SID_TSECB             0x0b
+#define TEGRA194_SID_SE                        0x0c
+#define TEGRA194_SID_SE1               0x0d
+#define TEGRA194_SID_SE2               0x0e
+#define TEGRA194_SID_SE3               0x0f
+
+/* GPU clients */
+#define TEGRA194_SID_GPU               0x10
+
+/* other SoC clients */
+#define TEGRA194_SID_AFI               0x11
+#define TEGRA194_SID_HDA               0x12
+#define TEGRA194_SID_ETR               0x13
+#define TEGRA194_SID_EQOS              0x14
+#define TEGRA194_SID_UFSHC             0x15
+#define TEGRA194_SID_AON               0x16
+#define TEGRA194_SID_SDMMC4            0x17
+#define TEGRA194_SID_SDMMC3            0x18
+#define TEGRA194_SID_SDMMC2            0x19
+#define TEGRA194_SID_SDMMC1            0x1a
+#define TEGRA194_SID_XUSB_HOST         0x1b
+#define TEGRA194_SID_XUSB_DEV          0x1c
+#define TEGRA194_SID_SATA              0x1d
+#define TEGRA194_SID_APE               0x1e
+#define TEGRA194_SID_SCE               0x1f
+
+/* GPC DMA clients */
+#define TEGRA194_SID_GPCDMA_0          0x20
+#define TEGRA194_SID_GPCDMA_1          0x21
+#define TEGRA194_SID_GPCDMA_2          0x22
+#define TEGRA194_SID_GPCDMA_3          0x23
+#define TEGRA194_SID_GPCDMA_4          0x24
+#define TEGRA194_SID_GPCDMA_5          0x25
+#define TEGRA194_SID_GPCDMA_6          0x26
+#define TEGRA194_SID_GPCDMA_7          0x27
+
+/* APE DMA clients */
+#define TEGRA194_SID_APE_1             0x28
+#define TEGRA194_SID_APE_2             0x29
+
+/* camera RTCPU */
+#define TEGRA194_SID_RCE               0x2a
+
+/* camera RTCPU on host1x address space */
+#define TEGRA194_SID_RCE_1X            0x2b
+
+/* APE DMA clients */
+#define TEGRA194_SID_APE_3             0x2c
+
+/* camera RTCPU running on APE */
+#define TEGRA194_SID_APE_CAM           0x2d
+#define TEGRA194_SID_APE_CAM_1X                0x2e
+
+#define TEGRA194_SID_RCE_RM            0x2f
+#define TEGRA194_SID_VI_FALCON         0x30
+#define TEGRA194_SID_ISP_FALCON                0x31
+
+/*
+ * The BPMP has its SID value hardcoded in the firmware. Changing it requires
+ * considerable effort.
+ */
+#define TEGRA194_SID_BPMP              0x32
+
+/* for SMMU tests */
+#define TEGRA194_SID_SMMU_TEST         0x33
+
+/* host1x virtualization channels */
+#define TEGRA194_SID_HOST1X_CTX0       0x38
+#define TEGRA194_SID_HOST1X_CTX1       0x39
+#define TEGRA194_SID_HOST1X_CTX2       0x3a
+#define TEGRA194_SID_HOST1X_CTX3       0x3b
+#define TEGRA194_SID_HOST1X_CTX4       0x3c
+#define TEGRA194_SID_HOST1X_CTX5       0x3d
+#define TEGRA194_SID_HOST1X_CTX6       0x3e
+#define TEGRA194_SID_HOST1X_CTX7       0x3f
+
+/* host1x command buffers */
+#define TEGRA194_SID_HOST1X_VM0                0x40
+#define TEGRA194_SID_HOST1X_VM1                0x41
+#define TEGRA194_SID_HOST1X_VM2                0x42
+#define TEGRA194_SID_HOST1X_VM3                0x43
+#define TEGRA194_SID_HOST1X_VM4                0x44
+#define TEGRA194_SID_HOST1X_VM5                0x45
+#define TEGRA194_SID_HOST1X_VM6                0x46
+#define TEGRA194_SID_HOST1X_VM7                0x47
+
+/* SE data buffers */
+#define TEGRA194_SID_SE_VM0            0x48
+#define TEGRA194_SID_SE_VM1            0x49
+#define TEGRA194_SID_SE_VM2            0x4a
+#define TEGRA194_SID_SE_VM3            0x4b
+#define TEGRA194_SID_SE_VM4            0x4c
+#define TEGRA194_SID_SE_VM5            0x4d
+#define TEGRA194_SID_SE_VM6            0x4e
+#define TEGRA194_SID_SE_VM7            0x4f
+
+#define TEGRA194_SID_MIU               0x50
+
+#define TEGRA194_SID_NVDLA0            0x51
+#define TEGRA194_SID_NVDLA1            0x52
+
+#define TEGRA194_SID_PVA0              0x53
+#define TEGRA194_SID_PVA1              0x54
+#define TEGRA194_SID_NVENC1            0x55
+#define TEGRA194_SID_PCIE0             0x56
+#define TEGRA194_SID_PCIE1             0x57
+#define TEGRA194_SID_PCIE2             0x58
+#define TEGRA194_SID_PCIE3             0x59
+#define TEGRA194_SID_PCIE4             0x5a
+#define TEGRA194_SID_PCIE5             0x5b
+#define TEGRA194_SID_NVDEC1            0x5c
+
+#define TEGRA194_SID_XUSB_VF0          0x5d
+#define TEGRA194_SID_XUSB_VF1          0x5e
+#define TEGRA194_SID_XUSB_VF2          0x5f
+#define TEGRA194_SID_XUSB_VF3          0x60
+
+#define TEGRA194_SID_RCE_VM3           0x61
+#define TEGRA194_SID_VI_VM2            0x62
+#define TEGRA194_SID_VI_VM3            0x63
+#define TEGRA194_SID_RCE_SERVER                0x64
+
+/*
+ * memory client IDs
+ */
+
+/* Misses from System Memory Management Unit (SMMU) Page Table Cache (PTC) */
+#define TEGRA194_MEMORY_CLIENT_PTCR 0x00
+/* MSS internal memqual MIU7 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU7R 0x01
+/* MSS internal memqual MIU7 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU7W 0x02
+/* High-definition audio (HDA) read clients */
+#define TEGRA194_MEMORY_CLIENT_HDAR 0x15
+/* Host channel data read clients */
+#define TEGRA194_MEMORY_CLIENT_HOST1XDMAR 0x16
+#define TEGRA194_MEMORY_CLIENT_NVENCSRD 0x1c
+/* SATA read clients */
+#define TEGRA194_MEMORY_CLIENT_SATAR 0x1f
+/* Reads from Cortex-A9 4 CPU cores via the L2 cache */
+#define TEGRA194_MEMORY_CLIENT_MPCORER 0x27
+#define TEGRA194_MEMORY_CLIENT_NVENCSWR 0x2b
+/* High-definition audio (HDA) write clients */
+#define TEGRA194_MEMORY_CLIENT_HDAW 0x35
+/* Writes from Cortex-A9 4 CPU cores via the L2 cache */
+#define TEGRA194_MEMORY_CLIENT_MPCOREW 0x39
+/* SATA write clients */
+#define TEGRA194_MEMORY_CLIENT_SATAW 0x3d
+/* ISP read client for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPRA 0x44
+/* ISP read client 1 for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPFALR 0x45
+/* ISP Write client for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPWA 0x46
+/* ISP Write client Crossbar B */
+#define TEGRA194_MEMORY_CLIENT_ISPWB 0x47
+/* XUSB_HOST read clients */
+#define TEGRA194_MEMORY_CLIENT_XUSB_HOSTR 0x4a
+/* XUSB_HOST write clients */
+#define TEGRA194_MEMORY_CLIENT_XUSB_HOSTW 0x4b
+/* XUSB read clients */
+#define TEGRA194_MEMORY_CLIENT_XUSB_DEVR 0x4c
+/* XUSB_DEV write clients */
+#define TEGRA194_MEMORY_CLIENT_XUSB_DEVW 0x4d
+/* sdmmca memory read client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCRA 0x60
+/* sdmmc memory read client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCR 0x62
+/* sdmmcd memory read client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCRAB 0x63
+/* sdmmca memory write client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCWA 0x64
+/* sdmmc memory write client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCW 0x66
+/* sdmmcd memory write client */
+#define TEGRA194_MEMORY_CLIENT_SDMMCWAB 0x67
+#define TEGRA194_MEMORY_CLIENT_VICSRD 0x6c
+#define TEGRA194_MEMORY_CLIENT_VICSWR 0x6d
+/* VI Write client */
+#define TEGRA194_MEMORY_CLIENT_VIW 0x72
+#define TEGRA194_MEMORY_CLIENT_NVDECSRD 0x78
+#define TEGRA194_MEMORY_CLIENT_NVDECSWR 0x79
+/* Audio Processing (APE) engine read clients */
+#define TEGRA194_MEMORY_CLIENT_APER 0x7a
+/* Audio Processing (APE) engine write clients */
+#define TEGRA194_MEMORY_CLIENT_APEW 0x7b
+#define TEGRA194_MEMORY_CLIENT_NVJPGSRD 0x7e
+#define TEGRA194_MEMORY_CLIENT_NVJPGSWR 0x7f
+/* AXI AP and DFD-AUX0/1 read clients Both share the same interface on the on MSS */
+#define TEGRA194_MEMORY_CLIENT_AXIAPR 0x82
+/* AXI AP and DFD-AUX0/1 write clients Both sahre the same interface on MSS */
+#define TEGRA194_MEMORY_CLIENT_AXIAPW 0x83
+/* ETR read clients */
+#define TEGRA194_MEMORY_CLIENT_ETRR 0x84
+/* ETR write clients */
+#define TEGRA194_MEMORY_CLIENT_ETRW 0x85
+/* AXI Switch read client */
+#define TEGRA194_MEMORY_CLIENT_AXISR 0x8c
+/* AXI Switch write client */
+#define TEGRA194_MEMORY_CLIENT_AXISW 0x8d
+/* EQOS read client */
+#define TEGRA194_MEMORY_CLIENT_EQOSR 0x8e
+/* EQOS write client */
+#define TEGRA194_MEMORY_CLIENT_EQOSW 0x8f
+/* UFSHC read client */
+#define TEGRA194_MEMORY_CLIENT_UFSHCR 0x90
+/* UFSHC write client */
+#define TEGRA194_MEMORY_CLIENT_UFSHCW 0x91
+/* NVDISPLAY read client */
+#define TEGRA194_MEMORY_CLIENT_NVDISPLAYR 0x92
+/* BPMP read client */
+#define TEGRA194_MEMORY_CLIENT_BPMPR 0x93
+/* BPMP write client */
+#define TEGRA194_MEMORY_CLIENT_BPMPW 0x94
+/* BPMPDMA read client */
+#define TEGRA194_MEMORY_CLIENT_BPMPDMAR 0x95
+/* BPMPDMA write client */
+#define TEGRA194_MEMORY_CLIENT_BPMPDMAW 0x96
+/* AON read client */
+#define TEGRA194_MEMORY_CLIENT_AONR 0x97
+/* AON write client */
+#define TEGRA194_MEMORY_CLIENT_AONW 0x98
+/* AONDMA read client */
+#define TEGRA194_MEMORY_CLIENT_AONDMAR 0x99
+/* AONDMA write client */
+#define TEGRA194_MEMORY_CLIENT_AONDMAW 0x9a
+/* SCE read client */
+#define TEGRA194_MEMORY_CLIENT_SCER 0x9b
+/* SCE write client */
+#define TEGRA194_MEMORY_CLIENT_SCEW 0x9c
+/* SCEDMA read client */
+#define TEGRA194_MEMORY_CLIENT_SCEDMAR 0x9d
+/* SCEDMA write client */
+#define TEGRA194_MEMORY_CLIENT_SCEDMAW 0x9e
+/* APEDMA read client */
+#define TEGRA194_MEMORY_CLIENT_APEDMAR 0x9f
+/* APEDMA write client */
+#define TEGRA194_MEMORY_CLIENT_APEDMAW 0xa0
+/* NVDISPLAY read client instance 2 */
+#define TEGRA194_MEMORY_CLIENT_NVDISPLAYR1 0xa1
+#define TEGRA194_MEMORY_CLIENT_VICSRD1 0xa2
+#define TEGRA194_MEMORY_CLIENT_NVDECSRD1 0xa3
+/* MSS internal memqual MIU0 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU0R 0xa6
+/* MSS internal memqual MIU0 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU0W 0xa7
+/* MSS internal memqual MIU1 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU1R 0xa8
+/* MSS internal memqual MIU1 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU1W 0xa9
+/* MSS internal memqual MIU2 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU2R 0xae
+/* MSS internal memqual MIU2 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU2W 0xaf
+/* MSS internal memqual MIU3 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU3R 0xb0
+/* MSS internal memqual MIU3 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU3W 0xb1
+/* MSS internal memqual MIU4 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU4R 0xb2
+/* MSS internal memqual MIU4 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU4W 0xb3
+#define TEGRA194_MEMORY_CLIENT_DPMUR 0xb4
+#define TEGRA194_MEMORY_CLIENT_DPMUW 0xb5
+#define TEGRA194_MEMORY_CLIENT_NVL0R 0xb6
+#define TEGRA194_MEMORY_CLIENT_NVL0W 0xb7
+#define TEGRA194_MEMORY_CLIENT_NVL1R 0xb8
+#define TEGRA194_MEMORY_CLIENT_NVL1W 0xb9
+#define TEGRA194_MEMORY_CLIENT_NVL2R 0xba
+#define TEGRA194_MEMORY_CLIENT_NVL2W 0xbb
+/* VI FLACON read clients */
+#define TEGRA194_MEMORY_CLIENT_VIFALR 0xbc
+/* VIFAL write clients */
+#define TEGRA194_MEMORY_CLIENT_VIFALW 0xbd
+/* DLA0ARDA read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0RDA 0xbe
+/* DLA0 Falcon read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0FALRDB 0xbf
+/* DLA0 write clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0WRA 0xc0
+/* DLA0 write clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0FALWRB 0xc1
+/* DLA1ARDA read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1RDA 0xc2
+/* DLA1 Falcon read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1FALRDB 0xc3
+/* DLA1 write clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1WRA 0xc4
+/* DLA1 write clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1FALWRB 0xc5
+/* PVA0RDA read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDA 0xc6
+/* PVA0RDB read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDB 0xc7
+/* PVA0RDC read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDC 0xc8
+/* PVA0WRA write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0WRA 0xc9
+/* PVA0WRB write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0WRB 0xca
+/* PVA0WRC write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0WRC 0xcb
+/* PVA1RDA read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDA 0xcc
+/* PVA1RDB read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDB 0xcd
+/* PVA1RDC read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDC 0xce
+/* PVA1WRA write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1WRA 0xcf
+/* PVA1WRB write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1WRB 0xd0
+/* PVA1WRC write clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1WRC 0xd1
+/* RCE read client */
+#define TEGRA194_MEMORY_CLIENT_RCER 0xd2
+/* RCE write client */
+#define TEGRA194_MEMORY_CLIENT_RCEW 0xd3
+/* RCEDMA read client */
+#define TEGRA194_MEMORY_CLIENT_RCEDMAR 0xd4
+/* RCEDMA write client */
+#define TEGRA194_MEMORY_CLIENT_RCEDMAW 0xd5
+#define TEGRA194_MEMORY_CLIENT_NVENC1SRD 0xd6
+#define TEGRA194_MEMORY_CLIENT_NVENC1SWR 0xd7
+/* PCIE0 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE0R 0xd8
+/* PCIE0 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE0W 0xd9
+/* PCIE1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE1R 0xda
+/* PCIE1 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE1W 0xdb
+/* PCIE2 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE2AR 0xdc
+/* PCIE2 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE2AW 0xdd
+/* PCIE3 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE3R 0xde
+/* PCIE3 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE3W 0xdf
+/* PCIE4 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE4R 0xe0
+/* PCIE4 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE4W 0xe1
+/* PCIE5 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE5R 0xe2
+/* PCIE5 write clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE5W 0xe3
+/* ISP read client 1 for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPFALW 0xe4
+#define TEGRA194_MEMORY_CLIENT_NVL3R 0xe5
+#define TEGRA194_MEMORY_CLIENT_NVL3W 0xe6
+#define TEGRA194_MEMORY_CLIENT_NVL4R 0xe7
+#define TEGRA194_MEMORY_CLIENT_NVL4W 0xe8
+/* DLA0ARDA1 read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA0RDA1 0xe9
+/* DLA1ARDA1 read clients */
+#define TEGRA194_MEMORY_CLIENT_DLA1RDA1 0xea
+/* PVA0RDA1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDA1 0xeb
+/* PVA0RDB1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA0RDB1 0xec
+/* PVA1RDA1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDA1 0xed
+/* PVA1RDB1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PVA1RDB1 0xee
+/* PCIE5r1 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE5R1 0xef
+#define TEGRA194_MEMORY_CLIENT_NVENCSRD1 0xf0
+#define TEGRA194_MEMORY_CLIENT_NVENC1SRD1 0xf1
+/* ISP read client for Crossbar A */
+#define TEGRA194_MEMORY_CLIENT_ISPRA1 0xf2
+/* PCIE0 read clients */
+#define TEGRA194_MEMORY_CLIENT_PCIE0R1 0xf3
+#define TEGRA194_MEMORY_CLIENT_NVL0RHP 0xf4
+#define TEGRA194_MEMORY_CLIENT_NVL1RHP 0xf5
+#define TEGRA194_MEMORY_CLIENT_NVL2RHP 0xf6
+#define TEGRA194_MEMORY_CLIENT_NVL3RHP 0xf7
+#define TEGRA194_MEMORY_CLIENT_NVL4RHP 0xf8
+#define TEGRA194_MEMORY_CLIENT_NVDEC1SRD 0xf9
+#define TEGRA194_MEMORY_CLIENT_NVDEC1SRD1 0xfa
+#define TEGRA194_MEMORY_CLIENT_NVDEC1SWR 0xfb
+/* MSS internal memqual MIU5 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU5R 0xfc
+/* MSS internal memqual MIU5 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU5W 0xfd
+/* MSS internal memqual MIU6 read clients */
+#define TEGRA194_MEMORY_CLIENT_MIU6R 0xfe
+/* MSS internal memqual MIU6 write clients */
+#define TEGRA194_MEMORY_CLIENT_MIU6W 0xff
+
+#endif
diff --git a/include/dt-bindings/power/mt6765-power.h b/include/dt-bindings/power/mt6765-power.h
new file mode 100644 (file)
index 0000000..d347b4e
--- /dev/null
@@ -0,0 +1,14 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _DT_BINDINGS_POWER_MT6765_POWER_H
+#define _DT_BINDINGS_POWER_MT6765_POWER_H
+
+#define MT6765_POWER_DOMAIN_CONN               0
+#define MT6765_POWER_DOMAIN_MM                 1
+#define MT6765_POWER_DOMAIN_MFG_ASYNC          2
+#define MT6765_POWER_DOMAIN_ISP                        3
+#define MT6765_POWER_DOMAIN_MFG                        4
+#define MT6765_POWER_DOMAIN_MFG_CORE0          5
+#define MT6765_POWER_DOMAIN_CAM                        6
+#define MT6765_POWER_DOMAIN_VCODEC             7
+
+#endif /* _DT_BINDINGS_POWER_MT6765_POWER_H */
index f05f8b1..3f74096 100644 (file)
 #define SDM845_GFX     7
 #define SDM845_MSS     8
 
+/* SM8150 Power Domain Indexes */
+#define SM8150_MSS     0
+#define SM8150_EBI     1
+#define SM8150_LMX     2
+#define SM8150_LCX     3
+#define SM8150_GFX     4
+#define SM8150_MX      5
+#define SM8150_MX_AO   6
+#define SM8150_CX      7
+#define SM8150_CX_AO   8
+#define SM8150_MMCX    9
+#define SM8150_MMCX_AO 10
+
+/* SC7180 Power Domain Indexes */
+#define SC7180_CX      0
+#define SC7180_CX_AO   1
+#define SC7180_GFX     2
+#define SC7180_MX      3
+#define SC7180_MX_AO   4
+#define SC7180_LMX     5
+#define SC7180_LCX     6
+#define SC7180_MSS     7
+
 /* SDM845 Power Domain performance levels */
 #define RPMH_REGULATOR_LEVEL_RETENTION 16
 #define RPMH_REGULATOR_LEVEL_MIN_SVS   48
 #define RPMH_REGULATOR_LEVEL_LOW_SVS   64
 #define RPMH_REGULATOR_LEVEL_SVS       128
 #define RPMH_REGULATOR_LEVEL_SVS_L1    192
+#define RPMH_REGULATOR_LEVEL_SVS_L2    224
 #define RPMH_REGULATOR_LEVEL_NOM       256
 #define RPMH_REGULATOR_LEVEL_NOM_L1    320
 #define RPMH_REGULATOR_LEVEL_NOM_L2    336
diff --git a/include/dt-bindings/reset-controller/mt2712-resets.h b/include/dt-bindings/reset-controller/mt2712-resets.h
new file mode 100644 (file)
index 0000000..9e7ee76
--- /dev/null
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Yong Liang <yong.liang@mediatek.com>
+ */
+
+#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT2712
+#define _DT_BINDINGS_RESET_CONTROLLER_MT2712
+
+#define MT2712_TOPRGU_INFRA_SW_RST                             0
+#define MT2712_TOPRGU_MM_SW_RST                                        1
+#define MT2712_TOPRGU_MFG_SW_RST                               2
+#define MT2712_TOPRGU_VENC_SW_RST                              3
+#define MT2712_TOPRGU_VDEC_SW_RST                              4
+#define MT2712_TOPRGU_IMG_SW_RST                               5
+#define MT2712_TOPRGU_INFRA_AO_SW_RST                          8
+#define MT2712_TOPRGU_USB_SW_RST                               9
+#define MT2712_TOPRGU_APMIXED_SW_RST                           10
+
+#define MT2712_TOPRGU_SW_RST_NUM                               11
+
+#endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT2712 */
index 8804e34..a1bbd41 100644 (file)
 #define MT8183_INFRACFG_AO_I2C7_SW_RST                         126
 #define MT8183_INFRACFG_AO_I2C8_SW_RST                         127
 
+#define MT8183_INFRACFG_SW_RST_NUM                             128
+
+#define MT8183_TOPRGU_MM_SW_RST                                        1
+#define MT8183_TOPRGU_MFG_SW_RST                               2
+#define MT8183_TOPRGU_VENC_SW_RST                              3
+#define MT8183_TOPRGU_VDEC_SW_RST                              4
+#define MT8183_TOPRGU_IMG_SW_RST                               5
+#define MT8183_TOPRGU_MD_SW_RST                                        7
+#define MT8183_TOPRGU_CONN_SW_RST                              9
+#define MT8183_TOPRGU_CONN_MCU_SW_RST                          12
+#define MT8183_TOPRGU_IPU0_SW_RST                              14
+#define MT8183_TOPRGU_IPU1_SW_RST                              15
+#define MT8183_TOPRGU_AUDIO_SW_RST                             17
+#define MT8183_TOPRGU_CAMSYS_SW_RST                            18
+
+#define MT8183_TOPRGU_SW_RST_NUM                               19
+
 #endif  /* _DT_BINDINGS_RESET_CONTROLLER_MT8183 */
diff --git a/include/dt-bindings/reset/nuvoton,npcm7xx-reset.h b/include/dt-bindings/reset/nuvoton,npcm7xx-reset.h
new file mode 100644 (file)
index 0000000..df088e6
--- /dev/null
@@ -0,0 +1,91 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+// Copyright (c) 2019 Nuvoton Technology corporation.
+
+#ifndef _DT_BINDINGS_NPCM7XX_RESET_H
+#define _DT_BINDINGS_NPCM7XX_RESET_H
+
+#define NPCM7XX_RESET_IPSRST1          0x20
+#define NPCM7XX_RESET_IPSRST2          0x24
+#define NPCM7XX_RESET_IPSRST3          0x34
+
+/* Reset lines on IP1 reset module (NPCM7XX_RESET_IPSRST1) */
+#define NPCM7XX_RESET_FIU3             1
+#define NPCM7XX_RESET_UDC1             5
+#define NPCM7XX_RESET_EMC1             6
+#define NPCM7XX_RESET_UART_2_3         7
+#define NPCM7XX_RESET_UDC2             8
+#define NPCM7XX_RESET_PECI             9
+#define NPCM7XX_RESET_AES              10
+#define NPCM7XX_RESET_UART_0_1         11
+#define NPCM7XX_RESET_MC               12
+#define NPCM7XX_RESET_SMB2             13
+#define NPCM7XX_RESET_SMB3             14
+#define NPCM7XX_RESET_SMB4             15
+#define NPCM7XX_RESET_SMB5             16
+#define NPCM7XX_RESET_PWM_M0           18
+#define NPCM7XX_RESET_TIMER_0_4                19
+#define NPCM7XX_RESET_TIMER_5_9                20
+#define NPCM7XX_RESET_EMC2             21
+#define NPCM7XX_RESET_UDC4             22
+#define NPCM7XX_RESET_UDC5             23
+#define NPCM7XX_RESET_UDC6             24
+#define NPCM7XX_RESET_UDC3             25
+#define NPCM7XX_RESET_ADC              27
+#define NPCM7XX_RESET_SMB6             28
+#define NPCM7XX_RESET_SMB7             29
+#define NPCM7XX_RESET_SMB0             30
+#define NPCM7XX_RESET_SMB1             31
+
+/* Reset lines on IP2 reset module (NPCM7XX_RESET_IPSRST2) */
+#define NPCM7XX_RESET_MFT0             0
+#define NPCM7XX_RESET_MFT1             1
+#define NPCM7XX_RESET_MFT2             2
+#define NPCM7XX_RESET_MFT3             3
+#define NPCM7XX_RESET_MFT4             4
+#define NPCM7XX_RESET_MFT5             5
+#define NPCM7XX_RESET_MFT6             6
+#define NPCM7XX_RESET_MFT7             7
+#define NPCM7XX_RESET_MMC              8
+#define NPCM7XX_RESET_SDHC             9
+#define NPCM7XX_RESET_GFX_SYS          10
+#define NPCM7XX_RESET_AHB_PCIBRG       11
+#define NPCM7XX_RESET_VDMA             12
+#define NPCM7XX_RESET_ECE              13
+#define NPCM7XX_RESET_VCD              14
+#define NPCM7XX_RESET_OTP              16
+#define NPCM7XX_RESET_SIOX1            18
+#define NPCM7XX_RESET_SIOX2            19
+#define NPCM7XX_RESET_3DES             21
+#define NPCM7XX_RESET_PSPI1            22
+#define NPCM7XX_RESET_PSPI2            23
+#define NPCM7XX_RESET_GMAC2            25
+#define NPCM7XX_RESET_USB_HOST         26
+#define NPCM7XX_RESET_GMAC1            28
+#define NPCM7XX_RESET_CP               31
+
+/* Reset lines on IP3 reset module (NPCM7XX_RESET_IPSRST3) */
+#define NPCM7XX_RESET_PWM_M1           0
+#define NPCM7XX_RESET_SMB12            1
+#define NPCM7XX_RESET_SPIX             2
+#define NPCM7XX_RESET_SMB13            3
+#define NPCM7XX_RESET_UDC0             4
+#define NPCM7XX_RESET_UDC7             5
+#define NPCM7XX_RESET_UDC8             6
+#define NPCM7XX_RESET_UDC9             7
+#define NPCM7XX_RESET_PCI_MAILBOX      9
+#define NPCM7XX_RESET_SMB14            12
+#define NPCM7XX_RESET_SHA              13
+#define NPCM7XX_RESET_SEC_ECC          14
+#define NPCM7XX_RESET_PCIE_RC          15
+#define NPCM7XX_RESET_TIMER_10_14      16
+#define NPCM7XX_RESET_RNG              17
+#define NPCM7XX_RESET_SMB15            18
+#define NPCM7XX_RESET_SMB8             19
+#define NPCM7XX_RESET_SMB9             20
+#define NPCM7XX_RESET_SMB10            21
+#define NPCM7XX_RESET_SMB11            22
+#define NPCM7XX_RESET_ESPI             23
+#define NPCM7XX_RESET_USB_PHY_1                24
+#define NPCM7XX_RESET_USB_PHY_2                25
+
+#endif
diff --git a/include/dt-bindings/reset/qcom,gcc-ipq6018.h b/include/dt-bindings/reset/qcom,gcc-ipq6018.h
new file mode 100644 (file)
index 0000000..02a220a
--- /dev/null
@@ -0,0 +1,157 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ */
+
+#ifndef _DT_BINDINGS_RESET_IPQ_GCC_6018_H
+#define _DT_BINDINGS_RESET_IPQ_GCC_6018_H
+
+#define GCC_BLSP1_BCR                          0
+#define GCC_BLSP1_QUP1_BCR                     1
+#define GCC_BLSP1_UART1_BCR                    2
+#define GCC_BLSP1_QUP2_BCR                     3
+#define GCC_BLSP1_UART2_BCR                    4
+#define GCC_BLSP1_QUP3_BCR                     5
+#define GCC_BLSP1_UART3_BCR                    6
+#define GCC_BLSP1_QUP4_BCR                     7
+#define GCC_BLSP1_UART4_BCR                    8
+#define GCC_BLSP1_QUP5_BCR                     9
+#define GCC_BLSP1_UART5_BCR                    10
+#define GCC_BLSP1_QUP6_BCR                     11
+#define GCC_BLSP1_UART6_BCR                    12
+#define GCC_IMEM_BCR                           13
+#define GCC_SMMU_BCR                           14
+#define GCC_APSS_TCU_BCR                       15
+#define GCC_SMMU_XPU_BCR                       16
+#define GCC_PCNOC_TBU_BCR                      17
+#define GCC_SMMU_CFG_BCR                       18
+#define GCC_PRNG_BCR                           19
+#define GCC_BOOT_ROM_BCR                       20
+#define GCC_CRYPTO_BCR                         21
+#define GCC_WCSS_BCR                           22
+#define GCC_WCSS_Q6_BCR                                23
+#define GCC_NSS_BCR                            24
+#define GCC_SEC_CTRL_BCR                       25
+#define GCC_DDRSS_BCR                          26
+#define GCC_SYSTEM_NOC_BCR                     27
+#define GCC_PCNOC_BCR                          28
+#define GCC_TCSR_BCR                           29
+#define GCC_QDSS_BCR                           30
+#define GCC_DCD_BCR                            31
+#define GCC_MSG_RAM_BCR                                32
+#define GCC_MPM_BCR                            33
+#define GCC_SPDM_BCR                           34
+#define GCC_RBCPR_BCR                          35
+#define GCC_RBCPR_MX_BCR                       36
+#define GCC_TLMM_BCR                           37
+#define GCC_RBCPR_WCSS_BCR                     38
+#define GCC_USB0_PHY_BCR                       39
+#define GCC_USB3PHY_0_PHY_BCR                  40
+#define GCC_USB0_BCR                           41
+#define GCC_USB1_BCR                           42
+#define GCC_QUSB2_0_PHY_BCR                    43
+#define GCC_QUSB2_1_PHY_BCR                    44
+#define GCC_SDCC1_BCR                          45
+#define GCC_SNOC_BUS_TIMEOUT0_BCR              46
+#define GCC_SNOC_BUS_TIMEOUT1_BCR              47
+#define GCC_SNOC_BUS_TIMEOUT2_BCR              48
+#define GCC_PCNOC_BUS_TIMEOUT0_BCR             49
+#define GCC_PCNOC_BUS_TIMEOUT1_BCR             50
+#define GCC_PCNOC_BUS_TIMEOUT2_BCR             51
+#define GCC_PCNOC_BUS_TIMEOUT3_BCR             52
+#define GCC_PCNOC_BUS_TIMEOUT4_BCR             53
+#define GCC_PCNOC_BUS_TIMEOUT5_BCR             54
+#define GCC_PCNOC_BUS_TIMEOUT6_BCR             55
+#define GCC_PCNOC_BUS_TIMEOUT7_BCR             56
+#define GCC_PCNOC_BUS_TIMEOUT8_BCR             57
+#define GCC_PCNOC_BUS_TIMEOUT9_BCR             58
+#define GCC_UNIPHY0_BCR                                59
+#define GCC_UNIPHY1_BCR                                60
+#define GCC_CMN_12GPLL_BCR                     61
+#define GCC_QPIC_BCR                           62
+#define GCC_MDIO_BCR                           63
+#define GCC_WCSS_CORE_TBU_BCR                  64
+#define GCC_WCSS_Q6_TBU_BCR                    65
+#define GCC_USB0_TBU_BCR                       66
+#define GCC_PCIE0_TBU_BCR                      67
+#define GCC_PCIE0_BCR                          68
+#define GCC_PCIE0_PHY_BCR                      69
+#define GCC_PCIE0PHY_PHY_BCR                   70
+#define GCC_PCIE0_LINK_DOWN_BCR                        71
+#define GCC_DCC_BCR                            72
+#define GCC_APC0_VOLTAGE_DROOP_DETECTOR_BCR    73
+#define GCC_SMMU_CATS_BCR                      74
+#define GCC_UBI0_AXI_ARES                      75
+#define GCC_UBI0_AHB_ARES                      76
+#define GCC_UBI0_NC_AXI_ARES                   77
+#define GCC_UBI0_DBG_ARES                      78
+#define GCC_UBI0_CORE_CLAMP_ENABLE             79
+#define GCC_UBI0_CLKRST_CLAMP_ENABLE           80
+#define GCC_UBI0_UTCM_ARES                     81
+#define GCC_NSS_CFG_ARES                       82
+#define GCC_NSS_NOC_ARES                       83
+#define GCC_NSS_CRYPTO_ARES                    84
+#define GCC_NSS_CSR_ARES                       85
+#define GCC_NSS_CE_APB_ARES                    86
+#define GCC_NSS_CE_AXI_ARES                    87
+#define GCC_NSSNOC_CE_APB_ARES                 88
+#define GCC_NSSNOC_CE_AXI_ARES                 89
+#define GCC_NSSNOC_UBI0_AHB_ARES               90
+#define GCC_NSSNOC_SNOC_ARES                   91
+#define GCC_NSSNOC_CRYPTO_ARES                 92
+#define GCC_NSSNOC_ATB_ARES                    93
+#define GCC_NSSNOC_QOSGEN_REF_ARES             94
+#define GCC_NSSNOC_TIMEOUT_REF_ARES            95
+#define GCC_PCIE0_PIPE_ARES                    96
+#define GCC_PCIE0_SLEEP_ARES                   97
+#define GCC_PCIE0_CORE_STICKY_ARES             98
+#define GCC_PCIE0_AXI_MASTER_ARES              99
+#define GCC_PCIE0_AXI_SLAVE_ARES               100
+#define GCC_PCIE0_AHB_ARES                     101
+#define GCC_PCIE0_AXI_MASTER_STICKY_ARES       102
+#define GCC_PCIE0_AXI_SLAVE_STICKY_ARES                103
+#define GCC_PPE_FULL_RESET                     104
+#define GCC_UNIPHY0_SOFT_RESET                 105
+#define GCC_UNIPHY0_XPCS_RESET                 106
+#define GCC_UNIPHY1_SOFT_RESET                 107
+#define GCC_UNIPHY1_XPCS_RESET                 108
+#define GCC_EDMA_HW_RESET                      109
+#define GCC_ADSS_BCR                           110
+#define GCC_NSS_NOC_TBU_BCR                    111
+#define GCC_NSSPORT1_RESET                     112
+#define GCC_NSSPORT2_RESET                     113
+#define GCC_NSSPORT3_RESET                     114
+#define GCC_NSSPORT4_RESET                     115
+#define GCC_NSSPORT5_RESET                     116
+#define GCC_UNIPHY0_PORT1_ARES                 117
+#define GCC_UNIPHY0_PORT2_ARES                 118
+#define GCC_UNIPHY0_PORT3_ARES                 119
+#define GCC_UNIPHY0_PORT4_ARES                 120
+#define GCC_UNIPHY0_PORT5_ARES                 121
+#define GCC_UNIPHY0_PORT_4_5_RESET             122
+#define GCC_UNIPHY0_PORT_4_RESET               123
+#define GCC_LPASS_BCR                          124
+#define GCC_UBI32_TBU_BCR                      125
+#define GCC_LPASS_TBU_BCR                      126
+#define GCC_WCSSAON_RESET                      127
+#define GCC_LPASS_Q6_AXIM_ARES                 128
+#define GCC_LPASS_Q6SS_TSCTR_1TO2_ARES         129
+#define GCC_LPASS_Q6SS_TRIG_ARES               130
+#define GCC_LPASS_Q6_ATBM_AT_ARES              131
+#define GCC_LPASS_Q6_PCLKDBG_ARES              132
+#define GCC_LPASS_CORE_AXIM_ARES               133
+#define GCC_LPASS_SNOC_CFG_ARES                        134
+#define GCC_WCSS_DBG_ARES                      135
+#define GCC_WCSS_ECAHB_ARES                    136
+#define GCC_WCSS_ACMT_ARES                     137
+#define GCC_WCSS_DBG_BDG_ARES                  138
+#define GCC_WCSS_AHB_S_ARES                    139
+#define GCC_WCSS_AXI_M_ARES                    140
+#define GCC_Q6SS_DBG_ARES                      141
+#define GCC_Q6_AHB_S_ARES                      142
+#define GCC_Q6_AHB_ARES                                143
+#define GCC_Q6_AXIM2_ARES                      144
+#define GCC_Q6_AXIM_ARES                       145
+#define GCC_UBI0_CORE_ARES                     146
+
+#endif
index 80ad521..e52ceb1 100644 (file)
@@ -186,7 +186,7 @@ bitmap_find_next_zero_area(unsigned long *map,
                                              align_mask, 0);
 }
 
-extern int __bitmap_parse(const char *buf, unsigned int buflen, int is_user,
+extern int bitmap_parse(const char *buf, unsigned int buflen,
                        unsigned long *dst, int nbits);
 extern int bitmap_parse_user(const char __user *ubuf, unsigned int ulen,
                        unsigned long *dst, int nbits);
@@ -454,12 +454,6 @@ static inline void bitmap_replace(unsigned long *dst,
                __bitmap_replace(dst, old, new, mask, nbits);
 }
 
-static inline int bitmap_parse(const char *buf, unsigned int buflen,
-                       unsigned long *maskp, int nmaskbits)
-{
-       return __bitmap_parse(buf, buflen, 0, maskp, nmaskbits);
-}
-
 static inline void bitmap_next_clear_region(unsigned long *bitmap,
                                            unsigned int *rs, unsigned int *re,
                                            unsigned int end)
index 6c7c413..47f54b4 100644 (file)
 #  define aligned_byte_mask(n) (~0xffUL << (BITS_PER_LONG - 8 - 8*(n)))
 #endif
 
-#define BITS_PER_TYPE(type) (sizeof(type) * BITS_PER_BYTE)
+#define BITS_PER_TYPE(type)    (sizeof(type) * BITS_PER_BYTE)
 #define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
+#define BITS_TO_U64(nr)                DIV_ROUND_UP(nr, BITS_PER_TYPE(u64))
+#define BITS_TO_U32(nr)                DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
 #define BITS_TO_BYTES(nr)      DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
 
 extern unsigned int __sw_hweight8(unsigned int w);
diff --git a/include/linux/bootconfig.h b/include/linux/bootconfig.h
new file mode 100644 (file)
index 0000000..7e18c93
--- /dev/null
@@ -0,0 +1,224 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_XBC_H
+#define _LINUX_XBC_H
+/*
+ * Extra Boot Config
+ * Copyright (C) 2019 Linaro Ltd.
+ * Author: Masami Hiramatsu <mhiramat@kernel.org>
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+
+/* XBC tree node */
+struct xbc_node {
+       u16 next;
+       u16 child;
+       u16 parent;
+       u16 data;
+} __attribute__ ((__packed__));
+
+#define XBC_KEY                0
+#define XBC_VALUE      (1 << 15)
+/* Maximum size of boot config is 32KB - 1 */
+#define XBC_DATA_MAX   (XBC_VALUE - 1)
+
+#define XBC_NODE_MAX   1024
+#define XBC_KEYLEN_MAX 256
+#define XBC_DEPTH_MAX  16
+
+/* Node tree access raw APIs */
+struct xbc_node * __init xbc_root_node(void);
+int __init xbc_node_index(struct xbc_node *node);
+struct xbc_node * __init xbc_node_get_parent(struct xbc_node *node);
+struct xbc_node * __init xbc_node_get_child(struct xbc_node *node);
+struct xbc_node * __init xbc_node_get_next(struct xbc_node *node);
+const char * __init xbc_node_get_data(struct xbc_node *node);
+
+/**
+ * xbc_node_is_value() - Test the node is a value node
+ * @node: An XBC node.
+ *
+ * Test the @node is a value node and return true if a value node, false if not.
+ */
+static inline __init bool xbc_node_is_value(struct xbc_node *node)
+{
+       return node->data & XBC_VALUE;
+}
+
+/**
+ * xbc_node_is_key() - Test the node is a key node
+ * @node: An XBC node.
+ *
+ * Test the @node is a key node and return true if a key node, false if not.
+ */
+static inline __init bool xbc_node_is_key(struct xbc_node *node)
+{
+       return !xbc_node_is_value(node);
+}
+
+/**
+ * xbc_node_is_array() - Test the node is an arraied value node
+ * @node: An XBC node.
+ *
+ * Test the @node is an arraied value node.
+ */
+static inline __init bool xbc_node_is_array(struct xbc_node *node)
+{
+       return xbc_node_is_value(node) && node->next != 0;
+}
+
+/**
+ * xbc_node_is_leaf() - Test the node is a leaf key node
+ * @node: An XBC node.
+ *
+ * Test the @node is a leaf key node which is a key node and has a value node
+ * or no child. Returns true if it is a leaf node, or false if not.
+ */
+static inline __init bool xbc_node_is_leaf(struct xbc_node *node)
+{
+       return xbc_node_is_key(node) &&
+               (!node->child || xbc_node_is_value(xbc_node_get_child(node)));
+}
+
+/* Tree-based key-value access APIs */
+struct xbc_node * __init xbc_node_find_child(struct xbc_node *parent,
+                                            const char *key);
+
+const char * __init xbc_node_find_value(struct xbc_node *parent,
+                                       const char *key,
+                                       struct xbc_node **vnode);
+
+struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
+                                                struct xbc_node *leaf);
+
+const char * __init xbc_node_find_next_key_value(struct xbc_node *root,
+                                                struct xbc_node **leaf);
+
+/**
+ * xbc_find_value() - Find a value which matches the key
+ * @key: Search key
+ * @vnode: A container pointer of XBC value node.
+ *
+ * Search a value whose key matches @key from whole of XBC tree and return
+ * the value if found. Found value node is stored in *@vnode.
+ * Note that this can return 0-length string and store NULL in *@vnode for
+ * key-only (non-value) entry.
+ */
+static inline const char * __init
+xbc_find_value(const char *key, struct xbc_node **vnode)
+{
+       return xbc_node_find_value(NULL, key, vnode);
+}
+
+/**
+ * xbc_find_node() - Find a node which matches the key
+ * @key: Search key
+ *
+ * Search a (key) node whose key matches @key from whole of XBC tree and
+ * return the node if found. If not found, returns NULL.
+ */
+static inline struct xbc_node * __init xbc_find_node(const char *key)
+{
+       return xbc_node_find_child(NULL, key);
+}
+
+/**
+ * xbc_array_for_each_value() - Iterate value nodes on an array
+ * @anode: An XBC arraied value node
+ * @value: A value
+ *
+ * Iterate array value nodes and values starts from @anode. This is expected to
+ * be used with xbc_find_value() and xbc_node_find_value(), so that user can
+ * process each array entry node.
+ */
+#define xbc_array_for_each_value(anode, value)                         \
+       for (value = xbc_node_get_data(anode); anode != NULL ;          \
+            anode = xbc_node_get_next(anode),                          \
+            value = anode ? xbc_node_get_data(anode) : NULL)
+
+/**
+ * xbc_node_for_each_child() - Iterate child nodes
+ * @parent: An XBC node.
+ * @child: Iterated XBC node.
+ *
+ * Iterate child nodes of @parent. Each child nodes are stored to @child.
+ */
+#define xbc_node_for_each_child(parent, child)                         \
+       for (child = xbc_node_get_child(parent); child != NULL ;        \
+            child = xbc_node_get_next(child))
+
+/**
+ * xbc_node_for_each_array_value() - Iterate array entries of geven key
+ * @node: An XBC node.
+ * @key: A key string searched under @node
+ * @anode: Iterated XBC node of array entry.
+ * @value: Iterated value of array entry.
+ *
+ * Iterate array entries of given @key under @node. Each array entry node
+ * is stroed to @anode and @value. If the @node doesn't have @key node,
+ * it does nothing.
+ * Note that even if the found key node has only one value (not array)
+ * this executes block once. Hoever, if the found key node has no value
+ * (key-only node), this does nothing. So don't use this for testing the
+ * key-value pair existence.
+ */
+#define xbc_node_for_each_array_value(node, key, anode, value)         \
+       for (value = xbc_node_find_value(node, key, &anode); value != NULL; \
+            anode = xbc_node_get_next(anode),                          \
+            value = anode ? xbc_node_get_data(anode) : NULL)
+
+/**
+ * xbc_node_for_each_key_value() - Iterate key-value pairs under a node
+ * @node: An XBC node.
+ * @knode: Iterated key node
+ * @value: Iterated value string
+ *
+ * Iterate key-value pairs under @node. Each key node and value string are
+ * stored in @knode and @value respectively.
+ */
+#define xbc_node_for_each_key_value(node, knode, value)                        \
+       for (knode = NULL, value = xbc_node_find_next_key_value(node, &knode);\
+            knode != NULL; value = xbc_node_find_next_key_value(node, &knode))
+
+/**
+ * xbc_for_each_key_value() - Iterate key-value pairs
+ * @knode: Iterated key node
+ * @value: Iterated value string
+ *
+ * Iterate key-value pairs in whole XBC tree. Each key node and value string
+ * are stored in @knode and @value respectively.
+ */
+#define xbc_for_each_key_value(knode, value)                           \
+       xbc_node_for_each_key_value(NULL, knode, value)
+
+/* Compose partial key */
+int __init xbc_node_compose_key_after(struct xbc_node *root,
+                       struct xbc_node *node, char *buf, size_t size);
+
+/**
+ * xbc_node_compose_key() - Compose full key string of the XBC node
+ * @node: An XBC node.
+ * @buf: A buffer to store the key.
+ * @size: The size of the @buf.
+ *
+ * Compose the full-length key of the @node into @buf. Returns the total
+ * length of the key stored in @buf. Or returns -EINVAL if @node is NULL,
+ * and -ERANGE if the key depth is deeper than max depth.
+ */
+static inline int __init xbc_node_compose_key(struct xbc_node *node,
+                                             char *buf, size_t size)
+{
+       return xbc_node_compose_key_after(NULL, node, buf, size);
+}
+
+/* XBC node initializer */
+int __init xbc_init(char *buf);
+
+/* XBC cleanup data structures */
+void __init xbc_destroy_all(void);
+
+/* Debug dump functions */
+void __init xbc_debug_dump(void);
+
+#endif
index 8e9ad39..49b1a70 100644 (file)
@@ -728,7 +728,7 @@ struct bpf_struct_ops {
 #if defined(CONFIG_BPF_JIT) && defined(CONFIG_BPF_SYSCALL)
 #define BPF_MODULE_OWNER ((void *)((0xeB9FUL << 2) + POISON_POINTER_DELTA))
 const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id);
-void bpf_struct_ops_init(struct btf *btf);
+void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log);
 bool bpf_struct_ops_get(const void *kdata);
 void bpf_struct_ops_put(const void *kdata);
 int bpf_struct_ops_map_sys_lookup_elem(struct bpf_map *map, void *key,
@@ -752,7 +752,10 @@ static inline const struct bpf_struct_ops *bpf_struct_ops_find(u32 type_id)
 {
        return NULL;
 }
-static inline void bpf_struct_ops_init(struct btf *btf) { }
+static inline void bpf_struct_ops_init(struct btf *btf,
+                                      struct bpf_verifier_log *log)
+{
+}
 static inline bool bpf_try_module_get(const void *data, struct module *owner)
 {
        return try_module_get(owner);
index 8fe9b80..ec73ebc 100644 (file)
@@ -281,11 +281,12 @@ extern int ceph_check_fsid(struct ceph_client *client, struct ceph_fsid *fsid);
 extern void *ceph_kvmalloc(size_t size, gfp_t flags);
 
 struct fs_parameter;
+struct fc_log;
 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);
+                      struct fc_log *l);
 int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
-                    struct fs_context *fc);
+                    struct fc_log *l);
 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 0067d76..35d3852 100644 (file)
@@ -25,8 +25,9 @@ struct ceph_mdsmap {
        u32 m_session_timeout;          /* seconds */
        u32 m_session_autoclose;        /* seconds */
        u64 m_max_file_size;
-       u32 m_max_mds;                  /* size of m_addr, m_state arrays */
-       int m_num_mds;
+       u32 m_max_mds;                  /* expected up:active mds number */
+       u32 m_num_active_mds;           /* actual up:active mds number */
+       u32 possible_max_rank;          /* possible max rank index */
        struct ceph_mds_info *m_info;
 
        /* which object pools file data can be stored in */
@@ -42,7 +43,7 @@ struct ceph_mdsmap {
 static inline struct ceph_entity_addr *
 ceph_mdsmap_get_addr(struct ceph_mdsmap *m, int w)
 {
-       if (w >= m->m_num_mds)
+       if (w >= m->possible_max_rank)
                return NULL;
        return &m->m_info[w].addr;
 }
@@ -50,14 +51,14 @@ ceph_mdsmap_get_addr(struct ceph_mdsmap *m, int w)
 static inline int ceph_mdsmap_get_state(struct ceph_mdsmap *m, int w)
 {
        BUG_ON(w < 0);
-       if (w >= m->m_num_mds)
+       if (w >= m->possible_max_rank)
                return CEPH_MDS_STATE_DNE;
        return m->m_info[w].state;
 }
 
 static inline bool ceph_mdsmap_is_laggy(struct ceph_mdsmap *m, int w)
 {
-       if (w >= 0 && w < m->m_num_mds)
+       if (w >= 0 && w < m->possible_max_rank)
                return m->m_info[w].laggy;
        return false;
 }
index eaffbdd..5a62dbd 100644 (file)
@@ -534,6 +534,7 @@ int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
                        struct ceph_object_id *dst_oid,
                        struct ceph_object_locator *dst_oloc,
                        u32 dst_fadvise_flags,
+                       u32 truncate_seq, u64 truncate_size,
                        u8 copy_from_flags);
 
 /* watch/notify */
index 3eb0e55..59bdfd4 100644 (file)
@@ -256,6 +256,7 @@ extern const char *ceph_osd_state_name(int s);
                                                                            \
        /* tiering */                                                       \
        f(COPY_FROM,    __CEPH_OSD_OP(WR, DATA, 26),    "copy-from")        \
+       f(COPY_FROM2,   __CEPH_OSD_OP(WR, DATA, 45),    "copy-from2")       \
        f(COPY_GET_CLASSIC, __CEPH_OSD_OP(RD, DATA, 27), "copy-get-classic") \
        f(UNDIRTY,      __CEPH_OSD_OP(WR, DATA, 28),    "undirty")          \
        f(ISDIRTY,      __CEPH_OSD_OP(RD, DATA, 29),    "isdirty")          \
@@ -446,6 +447,7 @@ enum {
        CEPH_OSD_COPY_FROM_FLAG_MAP_SNAP_CLONE = 8, /* map snap direct to
                                                     * cloneid */
        CEPH_OSD_COPY_FROM_FLAG_RWORDERED = 16,     /* order with write */
+       CEPH_OSD_COPY_FROM_FLAG_TRUNCATE_SEQ = 32,  /* send truncate_{seq,size} */
 };
 
 enum {
index caf4b9d..952ac03 100644 (file)
@@ -190,8 +190,14 @@ struct clk_duty {
  *
  * @init:      Perform platform-specific initialization magic.
  *             This is not not used by any of the basic clock types.
- *             Please consider other ways of solving initialization problems
- *             before using this callback, as its use is discouraged.
+ *             This callback exist for HW which needs to perform some
+ *             initialisation magic for CCF to get an accurate view of the
+ *             clock. It may also be used dynamic resource allocation is
+ *             required. It shall not used to deal with clock parameters,
+ *             such as rate or parents.
+ *             Returns 0 on success, -EERROR otherwise.
+ *
+ * @terminate:  Free any resource allocated by init.
  *
  * @debug_init:        Set up type-specific debugfs entries for this clock.  This
  *             is called once, after the debugfs directory entry for this
@@ -243,7 +249,8 @@ struct clk_ops {
                                          struct clk_duty *duty);
        int             (*set_duty_cycle)(struct clk_hw *hw,
                                          struct clk_duty *duty);
-       void            (*init)(struct clk_hw *hw);
+       int             (*init)(struct clk_hw *hw);
+       void            (*terminate)(struct clk_hw *hw);
        void            (*debug_init)(struct clk_hw *hw, struct dentry *dentry);
 };
 
@@ -321,29 +328,119 @@ struct clk_hw {
  * struct clk_fixed_rate - fixed-rate clock
  * @hw:                handle between common and hardware-specific interfaces
  * @fixed_rate:        constant frequency of clock
+ * @fixed_accuracy: constant accuracy of clock in ppb (parts per billion)
+ * @flags:     hardware specific flags
+ *
+ * Flags:
+ * * CLK_FIXED_RATE_PARENT_ACCURACY - Use the accuracy of the parent clk
+ *                                    instead of what's set in @fixed_accuracy.
  */
 struct clk_fixed_rate {
        struct          clk_hw hw;
        unsigned long   fixed_rate;
        unsigned long   fixed_accuracy;
+       unsigned long   flags;
 };
 
-#define to_clk_fixed_rate(_hw) container_of(_hw, struct clk_fixed_rate, hw)
+#define CLK_FIXED_RATE_PARENT_ACCURACY         BIT(0)
 
 extern const struct clk_ops clk_fixed_rate_ops;
+struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data, unsigned long flags,
+               unsigned long fixed_rate, unsigned long fixed_accuracy,
+               unsigned long clk_fixed_flags);
 struct clk *clk_register_fixed_rate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                unsigned long fixed_rate);
-struct clk_hw *clk_hw_register_fixed_rate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate);
-struct clk *clk_register_fixed_rate_with_accuracy(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate, unsigned long fixed_accuracy);
+/**
+ * clk_hw_register_fixed_rate - register fixed-rate clock with the clock
+ * framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
+#define clk_hw_register_fixed_rate(dev, name, parent_name, flags, fixed_rate)  \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), (parent_name), NULL, \
+                                    NULL, (flags), (fixed_rate), 0, 0)
+/**
+ * clk_hw_register_fixed_rate_parent_hw - register fixed-rate clock with
+ * the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
+#define clk_hw_register_fixed_rate_parent_hw(dev, name, parent_hw, flags,     \
+                                            fixed_rate)                      \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw),  \
+                                    NULL, (flags), (fixed_rate), 0, 0)
+/**
+ * clk_hw_register_fixed_rate_parent_data - register fixed-rate clock with
+ * the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ */
+#define clk_hw_register_fixed_rate_parent_data(dev, name, parent_hw, flags,   \
+                                            fixed_rate)                      \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL,         \
+                                    (parent_data), (flags), (fixed_rate), 0, \
+                                    0)
+/**
+ * clk_hw_register_fixed_rate_with_accuracy - register fixed-rate clock with
+ * the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ * @fixed_accuracy: non-adjustable clock accuracy
+ */
+#define clk_hw_register_fixed_rate_with_accuracy(dev, name, parent_name,      \
+                                                flags, fixed_rate,           \
+                                                fixed_accuracy)              \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), (parent_name),      \
+                                    NULL, NULL, (flags), (fixed_rate),       \
+                                    (fixed_accuracy), 0)
+/**
+ * clk_hw_register_fixed_rate_with_accuracy_parent_hw - register fixed-rate
+ * clock with the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ * @fixed_accuracy: non-adjustable clock accuracy
+ */
+#define clk_hw_register_fixed_rate_with_accuracy_parent_hw(dev, name,        \
+               parent_hw, flags, fixed_rate, fixed_accuracy)                 \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, (parent_hw)   \
+                                    NULL, NULL, (flags), (fixed_rate),       \
+                                    (fixed_accuracy), 0)
+/**
+ * clk_hw_register_fixed_rate_with_accuracy_parent_data - register fixed-rate
+ * clock with the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @fixed_rate: non-adjustable clock rate
+ * @fixed_accuracy: non-adjustable clock accuracy
+ */
+#define clk_hw_register_fixed_rate_with_accuracy_parent_data(dev, name,              \
+               parent_data, flags, fixed_rate, fixed_accuracy)               \
+       __clk_hw_register_fixed_rate((dev), NULL, (name), NULL, NULL,         \
+                                    (parent_data), NULL, (flags),            \
+                                    (fixed_rate), (fixed_accuracy), 0)
+
 void clk_unregister_fixed_rate(struct clk *clk);
-struct clk_hw *clk_hw_register_fixed_rate_with_accuracy(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               unsigned long fixed_rate, unsigned long fixed_accuracy);
 void clk_hw_unregister_fixed_rate(struct clk_hw *hw);
 
 void of_fixed_clk_setup(struct device_node *np);
@@ -386,14 +483,67 @@ struct clk_gate {
 #define CLK_GATE_BIG_ENDIAN            BIT(2)
 
 extern const struct clk_ops clk_gate_ops;
-struct clk *clk_register_gate(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
+struct clk_hw *__clk_hw_register_gate(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock);
-struct clk_hw *clk_hw_register_gate(struct device *dev, const char *name,
+struct clk *clk_register_gate(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 bit_idx,
                u8 clk_gate_flags, spinlock_t *lock);
+/**
+ * clk_hw_register_gate - register a gate clock with the clock framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_name: name of this clock's parent
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_gate(dev, name, parent_name, flags, reg, bit_idx,     \
+                            clk_gate_flags, lock)                            \
+       __clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL,      \
+                              NULL, (flags), (reg), (bit_idx),               \
+                              (clk_gate_flags), (lock))
+/**
+ * clk_hw_register_gate_parent_hw - register a gate clock with the clock
+ * framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_gate_parent_hw(dev, name, parent_name, flags, reg,    \
+                                      bit_idx, clk_gate_flags, lock)         \
+       __clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL,      \
+                              NULL, (flags), (reg), (bit_idx),               \
+                              (clk_gate_flags), (lock))
+/**
+ * clk_hw_register_gate_parent_data - register a gate clock with the clock
+ * framework
+ * @dev: device that is registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags for this clock
+ * @reg: register address to control gating of this clock
+ * @bit_idx: which bit in the register controls gating of this clock
+ * @clk_gate_flags: gate-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_gate_parent_data(dev, name, parent_name, flags, reg,  \
+                                      bit_idx, clk_gate_flags, lock)         \
+       __clk_hw_register_gate((dev), NULL, (name), (parent_name), NULL,      \
+                              NULL, (flags), (reg), (bit_idx),               \
+                              (clk_gate_flags), (lock))
 void clk_unregister_gate(struct clk *clk);
 void clk_hw_unregister_gate(struct clk_hw *hw);
 int clk_gate_is_enabled(struct clk_hw *hw);
@@ -483,24 +633,153 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,
                const struct clk_div_table *table, u8 width,
                unsigned long flags);
 
-struct clk *clk_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, spinlock_t *lock);
-struct clk_hw *clk_hw_register_divider(struct device *dev, const char *name,
-               const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, spinlock_t *lock);
+struct clk_hw *__clk_hw_register_divider(struct device *dev,
+               struct device_node *np, const char *name,
+               const char *parent_name, const struct clk_hw *parent_hw,
+               const struct clk_parent_data *parent_data, unsigned long flags,
+               void __iomem *reg, u8 shift, u8 width, u8 clk_divider_flags,
+               const struct clk_div_table *table, spinlock_t *lock);
 struct clk *clk_register_divider_table(struct device *dev, const char *name,
                const char *parent_name, unsigned long flags,
                void __iomem *reg, u8 shift, u8 width,
                u8 clk_divider_flags, const struct clk_div_table *table,
                spinlock_t *lock);
-struct clk_hw *clk_hw_register_divider_table(struct device *dev,
-               const char *name, const char *parent_name, unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_divider_flags, const struct clk_div_table *table,
-               spinlock_t *lock);
+/**
+ * clk_register_divider - register a divider clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_register_divider(dev, name, parent_name, flags, reg, shift, width, \
+                            clk_divider_flags, lock)                          \
+       clk_register_divider_table((dev), (name), (parent_name), (flags),      \
+                                  (reg), (shift), (width),                    \
+                                  (clk_divider_flags), NULL, (lock))
+/**
+ * clk_hw_register_divider - register a divider clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider(dev, name, parent_name, flags, reg, shift,    \
+                               width, clk_divider_flags, lock)               \
+       __clk_hw_register_divider((dev), NULL, (name), (parent_name), NULL,   \
+                                 NULL, (flags), (reg), (shift), (width),     \
+                                 (clk_divider_flags), NULL, (lock))
+/**
+ * clk_hw_register_divider_parent_hw - register a divider clock with the clock
+ * framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_parent_hw(dev, name, parent_hw, flags, reg,   \
+                                         shift, width, clk_divider_flags,    \
+                                         lock)                               \
+       __clk_hw_register_divider((dev), NULL, (name), NULL, (parent_hw),     \
+                                 NULL, (flags), (reg), (shift), (width),     \
+                                 (clk_divider_flags), NULL, (lock))
+/**
+ * clk_hw_register_divider_parent_data - register a divider clock with the clock
+ * framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_parent_data(dev, name, parent_data, flags,    \
+                                           reg, shift, width,                \
+                                           clk_divider_flags, lock)          \
+       __clk_hw_register_divider((dev), NULL, (name), NULL, NULL,            \
+                                 (parent_data), (flags), (reg), (shift),     \
+                                 (width), (clk_divider_flags), NULL, (lock))
+/**
+ * clk_hw_register_divider_table - register a table based divider clock with
+ * the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_name: name of clock's parent
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @table: array of divider/value pairs ending with a div set to 0
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_table(dev, name, parent_name, flags, reg,     \
+                                     shift, width, clk_divider_flags, table, \
+                                     lock)                                   \
+       __clk_hw_register_divider((dev), NULL, (name), (parent_name), NULL,   \
+                                 NULL, (flags), (reg), (shift), (width),     \
+                                 (clk_divider_flags), (table), (lock))
+/**
+ * clk_hw_register_divider_table_parent_hw - register a table based divider
+ * clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_hw: pointer to parent clk
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @table: array of divider/value pairs ending with a div set to 0
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_table_parent_hw(dev, name, parent_hw, flags,  \
+                                               reg, shift, width,            \
+                                               clk_divider_flags, table,     \
+                                               lock)                         \
+       __clk_hw_register_divider((dev), NULL, (name), NULL, (parent_hw),     \
+                                 NULL, (flags), (reg), (shift), (width),     \
+                                 (clk_divider_flags), (table), (lock))
+/**
+ * clk_hw_register_divider_table_parent_data - register a table based divider
+ * clock with the clock framework
+ * @dev: device registering this clock
+ * @name: name of this clock
+ * @parent_data: parent clk data
+ * @flags: framework-specific flags
+ * @reg: register address to adjust divider
+ * @shift: number of bits to shift the bitfield
+ * @width: width of the bitfield
+ * @clk_divider_flags: divider-specific flags for this clock
+ * @table: array of divider/value pairs ending with a div set to 0
+ * @lock: shared register lock for this clock
+ */
+#define clk_hw_register_divider_table_parent_data(dev, name, parent_data,     \
+                                                 flags, reg, shift, width,   \
+                                                 clk_divider_flags, table,   \
+                                                 lock)                       \
+       __clk_hw_register_divider((dev), NULL, (name), NULL, NULL,            \
+                                 (parent_data), (flags), (reg), (shift),     \
+                                 (width), (clk_divider_flags), (table),      \
+                                 (lock))
+
 void clk_unregister_divider(struct clk *clk);
 void clk_hw_unregister_divider(struct clk_hw *hw);
 
@@ -555,28 +834,48 @@ struct clk_mux {
 extern const struct clk_ops clk_mux_ops;
 extern const struct clk_ops clk_mux_ro_ops;
 
-struct clk *clk_register_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock);
-struct clk_hw *clk_hw_register_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u8 width,
-               u8 clk_mux_flags, spinlock_t *lock);
-
-struct clk *clk_register_mux_table(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
+struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np,
+               const char *name, u8 num_parents,
+               const char * const *parent_names,
+               const struct clk_hw **parent_hws,
+               const struct clk_parent_data *parent_data,
+               unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock);
-struct clk_hw *clk_hw_register_mux_table(struct device *dev, const char *name,
+struct clk *clk_register_mux_table(struct device *dev, const char *name,
                const char * const *parent_names, u8 num_parents,
-               unsigned long flags,
-               void __iomem *reg, u8 shift, u32 mask,
+               unsigned long flags, void __iomem *reg, u8 shift, u32 mask,
                u8 clk_mux_flags, u32 *table, spinlock_t *lock);
 
+#define clk_register_mux(dev, name, parent_names, num_parents, flags, reg,    \
+                        shift, width, clk_mux_flags, lock)                   \
+       clk_register_mux_table((dev), (name), (parent_names), (num_parents),  \
+                              (flags), (reg), (shift), BIT((width)) - 1,     \
+                              (clk_mux_flags), NULL, (lock))
+#define clk_hw_register_mux_table(dev, name, parent_names, num_parents,              \
+                                 flags, reg, shift, mask, clk_mux_flags,     \
+                                 table, lock)                                \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents),             \
+                             (parent_names), NULL, NULL, (flags), (reg),     \
+                             (shift), (mask), (clk_mux_flags), (table),      \
+                             (lock))
+#define clk_hw_register_mux(dev, name, parent_names, num_parents, flags, reg, \
+                           shift, width, clk_mux_flags, lock)                \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents),             \
+                             (parent_names), NULL, NULL, (flags), (reg),     \
+                             (shift), BIT((width)) - 1, (clk_mux_flags),     \
+                             NULL, (lock))
+#define clk_hw_register_mux_hws(dev, name, parent_hws, num_parents, flags,    \
+                               reg, shift, width, clk_mux_flags, lock)       \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents), NULL,       \
+                             (parent_hws), NULL, (flags), (reg), (shift),    \
+                             BIT((width)) - 1, (clk_mux_flags), NULL, (lock))
+#define clk_hw_register_mux_parent_data(dev, name, parent_data, num_parents,  \
+                                       flags, reg, shift, width,             \
+                                       clk_mux_flags, lock)                  \
+       __clk_hw_register_mux((dev), NULL, (name), (num_parents), NULL, NULL, \
+                             (parent_data), (flags), (reg), (shift),         \
+                             BIT((width)) - 1, (clk_mux_flags), NULL, (lock))
+
 int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags,
                         unsigned int val);
 unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index);
@@ -743,6 +1042,12 @@ struct clk *clk_register_composite(struct device *dev, const char *name,
                struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
                struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
                unsigned long flags);
+struct clk *clk_register_composite_pdata(struct device *dev, const char *name,
+               const struct clk_parent_data *parent_data, int num_parents,
+               struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+               struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+               struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
+               unsigned long flags);
 void clk_unregister_composite(struct clk *clk);
 struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
                const char * const *parent_names, int num_parents,
@@ -750,45 +1055,14 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
                struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
                struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
                unsigned long flags);
-void clk_hw_unregister_composite(struct clk_hw *hw);
-
-/**
- * struct clk_gpio - gpio gated clock
- *
- * @hw:                handle between common and hardware-specific interfaces
- * @gpiod:     gpio descriptor
- *
- * Clock with a gpio control for enabling and disabling the parent clock
- * or switching between two parents by asserting or deasserting the gpio.
- *
- * Implements .enable, .disable and .is_enabled or
- * .get_parent, .set_parent and .determine_rate depending on which clk_ops
- * is used.
- */
-struct clk_gpio {
-       struct clk_hw   hw;
-       struct gpio_desc *gpiod;
-};
-
-#define to_clk_gpio(_hw) container_of(_hw, struct clk_gpio, hw)
-
-extern const struct clk_ops clk_gpio_gate_ops;
-struct clk *clk_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, struct gpio_desc *gpiod,
-               unsigned long flags);
-struct clk_hw *clk_hw_register_gpio_gate(struct device *dev, const char *name,
-               const char *parent_name, struct gpio_desc *gpiod,
-               unsigned long flags);
-void clk_hw_unregister_gpio_gate(struct clk_hw *hw);
-
-extern const struct clk_ops clk_gpio_mux_ops;
-struct clk *clk_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
-               unsigned long flags);
-struct clk_hw *clk_hw_register_gpio_mux(struct device *dev, const char *name,
-               const char * const *parent_names, u8 num_parents, struct gpio_desc *gpiod,
+struct clk_hw *clk_hw_register_composite_pdata(struct device *dev,
+               const char *name,
+               const struct clk_parent_data *parent_data, int num_parents,
+               struct clk_hw *mux_hw, const struct clk_ops *mux_ops,
+               struct clk_hw *rate_hw, const struct clk_ops *rate_ops,
+               struct clk_hw *gate_hw, const struct clk_ops *gate_ops,
                unsigned long flags);
-void clk_hw_unregister_gpio_mux(struct clk_hw *hw);
+void clk_hw_unregister_composite(struct clk_hw *hw);
 
 struct clk *clk_register(struct device *dev, struct clk_hw *hw);
 struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw);
index 18b7b95..7fd6a1f 100644 (file)
@@ -627,6 +627,9 @@ long clk_round_rate(struct clk *clk, unsigned long rate);
  * @clk: clock source
  * @rate: desired clock rate in Hz
  *
+ * Updating the rate starts at the top-most affected clock and then
+ * walks the tree down to the bottom-most clock that needs updating.
+ *
  * Returns success (0) or negative errno.
  */
 int clk_set_rate(struct clk *clk, unsigned long rate);
index def48a5..d37c17e 100644 (file)
@@ -96,6 +96,7 @@ enum cpuhp_state {
        CPUHP_AP_OFFLINE,
        CPUHP_AP_SCHED_STARTING,
        CPUHP_AP_RCUTREE_DYING,
+       CPUHP_AP_CPU_PM_STARTING,
        CPUHP_AP_IRQ_GIC_STARTING,
        CPUHP_AP_IRQ_HIP04_STARTING,
        CPUHP_AP_IRQ_ARMADA_XP_STARTING,
index 78a73eb..d5cc885 100644 (file)
@@ -663,9 +663,7 @@ static inline int cpumask_parselist_user(const char __user *buf, int len,
  */
 static inline int cpumask_parse(const char *buf, struct cpumask *dstp)
 {
-       unsigned int len = strchrnul(buf, '\n') - buf;
-
-       return bitmap_parse(buf, len, cpumask_bits(dstp), nr_cpumask_bits);
+       return bitmap_parse(buf, UINT_MAX, cpumask_bits(dstp), nr_cpumask_bits);
 }
 
 /**
index bf9b6ca..3d013de 100644 (file)
@@ -83,7 +83,7 @@ struct dentry *debugfs_create_automount(const char *name,
                                        void *data);
 
 void debugfs_remove(struct dentry *dentry);
-void debugfs_remove_recursive(struct dentry *dentry);
+#define debugfs_remove_recursive debugfs_remove
 
 const struct file_operations *debugfs_real_fops(const struct file *filp);
 
index ffcc772..dc4fd8a 100644 (file)
@@ -12,6 +12,8 @@
 #include <linux/fcntl.h>
 #include <linux/wait.h>
 #include <linux/err.h>
+#include <linux/percpu-defs.h>
+#include <linux/percpu.h>
 
 /*
  * CAREFUL: Check include/uapi/asm-generic/fcntl.h when defining
@@ -40,6 +42,13 @@ __u64 eventfd_signal(struct eventfd_ctx *ctx, __u64 n);
 int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_entry_t *wait,
                                  __u64 *cnt);
 
+DECLARE_PER_CPU(int, eventfd_wake_count);
+
+static inline bool eventfd_signal_count(void)
+{
+       return this_cpu_read(eventfd_wake_count);
+}
+
 #else /* CONFIG_EVENTFD */
 
 /*
@@ -68,6 +77,11 @@ static inline int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx,
        return -ENOSYS;
 }
 
+static inline bool eventfd_signal_count(void)
+{
+       return false;
+}
+
 #endif
 
 #endif /* _LINUX_EVENTFD_H */
index e41ad9e..2cd12eb 100644 (file)
 #define        ZYNQMP_PM_CAPABILITY_WAKEUP     0x4U
 #define        ZYNQMP_PM_CAPABILITY_UNUSABLE   0x8U
 
+/* Feature check status */
+#define PM_FEATURE_INVALID             -1
+#define PM_FEATURE_UNCHECKED           0
+
 /*
  * Firmware FPGA Manager flags
  * XILINX_ZYNQMP_PM_FPGA_FULL: FPGA full reconfiguration
@@ -78,17 +82,21 @@ enum pm_api_id {
        PM_CLOCK_GETRATE,
        PM_CLOCK_SETPARENT,
        PM_CLOCK_GETPARENT,
+       PM_FEATURE_CHECK = 63,
+       PM_API_MAX,
 };
 
 /* PMU-FW return status codes */
 enum pm_ret_status {
        XST_PM_SUCCESS = 0,
+       XST_PM_NO_FEATURE = 19,
        XST_PM_INTERNAL = 2000,
        XST_PM_CONFLICT,
        XST_PM_NO_ACCESS,
        XST_PM_INVALID_NODE,
        XST_PM_DOUBLE_REQ,
        XST_PM_ABORT_SUSPEND,
+       XST_PM_MULT_USER = 2008,
 };
 
 enum pm_ioctl_id {
@@ -107,6 +115,7 @@ enum pm_query_id {
        PM_QID_CLOCK_GET_PARENTS,
        PM_QID_CLOCK_GET_ATTRIBUTES,
        PM_QID_CLOCK_GET_NUM_CLOCKS = 12,
+       PM_QID_CLOCK_GET_MAX_DIVISOR,
 };
 
 enum zynqmp_pm_reset_action {
index 41584f5..3cd4fe6 100644 (file)
@@ -67,7 +67,7 @@ struct fscrypt_operations;
 struct fsverity_info;
 struct fsverity_operations;
 struct fs_context;
-struct fs_parameter_description;
+struct fs_parameter_spec;
 
 extern void __init inode_init(void);
 extern void __init inode_init_early(void);
@@ -1575,7 +1575,6 @@ static inline void i_gid_write(struct inode *inode, gid_t gid)
        inode->i_gid = make_kgid(inode->i_sb->s_user_ns, gid);
 }
 
-extern struct timespec64 timespec64_trunc(struct timespec64 t, unsigned gran);
 extern struct timespec64 current_time(struct inode *inode);
 
 /*
@@ -2078,6 +2077,18 @@ static inline void init_sync_kiocb(struct kiocb *kiocb, struct file *filp)
        };
 }
 
+static inline void kiocb_clone(struct kiocb *kiocb, struct kiocb *kiocb_src,
+                              struct file *filp)
+{
+       *kiocb = (struct kiocb) {
+               .ki_filp = filp,
+               .ki_flags = kiocb_src->ki_flags,
+               .ki_hint = kiocb_src->ki_hint,
+               .ki_ioprio = kiocb_src->ki_ioprio,
+               .ki_pos = kiocb_src->ki_pos,
+       };
+}
+
 /*
  * Inode state bits.  Protected by inode->i_lock
  *
@@ -2224,7 +2235,7 @@ struct file_system_type {
 #define FS_DISALLOW_NOTIFY_PERM        16      /* Disable fanotify permission events */
 #define FS_RENAME_DOES_D_MOVE  32768   /* FS will handle d_move() during rename() internally. */
        int (*init_fs_context)(struct fs_context *);
-       const struct fs_parameter_description *parameters;
+       const struct fs_parameter_spec *parameters;
        struct dentry *(*mount) (struct file_system_type *, int,
                       const char *, void *);
        void (*kill_sb) (struct super_block *);
@@ -2865,9 +2876,16 @@ static inline ssize_t generic_write_sync(struct kiocb *iocb, ssize_t count)
 
 extern void emergency_sync(void);
 extern void emergency_remount(void);
+
 #ifdef CONFIG_BLOCK
-extern sector_t bmap(struct inode *, sector_t);
+extern int bmap(struct inode *inode, sector_t *block);
+#else
+static inline int bmap(struct inode *inode,  sector_t *block)
+{
+       return -EINVAL;
+}
 #endif
+
 extern int notify_change(struct dentry *, struct iattr *, struct inode **);
 extern int inode_permission(struct inode *, int);
 extern int generic_permission(struct inode *, int);
@@ -3108,6 +3126,10 @@ ssize_t vfs_iter_read(struct file *file, struct iov_iter *iter, loff_t *ppos,
                rwf_t flags);
 ssize_t vfs_iter_write(struct file *file, struct iov_iter *iter, loff_t *ppos,
                rwf_t flags);
+ssize_t vfs_iocb_iter_read(struct file *file, struct kiocb *iocb,
+                          struct iov_iter *iter);
+ssize_t vfs_iocb_iter_write(struct file *file, struct kiocb *iocb,
+                           struct iov_iter *iter);
 
 /* fs/block_dev.c */
 extern ssize_t blkdev_read_iter(struct kiocb *iocb, struct iov_iter *to);
@@ -3303,6 +3325,8 @@ extern int simple_unlink(struct inode *, struct dentry *);
 extern int simple_rmdir(struct inode *, struct dentry *);
 extern int simple_rename(struct inode *, struct dentry *,
                         struct inode *, struct dentry *, unsigned int);
+extern void simple_recursive_removal(struct dentry *,
+                              void (*callback)(struct dentry *));
 extern int noop_fsync(struct file *, loff_t, loff_t, int);
 extern int noop_set_page_dirty(struct page *page);
 extern void noop_invalidatepage(struct page *page, unsigned int offset,
index e5c14e2..e6c3e4c 100644 (file)
@@ -54,7 +54,6 @@ enum fs_value_type {
        fs_value_is_string,             /* Value is a string */
        fs_value_is_blob,               /* Value is a binary blob */
        fs_value_is_filename,           /* Value is a filename* + dirfd */
-       fs_value_is_filename_empty,     /* Value is a filename* + dirfd + AT_EMPTY_PATH */
        fs_value_is_file,               /* Value is a file* */
 };
 
@@ -74,6 +73,11 @@ struct fs_parameter {
        int     dirfd;
 };
 
+struct p_log {
+       const char *prefix;
+       struct fc_log *log;
+};
+
 /*
  * Filesystem context for holding the parameters used in the creation or
  * reconfiguration of a superblock.
@@ -93,7 +97,7 @@ struct fs_context {
        struct user_namespace   *user_ns;       /* The user namespace for this mount */
        struct net              *net_ns;        /* The network namespace for this mount */
        const struct cred       *cred;          /* The mounter's credentials */
-       struct fc_log           *log;           /* Logging buffer */
+       struct p_log            log;            /* Logging buffer */
        const char              *source;        /* The source name (eg. dev path) */
        void                    *security;      /* Linux S&M options */
        void                    *s_fs_info;     /* Proposed s_fs_info */
@@ -182,9 +186,13 @@ struct fc_log {
        char            *buffer[8];
 };
 
-extern __attribute__((format(printf, 2, 3)))
-void logfc(struct fs_context *fc, const char *fmt, ...);
+extern __attribute__((format(printf, 4, 5)))
+void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...);
 
+#define __logfc(fc, l, fmt, ...) logfc((fc)->log.log, NULL, \
+                                       l, fmt, ## __VA_ARGS__)
+#define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \
+                                       l, fmt, ## __VA_ARGS__)
 /**
  * infof - Store supplementary informational message
  * @fc: The context in which to log the informational message
@@ -193,7 +201,9 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
  * Store the supplementary informational message for the process if the process
  * has enabled the facility.
  */
-#define infof(fc, fmt, ...) ({ logfc(fc, "i "fmt, ## __VA_ARGS__); })
+#define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__)
+#define info_plog(p, fmt, ...) __plog(p, 'i', fmt, ## __VA_ARGS__)
+#define infofc(p, fmt, ...) __plog((&(fc)->log), 'i', fmt, ## __VA_ARGS__)
 
 /**
  * warnf - Store supplementary warning message
@@ -203,7 +213,9 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
  * Store the supplementary warning message for the process if the process has
  * enabled the facility.
  */
-#define warnf(fc, fmt, ...) ({ logfc(fc, "w "fmt, ## __VA_ARGS__); })
+#define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__)
+#define warn_plog(p, fmt, ...) __plog(p, 'w', fmt, ## __VA_ARGS__)
+#define warnfc(fc, fmt, ...) __plog((&(fc)->log), 'w', fmt, ## __VA_ARGS__)
 
 /**
  * errorf - Store supplementary error message
@@ -213,7 +225,9 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
  * Store the supplementary error message for the process if the process has
  * enabled the facility.
  */
-#define errorf(fc, fmt, ...) ({ logfc(fc, "e "fmt, ## __VA_ARGS__); })
+#define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__)
+#define error_plog(p, fmt, ...) __plog(p, 'e', fmt, ## __VA_ARGS__)
+#define errorfc(fc, fmt, ...) __plog((&(fc)->log), 'e', fmt, ## __VA_ARGS__)
 
 /**
  * invalf - Store supplementary invalid argument error message
@@ -223,6 +237,8 @@ void logfc(struct fs_context *fc, const char *fmt, ...);
  * Store the supplementary error message for the process if the process has
  * enabled the facility and return -EINVAL.
  */
-#define invalf(fc, fmt, ...) ({        errorf(fc, fmt, ## __VA_ARGS__); -EINVAL; })
+#define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL)
+#define inval_plog(p, fmt, ...) (error_plog(p, fmt, ## __VA_ARGS__), -EINVAL)
+#define invalfc(fc, fmt, ...) (errorfc(fc, fmt, ## __VA_ARGS__), -EINVAL)
 
 #endif /* _LINUX_FS_CONTEXT_H */
index dee140d..2eab6d5 100644 (file)
@@ -17,26 +17,18 @@ struct constant_table {
        int             value;
 };
 
+struct fs_parameter_spec;
+struct fs_parse_result;
+typedef int fs_param_type(struct p_log *,
+                         const struct fs_parameter_spec *,
+                         struct fs_parameter *,
+                         struct fs_parse_result *);
 /*
  * The type of parameter expected.
  */
-enum fs_parameter_type {
-       __fs_param_wasnt_defined,
-       fs_param_is_flag,
-       fs_param_is_bool,
-       fs_param_is_u32,
-       fs_param_is_u32_octal,
-       fs_param_is_u32_hex,
-       fs_param_is_s32,
-       fs_param_is_u64,
-       fs_param_is_enum,
-       fs_param_is_string,
-       fs_param_is_blob,
-       fs_param_is_blockdev,
-       fs_param_is_path,
-       fs_param_is_fd,
-       nr__fs_parameter_type,
-};
+fs_param_type fs_param_is_bool, fs_param_is_u32, fs_param_is_s32, fs_param_is_u64,
+       fs_param_is_enum, fs_param_is_string, fs_param_is_blob, fs_param_is_blockdev,
+       fs_param_is_path, fs_param_is_fd;
 
 /*
  * Specification of the type of value a parameter wants.
@@ -46,25 +38,13 @@ enum fs_parameter_type {
  */
 struct fs_parameter_spec {
        const char              *name;
+       fs_param_type           *type;  /* The desired parameter type */
        u8                      opt;    /* Option number (returned by fs_parse()) */
-       enum fs_parameter_type  type:8; /* The desired parameter type */
        unsigned short          flags;
-#define fs_param_v_optional    0x0001  /* The value is optional */
 #define fs_param_neg_with_no   0x0002  /* "noxxx" is negative param */
 #define fs_param_neg_with_empty        0x0004  /* "xxx=" is negative param */
 #define fs_param_deprecated    0x0008  /* The param is deprecated */
-};
-
-struct fs_parameter_enum {
-       u8              opt;            /* Option number (as fs_parameter_spec::opt) */
-       char            name[14];
-       u8              value;
-};
-
-struct fs_parameter_description {
-       const char      name[16];               /* Name for logging purposes */
-       const struct fs_parameter_spec *specs;  /* List of param specifications */
-       const struct fs_parameter_enum *enums;  /* Enum values */
+       const void              *data;
 };
 
 /*
@@ -72,7 +52,6 @@ struct fs_parameter_description {
  */
 struct fs_parse_result {
        bool                    negated;        /* T if param was "noxxx" */
-       bool                    has_value;      /* T if value supplied to param */
        union {
                bool            boolean;        /* For spec_bool */
                int             int_32;         /* For spec_s32/spec_enum */
@@ -81,28 +60,37 @@ struct fs_parse_result {
        };
 };
 
-extern int fs_parse(struct fs_context *fc,
-                   const struct fs_parameter_description *desc,
+extern int __fs_parse(struct p_log *log,
+                   const struct fs_parameter_spec *desc,
                    struct fs_parameter *value,
                    struct fs_parse_result *result);
+
+static inline int fs_parse(struct fs_context *fc,
+            const struct fs_parameter_spec *desc,
+            struct fs_parameter *param,
+            struct fs_parse_result *result)
+{
+       return __fs_parse(&fc->log, desc, param, result);
+}
+
 extern int fs_lookup_param(struct fs_context *fc,
                           struct fs_parameter *param,
                           bool want_bdev,
                           struct path *_path);
 
-extern int __lookup_constant(const struct constant_table tbl[], size_t tbl_size,
-                            const char *name, int not_found);
-#define lookup_constant(t, n, nf) __lookup_constant(t, ARRAY_SIZE(t), (n), (nf))
+extern int lookup_constant(const struct constant_table tbl[], const char *name, int not_found);
 
 #ifdef CONFIG_VALIDATE_FS_PARSER
 extern bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
                                    int low, int high, int special);
-extern bool fs_validate_description(const struct fs_parameter_description *desc);
+extern bool fs_validate_description(const char *name,
+                                   const struct fs_parameter_spec *desc);
 #else
 static inline bool validate_constant_table(const struct constant_table *tbl, size_t tbl_size,
                                           int low, int high, int special)
 { return true; }
-static inline bool fs_validate_description(const struct fs_parameter_description *desc)
+static inline bool fs_validate_description(const char *name,
+                                          const struct fs_parameter_spec *desc)
 { return true; }
 #endif
 
@@ -115,33 +103,32 @@ static inline bool fs_validate_description(const struct fs_parameter_description
  * work, but any such case is probably a sign that new helper is needed.
  * Helpers will remain stable; low-level implementation may change.
  */
-#define __fsparam(TYPE, NAME, OPT, FLAGS) \
+#define __fsparam(TYPE, NAME, OPT, FLAGS, DATA) \
        { \
                .name = NAME, \
                .opt = OPT, \
                .type = TYPE, \
-               .flags = FLAGS \
+               .flags = FLAGS, \
+               .data = DATA \
        }
 
-#define fsparam_flag(NAME, OPT)        __fsparam(fs_param_is_flag, NAME, OPT, 0)
+#define fsparam_flag(NAME, OPT)        __fsparam(NULL, NAME, OPT, 0, NULL)
 #define fsparam_flag_no(NAME, OPT) \
-                               __fsparam(fs_param_is_flag, NAME, OPT, \
-                                           fs_param_neg_with_no)
-#define fsparam_bool(NAME, OPT)        __fsparam(fs_param_is_bool, NAME, OPT, 0)
-#define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0)
+                       __fsparam(NULL, NAME, OPT, fs_param_neg_with_no, NULL)
+#define fsparam_bool(NAME, OPT)        __fsparam(fs_param_is_bool, NAME, OPT, 0, NULL)
+#define fsparam_u32(NAME, OPT) __fsparam(fs_param_is_u32, NAME, OPT, 0, NULL)
 #define fsparam_u32oct(NAME, OPT) \
-                               __fsparam(fs_param_is_u32_octal, NAME, OPT, 0)
+                       __fsparam(fs_param_is_u32, NAME, OPT, 0, (void *)8)
 #define fsparam_u32hex(NAME, OPT) \
-                               __fsparam(fs_param_is_u32_hex, NAME, OPT, 0)
-#define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0)
-#define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0)
-#define fsparam_enum(NAME, OPT)        __fsparam(fs_param_is_enum, NAME, OPT, 0)
+                       __fsparam(fs_param_is_u32_hex, NAME, OPT, 0, (void *16))
+#define fsparam_s32(NAME, OPT) __fsparam(fs_param_is_s32, NAME, OPT, 0, NULL)
+#define fsparam_u64(NAME, OPT) __fsparam(fs_param_is_u64, NAME, OPT, 0, NULL)
+#define fsparam_enum(NAME, OPT, array) __fsparam(fs_param_is_enum, NAME, OPT, 0, array)
 #define fsparam_string(NAME, OPT) \
-                               __fsparam(fs_param_is_string, NAME, OPT, 0)
-#define fsparam_blob(NAME, OPT)        __fsparam(fs_param_is_blob, NAME, OPT, 0)
-#define fsparam_bdev(NAME, OPT)        __fsparam(fs_param_is_blockdev, NAME, OPT, 0)
-#define fsparam_path(NAME, OPT)        __fsparam(fs_param_is_path, NAME, OPT, 0)
-#define fsparam_fd(NAME, OPT)  __fsparam(fs_param_is_fd, NAME, OPT, 0)
-
+                               __fsparam(fs_param_is_string, NAME, OPT, 0, NULL)
+#define fsparam_blob(NAME, OPT)        __fsparam(fs_param_is_blob, NAME, OPT, 0, NULL)
+#define fsparam_bdev(NAME, OPT)        __fsparam(fs_param_is_blockdev, NAME, OPT, 0, NULL)
+#define fsparam_path(NAME, OPT)        __fsparam(fs_param_is_path, NAME, OPT, 0, NULL)
+#define fsparam_fd(NAME, OPT)  __fsparam(fs_param_is_fd, NAME, OPT, 0, NULL)
 
 #endif /* _LINUX_FS_PARSER_H */
index 26f3aee..692c89c 100644 (file)
@@ -425,6 +425,8 @@ enum vmbus_channel_message_type {
        CHANNELMSG_19                           = 19,
        CHANNELMSG_20                           = 20,
        CHANNELMSG_TL_CONNECT_REQUEST           = 21,
+       CHANNELMSG_22                           = 22,
+       CHANNELMSG_TL_CONNECT_RESULT            = 23,
        CHANNELMSG_COUNT
 };
 
@@ -1433,6 +1435,8 @@ struct hv_util_service {
        void (*util_cb)(void *);
        int (*util_init)(struct hv_util_service *);
        void (*util_deinit)(void);
+       int (*util_pre_suspend)(void);
+       int (*util_pre_resume)(void);
 };
 
 struct vmbuspipe_hdr {
index 582ef05..f834687 100644 (file)
@@ -50,8 +50,8 @@ struct property_entry;
  * transmit an arbitrary number of messages without interruption.
  * @count must be be less than 64k since msg.len is u16.
  */
-extern int i2c_transfer_buffer_flags(const struct i2c_client *client,
-                                    char *buf, int count, u16 flags);
+int i2c_transfer_buffer_flags(const struct i2c_client *client,
+                             char *buf, int count, u16 flags);
 
 /**
  * i2c_master_recv - issue a single I2C message in master receive mode
@@ -115,11 +115,9 @@ static inline int i2c_master_send_dmasafe(const struct i2c_client *client,
 
 /* Transfer num messages.
  */
-extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
-                       int num);
+int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
 /* Unlocked flavor */
-extern int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
-                         int num);
+int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
 
 /* This is the very generalized SMBus access routine. You probably do not
    want to use this, though; one of the functions below may be much easier,
@@ -138,16 +136,14 @@ s32 __i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
 /* Now follow the 'nice' access routines. These also document the calling
    conventions of i2c_smbus_xfer. */
 
-extern s32 i2c_smbus_read_byte(const struct i2c_client *client);
-extern s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value);
-extern s32 i2c_smbus_read_byte_data(const struct i2c_client *client,
-                                   u8 command);
-extern s32 i2c_smbus_write_byte_data(const struct i2c_client *client,
-                                    u8 command, u8 value);
-extern s32 i2c_smbus_read_word_data(const struct i2c_client *client,
-                                   u8 command);
-extern s32 i2c_smbus_write_word_data(const struct i2c_client *client,
-                                    u8 command, u16 value);
+s32 i2c_smbus_read_byte(const struct i2c_client *client);
+s32 i2c_smbus_write_byte(const struct i2c_client *client, u8 value);
+s32 i2c_smbus_read_byte_data(const struct i2c_client *client, u8 command);
+s32 i2c_smbus_write_byte_data(const struct i2c_client *client,
+                             u8 command, u8 value);
+s32 i2c_smbus_read_word_data(const struct i2c_client *client, u8 command);
+s32 i2c_smbus_write_word_data(const struct i2c_client *client,
+                             u8 command, u16 value);
 
 static inline s32
 i2c_smbus_read_word_swapped(const struct i2c_client *client, u8 command)
@@ -165,19 +161,18 @@ i2c_smbus_write_word_swapped(const struct i2c_client *client,
 }
 
 /* Returns the number of read bytes */
-extern s32 i2c_smbus_read_block_data(const struct i2c_client *client,
-                                    u8 command, u8 *values);
-extern s32 i2c_smbus_write_block_data(const struct i2c_client *client,
-                                     u8 command, u8 length, const u8 *values);
+s32 i2c_smbus_read_block_data(const struct i2c_client *client,
+                             u8 command, u8 *values);
+s32 i2c_smbus_write_block_data(const struct i2c_client *client,
+                              u8 command, u8 length, const u8 *values);
 /* Returns the number of read bytes */
-extern s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client,
-                                        u8 command, u8 length, u8 *values);
-extern s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client,
-                                         u8 command, u8 length,
-                                         const u8 *values);
-extern s32
-i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
-                                         u8 command, u8 length, u8 *values);
+s32 i2c_smbus_read_i2c_block_data(const struct i2c_client *client,
+                                 u8 command, u8 length, u8 *values);
+s32 i2c_smbus_write_i2c_block_data(const struct i2c_client *client,
+                                  u8 command, u8 length, const u8 *values);
+s32 i2c_smbus_read_i2c_block_data_or_emulated(const struct i2c_client *client,
+                                             u8 command, u8 length,
+                                             u8 *values);
 int i2c_get_device_id(const struct i2c_client *client,
                      struct i2c_device_identity *id);
 #endif /* I2C */
@@ -337,10 +332,10 @@ struct i2c_client {
 };
 #define to_i2c_client(d) container_of(d, struct i2c_client, dev)
 
-extern struct i2c_client *i2c_verify_client(struct device *dev);
-extern struct i2c_adapter *i2c_verify_adapter(struct device *dev);
-extern const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
-                                       const struct i2c_client *client);
+struct i2c_client *i2c_verify_client(struct device *dev);
+struct i2c_adapter *i2c_verify_adapter(struct device *dev);
+const struct i2c_device_id *i2c_match_id(const struct i2c_device_id *id,
+                                        const struct i2c_client *client);
 
 static inline struct i2c_client *kobj_to_i2c_client(struct kobject *kobj)
 {
@@ -369,9 +364,9 @@ enum i2c_slave_event {
        I2C_SLAVE_STOP,
 };
 
-extern int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb);
-extern int i2c_slave_unregister(struct i2c_client *client);
-extern bool i2c_detect_slave_mode(struct device *dev);
+int i2c_slave_register(struct i2c_client *client, i2c_slave_cb_t slave_cb);
+int i2c_slave_unregister(struct i2c_client *client);
+bool i2c_detect_slave_mode(struct device *dev);
 
 static inline int i2c_slave_event(struct i2c_client *client,
                                  enum i2c_slave_event event, u8 *val)
@@ -440,10 +435,10 @@ struct i2c_board_info {
  * with integrated I2C, a config eeprom, sensors, and a codec that's
  * used in conjunction with the primary hardware.
  */
-extern struct i2c_client *
+struct i2c_client *
 i2c_new_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
 
-extern struct i2c_client *
+struct i2c_client *
 i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *info);
 
 /* If you don't know the exact address of an I2C device, use this variant
@@ -452,33 +447,33 @@ i2c_new_client_device(struct i2c_adapter *adap, struct i2c_board_info const *inf
  * it must return 1 on successful probe, 0 otherwise. If it is not provided,
  * a default probing method is used.
  */
-extern struct i2c_client *
+struct i2c_client *
 i2c_new_scanned_device(struct i2c_adapter *adap,
                       struct i2c_board_info *info,
                       unsigned short const *addr_list,
                       int (*probe)(struct i2c_adapter *adap, unsigned short addr));
 
-extern struct i2c_client *
+struct i2c_client *
 i2c_new_probed_device(struct i2c_adapter *adap,
                       struct i2c_board_info *info,
                       unsigned short const *addr_list,
                       int (*probe)(struct i2c_adapter *adap, unsigned short addr));
 
 /* Common custom probe functions */
-extern int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr);
+int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr);
 
-extern struct i2c_client *
+struct i2c_client *
 i2c_new_dummy_device(struct i2c_adapter *adapter, u16 address);
 
-extern struct i2c_client *
+struct i2c_client *
 devm_i2c_new_dummy_device(struct device *dev, struct i2c_adapter *adap, u16 address);
 
-extern struct i2c_client *
+struct i2c_client *
 i2c_new_ancillary_device(struct i2c_client *client,
-                               const char *name,
-                               u16 default_addr);
+                        const char *name,
+                        u16 default_addr);
 
-extern void i2c_unregister_device(struct i2c_client *client);
+void i2c_unregister_device(struct i2c_client *client);
 #endif /* I2C */
 
 /* Mainboard arch_initcall() code should register all its I2C devices.
@@ -486,7 +481,7 @@ extern void i2c_unregister_device(struct i2c_client *client);
  * Modules for add-on boards must use other calls.
  */
 #ifdef CONFIG_I2C_BOARDINFO
-extern int
+int
 i2c_register_board_info(int busnum, struct i2c_board_info const *info,
                        unsigned n);
 #else
@@ -840,12 +835,12 @@ static inline void i2c_mark_adapter_resumed(struct i2c_adapter *adap)
 /* administration...
  */
 #if IS_ENABLED(CONFIG_I2C)
-extern int i2c_add_adapter(struct i2c_adapter *adap);
-extern void i2c_del_adapter(struct i2c_adapter *adap);
-extern int i2c_add_numbered_adapter(struct i2c_adapter *adap);
+int i2c_add_adapter(struct i2c_adapter *adap);
+void i2c_del_adapter(struct i2c_adapter *adap);
+int i2c_add_numbered_adapter(struct i2c_adapter *adap);
 
-extern int i2c_register_driver(struct module *owner, struct i2c_driver *driver);
-extern void i2c_del_driver(struct i2c_driver *driver);
+int i2c_register_driver(struct module *owner, struct i2c_driver *driver);
+void i2c_del_driver(struct i2c_driver *driver);
 
 /* use a define to avoid include chaining to get THIS_MODULE */
 #define i2c_add_driver(driver) \
@@ -858,12 +853,12 @@ static inline bool i2c_client_has_driver(struct i2c_client *client)
 
 /* call the i2c_client->command() of all attached clients with
  * the given arguments */
-extern void i2c_clients_command(struct i2c_adapter *adap,
-                               unsigned int cmd, void *arg);
+void i2c_clients_command(struct i2c_adapter *adap,
+                        unsigned int cmd, void *arg);
 
-extern struct i2c_adapter *i2c_get_adapter(int nr);
-extern void i2c_put_adapter(struct i2c_adapter *adap);
-extern unsigned int i2c_adapter_depth(struct i2c_adapter *adapter);
+struct i2c_adapter *i2c_get_adapter(int nr);
+void i2c_put_adapter(struct i2c_adapter *adap);
+unsigned int i2c_adapter_depth(struct i2c_adapter *adapter);
 
 void i2c_parse_fw_timings(struct device *dev, struct i2c_timings *t, bool use_defaults);
 
@@ -935,15 +930,15 @@ int i2c_handle_smbus_host_notify(struct i2c_adapter *adap, unsigned short addr);
 
 #if IS_ENABLED(CONFIG_OF)
 /* must call put_device() when done with returned i2c_client device */
-extern struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
+struct i2c_client *of_find_i2c_device_by_node(struct device_node *node);
 
 /* must call put_device() when done with returned i2c_adapter device */
-extern struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node);
+struct i2c_adapter *of_find_i2c_adapter_by_node(struct device_node *node);
 
 /* must call i2c_put_adapter() when done with returned i2c_adapter device */
 struct i2c_adapter *of_get_i2c_adapter_by_node(struct device_node *node);
 
-extern const struct of_device_id
+const struct of_device_id
 *i2c_of_match_device(const struct of_device_id *matches,
                     struct i2c_client *client);
 
index 6d8bf4b..4a16b39 100644 (file)
 #define VTD_STRIDE_SHIFT        (9)
 #define VTD_STRIDE_MASK         (((u64)-1) << VTD_STRIDE_SHIFT)
 
-#define DMA_PTE_READ (1)
-#define DMA_PTE_WRITE (2)
-#define DMA_PTE_LARGE_PAGE (1 << 7)
-#define DMA_PTE_SNP (1 << 11)
+#define DMA_PTE_READ           BIT_ULL(0)
+#define DMA_PTE_WRITE          BIT_ULL(1)
+#define DMA_PTE_LARGE_PAGE     BIT_ULL(7)
+#define DMA_PTE_SNP            BIT_ULL(11)
+
+#define DMA_FL_PTE_PRESENT     BIT_ULL(0)
+#define DMA_FL_PTE_XD          BIT_ULL(63)
 
 #define CONTEXT_TT_MULTI_LEVEL 0
 #define CONTEXT_TT_DEV_IOTLB   1
@@ -435,8 +438,10 @@ enum {
 
 #define VTD_FLAG_TRANS_PRE_ENABLED     (1 << 0)
 #define VTD_FLAG_IRQ_REMAP_PRE_ENABLED (1 << 1)
+#define VTD_FLAG_SVM_CAPABLE           (1 << 2)
 
 extern int intel_iommu_sm;
+extern spinlock_t device_domain_lock;
 
 #define sm_supported(iommu)    (intel_iommu_sm && ecap_smts((iommu)->ecap))
 #define pasid_supported(iommu) (sm_supported(iommu) &&                 \
@@ -609,10 +614,11 @@ static inline void dma_clear_pte(struct dma_pte *pte)
 static inline u64 dma_pte_addr(struct dma_pte *pte)
 {
 #ifdef CONFIG_64BIT
-       return pte->val & VTD_PAGE_MASK;
+       return pte->val & VTD_PAGE_MASK & (~DMA_FL_PTE_XD);
 #else
        /* Must have a full atomic 64-bit read */
-       return  __cmpxchg64(&pte->val, 0ULL, 0ULL) & VTD_PAGE_MASK;
+       return  __cmpxchg64(&pte->val, 0ULL, 0ULL) &
+                       VTD_PAGE_MASK & (~DMA_FL_PTE_XD);
 #endif
 }
 
@@ -645,6 +651,8 @@ extern void qi_flush_iotlb(struct intel_iommu *iommu, u16 did, u64 addr,
                          unsigned int size_order, u64 type);
 extern void qi_flush_dev_iotlb(struct intel_iommu *iommu, u16 sid, u16 pfsid,
                        u16 qdep, u64 addr, unsigned mask);
+void qi_flush_piotlb(struct intel_iommu *iommu, u16 did, u32 pasid, u64 addr,
+                    unsigned long npages, bool ih);
 extern int qi_submit_sync(struct qi_desc *desc, struct intel_iommu *iommu);
 
 extern int dmar_ir_support(void);
@@ -656,9 +664,10 @@ int for_each_device_domain(int (*fn)(struct device_domain_info *info,
                                     void *data), void *data);
 void iommu_flush_write_buffer(struct intel_iommu *iommu);
 int intel_iommu_enable_pasid(struct intel_iommu *iommu, struct device *dev);
+struct dmar_domain *find_domain(struct device *dev);
 
 #ifdef CONFIG_INTEL_IOMMU_SVM
-int intel_svm_init(struct intel_iommu *iommu);
+extern void intel_svm_check(struct intel_iommu *iommu);
 extern int intel_svm_enable_prq(struct intel_iommu *iommu);
 extern int intel_svm_finish_prq(struct intel_iommu *iommu);
 
@@ -686,6 +695,8 @@ struct intel_svm {
 };
 
 extern struct intel_iommu *intel_svm_device_to_iommu(struct device *dev);
+#else
+static inline void intel_svm_check(struct intel_iommu *iommu) {}
 #endif
 
 #ifdef CONFIG_INTEL_IOMMU_DEBUGFS
index ee21eed..53d53c6 100644 (file)
@@ -83,12 +83,16 @@ struct io_pgtable_cfg {
         * IO_PGTABLE_QUIRK_NON_STRICT: Skip issuing synchronous leaf TLBIs
         *      on unmap, for DMA domains using the flush queue mechanism for
         *      delayed invalidation.
+        *
+        * IO_PGTABLE_QUIRK_ARM_TTBR1: (ARM LPAE format) Configure the table
+        *      for use in the upper half of a split address space.
         */
        #define IO_PGTABLE_QUIRK_ARM_NS         BIT(0)
        #define IO_PGTABLE_QUIRK_NO_PERMS       BIT(1)
        #define IO_PGTABLE_QUIRK_TLBI_ON_MAP    BIT(2)
        #define IO_PGTABLE_QUIRK_ARM_MTK_EXT    BIT(3)
        #define IO_PGTABLE_QUIRK_NON_STRICT     BIT(4)
+       #define IO_PGTABLE_QUIRK_ARM_TTBR1      BIT(5)
        unsigned long                   quirks;
        unsigned long                   pgsize_bitmap;
        unsigned int                    ias;
@@ -100,18 +104,33 @@ struct io_pgtable_cfg {
        /* Low-level data specific to the table format */
        union {
                struct {
-                       u64     ttbr[2];
-                       u64     tcr;
+                       u64     ttbr;
+                       struct {
+                               u32     ips:3;
+                               u32     tg:2;
+                               u32     sh:2;
+                               u32     orgn:2;
+                               u32     irgn:2;
+                               u32     tsz:6;
+                       }       tcr;
                        u64     mair;
                } arm_lpae_s1_cfg;
 
                struct {
                        u64     vttbr;
-                       u64     vtcr;
+                       struct {
+                               u32     ps:3;
+                               u32     tg:2;
+                               u32     sh:2;
+                               u32     orgn:2;
+                               u32     irgn:2;
+                               u32     sl:2;
+                               u32     tsz:6;
+                       }       vtcr;
                } arm_lpae_s2_cfg;
 
                struct {
-                       u32     ttbr[2];
+                       u32     ttbr;
                        u32     tcr;
                        u32     nmrr;
                        u32     prrr;
index f2223cb..d1b5f4d 100644 (file)
@@ -246,9 +246,10 @@ struct iommu_iotlb_gather {
  * @sva_get_pasid: Get PASID associated to a SVA handle
  * @page_response: handle page request response
  * @cache_invalidate: invalidate translation caches
- * @pgsize_bitmap: bitmap of all possible supported page sizes
  * @sva_bind_gpasid: bind guest pasid and mm
  * @sva_unbind_gpasid: unbind guest pasid and mm
+ * @pgsize_bitmap: bitmap of all possible supported page sizes
+ * @owner: Driver module providing these ops
  */
 struct iommu_ops {
        bool (*capable)(enum iommu_cap);
@@ -318,6 +319,7 @@ struct iommu_ops {
        int (*sva_unbind_gpasid)(struct device *dev, int pasid);
 
        unsigned long pgsize_bitmap;
+       struct module *owner;
 };
 
 /**
@@ -386,12 +388,19 @@ void iommu_device_sysfs_remove(struct iommu_device *iommu);
 int  iommu_device_link(struct iommu_device   *iommu, struct device *link);
 void iommu_device_unlink(struct iommu_device *iommu, struct device *link);
 
-static inline void iommu_device_set_ops(struct iommu_device *iommu,
-                                       const struct iommu_ops *ops)
+static inline void __iommu_device_set_ops(struct iommu_device *iommu,
+                                         const struct iommu_ops *ops)
 {
        iommu->ops = ops;
 }
 
+#define iommu_device_set_ops(iommu, ops)                               \
+do {                                                                   \
+       struct iommu_ops *__ops = (struct iommu_ops *)(ops);            \
+       __ops->owner = THIS_MODULE;                                     \
+       __iommu_device_set_ops(iommu, __ops);                           \
+} while (0)
+
 static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
                                           struct fwnode_handle *fwnode)
 {
@@ -456,6 +465,8 @@ extern void iommu_set_fault_handler(struct iommu_domain *domain,
 
 extern void iommu_get_resv_regions(struct device *dev, struct list_head *list);
 extern void iommu_put_resv_regions(struct device *dev, struct list_head *list);
+extern void generic_iommu_put_resv_regions(struct device *dev,
+                                          struct list_head *list);
 extern int iommu_request_dm_for_dev(struct device *dev);
 extern int iommu_request_dma_domain_for_dev(struct device *dev);
 extern void iommu_set_default_passthrough(bool cmd_line);
@@ -570,6 +581,7 @@ struct iommu_group *fsl_mc_device_group(struct device *dev);
  * @ops: ops for this device's IOMMU
  * @iommu_fwnode: firmware handle for this device's IOMMU
  * @iommu_priv: IOMMU driver private data for this device
+ * @num_pasid_bits: number of PASID bits supported by this device
  * @num_ids: number of associated device IDs
  * @ids: IDs which this device may present to the IOMMU
  */
@@ -578,6 +590,7 @@ struct iommu_fwspec {
        struct fwnode_handle    *iommu_fwnode;
        void                    *iommu_priv;
        u32                     flags;
+       u32                     num_pasid_bits;
        unsigned int            num_ids;
        u32                     ids[1];
 };
index 7853eb9..3ed5a05 100644 (file)
@@ -209,6 +209,8 @@ struct irq_data {
  * IRQD_SINGLE_TARGET          - IRQ allows only a single affinity target
  * IRQD_DEFAULT_TRIGGER_SET    - Expected trigger already been set
  * IRQD_CAN_RESERVE            - Can use reservation mode
+ * IRQD_MSI_NOMASK_QUIRK       - Non-maskable MSI quirk for affinity change
+ *                               required
  */
 enum {
        IRQD_TRIGGER_MASK               = 0xf,
@@ -231,6 +233,7 @@ enum {
        IRQD_SINGLE_TARGET              = (1 << 24),
        IRQD_DEFAULT_TRIGGER_SET        = (1 << 25),
        IRQD_CAN_RESERVE                = (1 << 26),
+       IRQD_MSI_NOMASK_QUIRK           = (1 << 27),
 };
 
 #define __irqd_to_state(d) ACCESS_PRIVATE((d)->common, state_use_accessors)
@@ -390,6 +393,21 @@ static inline bool irqd_can_reserve(struct irq_data *d)
        return __irqd_to_state(d) & IRQD_CAN_RESERVE;
 }
 
+static inline void irqd_set_msi_nomask_quirk(struct irq_data *d)
+{
+       __irqd_to_state(d) |= IRQD_MSI_NOMASK_QUIRK;
+}
+
+static inline void irqd_clr_msi_nomask_quirk(struct irq_data *d)
+{
+       __irqd_to_state(d) &= ~IRQD_MSI_NOMASK_QUIRK;
+}
+
+static inline bool irqd_msi_nomask_quirk(struct irq_data *d)
+{
+       return __irqd_to_state(d) & IRQD_MSI_NOMASK_QUIRK;
+}
+
 #undef __irqd_to_state
 
 static inline irq_hw_number_t irqd_to_hwirq(struct irq_data *d)
index f0b8ca7..83439bf 100644 (file)
@@ -652,10 +652,10 @@ struct rdists {
        struct {
                void __iomem    *rd_base;
                struct page     *pend_page;
-               struct page     *vpe_l1_page;
                phys_addr_t     phys_base;
                bool            lpi_enabled;
                cpumask_t       *vpe_table_mask;
+               void            *vpe_l1_base;
        } __percpu              *rdist;
        phys_addr_t             prop_table_pa;
        void                    *prop_table_va;
index 698749f..b2d4757 100644 (file)
@@ -207,6 +207,13 @@ enum {
        IRQ_DOMAIN_FLAG_MSI_REMAP       = (1 << 5),
 
        /*
+        * Quirk to handle MSI implementations which do not provide
+        * masking. Currently known to affect x86, but partially
+        * handled in core code.
+        */
+       IRQ_DOMAIN_MSI_NOMASK_QUIRK     = (1 << 6),
+
+       /*
         * Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
         * for implementation specific purposes and ignored by the
         * core code.
index 68bd882..24cd447 100644 (file)
@@ -183,8 +183,6 @@ int kdb_process_cpu(const struct task_struct *p)
        return cpu;
 }
 
-/* kdb access to register set for stack dumping */
-extern struct pt_regs *kdb_current_regs;
 #ifdef CONFIG_KALLSYMS
 extern const char *kdb_walk_kallsyms(loff_t *pos);
 #else /* ! CONFIG_KALLSYMS */
index dd93c8d..ec577f5 100644 (file)
@@ -11,7 +11,6 @@
 #define _LEDS_BD2802_H_
 
 struct bd2802_led_platform_data{
-       int     reset_gpio;
        u8      rgb_time;
 };
 
index 242258f..75353e5 100644 (file)
@@ -20,6 +20,7 @@
 
 struct device;
 struct led_pattern;
+struct device_node;
 /*
  * LED Core
  */
@@ -196,6 +197,11 @@ void devm_led_classdev_unregister(struct device *parent,
 void led_classdev_suspend(struct led_classdev *led_cdev);
 void led_classdev_resume(struct led_classdev *led_cdev);
 
+extern struct led_classdev *of_led_get(struct device_node *np, int index);
+extern void led_put(struct led_classdev *led_cdev);
+struct led_classdev *__must_check devm_of_led_get(struct device *dev,
+                                                 int index);
+
 /**
  * led_blink_set - set blinking with software fallback
  * @led_cdev: the LED to start blinking
index a36bdcb..2ca9b70 100644 (file)
@@ -1226,6 +1226,7 @@ struct pci_bits {
 };
 
 extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
+extern void ata_pci_shutdown_one(struct pci_dev *pdev);
 extern void ata_pci_remove_one(struct pci_dev *pdev);
 
 #ifdef CONFIG_PM
index ffa6ad1..f4d5915 100644 (file)
@@ -96,8 +96,8 @@ extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
 /* VM interface that may be used by firmware interface */
 extern int online_pages(unsigned long pfn, unsigned long nr_pages,
                        int online_type, int nid);
-extern int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,
-       unsigned long *valid_start, unsigned long *valid_end);
+extern struct zone *test_pages_in_a_zone(unsigned long start_pfn,
+                                        unsigned long end_pfn);
 extern unsigned long __offline_isolated_pages(unsigned long start_pfn,
                                                unsigned long end_pfn);
 
diff --git a/include/linux/mfd/cros_ec.h b/include/linux/mfd/cros_ec.h
deleted file mode 100644 (file)
index 61c2875..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * ChromeOS EC multi-function device
- *
- * Copyright (C) 2012 Google, Inc
- */
-
-#ifndef __LINUX_MFD_CROS_EC_H
-#define __LINUX_MFD_CROS_EC_H
-
-#include <linux/device.h>
-
-/**
- * struct cros_ec_dev - ChromeOS EC device entry point.
- * @class_dev: Device structure used in sysfs.
- * @ec_dev: cros_ec_device structure to talk to the physical device.
- * @dev: Pointer to the platform device.
- * @debug_info: cros_ec_debugfs structure for debugging information.
- * @has_kb_wake_angle: True if at least 2 accelerometer are connected to the EC.
- * @cmd_offset: Offset to apply for each command.
- * @features: Features supported by the EC.
- */
-struct cros_ec_dev {
-       struct device class_dev;
-       struct cros_ec_device *ec_dev;
-       struct device *dev;
-       struct cros_ec_debugfs *debug_info;
-       bool has_kb_wake_angle;
-       u16 cmd_offset;
-       u32 features[2];
-};
-
-#define to_cros_ec_dev(dev)  container_of(dev, struct cros_ec_dev, class_dev)
-
-#endif /* __LINUX_MFD_CROS_EC_H */
index 1fc75d2..4b63d3e 100644 (file)
@@ -525,9 +525,6 @@ u8 db8500_prcmu_get_power_state_result(void);
 void db8500_prcmu_enable_wakeups(u32 wakeups);
 int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state);
 int db8500_prcmu_request_clock(u8 clock, bool enable);
-int db8500_prcmu_set_display_clocks(void);
-int db8500_prcmu_disable_dsipll(void);
-int db8500_prcmu_enable_dsipll(void);
 void db8500_prcmu_config_abb_event_readout(u32 abb_events);
 void db8500_prcmu_get_abb_event_buffer(void __iomem **buf);
 int db8500_prcmu_config_esram0_deep_sleep(u8 state);
@@ -682,21 +679,6 @@ static inline int db8500_prcmu_request_clock(u8 clock, bool enable)
        return 0;
 }
 
-static inline int db8500_prcmu_set_display_clocks(void)
-{
-       return 0;
-}
-
-static inline int db8500_prcmu_disable_dsipll(void)
-{
-       return 0;
-}
-
-static inline int db8500_prcmu_enable_dsipll(void)
-{
-       return 0;
-}
-
 static inline int db8500_prcmu_config_esram0_deep_sleep(u8 state)
 {
        return 0;
index e257104..e6ee2ec 100644 (file)
@@ -321,21 +321,6 @@ static inline bool prcmu_is_ac_wake_requested(void)
        return db8500_prcmu_is_ac_wake_requested();
 }
 
-static inline int prcmu_set_display_clocks(void)
-{
-       return db8500_prcmu_set_display_clocks();
-}
-
-static inline int prcmu_disable_dsipll(void)
-{
-       return db8500_prcmu_disable_dsipll();
-}
-
-static inline int prcmu_enable_dsipll(void)
-{
-       return db8500_prcmu_enable_dsipll();
-}
-
 static inline int prcmu_config_esram0_deep_sleep(u8 state)
 {
        return db8500_prcmu_config_esram0_deep_sleep(state);
@@ -511,21 +496,6 @@ static inline bool prcmu_is_ac_wake_requested(void)
        return false;
 }
 
-static inline int prcmu_set_display_clocks(void)
-{
-       return 0;
-}
-
-static inline int prcmu_disable_dsipll(void)
-{
-       return 0;
-}
-
-static inline int prcmu_enable_dsipll(void)
-{
-       return 0;
-}
-
 static inline int prcmu_config_esram0_deep_sleep(u8 state)
 {
        return 0;
index 1013e60..a57af87 100644 (file)
@@ -7,6 +7,7 @@
 #include <linux/bits.h>
 #include <linux/device.h>
 #include <linux/mfd/rohm-generic.h>
+#include <linux/mfd/rohm-shared.h>
 #include <linux/regmap.h>
 
 enum {
@@ -89,10 +90,6 @@ struct bd70528_data {
 #define BD70528_REG_GPIO3_OUT  0x52
 #define BD70528_REG_GPIO4_OUT  0x54
 
-/* clk control */
-
-#define BD70528_REG_CLK_OUT    0x2c
-
 /* RTC */
 
 #define BD70528_REG_RTC_COUNT_H                0x2d
@@ -309,21 +306,8 @@ enum {
 
 #define BD70528_GPIO_IN_STATE_BASE 1
 
-#define BD70528_CLK_OUT_EN_MASK 0x1
-
 /* RTC masks to mask out reserved bits */
 
-#define BD70528_MASK_RTC_SEC           0x7f
-#define BD70528_MASK_RTC_MINUTE                0x7f
-#define BD70528_MASK_RTC_HOUR_24H      0x80
-#define BD70528_MASK_RTC_HOUR_PM       0x20
-#define BD70528_MASK_RTC_HOUR          0x1f
-#define BD70528_MASK_RTC_DAY           0x3f
-#define BD70528_MASK_RTC_WEEK          0x07
-#define BD70528_MASK_RTC_MONTH         0x1f
-#define BD70528_MASK_RTC_YEAR          0xff
-#define BD70528_MASK_RTC_COUNT_L       0x7f
-
 #define BD70528_MASK_ELAPSED_TIMER_EN  0x1
 /* Mask second, min and hour fields
  * HW would support ALM irq for over 24h
@@ -332,7 +316,6 @@ enum {
  * wake-up we limit ALM to 24H and only
  * unmask sec, min and hour
  */
-#define BD70528_MASK_ALM_EN            0x7
 #define BD70528_MASK_WAKE_EN           0x1
 
 /* WDT masks */
diff --git a/include/linux/mfd/rohm-bd71828.h b/include/linux/mfd/rohm-bd71828.h
new file mode 100644 (file)
index 0000000..017a4c0
--- /dev/null
@@ -0,0 +1,423 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Copyright (C) 2019 ROHM Semiconductors */
+
+#ifndef __LINUX_MFD_BD71828_H__
+#define __LINUX_MFD_BD71828_H__
+
+#include <linux/mfd/rohm-generic.h>
+#include <linux/mfd/rohm-shared.h>
+
+/* Regulator IDs */
+enum {
+       BD71828_BUCK1,
+       BD71828_BUCK2,
+       BD71828_BUCK3,
+       BD71828_BUCK4,
+       BD71828_BUCK5,
+       BD71828_BUCK6,
+       BD71828_BUCK7,
+       BD71828_LDO1,
+       BD71828_LDO2,
+       BD71828_LDO3,
+       BD71828_LDO4,
+       BD71828_LDO5,
+       BD71828_LDO6,
+       BD71828_LDO_SNVS,
+       BD71828_REGULATOR_AMOUNT,
+};
+
+#define BD71828_BUCK1267_VOLTS         0xEF
+#define BD71828_BUCK3_VOLTS            0x10
+#define BD71828_BUCK4_VOLTS            0x20
+#define BD71828_BUCK5_VOLTS            0x10
+#define BD71828_LDO_VOLTS              0x32
+/* LDO6 is fixed 1.8V voltage */
+#define BD71828_LDO_6_VOLTAGE          1800000
+
+/* Registers and masks*/
+
+/* MODE control */
+#define BD71828_REG_PS_CTRL_1          0x04
+#define BD71828_REG_PS_CTRL_2          0x05
+#define BD71828_REG_PS_CTRL_3          0x06
+
+//#define BD71828_REG_SWRESET          0x06
+#define BD71828_MASK_RUN_LVL_CTRL      0x30
+
+/* Regulator control masks */
+
+#define BD71828_MASK_RAMP_DELAY                0x6
+
+#define BD71828_MASK_RUN_EN            0x08
+#define BD71828_MASK_SUSP_EN           0x04
+#define BD71828_MASK_IDLE_EN           0x02
+#define BD71828_MASK_LPSR_EN           0x01
+
+#define BD71828_MASK_RUN0_EN           0x01
+#define BD71828_MASK_RUN1_EN           0x02
+#define BD71828_MASK_RUN2_EN           0x04
+#define BD71828_MASK_RUN3_EN           0x08
+
+#define BD71828_MASK_DVS_BUCK1_CTRL    0x10
+#define BD71828_DVS_BUCK1_CTRL_I2C     0
+#define BD71828_DVS_BUCK1_USE_RUNLVL   0x10
+
+#define BD71828_MASK_DVS_BUCK2_CTRL    0x20
+#define BD71828_DVS_BUCK2_CTRL_I2C     0
+#define BD71828_DVS_BUCK2_USE_RUNLVL   0x20
+
+#define BD71828_MASK_DVS_BUCK6_CTRL    0x40
+#define BD71828_DVS_BUCK6_CTRL_I2C     0
+#define BD71828_DVS_BUCK6_USE_RUNLVL   0x40
+
+#define BD71828_MASK_DVS_BUCK7_CTRL    0x80
+#define BD71828_DVS_BUCK7_CTRL_I2C     0
+#define BD71828_DVS_BUCK7_USE_RUNLVL   0x80
+
+#define BD71828_MASK_BUCK1267_VOLT     0xff
+#define BD71828_MASK_BUCK3_VOLT                0x1f
+#define BD71828_MASK_BUCK4_VOLT                0x3f
+#define BD71828_MASK_BUCK5_VOLT                0x1f
+#define BD71828_MASK_LDO_VOLT          0x3f
+
+/* Regulator control regs */
+#define BD71828_REG_BUCK1_EN           0x08
+#define BD71828_REG_BUCK1_CTRL         0x09
+#define BD71828_REG_BUCK1_MODE         0x0a
+#define BD71828_REG_BUCK1_IDLE_VOLT    0x0b
+#define BD71828_REG_BUCK1_SUSP_VOLT    0x0c
+#define BD71828_REG_BUCK1_VOLT         0x0d
+
+#define BD71828_REG_BUCK2_EN           0x12
+#define BD71828_REG_BUCK2_CTRL         0x13
+#define BD71828_REG_BUCK2_MODE         0x14
+#define BD71828_REG_BUCK2_IDLE_VOLT    0x15
+#define BD71828_REG_BUCK2_SUSP_VOLT    0x16
+#define BD71828_REG_BUCK2_VOLT         0x17
+
+#define BD71828_REG_BUCK3_EN           0x1c
+#define BD71828_REG_BUCK3_MODE         0x1d
+#define BD71828_REG_BUCK3_VOLT         0x1e
+
+#define BD71828_REG_BUCK4_EN           0x1f
+#define BD71828_REG_BUCK4_MODE         0x20
+#define BD71828_REG_BUCK4_VOLT         0x21
+
+#define BD71828_REG_BUCK5_EN           0x22
+#define BD71828_REG_BUCK5_MODE         0x23
+#define BD71828_REG_BUCK5_VOLT         0x24
+
+#define BD71828_REG_BUCK6_EN           0x25
+#define BD71828_REG_BUCK6_CTRL         0x26
+#define BD71828_REG_BUCK6_MODE         0x27
+#define BD71828_REG_BUCK6_IDLE_VOLT    0x28
+#define BD71828_REG_BUCK6_SUSP_VOLT    0x29
+#define BD71828_REG_BUCK6_VOLT         0x2a
+
+#define BD71828_REG_BUCK7_EN           0x2f
+#define BD71828_REG_BUCK7_CTRL         0x30
+#define BD71828_REG_BUCK7_MODE         0x31
+#define BD71828_REG_BUCK7_IDLE_VOLT    0x32
+#define BD71828_REG_BUCK7_SUSP_VOLT    0x33
+#define BD71828_REG_BUCK7_VOLT         0x34
+
+#define BD71828_REG_LDO1_EN            0x39
+#define BD71828_REG_LDO1_VOLT          0x3a
+#define BD71828_REG_LDO2_EN            0x3b
+#define BD71828_REG_LDO2_VOLT          0x3c
+#define BD71828_REG_LDO3_EN            0x3d
+#define BD71828_REG_LDO3_VOLT          0x3e
+#define BD71828_REG_LDO4_EN            0x3f
+#define BD71828_REG_LDO4_VOLT          0x40
+#define BD71828_REG_LDO5_EN            0x41
+#define BD71828_REG_LDO5_VOLT          0x43
+#define BD71828_REG_LDO5_VOLT_OPT      0x42
+#define BD71828_REG_LDO6_EN            0x44
+//#define BD71828_REG_LDO6_VOLT                0x4
+#define BD71828_REG_LDO7_EN            0x45
+#define BD71828_REG_LDO7_VOLT          0x46
+
+/* GPIO */
+
+#define BD71828_GPIO_DRIVE_MASK                0x2
+#define BD71828_GPIO_OPEN_DRAIN                0x0
+#define BD71828_GPIO_PUSH_PULL         0x2
+#define BD71828_GPIO_OUT_HI            0x1
+#define BD71828_GPIO_OUT_LO            0x0
+#define BD71828_GPIO_OUT_MASK          0x1
+
+#define BD71828_REG_GPIO_CTRL1         0x47
+#define BD71828_REG_GPIO_CTRL2         0x48
+#define BD71828_REG_GPIO_CTRL3         0x49
+#define BD71828_REG_IO_STAT            0xed
+
+/* RTC */
+#define BD71828_REG_RTC_SEC            0x4c
+#define BD71828_REG_RTC_MINUTE         0x4d
+#define BD71828_REG_RTC_HOUR           0x4e
+#define BD71828_REG_RTC_WEEK           0x4f
+#define BD71828_REG_RTC_DAY            0x50
+#define BD71828_REG_RTC_MONTH          0x51
+#define BD71828_REG_RTC_YEAR           0x52
+
+#define BD71828_REG_RTC_ALM0_SEC       0x53
+#define BD71828_REG_RTC_ALM_START      BD71828_REG_RTC_ALM0_SEC
+#define BD71828_REG_RTC_ALM0_MINUTE    0x54
+#define BD71828_REG_RTC_ALM0_HOUR      0x55
+#define BD71828_REG_RTC_ALM0_WEEK      0x56
+#define BD71828_REG_RTC_ALM0_DAY       0x57
+#define BD71828_REG_RTC_ALM0_MONTH     0x58
+#define BD71828_REG_RTC_ALM0_YEAR      0x59
+#define BD71828_REG_RTC_ALM0_MASK      0x61
+
+#define BD71828_REG_RTC_ALM1_SEC       0x5a
+#define BD71828_REG_RTC_ALM1_MINUTE    0x5b
+#define BD71828_REG_RTC_ALM1_HOUR      0x5c
+#define BD71828_REG_RTC_ALM1_WEEK      0x5d
+#define BD71828_REG_RTC_ALM1_DAY       0x5e
+#define BD71828_REG_RTC_ALM1_MONTH     0x5f
+#define BD71828_REG_RTC_ALM1_YEAR      0x60
+#define BD71828_REG_RTC_ALM1_MASK      0x62
+
+#define BD71828_REG_RTC_ALM2           0x63
+#define BD71828_REG_RTC_START          BD71828_REG_RTC_SEC
+
+/* Charger/Battey */
+#define BD71828_REG_CHG_STATE          0x65
+#define BD71828_REG_CHG_FULL           0xd2
+
+/* LEDs */
+#define BD71828_REG_LED_CTRL           0x4A
+#define BD71828_MASK_LED_AMBER         0x80
+#define BD71828_MASK_LED_GREEN         0x40
+#define BD71828_LED_ON                 0xff
+#define BD71828_LED_OFF                        0x0
+
+/* IRQ registers */
+#define BD71828_REG_INT_MASK_BUCK      0xd3
+#define BD71828_REG_INT_MASK_DCIN1     0xd4
+#define BD71828_REG_INT_MASK_DCIN2     0xd5
+#define BD71828_REG_INT_MASK_VSYS      0xd6
+#define BD71828_REG_INT_MASK_CHG       0xd7
+#define BD71828_REG_INT_MASK_BAT       0xd8
+#define BD71828_REG_INT_MASK_BAT_MON1  0xd9
+#define BD71828_REG_INT_MASK_BAT_MON2  0xda
+#define BD71828_REG_INT_MASK_BAT_MON3  0xdb
+#define BD71828_REG_INT_MASK_BAT_MON4  0xdc
+#define BD71828_REG_INT_MASK_TEMP      0xdd
+#define BD71828_REG_INT_MASK_RTC       0xde
+
+#define BD71828_REG_INT_MAIN           0xdf
+#define BD71828_REG_INT_BUCK           0xe0
+#define BD71828_REG_INT_DCIN1          0xe1
+#define BD71828_REG_INT_DCIN2          0xe2
+#define BD71828_REG_INT_VSYS           0xe3
+#define BD71828_REG_INT_CHG            0xe4
+#define BD71828_REG_INT_BAT            0xe5
+#define BD71828_REG_INT_BAT_MON1       0xe6
+#define BD71828_REG_INT_BAT_MON2       0xe7
+#define BD71828_REG_INT_BAT_MON3       0xe8
+#define BD71828_REG_INT_BAT_MON4       0xe9
+#define BD71828_REG_INT_TEMP           0xea
+#define BD71828_REG_INT_RTC            0xeb
+#define BD71828_REG_INT_UPDATE         0xec
+
+#define BD71828_MAX_REGISTER BD71828_REG_IO_STAT
+
+/* Masks for main IRQ register bits */
+enum {
+       BD71828_INT_BUCK,
+#define BD71828_INT_BUCK_MASK BIT(BD71828_INT_BUCK)
+       BD71828_INT_DCIN,
+#define BD71828_INT_DCIN_MASK BIT(BD71828_INT_DCIN)
+       BD71828_INT_VSYS,
+#define BD71828_INT_VSYS_MASK BIT(BD71828_INT_VSYS)
+       BD71828_INT_CHG,
+#define BD71828_INT_CHG_MASK BIT(BD71828_INT_CHG)
+       BD71828_INT_BAT,
+#define BD71828_INT_BAT_MASK BIT(BD71828_INT_BAT)
+       BD71828_INT_BAT_MON,
+#define BD71828_INT_BAT_MON_MASK BIT(BD71828_INT_BAT_MON)
+       BD71828_INT_TEMP,
+#define BD71828_INT_TEMP_MASK BIT(BD71828_INT_TEMP)
+       BD71828_INT_RTC,
+#define BD71828_INT_RTC_MASK BIT(BD71828_INT_RTC)
+};
+
+/* Interrupts */
+enum {
+       /* BUCK reg interrupts */
+       BD71828_INT_BUCK1_OCP,
+       BD71828_INT_BUCK2_OCP,
+       BD71828_INT_BUCK3_OCP,
+       BD71828_INT_BUCK4_OCP,
+       BD71828_INT_BUCK5_OCP,
+       BD71828_INT_BUCK6_OCP,
+       BD71828_INT_BUCK7_OCP,
+       BD71828_INT_PGFAULT,
+       /* DCIN1 interrupts */
+       BD71828_INT_DCIN_DET,
+       BD71828_INT_DCIN_RMV,
+       BD71828_INT_CLPS_OUT,
+       BD71828_INT_CLPS_IN,
+       /* DCIN2 interrupts */
+       BD71828_INT_DCIN_MON_RES,
+       BD71828_INT_DCIN_MON_DET,
+       BD71828_INT_LONGPUSH,
+       BD71828_INT_MIDPUSH,
+       BD71828_INT_SHORTPUSH,
+       BD71828_INT_PUSH,
+       BD71828_INT_WDOG,
+       BD71828_INT_SWRESET,
+       /* Vsys */
+       BD71828_INT_VSYS_UV_RES,
+       BD71828_INT_VSYS_UV_DET,
+       BD71828_INT_VSYS_LOW_RES,
+       BD71828_INT_VSYS_LOW_DET,
+       BD71828_INT_VSYS_HALL_IN,
+       BD71828_INT_VSYS_HALL_TOGGLE,
+       BD71828_INT_VSYS_MON_RES,
+       BD71828_INT_VSYS_MON_DET,
+       /* Charger */
+       BD71828_INT_CHG_DCIN_ILIM,
+       BD71828_INT_CHG_TOPOFF_TO_DONE,
+       BD71828_INT_CHG_WDG_TEMP,
+       BD71828_INT_CHG_WDG_TIME,
+       BD71828_INT_CHG_RECHARGE_RES,
+       BD71828_INT_CHG_RECHARGE_DET,
+       BD71828_INT_CHG_RANGED_TEMP_TRANSITION,
+       BD71828_INT_CHG_STATE_TRANSITION,
+       /* Battery */
+       BD71828_INT_BAT_TEMP_NORMAL,
+       BD71828_INT_BAT_TEMP_ERANGE,
+       BD71828_INT_BAT_TEMP_WARN,
+       BD71828_INT_BAT_REMOVED,
+       BD71828_INT_BAT_DETECTED,
+       BD71828_INT_THERM_REMOVED,
+       BD71828_INT_THERM_DETECTED,
+       /* Battery Mon 1 */
+       BD71828_INT_BAT_DEAD,
+       BD71828_INT_BAT_SHORTC_RES,
+       BD71828_INT_BAT_SHORTC_DET,
+       BD71828_INT_BAT_LOW_VOLT_RES,
+       BD71828_INT_BAT_LOW_VOLT_DET,
+       BD71828_INT_BAT_OVER_VOLT_RES,
+       BD71828_INT_BAT_OVER_VOLT_DET,
+       /* Battery Mon 2 */
+       BD71828_INT_BAT_MON_RES,
+       BD71828_INT_BAT_MON_DET,
+       /* Battery Mon 3 (Coulomb counter) */
+       BD71828_INT_BAT_CC_MON1,
+       BD71828_INT_BAT_CC_MON2,
+       BD71828_INT_BAT_CC_MON3,
+       /* Battery Mon 4 */
+       BD71828_INT_BAT_OVER_CURR_1_RES,
+       BD71828_INT_BAT_OVER_CURR_1_DET,
+       BD71828_INT_BAT_OVER_CURR_2_RES,
+       BD71828_INT_BAT_OVER_CURR_2_DET,
+       BD71828_INT_BAT_OVER_CURR_3_RES,
+       BD71828_INT_BAT_OVER_CURR_3_DET,
+       /* Temperature */
+       BD71828_INT_TEMP_BAT_LOW_RES,
+       BD71828_INT_TEMP_BAT_LOW_DET,
+       BD71828_INT_TEMP_BAT_HI_RES,
+       BD71828_INT_TEMP_BAT_HI_DET,
+       BD71828_INT_TEMP_CHIP_OVER_125_RES,
+       BD71828_INT_TEMP_CHIP_OVER_125_DET,
+       BD71828_INT_TEMP_CHIP_OVER_VF_DET,
+       BD71828_INT_TEMP_CHIP_OVER_VF_RES,
+       /* RTC Alarm */
+       BD71828_INT_RTC0,
+       BD71828_INT_RTC1,
+       BD71828_INT_RTC2,
+};
+
+#define BD71828_INT_BUCK1_OCP_MASK                     0x1
+#define BD71828_INT_BUCK2_OCP_MASK                     0x2
+#define BD71828_INT_BUCK3_OCP_MASK                     0x4
+#define BD71828_INT_BUCK4_OCP_MASK                     0x8
+#define BD71828_INT_BUCK5_OCP_MASK                     0x10
+#define BD71828_INT_BUCK6_OCP_MASK                     0x20
+#define BD71828_INT_BUCK7_OCP_MASK                     0x40
+#define BD71828_INT_PGFAULT_MASK                       0x80
+
+#define BD71828_INT_DCIN_DET_MASK                      0x1
+#define BD71828_INT_DCIN_RMV_MASK                      0x2
+#define BD71828_INT_CLPS_OUT_MASK                      0x4
+#define BD71828_INT_CLPS_IN_MASK                       0x8
+       /* DCIN2 interrupts */
+#define BD71828_INT_DCIN_MON_RES_MASK                  0x1
+#define BD71828_INT_DCIN_MON_DET_MASK                  0x2
+#define BD71828_INT_LONGPUSH_MASK                      0x4
+#define BD71828_INT_MIDPUSH_MASK                       0x8
+#define BD71828_INT_SHORTPUSH_MASK                     0x10
+#define BD71828_INT_PUSH_MASK                          0x20
+#define BD71828_INT_WDOG_MASK                          0x40
+#define BD71828_INT_SWRESET_MASK                       0x80
+       /* Vsys */
+#define BD71828_INT_VSYS_UV_RES_MASK                   0x1
+#define BD71828_INT_VSYS_UV_DET_MASK                   0x2
+#define BD71828_INT_VSYS_LOW_RES_MASK                  0x4
+#define BD71828_INT_VSYS_LOW_DET_MASK                  0x8
+#define BD71828_INT_VSYS_HALL_IN_MASK                  0x10
+#define BD71828_INT_VSYS_HALL_TOGGLE_MASK              0x20
+#define BD71828_INT_VSYS_MON_RES_MASK                  0x40
+#define BD71828_INT_VSYS_MON_DET_MASK                  0x80
+       /* Charger */
+#define BD71828_INT_CHG_DCIN_ILIM_MASK                 0x1
+#define BD71828_INT_CHG_TOPOFF_TO_DONE_MASK            0x2
+#define BD71828_INT_CHG_WDG_TEMP_MASK                  0x4
+#define BD71828_INT_CHG_WDG_TIME_MASK                  0x8
+#define BD71828_INT_CHG_RECHARGE_RES_MASK              0x10
+#define BD71828_INT_CHG_RECHARGE_DET_MASK              0x20
+#define BD71828_INT_CHG_RANGED_TEMP_TRANSITION_MASK    0x40
+#define BD71828_INT_CHG_STATE_TRANSITION_MASK          0x80
+       /* Battery */
+#define BD71828_INT_BAT_TEMP_NORMAL_MASK               0x1
+#define BD71828_INT_BAT_TEMP_ERANGE_MASK               0x2
+#define BD71828_INT_BAT_TEMP_WARN_MASK                 0x4
+#define BD71828_INT_BAT_REMOVED_MASK                   0x10
+#define BD71828_INT_BAT_DETECTED_MASK                  0x20
+#define BD71828_INT_THERM_REMOVED_MASK                 0x40
+#define BD71828_INT_THERM_DETECTED_MASK                        0x80
+       /* Battery Mon 1 */
+#define BD71828_INT_BAT_DEAD_MASK                      0x2
+#define BD71828_INT_BAT_SHORTC_RES_MASK                        0x4
+#define BD71828_INT_BAT_SHORTC_DET_MASK                        0x8
+#define BD71828_INT_BAT_LOW_VOLT_RES_MASK              0x10
+#define BD71828_INT_BAT_LOW_VOLT_DET_MASK              0x20
+#define BD71828_INT_BAT_OVER_VOLT_RES_MASK             0x40
+#define BD71828_INT_BAT_OVER_VOLT_DET_MASK             0x80
+       /* Battery Mon 2 */
+#define BD71828_INT_BAT_MON_RES_MASK                   0x1
+#define BD71828_INT_BAT_MON_DET_MASK                   0x2
+       /* Battery Mon 3 (Coulomb counter) */
+#define BD71828_INT_BAT_CC_MON1_MASK                   0x1
+#define BD71828_INT_BAT_CC_MON2_MASK                   0x2
+#define BD71828_INT_BAT_CC_MON3_MASK                   0x4
+       /* Battery Mon 4 */
+#define BD71828_INT_BAT_OVER_CURR_1_RES_MASK           0x1
+#define BD71828_INT_BAT_OVER_CURR_1_DET_MASK           0x2
+#define BD71828_INT_BAT_OVER_CURR_2_RES_MASK           0x4
+#define BD71828_INT_BAT_OVER_CURR_2_DET_MASK           0x8
+#define BD71828_INT_BAT_OVER_CURR_3_RES_MASK           0x10
+#define BD71828_INT_BAT_OVER_CURR_3_DET_MASK           0x20
+       /* Temperature */
+#define BD71828_INT_TEMP_BAT_LOW_RES_MASK              0x1
+#define BD71828_INT_TEMP_BAT_LOW_DET_MASK              0x2
+#define BD71828_INT_TEMP_BAT_HI_RES_MASK               0x4
+#define BD71828_INT_TEMP_BAT_HI_DET_MASK               0x8
+#define BD71828_INT_TEMP_CHIP_OVER_125_RES_MASK                0x10
+#define BD71828_INT_TEMP_CHIP_OVER_125_DET_MASK                0x20
+#define BD71828_INT_TEMP_CHIP_OVER_VF_RES_MASK         0x40
+#define BD71828_INT_TEMP_CHIP_OVER_VF_DET_MASK         0x80
+       /* RTC Alarm */
+#define BD71828_INT_RTC0_MASK                          0x1
+#define BD71828_INT_RTC1_MASK                          0x2
+#define BD71828_INT_RTC2_MASK                          0x4
+
+#define BD71828_OUT_TYPE_MASK                          0x2
+#define BD71828_OUT_TYPE_OPEN_DRAIN                    0x0
+#define BD71828_OUT_TYPE_CMOS                          0x2
+
+#endif /* __LINUX_MFD_BD71828_H__ */
index 7f2dbde..bee2474 100644 (file)
@@ -191,12 +191,6 @@ enum {
 #define IRQ_ON_REQ             0x02
 #define IRQ_STBY_REQ           0x01
 
-/* BD718XX_REG_OUT32K bits */
-#define BD718XX_OUT32K_EN      0x01
-
-/* BD7183XX gated clock rate */
-#define BD718XX_CLK_RATE 32768
-
 /* ROHM BD718XX irqs */
 enum {
        BD718XX_INT_STBY_REQ,
index bff15ac..4283b5b 100644 (file)
@@ -4,17 +4,83 @@
 #ifndef __LINUX_MFD_ROHM_H__
 #define __LINUX_MFD_ROHM_H__
 
-enum {
+#include <linux/regmap.h>
+#include <linux/regulator/driver.h>
+
+enum rohm_chip_type {
        ROHM_CHIP_TYPE_BD71837 = 0,
        ROHM_CHIP_TYPE_BD71847,
        ROHM_CHIP_TYPE_BD70528,
+       ROHM_CHIP_TYPE_BD71828,
        ROHM_CHIP_TYPE_AMOUNT
 };
 
 struct rohm_regmap_dev {
-       unsigned int chip_type;
        struct device *dev;
        struct regmap *regmap;
 };
 
+enum {
+       ROHM_DVS_LEVEL_UNKNOWN,
+       ROHM_DVS_LEVEL_RUN,
+       ROHM_DVS_LEVEL_IDLE,
+       ROHM_DVS_LEVEL_SUSPEND,
+       ROHM_DVS_LEVEL_LPSR,
+       ROHM_DVS_LEVEL_MAX = ROHM_DVS_LEVEL_LPSR,
+};
+
+/**
+ * struct rohm_dvs_config - dynamic voltage scaling register descriptions
+ *
+ * @level_map:         bitmap representing supported run-levels for this
+ *                     regulator
+ * @run_reg:           register address for regulator config at 'run' state
+ * @run_mask:          value mask for regulator voltages at 'run' state
+ * @run_on_mask:       enable mask for regulator at 'run' state
+ * @idle_reg:          register address for regulator config at 'idle' state
+ * @idle_mask:         value mask for regulator voltages at 'idle' state
+ * @idle_on_mask:      enable mask for regulator at 'idle' state
+ * @suspend_reg:       register address for regulator config at 'suspend' state
+ * @suspend_mask:      value mask for regulator voltages at 'suspend' state
+ * @suspend_on_mask:   enable mask for regulator at 'suspend' state
+ * @lpsr_reg:          register address for regulator config at 'lpsr' state
+ * @lpsr_mask:         value mask for regulator voltages at 'lpsr' state
+ * @lpsr_on_mask:      enable mask for regulator at 'lpsr' state
+ *
+ * Description of ROHM PMICs voltage configuration registers for different
+ * system states. This is used to correctly configure the PMIC at startup
+ * based on values read from DT.
+ */
+struct rohm_dvs_config {
+       uint64_t level_map;
+       unsigned int run_reg;
+       unsigned int run_mask;
+       unsigned int run_on_mask;
+       unsigned int idle_reg;
+       unsigned int idle_mask;
+       unsigned int idle_on_mask;
+       unsigned int suspend_reg;
+       unsigned int suspend_mask;
+       unsigned int suspend_on_mask;
+       unsigned int lpsr_reg;
+       unsigned int lpsr_mask;
+       unsigned int lpsr_on_mask;
+};
+
+#if IS_ENABLED(CONFIG_REGULATOR_ROHM)
+int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,
+                                 struct device_node *np,
+                                 const struct regulator_desc *desc,
+                                 struct regmap *regmap);
+
+#else
+static inline int rohm_regulator_set_dvs_levels(const struct rohm_dvs_config *dvs,
+                                               struct device_node *np,
+                                               const struct regulator_desc *desc,
+                                               struct regmap *regmap)
+{
+       return 0;
+}
+#endif
+
 #endif
diff --git a/include/linux/mfd/rohm-shared.h b/include/linux/mfd/rohm-shared.h
new file mode 100644 (file)
index 0000000..53dd7f6
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/* Copyright (C) 2020 ROHM Semiconductors */
+
+
+#ifndef __LINUX_MFD_ROHM_SHARED_H__
+#define __LINUX_MFD_ROHM_SHARED_H__
+
+/* RTC definitions shared between BD70528 and BD71828 */
+
+#define BD70528_MASK_RTC_SEC           0x7f
+#define BD70528_MASK_RTC_MINUTE                0x7f
+#define BD70528_MASK_RTC_HOUR_24H      0x80
+#define BD70528_MASK_RTC_HOUR_PM       0x20
+#define BD70528_MASK_RTC_HOUR          0x3f
+#define BD70528_MASK_RTC_DAY           0x3f
+#define BD70528_MASK_RTC_WEEK          0x07
+#define BD70528_MASK_RTC_MONTH         0x1f
+#define BD70528_MASK_RTC_YEAR          0xff
+#define BD70528_MASK_ALM_EN            0x7
+
+#endif /* __LINUX_MFD_ROHM_SHARED_H__ */
index 112dc66..7f20e9b 100644 (file)
@@ -23,6 +23,11 @@ extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
 extern struct regmap *syscon_regmap_lookup_by_phandle(
                                        struct device_node *np,
                                        const char *property);
+extern struct regmap *syscon_regmap_lookup_by_phandle_args(
+                                       struct device_node *np,
+                                       const char *property,
+                                       int arg_count,
+                                       unsigned int *out_args);
 #else
 static inline struct regmap *device_node_to_regmap(struct device_node *np)
 {
@@ -45,6 +50,15 @@ static inline struct regmap *syscon_regmap_lookup_by_phandle(
 {
        return ERR_PTR(-ENOTSUPP);
 }
+
+static inline struct regmap *syscon_regmap_lookup_by_phandle_args(
+                                       struct device_node *np,
+                                       const char *property,
+                                       int arg_count,
+                                       unsigned int *out_args)
+{
+       return ERR_PTR(-ENOTSUPP);
+}
 #endif
 
 #endif /* __LINUX_MFD_SYSCON_H__ */
diff --git a/include/linux/mfd/wcd934x/registers.h b/include/linux/mfd/wcd934x/registers.h
new file mode 100644 (file)
index 0000000..bb8d2e2
--- /dev/null
@@ -0,0 +1,531 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _WCD934X_REGISTERS_H
+#define _WCD934X_REGISTERS_H
+
+#define WCD934X_CODEC_RPM_CLK_GATE                             0x0002
+#define WCD934X_CODEC_RPM_CLK_GATE_MASK                                GENMASK(1, 0)
+#define WCD934X_CODEC_RPM_CLK_MCLK_CFG                         0x0003
+#define WCD934X_CODEC_RPM_CLK_MCLK_CFG_9P6MHZ                  BIT(0)
+#define WCD934X_CODEC_RPM_CLK_MCLK_CFG_12P288MHZ               BIT(1)
+#define WCD934X_CODEC_RPM_CLK_MCLK_CFG_MCLK_MASK               GENMASK(1, 0)
+#define WCD934X_CODEC_RPM_RST_CTL                              0x0009
+#define WCD934X_CODEC_RPM_PWR_CDC_DIG_HM_CTL                   0x0011
+#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE0                   0x0021
+#define WCD934X_CHIP_TIER_CTRL_CHIP_ID_BYTE2                   0x0023
+#define WCD934X_CHIP_TIER_CTRL_EFUSE_CTL                       0x0025
+#define WCD934X_EFUSE_SENSE_STATE_MASK                         GENMASK(4, 1)
+#define WCD934X_EFUSE_SENSE_STATE_DEF                          0x10
+#define WCD934X_EFUSE_SENSE_EN_MASK                            BIT(0)
+#define WCD934X_EFUSE_SENSE_ENABLE                             BIT(0)
+#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT14                 0x0037
+#define WCD934X_CHIP_TIER_CTRL_EFUSE_VAL_OUT15                 0x0038
+#define WCD934X_CHIP_TIER_CTRL_EFUSE_STATUS                    0x0039
+#define WCD934X_DATA_HUB_SB_TX10_INP_CFG                       0x006b
+#define WCD934X_DATA_HUB_SB_TX11_INP_CFG                       0x006c
+#define WCD934X_DATA_HUB_SB_TX13_INP_CFG                       0x006e
+#define WCD934X_CPE_FLL_CONFIG_CTL_2                           0x0111
+#define WCD934X_CPE_SS_CPARMAD_BUFRDY_INT_PERIOD               0x0213
+#define WCD934X_CPE_SS_SVA_CFG                                 0x0214
+#define WCD934X_CPE_SS_DMIC0_CTL                               0x0218
+#define WCD934X_CPE_SS_DMIC1_CTL                               0x0219
+#define WCD934X_DMIC_RATE_MASK                                 GENMASK(3, 1)
+#define WCD934X_CPE_SS_DMIC2_CTL                               0x021a
+#define WCD934X_CPE_SS_DMIC_CFG                                        0x021b
+#define WCD934X_CPE_SS_DMIC_CFG                                        0x021b
+#define WCD934X_CPE_SS_CPAR_CFG                                        0x021c
+#define WCD934X_INTR_PIN1_MASK0                                        0x0409
+#define WCD934X_INTR_PIN1_STATUS0                              0x0411
+#define WCD934X_INTR_PIN1_CLEAR0                               0x0419
+#define WCD934X_INTR_PIN2_CLEAR3                               0x0434
+#define WCD934X_INTR_LEVEL0                                    0x0461
+/* INTR_REG 0 */
+#define        WCD934X_IRQ_SLIMBUS                     0
+#define        WCD934X_IRQ_MISC                        1
+#define        WCD934X_IRQ_HPH_PA_OCPL_FAULT           2
+#define        WCD934X_IRQ_HPH_PA_OCPR_FAULT           3
+#define        WCD934X_IRQ_EAR_PA_OCP_FAULT            4
+#define        WCD934X_IRQ_HPH_PA_CNPL_COMPLETE        5
+#define        WCD934X_IRQ_HPH_PA_CNPR_COMPLETE        6
+#define        WCD934X_IRQ_EAR_PA_CNP_COMPLETE         7
+/* INTR_REG 1 */
+#define        WCD934X_IRQ_MBHC_SW_DET                 8
+#define        WCD934X_IRQ_MBHC_ELECT_INS_REM_DET      9
+#define        WCD934X_IRQ_MBHC_BUTTON_PRESS_DET       10
+#define        WCD934X_IRQ_MBHC_BUTTON_RELEASE_DET     11
+#define        WCD934X_IRQ_MBHC_ELECT_INS_REM_LEG_DET  12
+#define        WCD934X_IRQ_RESERVED_0                  13
+#define        WCD934X_IRQ_RESERVED_1                  14
+#define        WCD934X_IRQ_RESERVED_2                  15
+/* INTR_REG 2 */
+#define        WCD934X_IRQ_LINE_PA1_CNP_COMPLETE       16
+#define        WCD934X_IRQ_LINE_PA2_CNP_COMPLETE       17
+#define        WCD934X_IRQ_SLNQ_ANALOG_ERROR           18
+#define        WCD934X_IRQ_RESERVED_3                  19
+#define        WCD934X_IRQ_SOUNDWIRE                   20
+#define        WCD934X_IRQ_VDD_DIG_RAMP_COMPLETE       21
+#define        WCD934X_IRQ_RCO_ERROR                   22
+#define        WCD934X_IRQ_CPE_ERROR                   23
+/* INTR_REG 3 */
+#define        WCD934X_IRQ_MAD_AUDIO                   24
+#define        WCD934X_IRQ_MAD_BEACON                  25
+#define        WCD934X_IRQ_MAD_ULTRASOUND              26
+#define        WCD934X_IRQ_VBAT_ATTACK                 27
+#define        WCD934X_IRQ_VBAT_RESTORE                28
+#define        WCD934X_IRQ_CPE1_INTR                   29
+#define        WCD934X_IRQ_RESERVED_4                  30
+#define        WCD934X_IRQ_SLNQ_DIGITAL                31
+#define WCD934X_NUM_IRQS                       32
+#define WCD934X_ANA_BIAS                                       0x0601
+#define WCD934X_ANA_BIAS_EN_MASK                               BIT(7)
+#define WCD934X_ANA_BIAS_EN                                    BIT(7)
+#define WCD934X_ANA_PRECHRG_EN_MASK                            BIT(6)
+#define WCD934X_ANA_PRECHRG_EN                                 BIT(6)
+#define WCD934X_ANA_PRECHRG_MODE_MASK                          BIT(5)
+#define WCD934X_ANA_PRECHRG_MODE_AUTO                          BIT(5)
+#define WCD934X_ANA_RCO                                                0x0603
+#define WCD934X_ANA_RCO_BG_EN_MASK                             BIT(7)
+#define WCD934X_ANA_RCO_BG_ENABLE                              BIT(7)
+#define WCD934X_ANA_BUCK_CTL                                   0x0606
+#define WCD934X_ANA_BUCK_HI_ACCU_PRE_ENX_MASK                  GENMASK(1, 0)
+#define WCD934X_ANA_BUCK_PRE_EN2_MASK                          BIT(0)
+#define WCD934X_ANA_BUCK_PRE_EN2_ENABLE                                BIT(0)
+#define WCD934X_ANA_BUCK_PRE_EN1_MASK                          BIT(1)
+#define WCD934X_ANA_BUCK_PRE_EN1_ENABLE                                BIT(1)
+#define WCD934X_ANA_BUCK_HI_ACCU_EN_MASK                       BIT(2)
+#define WCD934X_ANA_BUCK_HI_ACCU_ENABLE                                BIT(2)
+#define WCD934X_ANA_RX_SUPPLIES                                        0x0608
+#define WCD934X_ANA_HPH                                                0x0609
+#define WCD934X_ANA_EAR                                                0x060a
+#define WCD934X_ANA_LO_1_2                                     0x060b
+#define WCD934X_ANA_AMIC1                                      0x060e
+#define WCD934X_ANA_AMIC2                                      0x060f
+#define WCD934X_ANA_AMIC3                                      0x0610
+#define WCD934X_ANA_AMIC4                                      0x0611
+#define WCD934X_ANA_MBHC_MECH                                  0x0614
+#define WCD934X_ANA_MBHC_ELECT                                 0x0615
+#define WCD934X_ANA_MBHC_ZDET                                  0x0616
+#define WCD934X_ANA_MBHC_RESULT_1                              0x0617
+#define WCD934X_ANA_MBHC_RESULT_2                              0x0618
+#define WCD934X_ANA_MBHC_RESULT_3                              0x0619
+#define WCD934X_ANA_MICB1                                      0x0622
+#define WCD934X_MICB_VAL_MASK                                  GENMASK(5, 0)
+#define WCD934X_ANA_MICB_EN_MASK                               GENMASK(7, 6)
+#define WCD934X_ANA_MICB_PULL_UP                               0x80
+#define WCD934X_ANA_MICB_ENABLE                                        0x40
+#define WCD934X_ANA_MICB_DISABLE                               0x0
+#define WCD934X_ANA_MICB2                                      0x0623
+#define WCD934X_ANA_MICB3                                      0x0625
+#define WCD934X_ANA_MICB4                                      0x0626
+#define WCD934X_BIAS_VBG_FINE_ADJ                              0x0629
+#define WCD934X_MICB1_TEST_CTL_1                               0x066b
+#define WCD934X_MICB1_TEST_CTL_2                               0x066c
+#define WCD934X_MICB2_TEST_CTL_1                               0x066e
+#define WCD934X_MICB3_TEST_CTL_1                               0x0671
+#define WCD934X_MICB4_TEST_CTL_1                               0x0674
+#define WCD934X_CLASSH_MODE_1                                  0x0697
+#define WCD934X_CLASSH_MODE_2                                  0x0698
+#define WCD934X_CLASSH_MODE_3                                  0x0699
+#define WCD934X_CLASSH_CTRL_VCL_1                              0x069a
+#define WCD934X_CLASSH_CTRL_VCL_2                              0x069b
+#define WCD934X_CLASSH_CTRL_CCL_1                              0x069c
+#define WCD934X_CLASSH_CTRL_CCL_2                              0x069d
+#define WCD934X_CLASSH_CTRL_CCL_3                              0x069e
+#define WCD934X_CLASSH_CTRL_CCL_4                              0x069f
+#define WCD934X_CLASSH_CTRL_CCL_5                              0x06a0
+#define WCD934X_CLASSH_BUCK_TMUX_A_D                           0x06a1
+#define WCD934X_CLASSH_BUCK_SW_DRV_CNTL                                0x06a2
+#define WCD934X_RX_OCP_CTL                                     0x06b6
+#define WCD934X_RX_OCP_COUNT                                   0x06b7
+#define WCD934X_HPH_CNP_EN                                     0x06cb
+#define WCD934X_HPH_CNP_WG_CTL                                 0x06cc
+#define WCD934X_HPH_GM3_BOOST_EN_MASK                          BIT(7)
+#define WCD934X_HPH_GM3_BOOST_ENABLE                           BIT(7)
+#define WCD934X_HPH_OCP_CTL                                    0x06ce
+#define WCD934X_HPH_L_EN                                       0x06d3
+#define WCD934X_HPH_GAIN_SRC_SEL_MASK                          BIT(5)
+#define WCD934X_HPH_GAIN_SRC_SEL_COMPANDER                     0
+#define WCD934X_HPH_GAIN_SRC_SEL_REGISTER                      BIT(5)
+#define WCD934X_HPH_L_TEST                                     0x06d4
+#define WCD934X_HPH_R_EN                                       0x06d6
+#define WCD934X_HPH_R_TEST                                     0x06d7
+#define WCD934X_HPH_OCP_DET_MASK                               BIT(0)
+#define WCD934X_HPH_OCP_DET_ENABLE                             BIT(0)
+#define WCD934X_HPH_OCP_DET_DISABLE                            0
+#define WCD934X_DIFF_LO_LO2_COMPANDER                          0x06ea
+#define WCD934X_DIFF_LO_LO1_COMPANDER                          0x06eb
+#define WCD934X_CLK_SYS_MCLK_PRG                               0x0711
+#define WCD934X_EXT_CLK_BUF_EN_MASK    BIT(7)
+#define WCD934X_EXT_CLK_BUF_EN         BIT(7)
+#define WCD934X_EXT_CLK_DIV_RATIO_MASK GENMASK(5, 4)
+#define WCD934X_EXT_CLK_DIV_BY_2       0x10
+#define WCD934X_MCLK_SRC_MASK          BIT(1)
+#define WCD934X_MCLK_SRC_EXT_CLK       0
+#define WCD934X_MCLK_SRC_MASK          BIT(1)
+#define WCD934X_MCLK_EN_MASK           BIT(0)
+#define WCD934X_MCLK_EN                        BIT(0)
+#define WCD934X_CLK_SYS_MCLK2_PRG1                             0x0712
+#define WCD934X_CLK_SYS_MCLK2_PRG2                             0x0713
+#define WCD934X_SIDO_NEW_VOUT_A_STARTUP                                0x071b
+#define WCD934X_SIDO_NEW_VOUT_D_STARTUP                                0x071c
+#define WCD934X_SIDO_NEW_VOUT_D_FREQ1                          0x071d
+#define WCD934X_SIDO_NEW_VOUT_D_FREQ2                          0x071e
+#define WCD934X_SIDO_RIPPLE_FREQ_EN_MASK                       BIT(0)
+#define WCD934X_SIDO_RIPPLE_FREQ_ENABLE                                BIT(0)
+#define WCD934X_MBHC_NEW_CTL_2                                 0x0721
+#define WCD934X_TX_NEW_AMIC_4_5_SEL                            0x0727
+#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_L                     0x0733
+#define WCD934X_HPH_NEW_INT_RDAC_OVERRIDE_CTL                  0x0735
+#define WCD934X_HPH_NEW_INT_RDAC_HD2_CTL_R                     0x0736
+#define WCD934X_HPH_NEW_INT_HPH_TIMER1                         0x073a
+#define WCD934X_HPH_AUTOCHOP_TIMER_EN_MASK                     BIT(1)
+#define WCD934X_HPH_AUTOCHOP_TIMER_ENABLE                      BIT(1)
+#define WCD934X_CDC_TX0_TX_PATH_CTL                            0x0a31
+#define WCD934X_CDC_TX_PATH_CTL_PCM_RATE_MASK                  GENMASK(3, 0)
+#define WCD934X_CDC_TX_PATH_CTL(dec)                   (0xa31 + dec * 0x10)
+#define WCD934X_CDC_TX0_TX_PATH_CFG0                           0x0a32
+#define WCD934X_CDC_TX0_TX_PATH_CFG1                           0x0a33
+#define WCD934X_CDC_TX0_TX_VOL_CTL                             0x0a34
+#define WCD934X_CDC_TX0_TX_PATH_192_CTL                                0x0a35
+#define WCD934X_CDC_TX0_TX_PATH_192_CFG                                0x0a36
+#define WCD934X_CDC_TX0_TX_PATH_SEC2                           0x0a39
+#define WCD934X_HPH_CUTOFF_FREQ_CHANGE_REQ_MASK                        BIT(1)
+#define WCD934X_HPH_CUTOFF_FREQ_CHANGE_REQ                     BIT(1)
+#define WCD934X_CDC_TX1_TX_PATH_CTL                            0x0a41
+#define WCD934X_CDC_TX1_TX_PATH_CFG0                           0x0a42
+#define WCD934X_CDC_TX1_TX_PATH_CFG1                           0x0a43
+#define WCD934X_CDC_TX1_TX_VOL_CTL                             0x0a44
+#define WCD934X_CDC_TX2_TX_PATH_CTL                            0x0a51
+#define WCD934X_CDC_TX2_TX_PATH_CFG0                           0x0a52
+#define WCD934X_CDC_TX2_TX_PATH_CFG1                           0x0a53
+#define WCD934X_CDC_TX2_TX_VOL_CTL                             0x0a54
+#define WCD934X_CDC_TX3_TX_PATH_CTL                            0x0a61
+#define WCD934X_CDC_TX3_TX_PATH_CFG0                           0x0a62
+#define WCD934X_CDC_TX3_TX_PATH_CFG1                           0x0a63
+#define WCD934X_CDC_TX3_TX_VOL_CTL                             0x0a64
+#define WCD934X_CDC_TX3_TX_PATH_192_CTL                                0x0a65
+#define WCD934X_CDC_TX3_TX_PATH_192_CFG                                0x0a66
+#define WCD934X_CDC_TX4_TX_PATH_CTL                            0x0a71
+#define WCD934X_CDC_TX4_TX_PATH_CFG0                           0x0a72
+#define WCD934X_CDC_TX4_TX_PATH_CFG1                           0x0a73
+#define WCD934X_CDC_TX4_TX_VOL_CTL                             0x0a74
+#define WCD934X_CDC_TX4_TX_PATH_192_CTL                                0x0a75
+#define WCD934X_CDC_TX4_TX_PATH_192_CFG                                0x0a76
+#define WCD934X_CDC_TX5_TX_PATH_CTL                            0x0a81
+#define WCD934X_CDC_TX5_TX_PATH_CFG0                           0x0a82
+#define WCD934X_CDC_TX5_TX_PATH_CFG1                           0x0a83
+#define WCD934X_CDC_TX5_TX_VOL_CTL                             0x0a84
+#define WCD934X_CDC_TX5_TX_PATH_192_CTL                                0x0a85
+#define WCD934X_CDC_TX5_TX_PATH_192_CFG                                0x0a86
+#define WCD934X_CDC_TX6_TX_PATH_CTL                            0x0a91
+#define WCD934X_CDC_TX6_TX_PATH_CFG0                           0x0a92
+#define WCD934X_CDC_TX6_TX_PATH_CFG1                           0x0a93
+#define WCD934X_CDC_TX6_TX_VOL_CTL                             0x0a94
+#define WCD934X_CDC_TX6_TX_PATH_192_CTL                                0x0a95
+#define WCD934X_CDC_TX6_TX_PATH_192_CFG                                0x0a96
+#define WCD934X_CDC_TX7_TX_PATH_CTL                            0x0aa1
+#define WCD934X_CDC_TX7_TX_PATH_CFG0                           0x0aa2
+#define WCD934X_CDC_TX7_TX_PATH_CFG1                           0x0aa3
+#define WCD934X_CDC_TX7_TX_VOL_CTL                             0x0aa4
+#define WCD934X_CDC_TX7_TX_PATH_192_CTL                                0x0aa5
+#define WCD934X_CDC_TX7_TX_PATH_192_CFG                                0x0aa6
+#define WCD934X_CDC_TX8_TX_PATH_CTL                            0x0ab1
+#define WCD934X_CDC_TX8_TX_PATH_CFG0                           0x0ab2
+#define WCD934X_CDC_TX8_TX_PATH_CFG1                           0x0ab3
+#define WCD934X_CDC_TX8_TX_VOL_CTL                             0x0ab4
+#define WCD934X_CDC_TX8_TX_PATH_192_CTL                                0x0ab5
+#define WCD934X_CDC_TX8_TX_PATH_192_CFG                                0x0ab6
+#define WCD934X_CDC_TX9_SPKR_PROT_PATH_CFG0                    0x0ac3
+#define WCD934X_CDC_TX10_SPKR_PROT_PATH_CFG0                   0x0ac7
+#define WCD934X_CDC_TX11_SPKR_PROT_PATH_CFG0                   0x0acb
+#define WCD934X_CDC_TX12_SPKR_PROT_PATH_CFG0                   0x0acf
+#define WCD934X_CDC_COMPANDER1_CTL0                            0x0b01
+#define WCD934X_COMP_CLK_EN_MASK                               BIT(0)
+#define WCD934X_COMP_CLK_ENABLE                                        BIT(0)
+#define WCD934X_COMP_SOFT_RST_MASK                             BIT(1)
+#define WCD934X_COMP_SOFT_RST_ENABLE                           BIT(1)
+#define WCD934X_COMP_HALT_MASK                                 BIT(2)
+#define WCD934X_COMP_HALT                                      BIT(2)
+#define WCD934X_COMP_SOFT_RST_DISABLE                          0
+#define WCD934X_CDC_COMPANDER1_CTL7                            0x0b08
+#define WCD934X_HPH_LOW_PWR_MODE_EN_MASK                       BIT(5)
+#define WCD934X_CDC_COMPANDER2_CTL7                            0x0b10
+#define WCD934X_CDC_COMPANDER7_CTL3                            0x0b34
+#define WCD934X_CDC_COMPANDER7_CTL7                            0x0b38
+#define WCD934X_CDC_COMPANDER8_CTL3                            0x0b3c
+#define WCD934X_CDC_COMPANDER8_CTL7                            0x0b40
+#define WCD934X_CDC_RX0_RX_PATH_CTL                            0x0b41
+#define WCD934X_CDC_RX_PGA_MUTE_EN_MASK                                BIT(4)
+#define WCD934X_CDC_RX_PGA_MUTE_ENABLE                         BIT(4)
+#define WCD934X_CDC_RX_PGA_MUTE_DISABLE                                0
+#define WCD934X_RX_CLK_EN_MASK                                 BIT(5)
+#define WCD934X_RX_CLK_ENABLE                                  BIT(5)
+#define WCD934X_RX_RESET_MASK                                  BIT(6)
+#define WCD934X_RX_RESET_ENABLE                                        BIT(6)
+#define WCD934X_RX_RESET_DISABLE                               0
+#define WCD934X_RX_PCM_RATE_MASK                               GENMASK(3, 0)
+#define WCD934X_RX_PCM_RATE_F_48K                              0x04
+#define WCD934X_CDC_RX_PATH_CTL(rx)                    (0xb41 + rx * 0x14)
+#define WCD934X_CDC_MIX_PCM_RATE_MASK                          GENMASK(3, 0)
+#define WCD934X_CDC_RX0_RX_PATH_CFG0                           0x0b42
+#define WCD934X_RX_DLY_ZN_EN_MASK                              BIT(3)
+#define WCD934X_RX_DLY_ZN_ENABLE                               BIT(3)
+#define WCD934X_RX_DLY_ZN_DISABLE                              0
+#define WCD934X_CDC_RX0_RX_PATH_CFG1                           0x0b43
+#define WCD934X_CDC_RX0_RX_PATH_CFG2                           0x0b44
+#define WCD934X_CDC_RX0_RX_VOL_CTL                             0x0b45
+#define WCD934X_CDC_RX0_RX_PATH_MIX_CTL                                0x0b46
+#define WCD934X_CDC_RX_MIX_CLK_EN_MASK                         BIT(5)
+#define WCD934X_CDC_RX_MIX_CLK_ENABLE                          BIT(5)
+#define WCD934X_CDC_RX_PATH_MIX_CTL(rx)                        (0xb46 + rx * 0x14)
+#define WCD934X_CDC_RX0_RX_PATH_MIX_CFG                                0x0b47
+#define WCD934X_CDC_RX0_RX_VOL_MIX_CTL                         0x0b48
+#define WCD934X_CDC_RX0_RX_PATH_SEC0                           0x0b49
+#define WCD934X_CDC_RX0_RX_PATH_DSMDEM_CTL                     0x0b53
+#define WCD934X_CDC_RX1_RX_PATH_CTL                            0x0b55
+#define WCD934X_RX_PATH_PGA_MUTE_EN_MASK                       BIT(4)
+#define WCD934X_RX_PATH_PGA_MUTE_ENABLE                                BIT(4)
+#define WCD934X_CDC_RX_PATH_PGA_MUTE_DISABLE                   0
+#define WCD934X_CDC_RX_PATH_CLK_EN_MASK                                BIT(5)
+#define WCD934X_CDC_RX_PATH_CLK_ENABLE                         BIT(5)
+#define WCD934X_CDC_RX_PATH_CLK_DISABLE                                0
+#define WCD934X_CDC_RX1_RX_PATH_CFG0                           0x0b56
+#define WCD934X_HPH_CMP_EN_MASK                                        BIT(1)
+#define WCD934X_HPH_CMP_ENABLE                                 BIT(1)
+#define WCD934X_HPH_CMP_DISABLE                                        0
+#define WCD934X_CDC_RX1_RX_PATH_CFG2                           0x0b58
+#define WCD934X_CDC_RX1_RX_VOL_CTL                             0x0b59
+#define WCD934X_CDC_RX1_RX_PATH_MIX_CTL                                0x0b5a
+#define WCD934X_CDC_RX1_RX_PATH_MIX_CFG                                0x0b5b
+#define WCD934X_CDC_RX1_RX_VOL_MIX_CTL                         0x0b5c
+#define WCD934X_CDC_RX1_RX_PATH_SEC0                           0x0b5d
+#define WCD934X_CDC_RX1_RX_PATH_SEC3                           0x0b60
+#define WCD934X_CDC_RX_PATH_SEC_HD2_ALPHA_MASK                 GENMASK(5, 2)
+#define WCD934X_CDC_RX_PATH_SEC_HD2_ALPHA_0P3125               0x14
+#define WCD934X_CDC_RX_PATH_SEC_HD2_ALPHA_0P0000               0
+#define WCD934X_CDC_RX1_RX_PATH_DSMDEM_CTL                     0x0b67
+#define WCD934X_CDC_RX2_RX_PATH_CTL                            0x0b69
+#define WCD934X_CDC_RX2_RX_PATH_CFG0                           0x0b6a
+#define WCD934X_CDC_RX_PATH_CFG_HD2_EN_MASK                    BIT(2)
+#define WCD934X_CDC_RX_PATH_CFG_HD2_ENABLE                     BIT(2)
+#define WCD934X_CDC_RX_PATH_CFG_HD2_DISABLE                    0
+#define WCD934X_CDC_RX2_RX_PATH_CFG2                           0x0b6c
+#define WCD934X_CDC_RX2_RX_VOL_CTL                             0x0b6d
+#define WCD934X_CDC_RX2_RX_PATH_MIX_CTL                                0x0b6e
+#define WCD934X_CDC_RX2_RX_PATH_MIX_CFG                                0x0b6f
+#define WCD934X_CDC_RX2_RX_VOL_MIX_CTL                         0x0b70
+#define WCD934X_CDC_RX2_RX_PATH_SEC0                           0x0b71
+#define WCD934X_CDC_RX2_RX_PATH_SEC3                           0x0b74
+#define WCD934X_CDC_RX2_RX_PATH_DSMDEM_CTL                     0x0b7b
+#define WCD934X_CDC_RX3_RX_PATH_CTL                            0x0b7d
+#define WCD934X_CDC_RX3_RX_PATH_CFG0                           0x0b6e
+#define WCD934X_CDC_RX3_RX_PATH_CFG2                           0x0b80
+#define WCD934X_CDC_RX3_RX_VOL_CTL                             0x0b81
+#define WCD934X_CDC_RX3_RX_PATH_MIX_CTL                                0x0b82
+#define WCD934X_CDC_RX3_RX_PATH_MIX_CFG                                0x0b83
+#define WCD934X_CDC_RX3_RX_VOL_MIX_CTL                         0x0b84
+#define WCD934X_CDC_RX3_RX_PATH_SEC0                           0x0b85
+#define WCD934X_CDC_RX3_RX_PATH_DSMDEM_CTL                     0x0b8f
+#define WCD934X_CDC_RX4_RX_PATH_CTL                            0x0b91
+#define WCD934X_CDC_RX4_RX_PATH_CFG0                           0x0b92
+#define WCD934X_CDC_RX4_RX_PATH_CFG2                           0x0b94
+#define WCD934X_CDC_RX4_RX_VOL_CTL                             0x0b95
+#define WCD934X_CDC_RX4_RX_PATH_MIX_CTL                                0x0b96
+#define WCD934X_CDC_RX4_RX_PATH_MIX_CFG                                0x0b97
+#define WCD934X_CDC_RX4_RX_VOL_MIX_CTL                         0x0b98
+#define WCD934X_CDC_RX4_RX_PATH_SEC0                           0x0b99
+#define WCD934X_CDC_RX4_RX_PATH_DSMDEM_CTL                     0x0ba3
+#define WCD934X_CDC_RX7_RX_PATH_CTL                            0x0bcd
+#define WCD934X_CDC_RX7_RX_PATH_CFG0                           0x0bce
+#define WCD934X_CDC_RX7_RX_PATH_CFG1                           0x0bcf
+#define WCD934X_CDC_RX7_RX_PATH_CFG2                           0x0bd0
+#define WCD934X_CDC_RX7_RX_VOL_CTL                             0x0bd1
+#define WCD934X_CDC_RX7_RX_PATH_MIX_CTL                                0x0bd2
+#define WCD934X_CDC_RX7_RX_PATH_MIX_CFG                                0x0bd3
+#define WCD934X_CDC_RX7_RX_VOL_MIX_CTL                         0x0bd4
+#define WCD934X_CDC_RX7_RX_PATH_SEC1                           0x0bd6
+#define WCD934X_CDC_RX7_RX_PATH_MIX_SEC0                       0x0bdd
+#define WCD934X_CDC_RX7_RX_PATH_DSMDEM_CTL                     0x0bdf
+#define WCD934X_CDC_RX8_RX_PATH_CTL                            0x0be1
+#define WCD934X_CDC_RX8_RX_PATH_CFG0                           0x0be2
+#define WCD934X_CDC_RX8_RX_PATH_CFG1                           0x0be3
+#define WCD934X_RX_SMART_BOOST_EN_MASK                         BIT(0)
+#define WCD934X_RX_SMART_BOOST_ENABLE                          BIT(0)
+#define WCD934X_RX_SMART_BOOST_DISABLE                 0
+#define WCD934X_CDC_RX8_RX_PATH_CFG2                           0x0be4
+#define WCD934X_CDC_RX8_RX_VOL_CTL                             0x0be5
+#define WCD934X_CDC_RX8_RX_PATH_MIX_CTL                                0x0be6
+#define WCD934X_CDC_RX8_RX_PATH_MIX_CFG                                0x0be7
+#define WCD934X_CDC_RX8_RX_VOL_MIX_CTL                         0x0be8
+#define WCD934X_CDC_RX8_RX_PATH_SEC1                           0x0bea
+#define WCD934X_CDC_RX8_RX_PATH_MIX_SEC0                       0x0bf1
+#define WCD934X_CDC_RX8_RX_PATH_DSMDEM_CTL                     0x0bf3
+#define WCD934X_CDC_CLSH_DECAY_CTRL                            0x0c03
+#define WCD934X_CDC_CLSH_K2_MSB                                        0x0c0a
+#define WCD934X_CDC_CLSH_K2_LSB                                        0x0c0b
+#define WCD934X_CDC_CLSH_TEST0                                 0x0c0f
+#define WCD934X_CDC_BOOST0_BOOST_PATH_CTL                      0x0c19
+#define WCD934X_BOOST_PATH_CLK_EN_MASK                         BIT(4)
+#define WCD934X_BOOST_PATH_CLK_ENABLE                          BIT(4)
+#define WCD934X_BOOST_PATH_CLK_DISABLE                         0
+#define WCD934X_CDC_BOOST0_BOOST_CTL                           0x0c1a
+#define WCD934X_CDC_BOOST0_BOOST_CFG1                          0x0c1b
+#define WCD934X_CDC_BOOST0_BOOST_CFG2                          0x0c1c
+#define WCD934X_CDC_BOOST1_BOOST_PATH_CTL                      0x0c21
+#define WCD934X_CDC_BOOST1_BOOST_CTL                           0x0c22
+#define WCD934X_CDC_BOOST1_BOOST_CFG1                          0x0c23
+#define WCD934X_CDC_BOOST1_BOOST_CFG2                          0x0c24
+#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_0                       0x0c91
+#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_1                       0x0c92
+#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_2                       0x0c93
+#define WCD934X_SWR_AHB_BRIDGE_RD_DATA_3                       0x0c94
+#define WCD934X_SWR_AHB_BRIDGE_ACCESS_STATUS                   0x0c96
+#define WCD934X_CDC_SIDETONE_SRC0_ST_SRC_PATH_CTL              0x0cb5
+#define WCD934X_CDC_SIDETONE_SRC1_ST_SRC_PATH_CTL              0x0cb9
+#define WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG0                    0x0d01
+#define WCD934X_CDC_RX_INP_MUX_RX_INT_CFG0(i)          (0xd01 + i * 0x2)
+#define WCD934X_CDC_RX_INP_MUX_RX_INT_SEL_MASK                 GENMASK(3, 0)
+#define WCD934X_CDC_RX_INP_MUX_RX_INT0_CFG1                    0x0d02
+#define WCD934X_CDC_RX_INP_MUX_RX_INT_CFG1(i)          (0xd02 + i * 0x2)
+#define WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG0                    0x0d03
+#define WCD934X_CDC_RX_INP_MUX_RX_INT1_CFG1                    0x0d04
+#define WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG0                    0x0d05
+#define WCD934X_CDC_RX_INP_MUX_RX_INT2_CFG1                    0x0d06
+#define WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG0                    0x0d07
+#define WCD934X_CDC_RX_INP_MUX_RX_INT3_CFG1                    0x0d08
+#define WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG0                    0x0d09
+#define WCD934X_CDC_RX_INP_MUX_RX_INT4_CFG1                    0x0d0a
+#define WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG0                    0x0d0f
+#define WCD934X_CDC_RX_INP_MUX_RX_INT7_CFG1                    0x0d10
+#define WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG0                    0x0d11
+#define WCD934X_CDC_RX_INP_MUX_RX_INT8_CFG1                    0x0d12
+#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG0                     0x0d13
+#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG1                     0x0d14
+#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG2                     0x0d15
+#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG3                     0x0d16
+#define WCD934X_CDC_RX_INP_MUX_RX_MIX_CFG4                     0x0d17
+#define WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG0               0x0d18
+#define WCD934X_CDC_RX_INP_MUX_SIDETONE_SRC_CFG1               0x0d19
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG0                   0x0d1d
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX0_CFG1                   0x0d1e
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG0                   0x0d1f
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX1_CFG1                   0x0d20
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG0                   0x0d21
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX2_CFG1                   0x0d22
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG0                   0x0d23
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX3_CFG1                   0x0d25
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX4_CFG0                   0x0d26
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX5_CFG0                   0x0d27
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX6_CFG0                   0x0d28
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX7_CFG0                   0x0d29
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX8_CFG0                   0x0d2a
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX10_CFG0                  0x0d2b
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX11_CFG0                  0x0d2c
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX12_CFG0                  0x0d2d
+#define WCD934X_CDC_TX_INP_MUX_ADC_MUX13_CFG0                  0x0d2e
+#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG0         0x0d31
+#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG1         0x0d32
+#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG2         0x0d33
+#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR0_MIX_CFG3         0x0d34
+#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG0         0x0d35
+#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG1         0x0d36
+#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG2         0x0d37
+#define WCD934X_CDC_SIDETONE_IIR_INP_MUX_IIR1_MIX_CFG3         0x0d38
+#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG0                      0x0d3a
+#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG1                      0x0d3b
+#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG2                      0x0d3c
+#define WCD934X_CDC_IF_ROUTER_TX_MUX_CFG3                      0x0d3d
+#define WCD934X_CDC_CLK_RST_CTRL_MCLK_CONTROL                  0x0d41
+#define WCD934X_CDC_MCLK_EN_MASK                               BIT(0)
+#define WCD934X_CDC_MCLK_EN_ENABLE                             BIT(0)
+#define WCD934X_CDC_CLK_RST_CTRL_FS_CNT_CONTROL                        0x0d42
+#define WCD934X_CDC_FS_MCLK_CNT_EN_MASK                                BIT(0)
+#define WCD934X_CDC_FS_MCLK_CNT_ENABLE                         BIT(0)
+#define WCD934X_CDC_CLK_RST_CTRL_SWR_CONTROL                   0x0d43
+#define WCD934X_CDC_SWR_CLK_EN_MASK                            BIT(0)
+#define WCD934X_CDC_SWR_CLK_ENABLE                             BIT(0)
+#define WCD934X_CDC_CLK_RST_CTRL_DSD_CONTROL                   0x0d44
+#define WCD934X_CDC_CLK_RST_CTRL_ASRC_SHARE_CONTROL            0x0d45
+#define WCD934X_CDC_CLK_RST_CTRL_GFM_CONTROL                   0x0d46
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_PATH_CTL                 0x0d55
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B1_CTL              0x0d56
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B2_CTL              0x0d57
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B3_CTL              0x0d58
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B4_CTL              0x0d59
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B5_CTL              0x0d5a
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B6_CTL              0x0d5b
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B7_CTL              0x0d5c
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_B8_CTL              0x0d5d
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_CTL                      0x0d5e
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_GAIN_TIMER_CTL           0x0d5f
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B1_CTL              0x0d60
+#define WCD934X_CDC_SIDETONE_IIR0_IIR_COEF_B2_CTL              0x0d61
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_PATH_CTL                 0x0d65
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B1_CTL              0x0d66
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B2_CTL              0x0d67
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B3_CTL              0x0d68
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B4_CTL              0x0d69
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B5_CTL              0x0d6a
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B6_CTL              0x0d6b
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B7_CTL              0x0d6c
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_B8_CTL              0x0d6d
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_CTL                      0x0d6e
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_GAIN_TIMER_CTL           0x0d6f
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B1_CTL              0x0d70
+#define WCD934X_CDC_SIDETONE_IIR1_IIR_COEF_B2_CTL              0x0d71
+#define WCD934X_CDC_TOP_TOP_CFG1                               0x0d82
+#define WCD934X_CDC_TOP_TOP_CFG7                               0x0d88
+#define WCD934X_CDC_TOP_HPHL_COMP_LUT                          0x0d8b
+#define WCD934X_CDC_TOP_HPHR_COMP_LUT                          0x0d90
+#define WCD934X_HPH_LUT_BYPASS_MASK                            BIT(7)
+#define WCD934X_HPH_LUT_BYPASS_ENABLE                          BIT(7)
+#define WCD934X_HPH_LUT_BYPASS_DISABLE                         0
+#define WCD934X_CODEC_CPR_WR_DATA_0                            0x5001
+#define WCD934X_CODEC_CPR_WR_ADDR_0                            0x5005
+#define WCD934X_CODEC_CPR_SVS_CX_VDD                           0x5022
+#define WCD934X_CODEC_CPR_SVS2_CX_VDD                          0x5023
+#define WCD934X_CODEC_CPR_SVS2_MIN_CX_VDD                      0x5027
+#define WCD934X_TLMM_DMIC1_CLK_PINCFG                          0x8015
+#define WCD934X_TLMM_DMIC1_DATA_PINCFG                         0x8016
+#define WCD934X_TLMM_DMIC2_CLK_PINCFG                          0x8017
+#define WCD934X_TLMM_DMIC2_DATA_PINCFG                         0x8018
+#define WCD934X_TLMM_DMIC3_CLK_PINCFG                          0x8019
+#define WCD934X_TLMM_DMIC3_DATA_PINCFG                         0x801a
+#define WCD934X_TEST_DEBUG_PAD_DRVCTL_0                                0x803b
+#define WCD934X_TEST_DEBUG_NPL_DLY_TEST_1                      0x803e
+
+#define WCD934X_MAX_REGISTER                                   0xffff
+#define WCD934X_SEL_REGISTER                                   0x800
+#define WCD934X_SEL_MASK                                       0xff
+#define WCD934X_SEL_SHIFT                                      0x0
+#define WCD934X_WINDOW_START                                   0x800
+#define WCD934X_WINDOW_LENGTH                                  0x100
+
+/* SLIMBUS Slave Registers */
+#define WCD934X_SLIM_PGD_PORT_INT_EN0                          0x30
+#define WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_0                  0x34
+#define WCD934X_SLIM_PGD_PORT_INT_STATUS_RX_1                  0x35
+#define WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_0                  0x36
+#define WCD934X_SLIM_PGD_PORT_INT_STATUS_TX_1                  0x37
+#define WCD934X_SLIM_PGD_PORT_INT_CLR_RX_0                     0x38
+#define WCD934X_SLIM_PGD_PORT_INT_CLR_RX_1                     0x39
+#define WCD934X_SLIM_PGD_PORT_INT_CLR_TX_0                     0x3A
+#define WCD934X_SLIM_PGD_PORT_INT_CLR_TX_1                     0x3B
+#define WCD934X_SLIM_PGD_PORT_INT_RX_SOURCE0                   0x60
+#define WCD934X_SLIM_PGD_PORT_INT_TX_SOURCE0                   0x70
+#define WCD934X_SLIM_PGD_RX_PORT_CFG(p)                                (0x30 + p)
+#define WCD934X_SLIM_PGD_PORT_CFG(p)                           (0x40 + p)
+#define WCD934X_SLIM_PGD_TX_PORT_CFG(p)                                (0x50 + p)
+#define WCD934X_SLIM_PGD_PORT_INT_SRC(p)                       (0x60 + p)
+#define WCD934X_SLIM_PGD_PORT_INT_STATUS(p)                    (0x80 + p)
+#define WCD934X_SLIM_PGD_TX_PORT_MULTI_CHNL_0(p)               (0x100 + 4 * p)
+/* ports range from 10-16 */
+#define WCD934X_SLIM_PGD_TX_PORT_MULTI_CHNL_1(p)               (0x101 + 4 * p)
+#define WCD934X_SLIM_PGD_RX_PORT_MULTI_CHNL_0(p)               (0x140 + 4 * p)
+
+#define SLIM_MANF_ID_QCOM                      0x217
+#define SLIM_PROD_CODE_WCD9340                 0x250
+#define SLIM_DEV_IDX_WCD9340                   0x1
+#define SLIM_DEV_INSTANCE_ID_WCD9340           0
+
+#endif
diff --git a/include/linux/mfd/wcd934x/wcd934x.h b/include/linux/mfd/wcd934x/wcd934x.h
new file mode 100644 (file)
index 0000000..f3c65a0
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef __WCD934X_H__
+#define __WCD934X_H__
+#include <linux/clk.h>
+#include <linux/regulator/consumer.h>
+#include <linux/regmap.h>
+#include <linux/slimbus.h>
+
+#define WCD934X_MAX_SUPPLY     5
+
+/**
+ * struct wcd934x_ddata - wcd934x driver data
+ *
+ * @supplies:  wcd934x regulator supplies
+ * @irq_data:  wcd934x irq_chip data
+ * @regmap:    wcd934x regmap pointer
+ * @extclk:    External clock
+ * @dev:       device instance of wcd934x slim device
+ * @irq:       irq for wcd934x.
+ */
+struct wcd934x_ddata {
+       struct regulator_bulk_data supplies[WCD934X_MAX_SUPPLY];
+       struct regmap_irq_chip_data *irq_data;
+       struct regmap *regmap;
+       struct clk *extclk;
+       struct device *dev;
+       int irq;
+};
+
+#endif /* __WCD934X_H__ */
index 032cd66..ff8c9d5 100644 (file)
@@ -1448,14 +1448,15 @@ struct mlx5_ifc_cmd_hca_cap_bits {
 
        u8         reserved_at_440[0x20];
 
-       u8         tls[0x1];
-       u8         reserved_at_461[0x2];
+       u8         reserved_at_460[0x3];
        u8         log_max_uctx[0x5];
        u8         reserved_at_468[0x3];
        u8         log_max_umem[0x5];
        u8         max_num_eqs[0x10];
 
-       u8         reserved_at_480[0x3];
+       u8         reserved_at_480[0x1];
+       u8         tls_tx[0x1];
+       u8         reserved_at_482[0x1];
        u8         log_max_l2_table[0x5];
        u8         reserved_at_488[0x8];
        u8         log_uar_page_sz[0x10];
index 73a044e..52269e5 100644 (file)
@@ -2182,12 +2182,6 @@ extern int __meminit __early_pfn_to_nid(unsigned long pfn,
                                        struct mminit_pfnnid_cache *state);
 #endif
 
-#if !defined(CONFIG_FLAT_NODE_MEM_MAP)
-void zero_resv_unavail(void);
-#else
-static inline void zero_resv_unavail(void) {}
-#endif
-
 extern void set_dma_reserve(unsigned long new_dma_reserve);
 extern void memmap_init_zone(unsigned long, int, unsigned long, unsigned long,
                enum memmap_context, struct vmem_altmap *);
@@ -2535,6 +2529,8 @@ vm_fault_t vmf_insert_pfn_prot(struct vm_area_struct *vma, unsigned long addr,
                        unsigned long pfn, pgprot_t pgprot);
 vm_fault_t vmf_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
                        pfn_t pfn);
+vm_fault_t vmf_insert_mixed_prot(struct vm_area_struct *vma, unsigned long addr,
+                       pfn_t pfn, pgprot_t pgprot);
 vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma,
                unsigned long addr, pfn_t pfn);
 int vm_iomap_memory(struct vm_area_struct *vma, phys_addr_t start, unsigned long len);
index e87bb86..c28911c 100644 (file)
@@ -312,7 +312,12 @@ struct vm_area_struct {
        /* Second cache line starts here. */
 
        struct mm_struct *vm_mm;        /* The address space we belong to. */
-       pgprot_t vm_page_prot;          /* Access permissions of this VMA. */
+
+       /*
+        * Access permissions of this VMA.
+        * See vmf_insert_mixed_prot() for discussion.
+        */
+       pgprot_t vm_page_prot;
        unsigned long vm_flags;         /* Flags, see mm.h. */
 
        /*
index c2bc309..462f687 100644 (file)
@@ -1379,6 +1379,16 @@ static inline int pfn_present(unsigned long pfn)
        return present_section(__nr_to_section(pfn_to_section_nr(pfn)));
 }
 
+static inline unsigned long next_present_section_nr(unsigned long section_nr)
+{
+       while (++section_nr <= __highest_present_section_nr) {
+               if (present_section_nr(section_nr))
+                       return section_nr;
+       }
+
+       return -1;
+}
+
 /*
  * These are _only_ used during initialisation, therefore they
  * can use __initdata ...  They could have names to indicate
index c06b1fd..a5f8f03 100644 (file)
@@ -168,6 +168,9 @@ struct nfs_inode {
        struct rw_semaphore     rmdir_sem;
        struct mutex            commit_mutex;
 
+       /* track last access to cached pages */
+       unsigned long           page_index;
+
 #if IS_ENABLED(CONFIG_NFS_V4)
        struct nfs4_cached_acl  *nfs4_acl;
         /* NFSv4 state */
index c176f70..465fa98 100644 (file)
@@ -152,6 +152,7 @@ struct nfs_server {
 #define NFS_MOUNT_LOCAL_FLOCK          0x100000
 #define NFS_MOUNT_LOCAL_FCNTL          0x200000
 #define NFS_MOUNT_SOFTERR              0x400000
+#define NFS_MOUNT_SOFTREVAL            0x800000
 
        unsigned int            caps;           /* server capabilities */
        unsigned int            rsize;          /* read size */
index 72d5695..94c77ed 100644 (file)
@@ -1639,6 +1639,7 @@ struct nfs_subversion;
 struct nfs_mount_info;
 struct nfs_client_initdata;
 struct nfs_pageio_descriptor;
+struct fs_context;
 
 /*
  * RPC procedure vector for NFSv2/NFSv3 demuxing
@@ -1653,16 +1654,14 @@ struct nfs_rpc_ops {
 
        int     (*getroot) (struct nfs_server *, struct nfs_fh *,
                            struct nfs_fsinfo *);
-       struct vfsmount *(*submount) (struct nfs_server *, struct dentry *,
-                                     struct nfs_fh *, struct nfs_fattr *);
-       struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *,
-                                    struct nfs_subversion *);
+       int     (*submount) (struct fs_context *, struct nfs_server *);
+       int     (*try_get_tree) (struct fs_context *);
        int     (*getattr) (struct nfs_server *, struct nfs_fh *,
                            struct nfs_fattr *, struct nfs4_label *,
                            struct inode *);
        int     (*setattr) (struct dentry *, struct nfs_fattr *,
                            struct iattr *);
-       int     (*lookup)  (struct inode *, const struct qstr *,
+       int     (*lookup)  (struct inode *, struct dentry *,
                            struct nfs_fh *, struct nfs_fattr *,
                            struct nfs4_label *);
        int     (*lookupp) (struct inode *, struct nfs_fh *,
@@ -1723,7 +1722,7 @@ struct nfs_rpc_ops {
        struct nfs_client *(*init_client) (struct nfs_client *,
                                const struct nfs_client_initdata *);
        void    (*free_client) (struct nfs_client *);
-       struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *);
+       struct nfs_server *(*create_server)(struct fs_context *);
        struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *,
                                           struct nfs_fattr *, rpc_authflavor_t);
 };
index fe05132..6d6f8e5 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <linux/err.h>
 #include <linux/errno.h>
+#include <linux/gpio/consumer.h>
 
 struct nvmem_device;
 struct nvmem_cell_info;
@@ -45,6 +46,7 @@ enum nvmem_type {
  * @word_size: Minimum read/write access granularity.
  * @stride:    Minimum read/write access stride.
  * @priv:      User context passed to read/write callbacks.
+ * @wp-gpio:   Write protect pin
  *
  * Note: A default "nvmem<id>" name will be assigned to the device if
  * no name is specified in its configuration. In such case "<id>" is
@@ -58,6 +60,7 @@ struct nvmem_config {
        const char              *name;
        int                     id;
        struct module           *owner;
+       struct gpio_desc        *wp_gpio;
        const struct nvmem_cell_info    *cells;
        int                     ncells;
        enum nvmem_type         type;
index 844f89e..c669c0a 100644 (file)
@@ -351,6 +351,8 @@ extern const void *of_get_property(const struct device_node *node,
                                int *lenp);
 extern struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
 extern struct device_node *of_get_next_cpu_node(struct device_node *prev);
+extern struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
+                                                int index);
 
 #define for_each_property_of_node(dn, pp) \
        for (pp = dn->properties; pp != NULL; pp = pp->next)
@@ -765,6 +767,12 @@ static inline struct device_node *of_get_next_cpu_node(struct device_node *prev)
        return NULL;
 }
 
+static inline struct device_node *of_get_cpu_state_node(struct device_node *cpu_node,
+                                       int index)
+{
+       return NULL;
+}
+
 static inline int of_n_addr_cells(struct device_node *np)
 {
        return 0;
index b27da9f..c86fcad 100644 (file)
@@ -6,6 +6,9 @@
 #ifndef __LINUX_OF_CLK_H
 #define __LINUX_OF_CLK_H
 
+struct device_node;
+struct of_device_id;
+
 #if defined(CONFIG_COMMON_CLK) && defined(CONFIG_OF)
 
 unsigned int of_clk_get_parent_count(struct device_node *np);
index ba3cfbb..5c5c93a 100644 (file)
 #define IS_WORD_16                     BIT(0xd)
 #define ENABLE_16XX_MODE               BIT(0xe)
 #define HS_CHANNELS_RESERVED           BIT(0xf)
-#define DMA_ENGINE_HANDLE_IRQ          BIT(0x10)
 
 /* Defines for DMA Capabilities */
 #define DMA_HAS_TRANSPARENT_CAPS       (0x1 << 18)
@@ -239,9 +238,6 @@ struct omap_dma_lch {
        void (*callback)(int lch, u16 ch_status, void *data);
        void *data;
        long flags;
-       /* required for Dynamic chaining */
-       int prev_linked_ch;
-       int next_linked_ch;
        int state;
        int chain_id;
        int status;
@@ -303,7 +299,6 @@ extern void omap_set_dma_priority(int lch, int dst_port, int priority);
 extern int omap_request_dma(int dev_id, const char *dev_name,
                        void (*callback)(int lch, u16 ch_status, void *data),
                        void *data, int *dma_ch);
-extern void omap_enable_dma_irq(int ch, u16 irq_bits);
 extern void omap_disable_dma_irq(int ch, u16 irq_bits);
 extern void omap_free_dma(int ch);
 extern void omap_start_dma(int lch);
@@ -312,7 +307,6 @@ extern void omap_set_dma_transfer_params(int lch, int data_type,
                                         int elem_count, int frame_count,
                                         int sync_mode,
                                         int dma_trigger, int src_or_dst_synch);
-extern void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode);
 extern void omap_set_dma_channel_mode(int lch, enum omap_dma_channel_mode mode);
 
 extern void omap_set_dma_src_params(int lch, int src_port, int src_amode,
@@ -329,22 +323,10 @@ extern void omap_set_dma_dest_data_pack(int lch, int enable);
 extern void omap_set_dma_dest_burst_mode(int lch,
                                         enum omap_dma_burst_mode burst_mode);
 
-extern void omap_set_dma_params(int lch,
-                               struct omap_dma_channel_params *params);
-
-extern void omap_dma_link_lch(int lch_head, int lch_queue);
-
-extern int omap_set_dma_callback(int lch,
-                       void (*callback)(int lch, u16 ch_status, void *data),
-                       void *data);
 extern dma_addr_t omap_get_dma_src_pos(int lch);
 extern dma_addr_t omap_get_dma_dst_pos(int lch);
 extern int omap_get_dma_active_status(int lch);
 extern int omap_dma_running(void);
-extern void omap_dma_set_global_params(int arb_rate, int max_fifo_depth,
-                                      int tparams);
-void omap_dma_global_context_save(void);
-void omap_dma_global_context_restore(void);
 
 #if defined(CONFIG_ARCH_OMAP1) && IS_ENABLED(CONFIG_FB_OMAP)
 #include <mach/lcd_dma.h>
index 6ec82e9..b1cb6b7 100644 (file)
@@ -8,16 +8,19 @@ struct mm_walk;
 
 /**
  * mm_walk_ops - callbacks for walk_page_range
- * @pud_entry:         if set, called for each non-empty PUD (2nd-level) entry
- *                     this handler should only handle pud_trans_huge() puds.
- *                     the pmd_entry or pte_entry callbacks will be used for
- *                     regular PUDs.
- * @pmd_entry:         if set, called for each non-empty PMD (3rd-level) entry
+ * @pgd_entry:         if set, called for each non-empty PGD (top-level) entry
+ * @p4d_entry:         if set, called for each non-empty P4D entry
+ * @pud_entry:         if set, called for each non-empty PUD entry
+ * @pmd_entry:         if set, called for each non-empty PMD entry
  *                     this handler is required to be able to handle
  *                     pmd_trans_huge() pmds.  They may simply choose to
  *                     split_huge_page() instead of handling it explicitly.
- * @pte_entry:         if set, called for each non-empty PTE (4th-level) entry
- * @pte_hole:          if set, called for each hole at all levels
+ * @pte_entry:         if set, called for each non-empty PTE (lowest-level)
+ *                     entry
+ * @pte_hole:          if set, called for each hole at all levels,
+ *                     depth is -1 if not known, 0:PGD, 1:P4D, 2:PUD, 3:PMD
+ *                     4:PTE. Any folded depths (where PTRS_PER_P?D is equal
+ *                     to 1) are skipped.
  * @hugetlb_entry:     if set, called for each hugetlb entry
  * @test_walk:         caller specific callback function to determine whether
  *                     we walk over the current vma or not. Returning 0 means
@@ -27,8 +30,15 @@ struct mm_walk;
  * @pre_vma:            if set, called before starting walk on a non-null vma.
  * @post_vma:           if set, called after a walk on a non-null vma, provided
  *                      that @pre_vma and the vma walk succeeded.
+ *
+ * p?d_entry callbacks are called even if those levels are folded on a
+ * particular architecture/configuration.
  */
 struct mm_walk_ops {
+       int (*pgd_entry)(pgd_t *pgd, unsigned long addr,
+                        unsigned long next, struct mm_walk *walk);
+       int (*p4d_entry)(p4d_t *p4d, unsigned long addr,
+                        unsigned long next, struct mm_walk *walk);
        int (*pud_entry)(pud_t *pud, unsigned long addr,
                         unsigned long next, struct mm_walk *walk);
        int (*pmd_entry)(pmd_t *pmd, unsigned long addr,
@@ -36,7 +46,7 @@ struct mm_walk_ops {
        int (*pte_entry)(pte_t *pte, unsigned long addr,
                         unsigned long next, struct mm_walk *walk);
        int (*pte_hole)(unsigned long addr, unsigned long next,
-                       struct mm_walk *walk);
+                       int depth, struct mm_walk *walk);
        int (*hugetlb_entry)(pte_t *pte, unsigned long hmask,
                             unsigned long addr, unsigned long next,
                             struct mm_walk *walk);
@@ -47,11 +57,27 @@ struct mm_walk_ops {
        void (*post_vma)(struct mm_walk *walk);
 };
 
+/*
+ * Action for pud_entry / pmd_entry callbacks.
+ * ACTION_SUBTREE is the default
+ */
+enum page_walk_action {
+       /* Descend to next level, splitting huge pages if needed and possible */
+       ACTION_SUBTREE = 0,
+       /* Continue to next entry at this level (ignoring any subtree) */
+       ACTION_CONTINUE = 1,
+       /* Call again for this entry */
+       ACTION_AGAIN = 2
+};
+
 /**
  * mm_walk - walk_page_range data
  * @ops:       operation to call during the walk
  * @mm:                mm_struct representing the target process of page table walk
+ * @pgd:       pointer to PGD; only valid with no_vma (otherwise set to NULL)
  * @vma:       vma currently walked (NULL if walking outside vmas)
+ * @action:    next action to perform (see enum page_walk_action)
+ * @no_vma:    walk ignoring vmas (vma will always be NULL)
  * @private:   private data for callbacks' usage
  *
  * (see the comment on walk_page_range() for more details)
@@ -59,13 +85,20 @@ struct mm_walk_ops {
 struct mm_walk {
        const struct mm_walk_ops *ops;
        struct mm_struct *mm;
+       pgd_t *pgd;
        struct vm_area_struct *vma;
+       enum page_walk_action action;
+       bool no_vma;
        void *private;
 };
 
 int walk_page_range(struct mm_struct *mm, unsigned long start,
                unsigned long end, const struct mm_walk_ops *ops,
                void *private);
+int walk_page_range_novma(struct mm_struct *mm, unsigned long start,
+                         unsigned long end, const struct mm_walk_ops *ops,
+                         pgd_t *pgd,
+                         void *private);
 int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops,
                void *private);
 int walk_page_mapping(struct address_space *mapping, pgoff_t first_index,
index 5d62e78..d08f086 100644 (file)
@@ -33,6 +33,9 @@ void pci_disable_pasid(struct pci_dev *pdev);
 int pci_pasid_features(struct pci_dev *pdev);
 int pci_max_pasids(struct pci_dev *pdev);
 #else /* CONFIG_PCI_PASID */
+static inline int pci_enable_pasid(struct pci_dev *pdev, int features)
+{ return -EINVAL; }
+static inline void pci_disable_pasid(struct pci_dev *pdev) { }
 static inline int pci_pasid_features(struct pci_dev *pdev)
 { return -EINVAL; }
 static inline int pci_max_pasids(struct pci_dev *pdev)
index a6fabd8..176bfbd 100644 (file)
  * Declaration/definition used for per-CPU variables that should be accessed
  * as decrypted when memory encryption is enabled in the guest.
  */
-#if defined(CONFIG_VIRTUALIZATION) && defined(CONFIG_AMD_MEM_ENCRYPT)
-
+#ifdef CONFIG_AMD_MEM_ENCRYPT
 #define DECLARE_PER_CPU_DECRYPTED(type, name)                          \
        DECLARE_PER_CPU_SECTION(type, name, "..decrypted")
 
index 6d4c22a..547773f 100644 (file)
@@ -582,7 +582,7 @@ struct swevent_hlist {
 #define PERF_ATTACH_ITRACE     0x10
 
 struct perf_cgroup;
-struct ring_buffer;
+struct perf_buffer;
 
 struct pmu_event_list {
        raw_spinlock_t          lock;
@@ -694,7 +694,7 @@ struct perf_event {
        struct mutex                    mmap_mutex;
        atomic_t                        mmap_count;
 
-       struct ring_buffer              *rb;
+       struct perf_buffer              *rb;
        struct list_head                rb_entry;
        unsigned long                   rcu_batches;
        int                             rcu_pending;
@@ -854,7 +854,7 @@ struct perf_cpu_context {
 
 struct perf_output_handle {
        struct perf_event               *event;
-       struct ring_buffer              *rb;
+       struct perf_buffer              *rb;
        unsigned long                   wakeup;
        unsigned long                   size;
        u64                             aux_flags;
@@ -1544,4 +1544,8 @@ int perf_event_exit_cpu(unsigned int cpu);
 #define perf_event_exit_cpu    NULL
 #endif
 
+extern void __weak arch_perf_update_userpage(struct perf_event *event,
+                                            struct perf_event_mmap_page *userpg,
+                                            u64 now);
+
 #endif /* _LINUX_PERF_EVENT_H */
index dbcfa68..d576503 100644 (file)
@@ -47,7 +47,7 @@ struct pipe_buffer {
  **/
 struct pipe_inode_info {
        struct mutex mutex;
-       wait_queue_head_t wait;
+       wait_queue_head_t rd_wait, wr_wait;
        unsigned int head;
        unsigned int tail;
        unsigned int max_usage;
index c3b61ea..6f6fed2 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef __B53_H
 #define __B53_H
 
-#include <linux/kernel.h>
+#include <linux/types.h>
 #include <linux/platform_data/dsa.h>
 
 struct b53_platform_data {
index 3bd0190..54a06a4 100644 (file)
@@ -9,7 +9,6 @@ struct device;
 
 struct bd6107_platform_data {
        struct device *fbdev;
-       int reset;                      /* Reset GPIO */
        unsigned int def_value;
 };
 
index 30098a5..ba59147 100644 (file)
@@ -12,7 +12,6 @@
 #include <linux/mutex.h>
 #include <linux/notifier.h>
 
-#include <linux/mfd/cros_ec.h>
 #include <linux/platform_data/cros_ec_commands.h>
 
 #define CROS_EC_DEV_NAME       "cros_ec"
@@ -185,9 +184,27 @@ struct cros_ec_platform {
        u16 cmd_offset;
 };
 
-int cros_ec_suspend(struct cros_ec_device *ec_dev);
+/**
+ * struct cros_ec_dev - ChromeOS EC device entry point.
+ * @class_dev: Device structure used in sysfs.
+ * @ec_dev: cros_ec_device structure to talk to the physical device.
+ * @dev: Pointer to the platform device.
+ * @debug_info: cros_ec_debugfs structure for debugging information.
+ * @has_kb_wake_angle: True if at least 2 accelerometer are connected to the EC.
+ * @cmd_offset: Offset to apply for each command.
+ * @features: Features supported by the EC.
+ */
+struct cros_ec_dev {
+       struct device class_dev;
+       struct cros_ec_device *ec_dev;
+       struct device *dev;
+       struct cros_ec_debugfs *debug_info;
+       bool has_kb_wake_angle;
+       u16 cmd_offset;
+       u32 features[2];
+};
 
-int cros_ec_resume(struct cros_ec_device *ec_dev);
+#define to_cros_ec_dev(dev)  container_of(dev, struct cros_ec_dev, class_dev)
 
 int cros_ec_prepare_tx(struct cros_ec_device *ec_dev,
                       struct cros_ec_command *msg);
@@ -201,10 +218,6 @@ int cros_ec_cmd_xfer(struct cros_ec_device *ec_dev,
 int cros_ec_cmd_xfer_status(struct cros_ec_device *ec_dev,
                            struct cros_ec_command *msg);
 
-int cros_ec_register(struct cros_ec_device *ec_dev);
-
-int cros_ec_unregister(struct cros_ec_device *ec_dev);
-
 int cros_ec_query_all(struct cros_ec_device *ec_dev);
 
 int cros_ec_get_next_event(struct cros_ec_device *ec_dev,
@@ -217,8 +230,6 @@ int cros_ec_check_features(struct cros_ec_dev *ec, int feature);
 
 int cros_ec_get_sensor_count(struct cros_ec_dev *ec);
 
-bool cros_ec_handle_event(struct cros_ec_device *ec_dev);
-
 /**
  * cros_ec_get_time_ns() - Return time in ns.
  *
index 84789ca..ea1cc6d 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef __MICROCHIP_KSZ_H
 #define __MICROCHIP_KSZ_H
 
-#include <linux/kernel.h>
+#include <linux/types.h>
 
 struct ksz_platform_data {
        u32 chip_id;
index 8cfe570..2cbde65 100644 (file)
@@ -49,6 +49,7 @@ struct sysc_regbits {
        s8 emufree_shift;
 };
 
+#define SYSC_QUIRK_CLKDM_NOAUTO                BIT(21)
 #define SYSC_QUIRK_FORCE_MSTANDBY      BIT(20)
 #define SYSC_MODULE_QUIRK_AESS         BIT(19)
 #define SYSC_MODULE_QUIRK_SGX          BIT(18)
index 5a31c71..9ec78ee 100644 (file)
@@ -284,6 +284,8 @@ void of_genpd_del_provider(struct device_node *np);
 int of_genpd_add_device(struct of_phandle_args *args, struct device *dev);
 int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
                           struct of_phandle_args *subdomain_spec);
+int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
+                             struct of_phandle_args *subdomain_spec);
 struct generic_pm_domain *of_genpd_remove_last(struct device_node *np);
 int of_genpd_parse_idle_states(struct device_node *dn,
                               struct genpd_power_state **states, int *n);
@@ -322,6 +324,12 @@ static inline int of_genpd_add_subdomain(struct of_phandle_args *parent_spec,
        return -ENODEV;
 }
 
+static inline int of_genpd_remove_subdomain(struct of_phandle_args *parent_spec,
+                                       struct of_phandle_args *subdomain_spec)
+{
+       return -ENODEV;
+}
+
 static inline int of_genpd_parse_idle_states(struct device_node *dn,
                        struct genpd_power_state **states, int *n)
 {
index 0640be5..3dfa926 100644 (file)
@@ -12,6 +12,21 @@ struct proc_dir_entry;
 struct seq_file;
 struct seq_operations;
 
+struct proc_ops {
+       int     (*proc_open)(struct inode *, struct file *);
+       ssize_t (*proc_read)(struct file *, char __user *, size_t, loff_t *);
+       ssize_t (*proc_write)(struct file *, const char __user *, size_t, loff_t *);
+       loff_t  (*proc_lseek)(struct file *, loff_t, int);
+       int     (*proc_release)(struct inode *, struct file *);
+       __poll_t (*proc_poll)(struct file *, struct poll_table_struct *);
+       long    (*proc_ioctl)(struct file *, unsigned int, unsigned long);
+#ifdef CONFIG_COMPAT
+       long    (*proc_compat_ioctl)(struct file *, unsigned int, unsigned long);
+#endif
+       int     (*proc_mmap)(struct file *, struct vm_area_struct *);
+       unsigned long (*proc_get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
+};
+
 #ifdef CONFIG_PROC_FS
 
 typedef int (*proc_write_t)(struct file *, char *, size_t);
@@ -43,10 +58,10 @@ struct proc_dir_entry *proc_create_single_data(const char *name, umode_t mode,
  
 extern struct proc_dir_entry *proc_create_data(const char *, umode_t,
                                               struct proc_dir_entry *,
-                                              const struct file_operations *,
+                                              const struct proc_ops *,
                                               void *);
 
-struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct file_operations *proc_fops);
+struct proc_dir_entry *proc_create(const char *name, umode_t mode, struct proc_dir_entry *parent, const struct proc_ops *proc_ops);
 extern void proc_set_size(struct proc_dir_entry *, loff_t);
 extern void proc_set_user(struct proc_dir_entry *, kuid_t, kgid_t);
 extern void *PDE_DATA(const struct inode *);
@@ -108,8 +123,8 @@ static inline struct proc_dir_entry *proc_mkdir_mode(const char *name,
 #define proc_create_seq(name, mode, parent, ops) ({NULL;})
 #define proc_create_single(name, mode, parent, show) ({NULL;})
 #define proc_create_single_data(name, mode, parent, show, data) ({NULL;})
-#define proc_create(name, mode, parent, proc_fops) ({NULL;})
-#define proc_create_data(name, mode, parent, proc_fops, data) ({NULL;})
+#define proc_create(name, mode, parent, proc_ops) ({NULL;})
+#define proc_create_data(name, mode, parent, proc_ops, data) ({NULL;})
 
 static inline void proc_set_size(struct proc_dir_entry *de, loff_t size) {}
 static inline void proc_set_user(struct proc_dir_entry *de, kuid_t uid, kgid_t gid) {}
index ebe0a88..a67712b 100644 (file)
@@ -18,6 +18,8 @@ bool psci_tos_resident_on(int cpu);
 
 int psci_cpu_suspend_enter(u32 state);
 bool psci_power_state_is_valid(u32 state);
+int psci_set_osi_mode(void);
+bool psci_has_osi_support(void);
 
 enum smccc_version {
        SMCCC_VERSION_1_0,
diff --git a/include/linux/ptdump.h b/include/linux/ptdump.h
new file mode 100644 (file)
index 0000000..a67065c
--- /dev/null
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+
+#ifndef _LINUX_PTDUMP_H
+#define _LINUX_PTDUMP_H
+
+#include <linux/mm_types.h>
+
+struct ptdump_range {
+       unsigned long start;
+       unsigned long end;
+};
+
+struct ptdump_state {
+       /* level is 0:PGD to 4:PTE, or -1 if unknown */
+       void (*note_page)(struct ptdump_state *st, unsigned long addr,
+                         int level, unsigned long val);
+       const struct ptdump_range *range;
+};
+
+void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd);
+
+#endif /* _LINUX_PTDUMP_H */
index d05ddac..3d6a246 100644 (file)
@@ -1,5 +1,5 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2010-2015, 2018, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2010-2015, 2018-2019 The Linux Foundation. All rights reserved.
  * Copyright (C) 2015 Linaro Ltd.
  */
 #ifndef __QCOM_SCM_H
@@ -55,77 +55,94 @@ enum qcom_scm_sec_dev_id {
 #define QCOM_SCM_PERM_RWX (QCOM_SCM_PERM_RW | QCOM_SCM_PERM_EXEC)
 
 #if IS_ENABLED(CONFIG_QCOM_SCM)
+extern bool qcom_scm_is_available(void);
+
 extern int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus);
 extern int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus);
-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 void qcom_scm_cpu_power_down(u32 flags);
+extern int qcom_scm_set_remote_state(u32 state, u32 id);
+
 extern int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
                                   size_t size);
 extern int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
                                  phys_addr_t size);
 extern int qcom_scm_pas_auth_and_reset(u32 peripheral);
 extern int qcom_scm_pas_shutdown(u32 peripheral);
-extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
-                              unsigned int *src,
-                              const struct qcom_scm_vmperm *newvm,
-                              unsigned int dest_cnt);
-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_pas_supported(u32 peripheral);
+
+extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
+extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
+
 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);
+extern int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
+                              unsigned int *src,
+                              const struct qcom_scm_vmperm *newvm,
+                              unsigned int dest_cnt);
+
+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_hdcp_available(void);
+extern int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
+                            u32 *resp);
+
 extern int qcom_scm_qsmmu500_wait_safe_toggle(bool en);
-extern int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val);
-extern int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
 #else
 
 #include <linux/errno.h>
 
-static inline
-int qcom_scm_set_cold_boot_addr(void *entry, const cpumask_t *cpus)
-{
-       return -ENODEV;
-}
-static inline
-int qcom_scm_set_warm_boot_addr(void *entry, const cpumask_t *cpus)
-{
-       return -ENODEV;
-}
 static inline bool qcom_scm_is_available(void) { return false; }
-static inline bool qcom_scm_hdcp_available(void) { return false; }
-static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
-                                   u32 *resp) { return -ENODEV; }
-static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; }
+
+static inline int qcom_scm_set_cold_boot_addr(void *entry,
+               const cpumask_t *cpus) { return -ENODEV; }
+static inline int qcom_scm_set_warm_boot_addr(void *entry,
+               const cpumask_t *cpus) { return -ENODEV; }
+static inline void qcom_scm_cpu_power_down(u32 flags) {}
+static inline u32 qcom_scm_set_remote_state(u32 state,u32 id)
+               { return -ENODEV; }
+
 static inline int qcom_scm_pas_init_image(u32 peripheral, const void *metadata,
-                                         size_t size) { return -ENODEV; }
+               size_t size) { return -ENODEV; }
 static inline int qcom_scm_pas_mem_setup(u32 peripheral, phys_addr_t addr,
-                                        phys_addr_t size) { return -ENODEV; }
-static inline int
-qcom_scm_pas_auth_and_reset(u32 peripheral) { return -ENODEV; }
+               phys_addr_t size) { return -ENODEV; }
+static inline int qcom_scm_pas_auth_and_reset(u32 peripheral)
+               { return -ENODEV; }
 static inline int qcom_scm_pas_shutdown(u32 peripheral) { return -ENODEV; }
+static inline bool qcom_scm_pas_supported(u32 peripheral) { return false; }
+
+static inline int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val)
+               { return -ENODEV; }
+static inline int qcom_scm_io_writel(phys_addr_t addr, unsigned int val)
+               { return -ENODEV; }
+
+static inline bool qcom_scm_restore_sec_cfg_available(void) { return false; }
+static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare)
+               { return -ENODEV; }
+static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size)
+               { return -ENODEV; }
+static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare)
+               { return -ENODEV; }
 static inline int qcom_scm_assign_mem(phys_addr_t mem_addr, size_t mem_sz,
-                                     unsigned int *src,
-                                     const struct qcom_scm_vmperm *newvm,
-                                     unsigned int dest_cnt) { return -ENODEV; }
-static inline void qcom_scm_cpu_power_down(u32 flags) {}
-static inline u32 qcom_scm_get_version(void) { return 0; }
-static inline u32
-qcom_scm_set_remote_state(u32 state,u32 id) { return -ENODEV; }
-static inline int qcom_scm_restore_sec_cfg(u32 device_id, u32 spare) { return -ENODEV; }
-static inline int qcom_scm_iommu_secure_ptbl_size(u32 spare, size_t *size) { return -ENODEV; }
-static inline int qcom_scm_iommu_secure_ptbl_init(u64 addr, u32 size, u32 spare) { return -ENODEV; }
-static inline int qcom_scm_qsmmu500_wait_safe_toggle(bool en) { return -ENODEV; }
-static inline int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val) { return -ENODEV; }
-static inline int qcom_scm_io_writel(phys_addr_t addr, unsigned int val) { return -ENODEV; }
+               unsigned int *src, const struct qcom_scm_vmperm *newvm,
+               unsigned int dest_cnt) { return -ENODEV; }
+
+static inline bool qcom_scm_ocmem_lock_available(void) { return false; }
+static inline int qcom_scm_ocmem_lock(enum qcom_scm_ocmem_client id, u32 offset,
+               u32 size, u32 mode) { return -ENODEV; }
+static inline int qcom_scm_ocmem_unlock(enum qcom_scm_ocmem_client id,
+               u32 offset, u32 size) { return -ENODEV; }
+
+static inline bool qcom_scm_hdcp_available(void) { return false; }
+static inline int qcom_scm_hdcp_req(struct qcom_scm_hdcp_req *req, u32 req_cnt,
+               u32 *resp) { return -ENODEV; }
+
+static inline int qcom_scm_qsmmu500_wait_safe_toggle(bool en)
+               { return -ENODEV; }
 #endif
 #endif
index b806a0f..917528d 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef _LINUX_RAMFS_H
 #define _LINUX_RAMFS_H
 
+#include <linux/fs_parser.h> // bleh...
+
 struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir,
         umode_t mode, dev_t dev);
 extern int ramfs_init_fs_context(struct fs_context *fc);
@@ -16,7 +18,7 @@ ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize)
 extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize);
 #endif
 
-extern const struct fs_parameter_description ramfs_fs_parameters;
+extern const struct fs_parameter_spec ramfs_fs_parameters[];
 extern const struct file_operations ramfs_file_operations;
 extern const struct vm_operations_struct generic_file_vm_ops;
 
diff --git a/include/linux/remoteproc/mtk_scp.h b/include/linux/remoteproc/mtk_scp.h
new file mode 100644 (file)
index 0000000..b47416f
--- /dev/null
@@ -0,0 +1,66 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright (c) 2019 MediaTek Inc.
+ */
+
+#ifndef _MTK_SCP_H
+#define _MTK_SCP_H
+
+#include <linux/platform_device.h>
+
+typedef void (*scp_ipi_handler_t) (void *data,
+                                  unsigned int len,
+                                  void *priv);
+struct mtk_scp;
+
+/**
+ * enum ipi_id - the id of inter-processor interrupt
+ *
+ * @SCP_IPI_INIT:       The interrupt from scp is to notfiy kernel
+ *                      SCP initialization completed.
+ *                      IPI_SCP_INIT is sent from SCP when firmware is
+ *                      loaded. AP doesn't need to send IPI_SCP_INIT
+ *                      command to SCP.
+ *                      For other IPI below, AP should send the request
+ *                      to SCP to trigger the interrupt.
+ * @SCP_IPI_MAX:        The maximum IPI number
+ */
+
+enum scp_ipi_id {
+       SCP_IPI_INIT = 0,
+       SCP_IPI_VDEC_H264,
+       SCP_IPI_VDEC_VP8,
+       SCP_IPI_VDEC_VP9,
+       SCP_IPI_VENC_H264,
+       SCP_IPI_VENC_VP8,
+       SCP_IPI_MDP_INIT,
+       SCP_IPI_MDP_DEINIT,
+       SCP_IPI_MDP_FRAME,
+       SCP_IPI_DIP,
+       SCP_IPI_ISP_CMD,
+       SCP_IPI_ISP_FRAME,
+       SCP_IPI_FD_CMD,
+       SCP_IPI_CROS_HOST_CMD,
+       SCP_IPI_NS_SERVICE = 0xFF,
+       SCP_IPI_MAX = 0x100,
+};
+
+struct mtk_scp *scp_get(struct platform_device *pdev);
+void scp_put(struct mtk_scp *scp);
+
+struct device *scp_get_device(struct mtk_scp *scp);
+struct rproc *scp_get_rproc(struct mtk_scp *scp);
+
+int scp_ipi_register(struct mtk_scp *scp, u32 id, scp_ipi_handler_t handler,
+                    void *priv);
+void scp_ipi_unregister(struct mtk_scp *scp, u32 id);
+
+int scp_ipi_send(struct mtk_scp *scp, u32 id, void *buf, unsigned int len,
+                unsigned int wait);
+
+unsigned int scp_get_vdec_hw_capa(struct mtk_scp *scp);
+unsigned int scp_get_venc_hw_capa(struct mtk_scp *scp);
+
+void *scp_mapping_dm_addr(struct mtk_scp *scp, u32 mem_addr);
+
+#endif /* _MTK_SCP_H */
index 1a40277..df0124e 100644 (file)
@@ -6,7 +6,7 @@
 #include <linux/seq_file.h>
 #include <linux/poll.h>
 
-struct ring_buffer;
+struct trace_buffer;
 struct ring_buffer_iter;
 
 /*
@@ -77,13 +77,13 @@ u64 ring_buffer_event_time_stamp(struct ring_buffer_event *event);
  *  else
  *    ring_buffer_unlock_commit(buffer, event);
  */
-void ring_buffer_discard_commit(struct ring_buffer *buffer,
+void ring_buffer_discard_commit(struct trace_buffer *buffer,
                                struct ring_buffer_event *event);
 
 /*
  * size is in bytes for each per CPU buffer.
  */
-struct ring_buffer *
+struct trace_buffer *
 __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *key);
 
 /*
@@ -97,38 +97,38 @@ __ring_buffer_alloc(unsigned long size, unsigned flags, struct lock_class_key *k
        __ring_buffer_alloc((size), (flags), &__key);   \
 })
 
-int ring_buffer_wait(struct ring_buffer *buffer, int cpu, int full);
-__poll_t ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
+int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full);
+__poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
                          struct file *filp, poll_table *poll_table);
 
 
 #define RING_BUFFER_ALL_CPUS -1
 
-void ring_buffer_free(struct ring_buffer *buffer);
+void ring_buffer_free(struct trace_buffer *buffer);
 
-int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size, int cpu);
+int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size, int cpu);
 
-void ring_buffer_change_overwrite(struct ring_buffer *buffer, int val);
+void ring_buffer_change_overwrite(struct trace_buffer *buffer, int val);
 
-struct ring_buffer_event *ring_buffer_lock_reserve(struct ring_buffer *buffer,
+struct ring_buffer_event *ring_buffer_lock_reserve(struct trace_buffer *buffer,
                                                   unsigned long length);
-int ring_buffer_unlock_commit(struct ring_buffer *buffer,
+int ring_buffer_unlock_commit(struct trace_buffer *buffer,
                              struct ring_buffer_event *event);
-int ring_buffer_write(struct ring_buffer *buffer,
+int ring_buffer_write(struct trace_buffer *buffer,
                      unsigned long length, void *data);
 
-void ring_buffer_nest_start(struct ring_buffer *buffer);
-void ring_buffer_nest_end(struct ring_buffer *buffer);
+void ring_buffer_nest_start(struct trace_buffer *buffer);
+void ring_buffer_nest_end(struct trace_buffer *buffer);
 
 struct ring_buffer_event *
-ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts,
+ring_buffer_peek(struct trace_buffer *buffer, int cpu, u64 *ts,
                 unsigned long *lost_events);
 struct ring_buffer_event *
-ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
+ring_buffer_consume(struct trace_buffer *buffer, int cpu, u64 *ts,
                    unsigned long *lost_events);
 
 struct ring_buffer_iter *
-ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu, gfp_t flags);
+ring_buffer_read_prepare(struct trace_buffer *buffer, int cpu, gfp_t flags);
 void ring_buffer_read_prepare_sync(void);
 void ring_buffer_read_start(struct ring_buffer_iter *iter);
 void ring_buffer_read_finish(struct ring_buffer_iter *iter);
@@ -140,59 +140,59 @@ ring_buffer_read(struct ring_buffer_iter *iter, u64 *ts);
 void ring_buffer_iter_reset(struct ring_buffer_iter *iter);
 int ring_buffer_iter_empty(struct ring_buffer_iter *iter);
 
-unsigned long ring_buffer_size(struct ring_buffer *buffer, int cpu);
+unsigned long ring_buffer_size(struct trace_buffer *buffer, int cpu);
 
-void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu);
-void ring_buffer_reset(struct ring_buffer *buffer);
+void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu);
+void ring_buffer_reset(struct trace_buffer *buffer);
 
 #ifdef CONFIG_RING_BUFFER_ALLOW_SWAP
-int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
-                        struct ring_buffer *buffer_b, int cpu);
+int ring_buffer_swap_cpu(struct trace_buffer *buffer_a,
+                        struct trace_buffer *buffer_b, int cpu);
 #else
 static inline int
-ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
-                    struct ring_buffer *buffer_b, int cpu)
+ring_buffer_swap_cpu(struct trace_buffer *buffer_a,
+                    struct trace_buffer *buffer_b, int cpu)
 {
        return -ENODEV;
 }
 #endif
 
-bool ring_buffer_empty(struct ring_buffer *buffer);
-bool ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu);
-
-void ring_buffer_record_disable(struct ring_buffer *buffer);
-void ring_buffer_record_enable(struct ring_buffer *buffer);
-void ring_buffer_record_off(struct ring_buffer *buffer);
-void ring_buffer_record_on(struct ring_buffer *buffer);
-bool ring_buffer_record_is_on(struct ring_buffer *buffer);
-bool ring_buffer_record_is_set_on(struct ring_buffer *buffer);
-void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu);
-void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu);
-
-u64 ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu);
-unsigned long ring_buffer_bytes_cpu(struct ring_buffer *buffer, int cpu);
-unsigned long ring_buffer_entries(struct ring_buffer *buffer);
-unsigned long ring_buffer_overruns(struct ring_buffer *buffer);
-unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu);
-unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu);
-unsigned long ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu);
-unsigned long ring_buffer_dropped_events_cpu(struct ring_buffer *buffer, int cpu);
-unsigned long ring_buffer_read_events_cpu(struct ring_buffer *buffer, int cpu);
-
-u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu);
-void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
+bool ring_buffer_empty(struct trace_buffer *buffer);
+bool ring_buffer_empty_cpu(struct trace_buffer *buffer, int cpu);
+
+void ring_buffer_record_disable(struct trace_buffer *buffer);
+void ring_buffer_record_enable(struct trace_buffer *buffer);
+void ring_buffer_record_off(struct trace_buffer *buffer);
+void ring_buffer_record_on(struct trace_buffer *buffer);
+bool ring_buffer_record_is_on(struct trace_buffer *buffer);
+bool ring_buffer_record_is_set_on(struct trace_buffer *buffer);
+void ring_buffer_record_disable_cpu(struct trace_buffer *buffer, int cpu);
+void ring_buffer_record_enable_cpu(struct trace_buffer *buffer, int cpu);
+
+u64 ring_buffer_oldest_event_ts(struct trace_buffer *buffer, int cpu);
+unsigned long ring_buffer_bytes_cpu(struct trace_buffer *buffer, int cpu);
+unsigned long ring_buffer_entries(struct trace_buffer *buffer);
+unsigned long ring_buffer_overruns(struct trace_buffer *buffer);
+unsigned long ring_buffer_entries_cpu(struct trace_buffer *buffer, int cpu);
+unsigned long ring_buffer_overrun_cpu(struct trace_buffer *buffer, int cpu);
+unsigned long ring_buffer_commit_overrun_cpu(struct trace_buffer *buffer, int cpu);
+unsigned long ring_buffer_dropped_events_cpu(struct trace_buffer *buffer, int cpu);
+unsigned long ring_buffer_read_events_cpu(struct trace_buffer *buffer, int cpu);
+
+u64 ring_buffer_time_stamp(struct trace_buffer *buffer, int cpu);
+void ring_buffer_normalize_time_stamp(struct trace_buffer *buffer,
                                      int cpu, u64 *ts);
-void ring_buffer_set_clock(struct ring_buffer *buffer,
+void ring_buffer_set_clock(struct trace_buffer *buffer,
                           u64 (*clock)(void));
-void ring_buffer_set_time_stamp_abs(struct ring_buffer *buffer, bool abs);
-bool ring_buffer_time_stamp_abs(struct ring_buffer *buffer);
+void ring_buffer_set_time_stamp_abs(struct trace_buffer *buffer, bool abs);
+bool ring_buffer_time_stamp_abs(struct trace_buffer *buffer);
 
-size_t ring_buffer_nr_pages(struct ring_buffer *buffer, int cpu);
-size_t ring_buffer_nr_dirty_pages(struct ring_buffer *buffer, int cpu);
+size_t ring_buffer_nr_pages(struct trace_buffer *buffer, int cpu);
+size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu);
 
-void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu);
-void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data);
-int ring_buffer_read_page(struct ring_buffer *buffer, void **data_page,
+void *ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu);
+void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu, void *data);
+int ring_buffer_read_page(struct trace_buffer *buffer, void **data_page,
                          size_t len, int cpu, int full);
 
 struct trace_seq;
diff --git a/include/linux/rpmsg/mtk_rpmsg.h b/include/linux/rpmsg/mtk_rpmsg.h
new file mode 100644 (file)
index 0000000..363b601
--- /dev/null
@@ -0,0 +1,38 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Copyright 2019 Google LLC.
+ */
+
+#ifndef __LINUX_RPMSG_MTK_RPMSG_H
+#define __LINUX_RPMSG_MTK_RPMSG_H
+
+#include <linux/platform_device.h>
+#include <linux/remoteproc.h>
+
+typedef void (*ipi_handler_t)(void *data, unsigned int len, void *priv);
+
+/*
+ * struct mtk_rpmsg_info - IPI functions tied to the rpmsg device.
+ * @register_ipi: register IPI handler for an IPI id.
+ * @unregister_ipi: unregister IPI handler for a registered IPI id.
+ * @send_ipi: send IPI to an IPI id. wait is the timeout (in msecs) to wait
+ *            until response, or 0 if there's no timeout.
+ * @ns_ipi_id: the IPI id used for name service, or -1 if name service isn't
+ *             supported.
+ */
+struct mtk_rpmsg_info {
+       int (*register_ipi)(struct platform_device *pdev, u32 id,
+                           ipi_handler_t handler, void *priv);
+       void (*unregister_ipi)(struct platform_device *pdev, u32 id);
+       int (*send_ipi)(struct platform_device *pdev, u32 id,
+                       void *buf, unsigned int len, unsigned int wait);
+       int ns_ipi_id;
+};
+
+struct rproc_subdev *
+mtk_rpmsg_create_rproc_subdev(struct platform_device *pdev,
+                             struct mtk_rpmsg_info *info);
+
+void mtk_rpmsg_destroy_rproc_subdev(struct rproc_subdev *subdev);
+
+#endif
index 4e9d3c7..23990bd 100644 (file)
@@ -167,6 +167,7 @@ struct rtc_device {
 #define RTC_TIMESTAMP_BEGIN_1900       -2208988800LL /* 1900-01-01 00:00:00 */
 #define RTC_TIMESTAMP_BEGIN_2000       946684800LL /* 2000-01-01 00:00:00 */
 #define RTC_TIMESTAMP_END_2063         2966371199LL /* 2063-12-31 23:59:59 */
+#define RTC_TIMESTAMP_END_2079         3471292799LL /* 2079-12-31 23:59:59 */
 #define RTC_TIMESTAMP_END_2099         4102444799LL /* 2099-12-31 23:59:59 */
 #define RTC_TIMESTAMP_END_2199         7258118399LL /* 2199-12-31 23:59:59 */
 #define RTC_TIMESTAMP_END_9999         253402300799LL /* 9999-12-31 23:59:59 */
index 881fea4..5c873a5 100644 (file)
@@ -257,6 +257,7 @@ enum scmi_std_protocol {
 struct scmi_device {
        u32 id;
        u8 protocol_id;
+       const char *name;
        struct device dev;
        struct scmi_handle *handle;
 };
@@ -264,11 +265,13 @@ struct scmi_device {
 #define to_scmi_dev(d) container_of(d, struct scmi_device, dev)
 
 struct scmi_device *
-scmi_device_create(struct device_node *np, struct device *parent, int protocol);
+scmi_device_create(struct device_node *np, struct device *parent, int protocol,
+                  const char *name);
 void scmi_device_destroy(struct scmi_device *scmi_dev);
 
 struct scmi_device_id {
        u8 protocol_id;
+       const char *name;
 };
 
 struct scmi_driver {
index 5998e1f..770c2bf 100644 (file)
@@ -160,6 +160,19 @@ static const struct file_operations __name ## _fops = {                    \
        .release        = single_release,                               \
 }
 
+#define DEFINE_PROC_SHOW_ATTRIBUTE(__name)                             \
+static int __name ## _open(struct inode *inode, struct file *file)     \
+{                                                                      \
+       return single_open(file, __name ## _show, inode->i_private);    \
+}                                                                      \
+                                                                       \
+static const struct proc_ops __name ## _proc_ops = {                   \
+       .proc_open      = __name ## _open,                              \
+       .proc_read      = seq_read,                                     \
+       .proc_lseek     = seq_lseek,                                    \
+       .proc_release   = single_release,                               \
+}
+
 static inline struct user_namespace *seq_user_ns(struct seq_file *seq)
 {
 #ifdef CONFIG_USER_NS
index de8e4b7..d56fefe 100644 (file)
@@ -8,6 +8,7 @@
 #include <linux/pagemap.h>
 #include <linux/percpu_counter.h>
 #include <linux/xattr.h>
+#include <linux/fs_parser.h>
 
 /* inode in-kernel data */
 
@@ -49,7 +50,7 @@ static inline struct shmem_inode_info *SHMEM_I(struct inode *inode)
 /*
  * Functions in mm/shmem.c called directly from elsewhere:
  */
-extern const struct fs_parameter_description shmem_fs_parameters;
+extern const struct fs_parameter_spec shmem_fs_parameters[];
 extern int shmem_init(void);
 extern int shmem_init_fs_context(struct fs_context *fc);
 extern struct file *shmem_file_setup(const char *name,
index 3d13a4b..ca8806b 100644 (file)
@@ -1822,6 +1822,18 @@ static inline __u32 skb_queue_len(const struct sk_buff_head *list_)
 }
 
 /**
+ *     skb_queue_len_lockless  - get queue length
+ *     @list_: list to measure
+ *
+ *     Return the length of an &sk_buff queue.
+ *     This variant can be used in lockless contexts.
+ */
+static inline __u32 skb_queue_len_lockless(const struct sk_buff_head *list_)
+{
+       return READ_ONCE(list_->qlen);
+}
+
+/**
  *     __skb_queue_head_init - initialize non-spinlock portions of sk_buff_head
  *     @list: queue to initialize
  *
@@ -2026,7 +2038,7 @@ static inline void __skb_unlink(struct sk_buff *skb, struct sk_buff_head *list)
 {
        struct sk_buff *next, *prev;
 
-       list->qlen--;
+       WRITE_ONCE(list->qlen, list->qlen - 1);
        next       = skb->next;
        prev       = skb->prev;
        skb->next  = skb->prev = NULL;
index 877a95c..03a3893 100644 (file)
@@ -184,7 +184,6 @@ void memcg_deactivate_kmem_caches(struct mem_cgroup *, struct mem_cgroup *);
 /*
  * Common kmalloc functions provided by all allocators
  */
-void * __must_check __krealloc(const void *, size_t, gfp_t);
 void * __must_check krealloc(const void *, size_t, gfp_t);
 void kfree(const void *);
 void kzfree(const void *);
index fc0b445..a4f5516 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * Header for EXYNOS PMU Driver support
+ * Header for Exynos PMU Driver support
  */
 
 #ifndef __LINUX_SOC_EXYNOS_PMU_H
index 5addaf5..fc9250f 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright (c) 2010-2015 Samsung Electronics Co., Ltd.
  *             http://www.samsung.com
  *
- * EXYNOS - Power management unit definition
+ * Exynos - Power management unit definition
  *
  * Notice:
  * This is not a list of all Exynos Power Management Unit SFRs.
 /* Only for S5Pv210 */
 #define S5PV210_EINT_WAKEUP_MASK       0xC004
 
-/* Only for EXYNOS4210 */
+/* Only for Exynos4210 */
 #define S5P_CMU_CLKSTOP_LCD1_LOWPWR    0x1154
 #define S5P_CMU_RESET_LCD1_LOWPWR      0x1174
 #define S5P_MODIMIF_MEM_LOWPWR         0x11C4
 #define S5P_SATA_MEM_LOWPWR            0x11E4
 #define S5P_LCD1_LOWPWR                        0x1394
 
-/* Only for EXYNOS4x12 */
+/* Only for Exynos4x12 */
 #define S5P_ISP_ARM_LOWPWR                     0x1050
 #define S5P_DIS_IRQ_ISP_ARM_LOCAL_LOWPWR       0x1054
 #define S5P_DIS_IRQ_ISP_ARM_CENTRAL_LOWPWR     0x1058
 #define S5P_SECSS_MEM_OPTION                   0x2EC8
 #define S5P_ROTATOR_MEM_OPTION                 0x2F48
 
-/* Only for EXYNOS4412 */
+/* Only for Exynos4412 */
 #define S5P_ARM_CORE2_LOWPWR                   0x1020
 #define S5P_DIS_IRQ_CORE2                      0x1024
 #define S5P_DIS_IRQ_CENTRAL2                   0x1028
 #define S5P_DIS_IRQ_CORE3                      0x1034
 #define S5P_DIS_IRQ_CENTRAL3                   0x1038
 
-/* Only for EXYNOS3XXX */
+/* Only for Exynos3XXX */
 #define EXYNOS3_ARM_CORE0_SYS_PWR_REG                  0x1000
 #define EXYNOS3_DIS_IRQ_ARM_CORE0_LOCAL_SYS_PWR_REG    0x1004
 #define EXYNOS3_DIS_IRQ_ARM_CORE0_CENTRAL_SYS_PWR_REG  0x1008
 #define EXYNOS3_OPTION_USE_SC_FEEDBACK                 (1 << 1)
 #define EXYNOS3_OPTION_SKIP_DEACTIVATE_ACEACP_IN_PWDN  (1 << 7)
 
-/* For EXYNOS5 */
+/* For Exynos5 */
 
 #define EXYNOS5_AUTO_WDTRESET_DISABLE                          0x0408
 #define EXYNOS5_MASK_WDTRESET_REQUEST                          0x040C
 
 #define EXYNOS5420_SWRESET_KFC_SEL                             0x3
 
-/* Only for EXYNOS5420 */
+/* Only for Exynos5420 */
 #define EXYNOS5420_L2RSTDISABLE_VALUE                          BIT(3)
 
 #define EXYNOS5420_LPI_MASK                                    0x0004
                                         | EXYNOS5420_KFC_USE_STANDBY_WFI2  \
                                         | EXYNOS5420_KFC_USE_STANDBY_WFI3)
 
-/* For EXYNOS5433 */
+/* For Exynos5433 */
 #define EXYNOS5433_EINT_WAKEUP_MASK                            (0x060C)
 #define EXYNOS5433_USBHOST30_PHY_CONTROL                       (0x0728)
 #define EXYNOS5433_PAD_RETENTION_AUD_OPTION                    (0x3028)
index 02894e4..6dfbb2e 100644 (file)
@@ -62,6 +62,7 @@ extern char * strchr(const char *,int);
 #ifndef __HAVE_ARCH_STRCHRNUL
 extern char * strchrnul(const char *,int);
 #endif
+extern char * strnchrnul(const char *, size_t, int);
 #ifndef __HAVE_ARCH_STRNCHR
 extern char * strnchr(const char *, size_t, int);
 #endif
index e9ec742..4f6b284 100644 (file)
@@ -113,7 +113,6 @@ struct rpc_authops {
        int                     (*hash_cred)(struct auth_cred *, unsigned int);
        struct rpc_cred *       (*lookup_cred)(struct rpc_auth *, struct auth_cred *, int);
        struct rpc_cred *       (*crcreate)(struct rpc_auth*, struct auth_cred *, int, gfp_t);
-       int                     (*list_pseudoflavors)(rpc_authflavor_t *, int);
        rpc_authflavor_t        (*info2flavor)(struct rpcsec_gss_info *);
        int                     (*flavor2info)(rpc_authflavor_t,
                                                struct rpcsec_gss_info *);
@@ -158,7 +157,6 @@ rpc_authflavor_t    rpcauth_get_pseudoflavor(rpc_authflavor_t,
                                struct rpcsec_gss_info *);
 int                    rpcauth_get_gssinfo(rpc_authflavor_t,
                                struct rpcsec_gss_info *);
-int                    rpcauth_list_flavors(rpc_authflavor_t *, int);
 struct rpc_cred *      rpcauth_lookup_credcache(struct rpc_auth *, struct auth_cred *, int, gfp_t);
 void                   rpcauth_init_cred(struct rpc_cred *, const struct auth_cred *, struct rpc_auth *, const struct rpc_credops *);
 struct rpc_cred *      rpcauth_lookupcred(struct rpc_auth *, int);
index 1cc6cef..48c1b16 100644 (file)
@@ -150,9 +150,6 @@ struct gss_api_mech *gss_mech_get_by_name(const char *);
 /* Similar, but get by pseudoflavor. */
 struct gss_api_mech *gss_mech_get_by_pseudoflavor(u32);
 
-/* Fill in an array with a list of supported pseudoflavors */
-int gss_mech_list_pseudoflavors(rpc_authflavor_t *, int);
-
 struct gss_api_mech * gss_mech_get(struct gss_api_mech *);
 
 /* For every successful gss_mech_get or gss_mech_get_by_* call there must be a
index 84b92b4..d94d4f4 100644 (file)
@@ -63,7 +63,7 @@ struct proc_dir_entry *       rpc_proc_register(struct net *,struct rpc_stat *);
 void                   rpc_proc_unregister(struct net *,const char *);
 void                   rpc_proc_zero(const struct rpc_program *);
 struct proc_dir_entry *        svc_proc_register(struct net *, struct svc_stat *,
-                                         const struct file_operations *);
+                                         const struct proc_ops *);
 void                   svc_proc_unregister(struct net *, const char *);
 
 void                   svc_seq_show(struct seq_file *,
@@ -75,7 +75,7 @@ static inline void rpc_proc_unregister(struct net *net, const char *p) {}
 static inline void rpc_proc_zero(const struct rpc_program *p) {}
 
 static inline struct proc_dir_entry *svc_proc_register(struct net *net, struct svc_stat *s,
-                                                      const struct file_operations *f) { return NULL; }
+                                                      const struct proc_ops *proc_ops) { return NULL; }
 static inline void svc_proc_unregister(struct net *net, const char *p) {}
 
 static inline void svc_seq_show(struct seq_file *seq,
index 13ea7f7..af2c85d 100644 (file)
@@ -11,7 +11,7 @@
 #include <linux/tracepoint.h>
 
 struct trace_array;
-struct trace_buffer;
+struct array_buffer;
 struct tracer;
 struct dentry;
 struct bpf_prog;
@@ -79,7 +79,7 @@ struct trace_entry {
 struct trace_iterator {
        struct trace_array      *tr;
        struct tracer           *trace;
-       struct trace_buffer     *trace_buffer;
+       struct array_buffer     *array_buffer;
        void                    *private;
        int                     cpu_file;
        struct mutex            mutex;
@@ -153,7 +153,7 @@ void tracing_generic_entry_update(struct trace_entry *entry,
 struct trace_event_file;
 
 struct ring_buffer_event *
-trace_event_buffer_lock_reserve(struct ring_buffer **current_buffer,
+trace_event_buffer_lock_reserve(struct trace_buffer **current_buffer,
                                struct trace_event_file *trace_file,
                                int type, unsigned long len,
                                unsigned long flags, int pc);
@@ -226,12 +226,13 @@ extern int trace_event_reg(struct trace_event_call *event,
                            enum trace_reg type, void *data);
 
 struct trace_event_buffer {
-       struct ring_buffer              *buffer;
+       struct trace_buffer             *buffer;
        struct ring_buffer_event        *event;
        struct trace_event_file         *trace_file;
        void                            *entry;
        unsigned long                   flags;
        int                             pc;
+       struct pt_regs                  *regs;
 };
 
 void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
@@ -364,6 +365,128 @@ enum {
        EVENT_FILE_FL_WAS_ENABLED_BIT,
 };
 
+extern struct trace_event_file *trace_get_event_file(const char *instance,
+                                                    const char *system,
+                                                    const char *event);
+extern void trace_put_event_file(struct trace_event_file *file);
+
+#define MAX_DYNEVENT_CMD_LEN   (2048)
+
+enum dynevent_type {
+       DYNEVENT_TYPE_SYNTH = 1,
+       DYNEVENT_TYPE_KPROBE,
+       DYNEVENT_TYPE_NONE,
+};
+
+struct dynevent_cmd;
+
+typedef int (*dynevent_create_fn_t)(struct dynevent_cmd *cmd);
+
+struct dynevent_cmd {
+       struct seq_buf          seq;
+       const char              *event_name;
+       unsigned int            n_fields;
+       enum dynevent_type      type;
+       dynevent_create_fn_t    run_command;
+       void                    *private_data;
+};
+
+extern int dynevent_create(struct dynevent_cmd *cmd);
+
+extern int synth_event_delete(const char *name);
+
+extern void synth_event_cmd_init(struct dynevent_cmd *cmd,
+                                char *buf, int maxlen);
+
+extern int __synth_event_gen_cmd_start(struct dynevent_cmd *cmd,
+                                      const char *name,
+                                      struct module *mod, ...);
+
+#define synth_event_gen_cmd_start(cmd, name, mod, ...) \
+       __synth_event_gen_cmd_start(cmd, name, mod, ## __VA_ARGS__, NULL)
+
+struct synth_field_desc {
+       const char *type;
+       const char *name;
+};
+
+extern int synth_event_gen_cmd_array_start(struct dynevent_cmd *cmd,
+                                          const char *name,
+                                          struct module *mod,
+                                          struct synth_field_desc *fields,
+                                          unsigned int n_fields);
+extern int synth_event_create(const char *name,
+                             struct synth_field_desc *fields,
+                             unsigned int n_fields, struct module *mod);
+
+extern int synth_event_add_field(struct dynevent_cmd *cmd,
+                                const char *type,
+                                const char *name);
+extern int synth_event_add_field_str(struct dynevent_cmd *cmd,
+                                    const char *type_name);
+extern int synth_event_add_fields(struct dynevent_cmd *cmd,
+                                 struct synth_field_desc *fields,
+                                 unsigned int n_fields);
+
+#define synth_event_gen_cmd_end(cmd)   \
+       dynevent_create(cmd)
+
+struct synth_event;
+
+struct synth_event_trace_state {
+       struct trace_event_buffer fbuffer;
+       struct synth_trace_event *entry;
+       struct trace_buffer *buffer;
+       struct synth_event *event;
+       unsigned int cur_field;
+       unsigned int n_u64;
+       bool enabled;
+       bool add_next;
+       bool add_name;
+};
+
+extern int synth_event_trace(struct trace_event_file *file,
+                            unsigned int n_vals, ...);
+extern int synth_event_trace_array(struct trace_event_file *file, u64 *vals,
+                                  unsigned int n_vals);
+extern int synth_event_trace_start(struct trace_event_file *file,
+                                  struct synth_event_trace_state *trace_state);
+extern int synth_event_add_next_val(u64 val,
+                                   struct synth_event_trace_state *trace_state);
+extern int synth_event_add_val(const char *field_name, u64 val,
+                              struct synth_event_trace_state *trace_state);
+extern int synth_event_trace_end(struct synth_event_trace_state *trace_state);
+
+extern int kprobe_event_delete(const char *name);
+
+extern void kprobe_event_cmd_init(struct dynevent_cmd *cmd,
+                                 char *buf, int maxlen);
+
+#define kprobe_event_gen_cmd_start(cmd, name, loc, ...)                        \
+       __kprobe_event_gen_cmd_start(cmd, false, name, loc, ## __VA_ARGS__, NULL)
+
+#define kretprobe_event_gen_cmd_start(cmd, name, loc, ...)             \
+       __kprobe_event_gen_cmd_start(cmd, true, name, loc, ## __VA_ARGS__, NULL)
+
+extern int __kprobe_event_gen_cmd_start(struct dynevent_cmd *cmd,
+                                       bool kretprobe,
+                                       const char *name,
+                                       const char *loc, ...);
+
+#define kprobe_event_add_fields(cmd, ...)      \
+       __kprobe_event_add_fields(cmd, ## __VA_ARGS__, NULL)
+
+#define kprobe_event_add_field(cmd, field)     \
+       __kprobe_event_add_fields(cmd, field, NULL)
+
+extern int __kprobe_event_add_fields(struct dynevent_cmd *cmd, ...);
+
+#define kprobe_event_gen_cmd_end(cmd)          \
+       dynevent_create(cmd)
+
+#define kretprobe_event_gen_cmd_end(cmd)       \
+       dynevent_create(cmd)
+
 /*
  * Event file flags:
  *  ENABLED      - The event is enabled
index 88d279c..9991244 100644 (file)
@@ -28,7 +28,6 @@ struct dentry *tracefs_create_file(const char *name, umode_t mode,
 struct dentry *tracefs_create_dir(const char *name, struct dentry *parent);
 
 void tracefs_remove(struct dentry *dentry);
-void tracefs_remove_recursive(struct dentry *dentry);
 
 struct dentry *tracefs_create_instance_dir(const char *name, struct dentry *parent,
                                           int (*mkdir)(const char *name),
index baf0903..9d13428 100644 (file)
@@ -47,11 +47,6 @@ struct ipxhdr {
 /* From af_ipx.c */
 extern int sysctl_ipx_pprop_broadcasting;
 
-static __inline__ struct ipxhdr *ipx_hdr(struct sk_buff *skb)
-{
-       return (struct ipxhdr *)skb_transport_header(skb);
-}
-
 struct ipx_interface {
        /* IPX address */
        __be32                  if_netnum;
diff --git a/include/soc/fsl/cpm.h b/include/soc/fsl/cpm.h
new file mode 100644 (file)
index 0000000..4c24ea8
--- /dev/null
@@ -0,0 +1,171 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __CPM_H
+#define __CPM_H
+
+#include <linux/compiler.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/of.h>
+#include <soc/fsl/qe/qe.h>
+
+/*
+ * SPI Parameter RAM common to QE and CPM.
+ */
+struct spi_pram {
+       __be16  rbase;  /* Rx Buffer descriptor base address */
+       __be16  tbase;  /* Tx Buffer descriptor base address */
+       u8      rfcr;   /* Rx function code */
+       u8      tfcr;   /* Tx function code */
+       __be16  mrblr;  /* Max receive buffer length */
+       __be32  rstate; /* Internal */
+       __be32  rdp;    /* Internal */
+       __be16  rbptr;  /* Internal */
+       __be16  rbc;    /* Internal */
+       __be32  rxtmp;  /* Internal */
+       __be32  tstate; /* Internal */
+       __be32  tdp;    /* Internal */
+       __be16  tbptr;  /* Internal */
+       __be16  tbc;    /* Internal */
+       __be32  txtmp;  /* Internal */
+       __be32  res;    /* Tx temp. */
+       __be16  rpbase; /* Relocation pointer (CPM1 only) */
+       __be16  res1;   /* Reserved */
+};
+
+/*
+ * USB Controller pram common to QE and CPM.
+ */
+struct usb_ctlr {
+       u8      usb_usmod;
+       u8      usb_usadr;
+       u8      usb_uscom;
+       u8      res1[1];
+       __be16  usb_usep[4];
+       u8      res2[4];
+       __be16  usb_usber;
+       u8      res3[2];
+       __be16  usb_usbmr;
+       u8      res4[1];
+       u8      usb_usbs;
+       /* Fields down below are QE-only */
+       __be16  usb_ussft;
+       u8      res5[2];
+       __be16  usb_usfrn;
+       u8      res6[0x22];
+} __attribute__ ((packed));
+
+/*
+ * Function code bits, usually generic to devices.
+ */
+#ifdef CONFIG_CPM1
+#define CPMFCR_GBL     ((u_char)0x00)  /* Flag doesn't exist in CPM1 */
+#define CPMFCR_TC2     ((u_char)0x00)  /* Flag doesn't exist in CPM1 */
+#define CPMFCR_DTB     ((u_char)0x00)  /* Flag doesn't exist in CPM1 */
+#define CPMFCR_BDB     ((u_char)0x00)  /* Flag doesn't exist in CPM1 */
+#else
+#define CPMFCR_GBL     ((u_char)0x20)  /* Set memory snooping */
+#define CPMFCR_TC2     ((u_char)0x04)  /* Transfer code 2 value */
+#define CPMFCR_DTB     ((u_char)0x02)  /* Use local bus for data when set */
+#define CPMFCR_BDB     ((u_char)0x01)  /* Use local bus for BD when set */
+#endif
+#define CPMFCR_EB      ((u_char)0x10)  /* Set big endian byte order */
+
+/* Opcodes common to CPM1 and CPM2
+*/
+#define CPM_CR_INIT_TRX                ((ushort)0x0000)
+#define CPM_CR_INIT_RX         ((ushort)0x0001)
+#define CPM_CR_INIT_TX         ((ushort)0x0002)
+#define CPM_CR_HUNT_MODE       ((ushort)0x0003)
+#define CPM_CR_STOP_TX         ((ushort)0x0004)
+#define CPM_CR_GRA_STOP_TX     ((ushort)0x0005)
+#define CPM_CR_RESTART_TX      ((ushort)0x0006)
+#define CPM_CR_CLOSE_RX_BD     ((ushort)0x0007)
+#define CPM_CR_SET_GADDR       ((ushort)0x0008)
+#define CPM_CR_SET_TIMER       ((ushort)0x0008)
+#define CPM_CR_STOP_IDMA       ((ushort)0x000b)
+
+/* Buffer descriptors used by many of the CPM protocols. */
+typedef struct cpm_buf_desc {
+       ushort  cbd_sc;         /* Status and Control */
+       ushort  cbd_datlen;     /* Data length in buffer */
+       uint    cbd_bufaddr;    /* Buffer address in host memory */
+} cbd_t;
+
+/* Buffer descriptor control/status used by serial
+ */
+
+#define BD_SC_EMPTY    (0x8000)        /* Receive is empty */
+#define BD_SC_READY    (0x8000)        /* Transmit is ready */
+#define BD_SC_WRAP     (0x2000)        /* Last buffer descriptor */
+#define BD_SC_INTRPT   (0x1000)        /* Interrupt on change */
+#define BD_SC_LAST     (0x0800)        /* Last buffer in frame */
+#define BD_SC_TC       (0x0400)        /* Transmit CRC */
+#define BD_SC_CM       (0x0200)        /* Continuous mode */
+#define BD_SC_ID       (0x0100)        /* Rec'd too many idles */
+#define BD_SC_P                (0x0100)        /* xmt preamble */
+#define BD_SC_BR       (0x0020)        /* Break received */
+#define BD_SC_FR       (0x0010)        /* Framing error */
+#define BD_SC_PR       (0x0008)        /* Parity error */
+#define BD_SC_NAK      (0x0004)        /* NAK - did not respond */
+#define BD_SC_OV       (0x0002)        /* Overrun */
+#define BD_SC_UN       (0x0002)        /* Underrun */
+#define BD_SC_CD       (0x0001)        /* */
+#define BD_SC_CL       (0x0001)        /* Collision */
+
+/* Buffer descriptor control/status used by Ethernet receive.
+ * Common to SCC and FCC.
+ */
+#define BD_ENET_RX_EMPTY       (0x8000)
+#define BD_ENET_RX_WRAP                (0x2000)
+#define BD_ENET_RX_INTR                (0x1000)
+#define BD_ENET_RX_LAST                (0x0800)
+#define BD_ENET_RX_FIRST       (0x0400)
+#define BD_ENET_RX_MISS                (0x0100)
+#define BD_ENET_RX_BC          (0x0080)        /* FCC Only */
+#define BD_ENET_RX_MC          (0x0040)        /* FCC Only */
+#define BD_ENET_RX_LG          (0x0020)
+#define BD_ENET_RX_NO          (0x0010)
+#define BD_ENET_RX_SH          (0x0008)
+#define BD_ENET_RX_CR          (0x0004)
+#define BD_ENET_RX_OV          (0x0002)
+#define BD_ENET_RX_CL          (0x0001)
+#define BD_ENET_RX_STATS       (0x01ff)        /* All status bits */
+
+/* Buffer descriptor control/status used by Ethernet transmit.
+ * Common to SCC and FCC.
+ */
+#define BD_ENET_TX_READY       (0x8000)
+#define BD_ENET_TX_PAD         (0x4000)
+#define BD_ENET_TX_WRAP                (0x2000)
+#define BD_ENET_TX_INTR                (0x1000)
+#define BD_ENET_TX_LAST                (0x0800)
+#define BD_ENET_TX_TC          (0x0400)
+#define BD_ENET_TX_DEF         (0x0200)
+#define BD_ENET_TX_HB          (0x0100)
+#define BD_ENET_TX_LC          (0x0080)
+#define BD_ENET_TX_RL          (0x0040)
+#define BD_ENET_TX_RCMASK      (0x003c)
+#define BD_ENET_TX_UN          (0x0002)
+#define BD_ENET_TX_CSL         (0x0001)
+#define BD_ENET_TX_STATS       (0x03ff)        /* All status bits */
+
+/* Buffer descriptor control/status used by Transparent mode SCC.
+ */
+#define BD_SCC_TX_LAST         (0x0800)
+
+/* Buffer descriptor control/status used by I2C.
+ */
+#define BD_I2C_START           (0x0400)
+
+#ifdef CONFIG_CPM
+int cpm_command(u32 command, u8 opcode);
+#else
+static inline int cpm_command(u32 command, u8 opcode)
+{
+       return -ENOSYS;
+}
+#endif /* CONFIG_CPM */
+
+int cpm2_gpiochip_add32(struct device *dev);
+
+#endif
index c1036d1..e282ac0 100644 (file)
@@ -17,7 +17,7 @@
 #include <linux/spinlock.h>
 #include <linux/errno.h>
 #include <linux/err.h>
-#include <asm/cpm.h>
+#include <soc/fsl/cpm.h>
 #include <soc/fsl/qe/immap_qe.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -98,26 +98,25 @@ static inline void qe_reset(void) {}
 int cpm_muram_init(void);
 
 #if defined(CONFIG_CPM) || defined(CONFIG_QUICC_ENGINE)
-unsigned long cpm_muram_alloc(unsigned long size, unsigned long align);
-int cpm_muram_free(unsigned long offset);
-unsigned long cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
+s32 cpm_muram_alloc(unsigned long size, unsigned long align);
+void cpm_muram_free(s32 offset);
+s32 cpm_muram_alloc_fixed(unsigned long offset, unsigned long size);
 void __iomem *cpm_muram_addr(unsigned long offset);
 unsigned long cpm_muram_offset(void __iomem *addr);
 dma_addr_t cpm_muram_dma(void __iomem *addr);
 #else
-static inline unsigned long cpm_muram_alloc(unsigned long size,
-                                           unsigned long align)
+static inline s32 cpm_muram_alloc(unsigned long size,
+                                 unsigned long align)
 {
        return -ENOSYS;
 }
 
-static inline int cpm_muram_free(unsigned long offset)
+static inline void cpm_muram_free(s32 offset)
 {
-       return -ENOSYS;
 }
 
-static inline unsigned long cpm_muram_alloc_fixed(unsigned long offset,
-                                                 unsigned long size)
+static inline s32 cpm_muram_alloc_fixed(unsigned long offset,
+                                       unsigned long size)
 {
        return -ENOSYS;
 }
@@ -241,21 +240,37 @@ static inline int qe_alive_during_sleep(void)
 #define qe_muram_offset cpm_muram_offset
 #define qe_muram_dma cpm_muram_dma
 
-#define qe_setbits32(_addr, _v) iowrite32be(ioread32be(_addr) |  (_v), (_addr))
-#define qe_clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr))
+#ifdef CONFIG_PPC32
+#define qe_iowrite8(val, addr)     out_8(addr, val)
+#define qe_iowrite16be(val, addr)  out_be16(addr, val)
+#define qe_iowrite32be(val, addr)  out_be32(addr, val)
+#define qe_ioread8(addr)           in_8(addr)
+#define qe_ioread16be(addr)        in_be16(addr)
+#define qe_ioread32be(addr)        in_be32(addr)
+#else
+#define qe_iowrite8(val, addr)     iowrite8(val, addr)
+#define qe_iowrite16be(val, addr)  iowrite16be(val, addr)
+#define qe_iowrite32be(val, addr)  iowrite32be(val, addr)
+#define qe_ioread8(addr)           ioread8(addr)
+#define qe_ioread16be(addr)        ioread16be(addr)
+#define qe_ioread32be(addr)        ioread32be(addr)
+#endif
+
+#define qe_setbits_be32(_addr, _v) qe_iowrite32be(qe_ioread32be(_addr) |  (_v), (_addr))
+#define qe_clrbits_be32(_addr, _v) qe_iowrite32be(qe_ioread32be(_addr) & ~(_v), (_addr))
 
-#define qe_setbits16(_addr, _v) iowrite16be(ioread16be(_addr) |  (_v), (_addr))
-#define qe_clrbits16(_addr, _v) iowrite16be(ioread16be(_addr) & ~(_v), (_addr))
+#define qe_setbits_be16(_addr, _v) qe_iowrite16be(qe_ioread16be(_addr) |  (_v), (_addr))
+#define qe_clrbits_be16(_addr, _v) qe_iowrite16be(qe_ioread16be(_addr) & ~(_v), (_addr))
 
-#define qe_setbits8(_addr, _v) iowrite8(ioread8(_addr) |  (_v), (_addr))
-#define qe_clrbits8(_addr, _v) iowrite8(ioread8(_addr) & ~(_v), (_addr))
+#define qe_setbits_8(_addr, _v) qe_iowrite8(qe_ioread8(_addr) |  (_v), (_addr))
+#define qe_clrbits_8(_addr, _v) qe_iowrite8(qe_ioread8(_addr) & ~(_v), (_addr))
 
-#define qe_clrsetbits32(addr, clear, set) \
-       iowrite32be((ioread32be(addr) & ~(clear)) | (set), (addr))
-#define qe_clrsetbits16(addr, clear, set) \
-       iowrite16be((ioread16be(addr) & ~(clear)) | (set), (addr))
-#define qe_clrsetbits8(addr, clear, set) \
-       iowrite8((ioread8(addr) & ~(clear)) | (set), (addr))
+#define qe_clrsetbits_be32(addr, clear, set) \
+       qe_iowrite32be((qe_ioread32be(addr) & ~(clear)) | (set), (addr))
+#define qe_clrsetbits_be16(addr, clear, set) \
+       qe_iowrite16be((qe_ioread16be(addr) & ~(clear)) | (set), (addr))
+#define qe_clrsetbits_8(addr, clear, set) \
+       qe_iowrite8((qe_ioread8(addr) & ~(clear)) | (set), (addr))
 
 /* Structure that defines QE firmware binary files.
  *
diff --git a/include/soc/fsl/qe/qe_ic.h b/include/soc/fsl/qe/qe_ic.h
deleted file mode 100644 (file)
index 714a9b8..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-/*
- * Copyright (C) 2006 Freescale Semiconductor, Inc. All rights reserved.
- *
- * Authors:    Shlomi Gridish <gridish@freescale.com>
- *             Li Yang <leoli@freescale.com>
- *
- * Description:
- * QE IC external definitions and structure.
- */
-#ifndef _ASM_POWERPC_QE_IC_H
-#define _ASM_POWERPC_QE_IC_H
-
-#include <linux/irq.h>
-
-struct device_node;
-struct qe_ic;
-
-#define NUM_OF_QE_IC_GROUPS    6
-
-/* Flags when we init the QE IC */
-#define QE_IC_SPREADMODE_GRP_W                 0x00000001
-#define QE_IC_SPREADMODE_GRP_X                 0x00000002
-#define QE_IC_SPREADMODE_GRP_Y                 0x00000004
-#define QE_IC_SPREADMODE_GRP_Z                 0x00000008
-#define QE_IC_SPREADMODE_GRP_RISCA             0x00000010
-#define QE_IC_SPREADMODE_GRP_RISCB             0x00000020
-
-#define QE_IC_LOW_SIGNAL                       0x00000100
-#define QE_IC_HIGH_SIGNAL                      0x00000200
-
-#define QE_IC_GRP_W_PRI0_DEST_SIGNAL_HIGH      0x00001000
-#define QE_IC_GRP_W_PRI1_DEST_SIGNAL_HIGH      0x00002000
-#define QE_IC_GRP_X_PRI0_DEST_SIGNAL_HIGH      0x00004000
-#define QE_IC_GRP_X_PRI1_DEST_SIGNAL_HIGH      0x00008000
-#define QE_IC_GRP_Y_PRI0_DEST_SIGNAL_HIGH      0x00010000
-#define QE_IC_GRP_Y_PRI1_DEST_SIGNAL_HIGH      0x00020000
-#define QE_IC_GRP_Z_PRI0_DEST_SIGNAL_HIGH      0x00040000
-#define QE_IC_GRP_Z_PRI1_DEST_SIGNAL_HIGH      0x00080000
-#define QE_IC_GRP_RISCA_PRI0_DEST_SIGNAL_HIGH  0x00100000
-#define QE_IC_GRP_RISCA_PRI1_DEST_SIGNAL_HIGH  0x00200000
-#define QE_IC_GRP_RISCB_PRI0_DEST_SIGNAL_HIGH  0x00400000
-#define QE_IC_GRP_RISCB_PRI1_DEST_SIGNAL_HIGH  0x00800000
-#define QE_IC_GRP_W_DEST_SIGNAL_SHIFT          (12)
-
-/* QE interrupt sources groups */
-enum qe_ic_grp_id {
-       QE_IC_GRP_W = 0,        /* QE interrupt controller group W */
-       QE_IC_GRP_X,            /* QE interrupt controller group X */
-       QE_IC_GRP_Y,            /* QE interrupt controller group Y */
-       QE_IC_GRP_Z,            /* QE interrupt controller group Z */
-       QE_IC_GRP_RISCA,        /* QE interrupt controller RISC group A */
-       QE_IC_GRP_RISCB         /* QE interrupt controller RISC group B */
-};
-
-#ifdef CONFIG_QUICC_ENGINE
-void qe_ic_init(struct device_node *node, unsigned int flags,
-               void (*low_handler)(struct irq_desc *desc),
-               void (*high_handler)(struct irq_desc *desc));
-unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic);
-unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic);
-#else
-static inline void qe_ic_init(struct device_node *node, unsigned int flags,
-               void (*low_handler)(struct irq_desc *desc),
-               void (*high_handler)(struct irq_desc *desc))
-{}
-static inline unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
-{ return 0; }
-static inline unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
-{ return 0; }
-#endif /* CONFIG_QUICC_ENGINE */
-
-void qe_ic_set_highest_priority(unsigned int virq, int high);
-int qe_ic_set_priority(unsigned int virq, unsigned int priority);
-int qe_ic_set_high_priority(unsigned int virq, unsigned int priority, int high);
-
-static inline void qe_ic_cascade_low_ipic(struct irq_desc *desc)
-{
-       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
-       unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
-
-       if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq);
-}
-
-static inline void qe_ic_cascade_high_ipic(struct irq_desc *desc)
-{
-       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
-       unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
-
-       if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq);
-}
-
-static inline void qe_ic_cascade_low_mpic(struct irq_desc *desc)
-{
-       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
-       unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
-       struct irq_chip *chip = irq_desc_get_chip(desc);
-
-       if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq);
-
-       chip->irq_eoi(&desc->irq_data);
-}
-
-static inline void qe_ic_cascade_high_mpic(struct irq_desc *desc)
-{
-       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
-       unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
-       struct irq_chip *chip = irq_desc_get_chip(desc);
-
-       if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq);
-
-       chip->irq_eoi(&desc->irq_data);
-}
-
-static inline void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
-{
-       struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
-       unsigned int cascade_irq;
-       struct irq_chip *chip = irq_desc_get_chip(desc);
-
-       cascade_irq = qe_ic_get_high_irq(qe_ic);
-       if (cascade_irq == NO_IRQ)
-               cascade_irq = qe_ic_get_low_irq(qe_ic);
-
-       if (cascade_irq != NO_IRQ)
-               generic_handle_irq(cascade_irq);
-
-       chip->irq_eoi(&desc->irq_data);
-}
-
-#endif /* _ASM_POWERPC_QE_IC_H */
index e9cc460..ba0e838 100644 (file)
@@ -188,9 +188,9 @@ struct ucc_fast_private {
        int stopped_tx;         /* Whether channel has been stopped for Tx
                                   (STOP_TX, etc.) */
        int stopped_rx;         /* Whether channel has been stopped for Rx */
-       u32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx
+       s32 ucc_fast_tx_virtual_fifo_base_offset;/* pointer to base of Tx
                                                    virtual fifo */
-       u32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx
+       s32 ucc_fast_rx_virtual_fifo_base_offset;/* pointer to base of Rx
                                                    virtual fifo */
 #ifdef STATISTICS
        u32 tx_frames;          /* Transmitted frames counter. */
index 8696fde..d187a6b 100644 (file)
@@ -185,7 +185,7 @@ struct ucc_slow_private {
        struct ucc_slow_info *us_info;
        struct ucc_slow __iomem *us_regs; /* Ptr to memory map of UCC regs */
        struct ucc_slow_pram *us_pram;  /* a pointer to the parameter RAM */
-       u32 us_pram_offset;
+       s32 us_pram_offset;
        int enabled_tx;         /* Whether channel is enabled for Tx (ENT) */
        int enabled_rx;         /* Whether channel is enabled for Rx (ENR) */
        int stopped_tx;         /* Whether channel has been stopped for Tx
@@ -194,8 +194,8 @@ struct ucc_slow_private {
        struct list_head confQ; /* frames passed to chip waiting for tx */
        u32 first_tx_bd_mask;   /* mask is used in Tx routine to save status
                                   and length for first BD in a frame */
-       u32 tx_base_offset;     /* first BD in Tx BD table offset (In MURAM) */
-       u32 rx_base_offset;     /* first BD in Rx BD table offset (In MURAM) */
+       s32 tx_base_offset;     /* first BD in Tx BD table offset (In MURAM) */
+       s32 rx_base_offset;     /* first BD in Rx BD table offset (In MURAM) */
        struct qe_bd *confBd;   /* next BD for confirm after Tx */
        struct qe_bd *tx_bd;    /* next BD for new Tx request */
        struct qe_bd *rx_bd;    /* next BD to collect after Rx */
diff --git a/include/sound/aess.h b/include/sound/aess.h
deleted file mode 100644 (file)
index cee0d09..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * AESS IP block reset
- *
- * Copyright (C) 2012 Texas Instruments, Inc.
- * Paul Walmsley
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any
- * kind, whether express or implied; without even the implied warranty
- * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- */
-#ifndef __SOUND_AESS_H__
-#define __SOUND_AESS_H__
-
-#include <linux/kernel.h>
-#include <linux/io.h>
-
-/*
- * AESS_AUTO_GATING_ENABLE_OFFSET: offset in bytes of the AESS IP
- *     block's AESS_AUTO_GATING_ENABLE__1 register from the IP block's
- *     base address
- */
-#define AESS_AUTO_GATING_ENABLE_OFFSET                 0x07c
-
-/* Register bitfields in the AESS_AUTO_GATING_ENABLE__1 register */
-#define AESS_AUTO_GATING_ENABLE_SHIFT                  0
-
-/**
- * aess_enable_autogating - enable AESS internal autogating
- * @oh: struct omap_hwmod *
- *
- * Enable internal autogating on the AESS.  This allows the AESS to
- * indicate that it is idle to the OMAP PRCM.  Returns 0.
- */
-static inline void aess_enable_autogating(void __iomem *base)
-{
-       u32 v;
-
-       /* Set AESS_AUTO_GATING_ENABLE__1.ENABLE to allow idle entry */
-       v = 1 << AESS_AUTO_GATING_ENABLE_SHIFT;
-       writel(v, base + AESS_AUTO_GATING_ENABLE_OFFSET);
-}
-
-#endif /* __SOUND_AESS_H__ */
index 5a31525..f657ff0 100644 (file)
@@ -1450,7 +1450,7 @@ struct snd_pcm_status64 {
 #define SNDRV_PCM_IOCTL_STATUS_EXT64   _IOWR('A', 0x24, struct snd_pcm_status64)
 
 struct snd_pcm_status32 {
-       s32 state;              /* stream state */
+       snd_pcm_state_t state;          /* stream state */
        s32 trigger_tstamp_sec; /* time when stream was started/stopped/paused */
        s32 trigger_tstamp_nsec;
        s32 tstamp_sec;         /* reference timestamp */
@@ -1461,7 +1461,7 @@ struct snd_pcm_status32 {
        u32 avail;              /* number of frames available */
        u32 avail_max;          /* max frames available on hw since last status */
        u32 overrange;          /* count of ADC (capture) overrange detections from last status */
-       s32 suspended_state;    /* suspended stream state */
+       snd_pcm_state_t suspended_state;        /* suspended stream state */
        u32 audio_tstamp_data;  /* needed for 64-bit alignment, used for configs/report to/from userspace */
        s32 audio_tstamp_sec;   /* sample counter, wall clock, PHC or on-demand sync'ed */
        s32 audio_tstamp_nsec;
index 54e61d4..112bd06 100644 (file)
@@ -49,12 +49,6 @@ DEFINE_EVENT(dma_map, map_single,
        TP_ARGS(dev, dev_addr, phys_addr, size)
 );
 
-DEFINE_EVENT(dma_map, map_sg,
-       TP_PROTO(struct device *dev, dma_addr_t dev_addr, phys_addr_t phys_addr,
-                size_t size),
-       TP_ARGS(dev, dev_addr, phys_addr, size)
-);
-
 DEFINE_EVENT(dma_map, bounce_map_single,
        TP_PROTO(struct device *dev, dma_addr_t dev_addr, phys_addr_t phys_addr,
                 size_t size),
@@ -99,6 +93,48 @@ DEFINE_EVENT(dma_unmap, bounce_unmap_single,
        TP_ARGS(dev, dev_addr, size)
 );
 
+DECLARE_EVENT_CLASS(dma_map_sg,
+       TP_PROTO(struct device *dev, int index, int total,
+                struct scatterlist *sg),
+
+       TP_ARGS(dev, index, total, sg),
+
+       TP_STRUCT__entry(
+               __string(dev_name, dev_name(dev))
+               __field(dma_addr_t, dev_addr)
+               __field(phys_addr_t, phys_addr)
+               __field(size_t, size)
+               __field(int, index)
+               __field(int, total)
+       ),
+
+       TP_fast_assign(
+               __assign_str(dev_name, dev_name(dev));
+               __entry->dev_addr = sg->dma_address;
+               __entry->phys_addr = sg_phys(sg);
+               __entry->size = sg->dma_length;
+               __entry->index = index;
+               __entry->total = total;
+       ),
+
+       TP_printk("dev=%s [%d/%d] dev_addr=0x%llx phys_addr=0x%llx size=%zu",
+                 __get_str(dev_name), __entry->index, __entry->total,
+                 (unsigned long long)__entry->dev_addr,
+                 (unsigned long long)__entry->phys_addr,
+                 __entry->size)
+);
+
+DEFINE_EVENT(dma_map_sg, map_sg,
+       TP_PROTO(struct device *dev, int index, int total,
+                struct scatterlist *sg),
+       TP_ARGS(dev, index, total, sg)
+);
+
+DEFINE_EVENT(dma_map_sg, bounce_map_sg,
+       TP_PROTO(struct device *dev, int index, int total,
+                struct scatterlist *sg),
+       TP_ARGS(dev, index, total, sg)
+);
 #endif /* _TRACE_INTEL_IOMMU_H */
 
 /* This part must be outside protection */
diff --git a/include/trace/events/pwm.h b/include/trace/events/pwm.h
new file mode 100644 (file)
index 0000000..cf243de
--- /dev/null
@@ -0,0 +1,58 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM pwm
+
+#if !defined(_TRACE_PWM_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_PWM_H
+
+#include <linux/pwm.h>
+#include <linux/tracepoint.h>
+
+DECLARE_EVENT_CLASS(pwm,
+
+       TP_PROTO(struct pwm_device *pwm, const struct pwm_state *state),
+
+       TP_ARGS(pwm, state),
+
+       TP_STRUCT__entry(
+               __field(struct pwm_device *, pwm)
+               __field(u64, period)
+               __field(u64, duty_cycle)
+               __field(enum pwm_polarity, polarity)
+               __field(bool, enabled)
+       ),
+
+       TP_fast_assign(
+               __entry->pwm = pwm;
+               __entry->period = state->period;
+               __entry->duty_cycle = state->duty_cycle;
+               __entry->polarity = state->polarity;
+               __entry->enabled = state->enabled;
+       ),
+
+       TP_printk("%p: period=%llu duty_cycle=%llu polarity=%d enabled=%d",
+                 __entry->pwm, __entry->period, __entry->duty_cycle,
+                 __entry->polarity, __entry->enabled)
+
+);
+
+DEFINE_EVENT(pwm, pwm_apply,
+
+       TP_PROTO(struct pwm_device *pwm, const struct pwm_state *state),
+
+       TP_ARGS(pwm, state)
+
+);
+
+DEFINE_EVENT(pwm, pwm_get,
+
+       TP_PROTO(struct pwm_device *pwm, const struct pwm_state *state),
+
+       TP_ARGS(pwm, state)
+
+);
+
+#endif /* _TRACE_PWM_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
index 1879058..c0e4c93 100644 (file)
@@ -729,6 +729,7 @@ TRACE_EVENT(xprtrdma_post_send,
 
        TP_STRUCT__entry(
                __field(const void *, req)
+               __field(const void *, sc)
                __field(unsigned int, task_id)
                __field(unsigned int, client_id)
                __field(int, num_sge)
@@ -743,14 +744,15 @@ 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->sc = req->rl_sendctx;
                __entry->num_sge = req->rl_wr.num_sge;
                __entry->signaled = req->rl_wr.send_flags & IB_SEND_SIGNALED;
                __entry->status = status;
        ),
 
-       TP_printk("task:%u@%u req=%p (%d SGE%s) %sstatus=%d",
+       TP_printk("task:%u@%u req=%p sc=%p (%d SGE%s) %sstatus=%d",
                __entry->task_id, __entry->client_id,
-               __entry->req, __entry->num_sge,
+               __entry->req, __entry->sc, __entry->num_sge,
                (__entry->num_sge == 1 ? "" : "s"),
                (__entry->signaled ? "signaled " : ""),
                __entry->status
@@ -849,6 +851,7 @@ TRACE_EVENT(xprtrdma_wc_send,
 
        TP_STRUCT__entry(
                __field(const void *, req)
+               __field(const void *, sc)
                __field(unsigned int, unmap_count)
                __field(unsigned int, status)
                __field(unsigned int, vendor_err)
@@ -856,13 +859,14 @@ TRACE_EVENT(xprtrdma_wc_send,
 
        TP_fast_assign(
                __entry->req = sc->sc_req;
+               __entry->sc = sc;
                __entry->unmap_count = sc->sc_unmap_count;
                __entry->status = wc->status;
                __entry->vendor_err = __entry->status ? wc->vendor_err : 0;
        ),
 
-       TP_printk("req=%p, unmapped %u pages: %s (%u/0x%x)",
-               __entry->req, __entry->unmap_count,
+       TP_printk("req=%p sc=%p unmapped=%u: %s (%u/0x%x)",
+               __entry->req, __entry->sc, __entry->unmap_count,
                rdma_show_wc_status(__entry->status),
                __entry->status, __entry->vendor_err
        )
diff --git a/include/trace/events/scmi.h b/include/trace/events/scmi.h
new file mode 100644 (file)
index 0000000..f076c43
--- /dev/null
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#undef TRACE_SYSTEM
+#define TRACE_SYSTEM scmi
+
+#if !defined(_TRACE_SCMI_H) || defined(TRACE_HEADER_MULTI_READ)
+#define _TRACE_SCMI_H
+
+#include <linux/tracepoint.h>
+
+TRACE_EVENT(scmi_xfer_begin,
+       TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
+                bool poll),
+       TP_ARGS(transfer_id, msg_id, protocol_id, seq, poll),
+
+       TP_STRUCT__entry(
+               __field(int, transfer_id)
+               __field(u8, msg_id)
+               __field(u8, protocol_id)
+               __field(u16, seq)
+               __field(bool, poll)
+       ),
+
+       TP_fast_assign(
+               __entry->transfer_id = transfer_id;
+               __entry->msg_id = msg_id;
+               __entry->protocol_id = protocol_id;
+               __entry->seq = seq;
+               __entry->poll = poll;
+       ),
+
+       TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u poll=%u",
+               __entry->transfer_id, __entry->msg_id, __entry->protocol_id,
+               __entry->seq, __entry->poll)
+);
+
+TRACE_EVENT(scmi_xfer_end,
+       TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
+                u32 status),
+       TP_ARGS(transfer_id, msg_id, protocol_id, seq, status),
+
+       TP_STRUCT__entry(
+               __field(int, transfer_id)
+               __field(u8, msg_id)
+               __field(u8, protocol_id)
+               __field(u16, seq)
+               __field(u32, status)
+       ),
+
+       TP_fast_assign(
+               __entry->transfer_id = transfer_id;
+               __entry->msg_id = msg_id;
+               __entry->protocol_id = protocol_id;
+               __entry->seq = seq;
+               __entry->status = status;
+       ),
+
+       TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u status=%u",
+               __entry->transfer_id, __entry->msg_id, __entry->protocol_id,
+               __entry->seq, __entry->status)
+);
+
+TRACE_EVENT(scmi_rx_done,
+       TP_PROTO(int transfer_id, u8 msg_id, u8 protocol_id, u16 seq,
+                u8 msg_type),
+       TP_ARGS(transfer_id, msg_id, protocol_id, seq, msg_type),
+
+       TP_STRUCT__entry(
+               __field(int, transfer_id)
+               __field(u8, msg_id)
+               __field(u8, protocol_id)
+               __field(u16, seq)
+               __field(u8, msg_type)
+       ),
+
+       TP_fast_assign(
+               __entry->transfer_id = transfer_id;
+               __entry->msg_id = msg_id;
+               __entry->protocol_id = protocol_id;
+               __entry->seq = seq;
+               __entry->msg_type = msg_type;
+       ),
+
+       TP_printk("transfer_id=%d msg_id=%u protocol_id=%u seq=%u msg_type=%u",
+               __entry->transfer_id, __entry->msg_id, __entry->protocol_id,
+               __entry->seq, __entry->msg_type)
+);
+#endif /* _TRACE_SCMI_H */
+
+/* This part must be outside protection */
+#include <trace/define_trace.h>
index 8c73ffb..ee99357 100644 (file)
@@ -185,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(signalled);
 DEFINE_RPC_RUNNING_EVENT(end);
 
 DECLARE_EVENT_CLASS(rpc_task_queued,
index 96d77e5..502c7be 100644 (file)
@@ -2,7 +2,8 @@
 /*
  * Stage 1 of the trace events.
  *
- * Override the macros in <trace/trace_events.h> to include the following:
+ * Override the macros in the event tracepoint header <trace/events/XXX.h>
+ * to include the following:
  *
  * struct trace_event_raw_<call> {
  *     struct trace_entry              ent;
@@ -223,7 +224,8 @@ TRACE_MAKE_SYSTEM_STR();
 /*
  * Stage 3 of the trace events.
  *
- * Override the macros in <trace/trace_events.h> to include the following:
+ * Override the macros in the event tracepoint header <trace/events/XXX.h>
+ * to include the following:
  *
  * enum print_line_t
  * trace_raw_output_<call>(struct trace_iterator *iter, int flags)
@@ -533,7 +535,8 @@ static inline notrace int trace_event_get_offsets_##call(           \
 /*
  * Stage 4 of the trace events.
  *
- * Override the macros in <trace/trace_events.h> to include the following:
+ * Override the macros in the event tracepoint header <trace/events/XXX.h>
+ * to include the following:
  *
  * For those macros defined with TRACE_EVENT:
  *
@@ -548,7 +551,7 @@ static inline notrace int trace_event_get_offsets_##call(           \
  *     enum event_trigger_type __tt = ETT_NONE;
  *     struct ring_buffer_event *event;
  *     struct trace_event_raw_<call> *entry; <-- defined in stage 1
- *     struct ring_buffer *buffer;
+ *     struct trace_buffer *buffer;
  *     unsigned long irq_flags;
  *     int __data_size;
  *     int pc;
index f0a16b4..4b95f9a 100644 (file)
@@ -1009,6 +1009,7 @@ struct kvm_ppc_resize_hpt {
 #define KVM_CAP_PPC_GUEST_DEBUG_SSTEP 176
 #define KVM_CAP_ARM_NISV_TO_USER 177
 #define KVM_CAP_ARM_INJECT_EXT_DABT 178
+#define KVM_CAP_S390_VCPU_RESETS 179
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
@@ -1473,6 +1474,10 @@ struct kvm_enc_region {
 /* Available with KVM_CAP_ARM_SVE */
 #define KVM_ARM_VCPU_FINALIZE    _IOW(KVMIO,  0xc2, int)
 
+/* Available with  KVM_CAP_S390_VCPU_RESETS */
+#define KVM_S390_NORMAL_RESET  _IO(KVMIO,   0xc3)
+#define KVM_S390_CLEAR_RESET   _IO(KVMIO,   0xc4)
+
 /* Secure Encrypted Virtualization command */
 enum sev_cmd_id {
        /* Guest initialization commands */
index 2ad1788..095af36 100644 (file)
@@ -92,7 +92,12 @@ struct rtc_pll_info {
 #define RTC_PLL_GET    _IOR('p', 0x11, struct rtc_pll_info)  /* Get PLL correction */
 #define RTC_PLL_SET    _IOW('p', 0x12, struct rtc_pll_info)  /* Set PLL correction */
 
-#define RTC_VL_READ    _IOR('p', 0x13, int)    /* Voltage low detector */
+#define RTC_VL_DATA_INVALID    BIT(0) /* Voltage too low, RTC data is invalid */
+#define RTC_VL_BACKUP_LOW      BIT(1) /* Backup voltage is low */
+#define RTC_VL_BACKUP_EMPTY    BIT(2) /* Backup empty or not present */
+#define RTC_VL_ACCURACY_LOW    BIT(3) /* Voltage is low, RTC accuracy is reduced */
+
+#define RTC_VL_READ    _IOR('p', 0x13, unsigned int)   /* Voltage low detection */
 #define RTC_VL_CLR     _IO('p', 0x14)          /* Clear voltage low information */
 
 /* interrupt flags */
index 30ebb2a..535a722 100644 (file)
@@ -564,13 +564,13 @@ typedef char __pad_after_uframe[sizeof(__u64) - sizeof(snd_pcm_uframes_t)];
 #endif
 
 struct __snd_pcm_mmap_status64 {
-       __s32 state;                    /* RO: state - SNDRV_PCM_STATE_XXXX */
+       snd_pcm_state_t state;          /* RO: state - SNDRV_PCM_STATE_XXXX */
        __u32 pad1;                     /* Needed for 64 bit alignment */
        __pad_before_uframe __pad1;
        snd_pcm_uframes_t hw_ptr;       /* RO: hw ptr (0...boundary-1) */
        __pad_after_uframe __pad2;
        struct __snd_timespec64 tstamp; /* Timestamp */
-       __s32 suspended_state;          /* RO: suspended stream state */
+       snd_pcm_state_t suspended_state;/* RO: suspended stream state */
        __u32 pad3;                     /* Needed for 64 bit alignment */
        struct __snd_timespec64 audio_tstamp; /* sample counter or wall clock */
 };
index 24228a1..89a8895 100644 (file)
@@ -76,6 +76,7 @@ struct xenbus_device {
        enum xenbus_state state;
        struct completion down;
        struct work_struct work;
+       spinlock_t reclaim_lock;
 };
 
 static inline struct xenbus_device *to_xenbus_device(struct device *dev)
@@ -105,6 +106,7 @@ struct xenbus_driver {
        struct device_driver driver;
        int (*read_otherend_details)(struct xenbus_device *dev);
        int (*is_ready)(struct xenbus_device *dev);
+       void (*reclaim_memory)(struct xenbus_device *dev);
 };
 
 static inline struct xenbus_driver *to_xenbus_driver(struct device_driver *drv)
index 24b23d8..cfee56c 100644 (file)
@@ -1224,6 +1224,20 @@ source "usr/Kconfig"
 
 endif
 
+config BOOT_CONFIG
+       bool "Boot config support"
+       depends on BLK_DEV_INITRD
+       select LIBXBC
+       default y
+       help
+         Extra boot config allows system admin to pass a config file as
+         complemental extension of kernel cmdline when booting.
+         The boot config file must be attached at the end of initramfs
+         with checksum and size.
+         See <file:Documentation/admin-guide/bootconfig.rst> for details.
+
+         If unsure, say Y.
+
 choice
        prompt "Compiler optimization level"
        default CC_OPTIMIZE_FOR_PERFORMANCE
index d8c7e86..cc0ee48 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/initrd.h>
 #include <linux/memblock.h>
 #include <linux/acpi.h>
+#include <linux/bootconfig.h>
 #include <linux/console.h>
 #include <linux/nmi.h>
 #include <linux/percpu.h>
@@ -136,8 +137,10 @@ char __initdata boot_command_line[COMMAND_LINE_SIZE];
 char *saved_command_line;
 /* Command line for parameter parsing */
 static char *static_command_line;
-/* Command line for per-initcall parameter parsing */
-static char *initcall_command_line;
+/* Untouched extra command line */
+static char *extra_command_line;
+/* Extra init arguments */
+static char *extra_init_args;
 
 static char *execute_command;
 static char *ramdisk_execute_command;
@@ -245,6 +248,156 @@ static int __init loglevel(char *str)
 
 early_param("loglevel", loglevel);
 
+#ifdef CONFIG_BOOT_CONFIG
+
+char xbc_namebuf[XBC_KEYLEN_MAX] __initdata;
+
+#define rest(dst, end) ((end) > (dst) ? (end) - (dst) : 0)
+
+static int __init xbc_snprint_cmdline(char *buf, size_t size,
+                                     struct xbc_node *root)
+{
+       struct xbc_node *knode, *vnode;
+       char *end = buf + size;
+       char c = '\"';
+       const char *val;
+       int ret;
+
+       xbc_node_for_each_key_value(root, knode, val) {
+               ret = xbc_node_compose_key_after(root, knode,
+                                       xbc_namebuf, XBC_KEYLEN_MAX);
+               if (ret < 0)
+                       return ret;
+
+               vnode = xbc_node_get_child(knode);
+               ret = snprintf(buf, rest(buf, end), "%s%c", xbc_namebuf,
+                               vnode ? '=' : ' ');
+               if (ret < 0)
+                       return ret;
+               buf += ret;
+               if (!vnode)
+                       continue;
+
+               c = '\"';
+               xbc_array_for_each_value(vnode, val) {
+                       ret = snprintf(buf, rest(buf, end), "%c%s", c, val);
+                       if (ret < 0)
+                               return ret;
+                       buf += ret;
+                       c = ',';
+               }
+               if (rest(buf, end) > 2)
+                       strcpy(buf, "\" ");
+               buf += 2;
+       }
+
+       return buf - (end - size);
+}
+#undef rest
+
+/* Make an extra command line under given key word */
+static char * __init xbc_make_cmdline(const char *key)
+{
+       struct xbc_node *root;
+       char *new_cmdline;
+       int ret, len = 0;
+
+       root = xbc_find_node(key);
+       if (!root)
+               return NULL;
+
+       /* Count required buffer size */
+       len = xbc_snprint_cmdline(NULL, 0, root);
+       if (len <= 0)
+               return NULL;
+
+       new_cmdline = memblock_alloc(len + 1, SMP_CACHE_BYTES);
+       if (!new_cmdline) {
+               pr_err("Failed to allocate memory for extra kernel cmdline.\n");
+               return NULL;
+       }
+
+       ret = xbc_snprint_cmdline(new_cmdline, len + 1, root);
+       if (ret < 0 || ret > len) {
+               pr_err("Failed to print extra kernel cmdline.\n");
+               return NULL;
+       }
+
+       return new_cmdline;
+}
+
+u32 boot_config_checksum(unsigned char *p, u32 size)
+{
+       u32 ret = 0;
+
+       while (size--)
+               ret += *p++;
+
+       return ret;
+}
+
+static void __init setup_boot_config(const char *cmdline)
+{
+       u32 size, csum;
+       char *data, *copy;
+       const char *p;
+       u32 *hdr;
+       int ret;
+
+       p = strstr(cmdline, "bootconfig");
+       if (!p || (p != cmdline && !isspace(*(p-1))) ||
+           (p[10] && !isspace(p[10])))
+               return;
+
+       if (!initrd_end)
+               goto not_found;
+
+       hdr = (u32 *)(initrd_end - 8);
+       size = hdr[0];
+       csum = hdr[1];
+
+       if (size >= XBC_DATA_MAX) {
+               pr_err("bootconfig size %d greater than max size %d\n",
+                       size, XBC_DATA_MAX);
+               return;
+       }
+
+       data = ((void *)hdr) - size;
+       if ((unsigned long)data < initrd_start)
+               goto not_found;
+
+       if (boot_config_checksum((unsigned char *)data, size) != csum) {
+               pr_err("bootconfig checksum failed\n");
+               return;
+       }
+
+       copy = memblock_alloc(size + 1, SMP_CACHE_BYTES);
+       if (!copy) {
+               pr_err("Failed to allocate memory for bootconfig\n");
+               return;
+       }
+
+       memcpy(copy, data, size);
+       copy[size] = '\0';
+
+       ret = xbc_init(copy);
+       if (ret < 0)
+               pr_err("Failed to parse bootconfig\n");
+       else {
+               pr_info("Load bootconfig: %d bytes %d nodes\n", size, ret);
+               /* keys starting with "kernel." are passed via cmdline */
+               extra_command_line = xbc_make_cmdline("kernel");
+               /* Also, "init." keys are init arguments */
+               extra_init_args = xbc_make_cmdline("init");
+       }
+       return;
+not_found:
+       pr_err("'bootconfig' found on command line, but no bootconfig found\n");
+}
+#else
+#define setup_boot_config(cmdline)     do { } while (0)
+#endif
+
 /* Change NUL term back to "=", to make "param" the whole string. */
 static void __init repair_env_string(char *param, char *val)
 {
@@ -373,22 +526,50 @@ static inline void smp_prepare_cpus(unsigned int maxcpus) { }
  */
 static void __init setup_command_line(char *command_line)
 {
-       size_t len = strlen(boot_command_line) + 1;
+       size_t len, xlen = 0, ilen = 0;
 
-       saved_command_line = memblock_alloc(len, SMP_CACHE_BYTES);
-       if (!saved_command_line)
-               panic("%s: Failed to allocate %zu bytes\n", __func__, len);
+       if (extra_command_line)
+               xlen = strlen(extra_command_line);
+       if (extra_init_args)
+               ilen = strlen(extra_init_args) + 4; /* for " -- " */
 
-       initcall_command_line = memblock_alloc(len, SMP_CACHE_BYTES);
-       if (!initcall_command_line)
-               panic("%s: Failed to allocate %zu bytes\n", __func__, len);
+       len = xlen + strlen(boot_command_line) + 1;
+
+       saved_command_line = memblock_alloc(len + ilen, SMP_CACHE_BYTES);
+       if (!saved_command_line)
+               panic("%s: Failed to allocate %zu bytes\n", __func__, len + ilen);
 
        static_command_line = memblock_alloc(len, SMP_CACHE_BYTES);
        if (!static_command_line)
                panic("%s: Failed to allocate %zu bytes\n", __func__, len);
 
-       strcpy(saved_command_line, boot_command_line);
-       strcpy(static_command_line, command_line);
+       if (xlen) {
+               /*
+                * We have to put extra_command_line before boot command
+                * lines because there could be dashes (separator of init
+                * command line) in the command lines.
+                */
+               strcpy(saved_command_line, extra_command_line);
+               strcpy(static_command_line, extra_command_line);
+       }
+       strcpy(saved_command_line + xlen, boot_command_line);
+       strcpy(static_command_line + xlen, command_line);
+
+       if (ilen) {
+               /*
+                * Append supplemental init boot args to saved_command_line
+                * so that user can check what command line options passed
+                * to init.
+                */
+               len = strlen(saved_command_line);
+               if (!strstr(boot_command_line, " -- ")) {
+                       strcpy(saved_command_line + len, " -- ");
+                       len += 4;
+               } else
+                       saved_command_line[len++] = ' ';
+
+               strcpy(saved_command_line + len, extra_init_args);
+       }
 }
 
 /*
@@ -595,6 +776,7 @@ asmlinkage __visible void __init start_kernel(void)
        pr_notice("%s", linux_banner);
        early_security_init();
        setup_arch(&command_line);
+       setup_boot_config(command_line);
        setup_command_line(command_line);
        setup_nr_cpu_ids();
        setup_per_cpu_areas();
@@ -604,7 +786,7 @@ asmlinkage __visible void __init start_kernel(void)
        build_all_zonelists(NULL);
        page_alloc_init();
 
-       pr_notice("Kernel command line: %s\n", boot_command_line);
+       pr_notice("Kernel command line: %s\n", saved_command_line);
        /* parameters may set static keys */
        jump_label_init();
        parse_early_param();
@@ -615,6 +797,9 @@ asmlinkage __visible void __init start_kernel(void)
        if (!IS_ERR_OR_NULL(after_dashes))
                parse_args("Setting init args", after_dashes, NULL, 0, -1, -1,
                           NULL, set_init_arg);
+       if (extra_init_args)
+               parse_args("Setting extra init args", extra_init_args,
+                          NULL, 0, -1, -1, NULL, set_init_arg);
 
        /*
         * These use large bootmem allocations and must precede
@@ -996,13 +1181,12 @@ static int __init ignore_unknown_bootoption(char *param, char *val,
        return 0;
 }
 
-static void __init do_initcall_level(int level)
+static void __init do_initcall_level(int level, char *command_line)
 {
        initcall_entry_t *fn;
 
-       strcpy(initcall_command_line, saved_command_line);
        parse_args(initcall_level_names[level],
-                  initcall_command_line, __start___param,
+                  command_line, __start___param,
                   __stop___param - __start___param,
                   level, level,
                   NULL, ignore_unknown_bootoption);
@@ -1015,9 +1199,20 @@ static void __init do_initcall_level(int level)
 static void __init do_initcalls(void)
 {
        int level;
+       size_t len = strlen(saved_command_line) + 1;
+       char *command_line;
+
+       command_line = kzalloc(len, GFP_KERNEL);
+       if (!command_line)
+               panic("%s: Failed to allocate %zu bytes\n", __func__, len);
+
+       for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++) {
+               /* Parser modifies command_line, restore it each time */
+               strcpy(command_line, saved_command_line);
+               do_initcall_level(level, command_line);
+       }
 
-       for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
-               do_initcall_level(level);
+       kfree(command_line);
 }
 
 /*
index 3d920ff..49a05ba 100644 (file)
@@ -63,6 +63,66 @@ struct posix_msg_tree_node {
        int                     priority;
 };
 
+/*
+ * Locking:
+ *
+ * Accesses to a message queue are synchronized by acquiring info->lock.
+ *
+ * There are two notable exceptions:
+ * - The actual wakeup of a sleeping task is performed using the wake_q
+ *   framework. info->lock is already released when wake_up_q is called.
+ * - The exit codepaths after sleeping check ext_wait_queue->state without
+ *   any locks. If it is STATE_READY, then the syscall is completed without
+ *   acquiring info->lock.
+ *
+ * MQ_BARRIER:
+ * To achieve proper release/acquire memory barrier pairing, the state is set to
+ * STATE_READY with smp_store_release(), and it is read with READ_ONCE followed
+ * by smp_acquire__after_ctrl_dep(). In addition, wake_q_add_safe() is used.
+ *
+ * This prevents the following races:
+ *
+ * 1) With the simple wake_q_add(), the task could be gone already before
+ *    the increase of the reference happens
+ * Thread A
+ *                             Thread B
+ * WRITE_ONCE(wait.state, STATE_NONE);
+ * schedule_hrtimeout()
+ *                             wake_q_add(A)
+ *                             if (cmpxchg()) // success
+ *                                ->state = STATE_READY (reordered)
+ * <timeout returns>
+ * if (wait.state == STATE_READY) return;
+ * sysret to user space
+ * sys_exit()
+ *                             get_task_struct() // UaF
+ *
+ * Solution: Use wake_q_add_safe() and perform the get_task_struct() before
+ * the smp_store_release() that does ->state = STATE_READY.
+ *
+ * 2) Without proper _release/_acquire barriers, the woken up task
+ *    could read stale data
+ *
+ * Thread A
+ *                             Thread B
+ * do_mq_timedreceive
+ * WRITE_ONCE(wait.state, STATE_NONE);
+ * schedule_hrtimeout()
+ *                             state = STATE_READY;
+ * <timeout returns>
+ * if (wait.state == STATE_READY) return;
+ * msg_ptr = wait.msg;         // Access to stale data!
+ *                             receiver->msg = message; (reordered)
+ *
+ * Solution: use _release and _acquire barriers.
+ *
+ * 3) There is intentionally no barrier when setting current->state
+ *    to TASK_INTERRUPTIBLE: spin_unlock(&info->lock) provides the
+ *    release memory barrier, and the wakeup is triggered when holding
+ *    info->lock, i.e. spin_lock(&info->lock) provided a pairing
+ *    acquire memory barrier.
+ */
+
 struct ext_wait_queue {                /* queue of sleeping tasks */
        struct task_struct *task;
        struct list_head list;
@@ -646,18 +706,23 @@ static int wq_sleep(struct mqueue_inode_info *info, int sr,
        wq_add(info, sr, ewp);
 
        for (;;) {
+               /* memory barrier not required, we hold info->lock */
                __set_current_state(TASK_INTERRUPTIBLE);
 
                spin_unlock(&info->lock);
                time = schedule_hrtimeout_range_clock(timeout, 0,
                        HRTIMER_MODE_ABS, CLOCK_REALTIME);
 
-               if (ewp->state == STATE_READY) {
+               if (READ_ONCE(ewp->state) == STATE_READY) {
+                       /* see MQ_BARRIER for purpose/pairing */
+                       smp_acquire__after_ctrl_dep();
                        retval = 0;
                        goto out;
                }
                spin_lock(&info->lock);
-               if (ewp->state == STATE_READY) {
+
+               /* we hold info->lock, so no memory barrier required */
+               if (READ_ONCE(ewp->state) == STATE_READY) {
                        retval = 0;
                        goto out_unlock;
                }
@@ -918,6 +983,18 @@ out_name:
  * The same algorithm is used for senders.
  */
 
+static inline void __pipelined_op(struct wake_q_head *wake_q,
+                                 struct mqueue_inode_info *info,
+                                 struct ext_wait_queue *this)
+{
+       list_del(&this->list);
+       get_task_struct(this->task);
+
+       /* see MQ_BARRIER for purpose/pairing */
+       smp_store_release(&this->state, STATE_READY);
+       wake_q_add_safe(wake_q, this->task);
+}
+
 /* pipelined_send() - send a message directly to the task waiting in
  * sys_mq_timedreceive() (without inserting message into a queue).
  */
@@ -927,17 +1004,7 @@ static inline void pipelined_send(struct wake_q_head *wake_q,
                                  struct ext_wait_queue *receiver)
 {
        receiver->msg = message;
-       list_del(&receiver->list);
-       wake_q_add(wake_q, receiver->task);
-       /*
-        * Rely on the implicit cmpxchg barrier from wake_q_add such
-        * that we can ensure that updating receiver->state is the last
-        * write operation: As once set, the receiver can continue,
-        * and if we don't have the reference count from the wake_q,
-        * yet, at that point we can later have a use-after-free
-        * condition and bogus wakeup.
-        */
-       receiver->state = STATE_READY;
+       __pipelined_op(wake_q, info, receiver);
 }
 
 /* pipelined_receive() - if there is task waiting in sys_mq_timedsend()
@@ -955,9 +1022,7 @@ static inline void pipelined_receive(struct wake_q_head *wake_q,
        if (msg_insert(sender->msg, info))
                return;
 
-       list_del(&sender->list);
-       wake_q_add(wake_q, sender->task);
-       sender->state = STATE_READY;
+       __pipelined_op(wake_q, info, sender);
 }
 
 static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
@@ -1044,7 +1109,9 @@ static int do_mq_timedsend(mqd_t mqdes, const char __user *u_msg_ptr,
                } else {
                        wait.task = current;
                        wait.msg = (void *) msg_ptr;
-                       wait.state = STATE_NONE;
+
+                       /* memory barrier not required, we hold info->lock */
+                       WRITE_ONCE(wait.state, STATE_NONE);
                        ret = wq_sleep(info, SEND, timeout, &wait);
                        /*
                         * wq_sleep must be called with info->lock held, and
@@ -1147,7 +1214,9 @@ static int do_mq_timedreceive(mqd_t mqdes, char __user *u_msg_ptr,
                        ret = -EAGAIN;
                } else {
                        wait.task = current;
-                       wait.state = STATE_NONE;
+
+                       /* memory barrier not required, we hold info->lock */
+                       WRITE_ONCE(wait.state, STATE_NONE);
                        ret = wq_sleep(info, RECV, timeout, &wait);
                        msg_ptr = wait.msg;
                }
index 8dec945..caca673 100644 (file)
--- a/ipc/msg.c
+++ b/ipc/msg.c
@@ -61,6 +61,16 @@ struct msg_queue {
        struct list_head q_senders;
 } __randomize_layout;
 
+/*
+ * MSG_BARRIER Locking:
+ *
+ * Similar to the optimization used in ipc/mqueue.c, one syscall return path
+ * does not acquire any locks when it sees that a message exists in
+ * msg_receiver.r_msg. Therefore r_msg is set using smp_store_release()
+ * and accessed using READ_ONCE()+smp_acquire__after_ctrl_dep(). In addition,
+ * wake_q_add_safe() is used. See ipc/mqueue.c for more details
+ */
+
 /* one msg_receiver structure for each sleeping receiver */
 struct msg_receiver {
        struct list_head        r_list;
@@ -184,6 +194,10 @@ static inline void ss_add(struct msg_queue *msq,
 {
        mss->tsk = current;
        mss->msgsz = msgsz;
+       /*
+        * No memory barrier required: we did ipc_lock_object(),
+        * and the waker obtains that lock before calling wake_q_add().
+        */
        __set_current_state(TASK_INTERRUPTIBLE);
        list_add_tail(&mss->list, &msq->q_senders);
 }
@@ -237,8 +251,11 @@ static void expunge_all(struct msg_queue *msq, int res,
        struct msg_receiver *msr, *t;
 
        list_for_each_entry_safe(msr, t, &msq->q_receivers, r_list) {
-               wake_q_add(wake_q, msr->r_tsk);
-               WRITE_ONCE(msr->r_msg, ERR_PTR(res));
+               get_task_struct(msr->r_tsk);
+
+               /* see MSG_BARRIER for purpose/pairing */
+               smp_store_release(&msr->r_msg, ERR_PTR(res));
+               wake_q_add_safe(wake_q, msr->r_tsk);
        }
 }
 
@@ -377,7 +394,7 @@ copy_msqid_from_user(struct msqid64_ds *out, void __user *buf, int version)
  * NOTE: no locks must be held, the rwsem is taken inside this function.
  */
 static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
-                       struct msqid64_ds *msqid64)
+                       struct ipc64_perm *perm, int msg_qbytes)
 {
        struct kern_ipc_perm *ipcp;
        struct msg_queue *msq;
@@ -387,7 +404,7 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
        rcu_read_lock();
 
        ipcp = ipcctl_obtain_check(ns, &msg_ids(ns), msqid, cmd,
-                                     &msqid64->msg_perm, msqid64->msg_qbytes);
+                                     perm, msg_qbytes);
        if (IS_ERR(ipcp)) {
                err = PTR_ERR(ipcp);
                goto out_unlock1;
@@ -409,18 +426,18 @@ static int msgctl_down(struct ipc_namespace *ns, int msqid, int cmd,
        {
                DEFINE_WAKE_Q(wake_q);
 
-               if (msqid64->msg_qbytes > ns->msg_ctlmnb &&
+               if (msg_qbytes > ns->msg_ctlmnb &&
                    !capable(CAP_SYS_RESOURCE)) {
                        err = -EPERM;
                        goto out_unlock1;
                }
 
                ipc_lock_object(&msq->q_perm);
-               err = ipc_update_perm(&msqid64->msg_perm, ipcp);
+               err = ipc_update_perm(perm, ipcp);
                if (err)
                        goto out_unlock0;
 
-               msq->q_qbytes = msqid64->msg_qbytes;
+               msq->q_qbytes = msg_qbytes;
 
                msq->q_ctime = ktime_get_real_seconds();
                /*
@@ -601,9 +618,10 @@ static long ksys_msgctl(int msqid, int cmd, struct msqid_ds __user *buf, int ver
        case IPC_SET:
                if (copy_msqid_from_user(&msqid64, buf, version))
                        return -EFAULT;
-               /* fallthru */
+               return msgctl_down(ns, msqid, cmd, &msqid64.msg_perm,
+                                  msqid64.msg_qbytes);
        case IPC_RMID:
-               return msgctl_down(ns, msqid, cmd, &msqid64);
+               return msgctl_down(ns, msqid, cmd, NULL, 0);
        default:
                return  -EINVAL;
        }
@@ -735,9 +753,9 @@ static long compat_ksys_msgctl(int msqid, int cmd, void __user *uptr, int versio
        case IPC_SET:
                if (copy_compat_msqid_from_user(&msqid64, uptr, version))
                        return -EFAULT;
-               /* fallthru */
+               return msgctl_down(ns, msqid, cmd, &msqid64.msg_perm, msqid64.msg_qbytes);
        case IPC_RMID:
-               return msgctl_down(ns, msqid, cmd, &msqid64);
+               return msgctl_down(ns, msqid, cmd, NULL, 0);
        default:
                return -EINVAL;
        }
@@ -798,13 +816,17 @@ static inline int pipelined_send(struct msg_queue *msq, struct msg_msg *msg,
                        list_del(&msr->r_list);
                        if (msr->r_maxsize < msg->m_ts) {
                                wake_q_add(wake_q, msr->r_tsk);
-                               WRITE_ONCE(msr->r_msg, ERR_PTR(-E2BIG));
+
+                               /* See expunge_all regarding memory barrier */
+                               smp_store_release(&msr->r_msg, ERR_PTR(-E2BIG));
                        } else {
                                ipc_update_pid(&msq->q_lrpid, task_pid(msr->r_tsk));
                                msq->q_rtime = ktime_get_real_seconds();
 
                                wake_q_add(wake_q, msr->r_tsk);
-                               WRITE_ONCE(msr->r_msg, msg);
+
+                               /* See expunge_all regarding memory barrier */
+                               smp_store_release(&msr->r_msg, msg);
                                return 1;
                        }
                }
@@ -1154,7 +1176,11 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
                        msr_d.r_maxsize = INT_MAX;
                else
                        msr_d.r_maxsize = bufsz;
-               msr_d.r_msg = ERR_PTR(-EAGAIN);
+
+               /* memory barrier not require due to ipc_lock_object() */
+               WRITE_ONCE(msr_d.r_msg, ERR_PTR(-EAGAIN));
+
+               /* memory barrier not required, we own ipc_lock_object() */
                __set_current_state(TASK_INTERRUPTIBLE);
 
                ipc_unlock_object(&msq->q_perm);
@@ -1183,8 +1209,12 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
                 * signal) it will either see the message and continue ...
                 */
                msg = READ_ONCE(msr_d.r_msg);
-               if (msg != ERR_PTR(-EAGAIN))
+               if (msg != ERR_PTR(-EAGAIN)) {
+                       /* see MSG_BARRIER for purpose/pairing */
+                       smp_acquire__after_ctrl_dep();
+
                        goto out_unlock1;
+               }
 
                 /*
                  * ... or see -EAGAIN, acquire the lock to check the message
@@ -1192,7 +1222,7 @@ static long do_msgrcv(int msqid, void __user *buf, size_t bufsz, long msgtyp, in
                  */
                ipc_lock_object(&msq->q_perm);
 
-               msg = msr_d.r_msg;
+               msg = READ_ONCE(msr_d.r_msg);
                if (msg != ERR_PTR(-EAGAIN))
                        goto out_unlock0;
 
index ec97a70..4f4303f 100644 (file)
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -205,15 +205,38 @@ static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
  *
  * Memory ordering:
  * Most ordering is enforced by using spin_lock() and spin_unlock().
- * The special case is use_global_lock:
+ *
+ * Exceptions:
+ * 1) use_global_lock: (SEM_BARRIER_1)
  * Setting it from non-zero to 0 is a RELEASE, this is ensured by
- * using smp_store_release().
+ * using smp_store_release(): Immediately after setting it to 0,
+ * a simple op can start.
  * Testing if it is non-zero is an ACQUIRE, this is ensured by using
  * smp_load_acquire().
  * Setting it from 0 to non-zero must be ordered with regards to
  * this smp_load_acquire(), this is guaranteed because the smp_load_acquire()
  * is inside a spin_lock() and after a write from 0 to non-zero a
  * spin_lock()+spin_unlock() is done.
+ *
+ * 2) queue.status: (SEM_BARRIER_2)
+ * Initialization is done while holding sem_lock(), so no further barrier is
+ * required.
+ * Setting it to a result code is a RELEASE, this is ensured by both a
+ * smp_store_release() (for case a) and while holding sem_lock()
+ * (for case b).
+ * The AQUIRE when reading the result code without holding sem_lock() is
+ * achieved by using READ_ONCE() + smp_acquire__after_ctrl_dep().
+ * (case a above).
+ * Reading the result code while holding sem_lock() needs no further barriers,
+ * the locks inside sem_lock() enforce ordering (case b above)
+ *
+ * 3) current->state:
+ * current->state is set to TASK_INTERRUPTIBLE while holding sem_lock().
+ * The wakeup is handled using the wake_q infrastructure. wake_q wakeups may
+ * happen immediately after calling wake_q_add. As wake_q_add_safe() is called
+ * when holding sem_lock(), no further barriers are required.
+ *
+ * See also ipc/mqueue.c for more details on the covered races.
  */
 
 #define sc_semmsl      sem_ctls[0]
@@ -344,12 +367,8 @@ static void complexmode_tryleave(struct sem_array *sma)
                return;
        }
        if (sma->use_global_lock == 1) {
-               /*
-                * Immediately after setting use_global_lock to 0,
-                * a simple op can start. Thus: all memory writes
-                * performed by the current operation must be visible
-                * before we set use_global_lock to 0.
-                */
+
+               /* See SEM_BARRIER_1 for purpose/pairing */
                smp_store_release(&sma->use_global_lock, 0);
        } else {
                sma->use_global_lock--;
@@ -400,7 +419,7 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
                 */
                spin_lock(&sem->lock);
 
-               /* pairs with smp_store_release() */
+               /* see SEM_BARRIER_1 for purpose/pairing */
                if (!smp_load_acquire(&sma->use_global_lock)) {
                        /* fast path successful! */
                        return sops->sem_num;
@@ -766,15 +785,12 @@ would_block:
 static inline void wake_up_sem_queue_prepare(struct sem_queue *q, int error,
                                             struct wake_q_head *wake_q)
 {
-       wake_q_add(wake_q, q->sleeper);
-       /*
-        * Rely on the above implicit barrier, such that we can
-        * ensure that we hold reference to the task before setting
-        * q->status. Otherwise we could race with do_exit if the
-        * task is awoken by an external event before calling
-        * wake_up_process().
-        */
-       WRITE_ONCE(q->status, error);
+       get_task_struct(q->sleeper);
+
+       /* see SEM_BARRIER_2 for purpuse/pairing */
+       smp_store_release(&q->status, error);
+
+       wake_q_add_safe(wake_q, q->sleeper);
 }
 
 static void unlink_queue(struct sem_array *sma, struct sem_queue *q)
@@ -2148,9 +2164,11 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
        }
 
        do {
+               /* memory ordering ensured by the lock in sem_lock() */
                WRITE_ONCE(queue.status, -EINTR);
                queue.sleeper = current;
 
+               /* memory ordering is ensured by the lock in sem_lock() */
                __set_current_state(TASK_INTERRUPTIBLE);
                sem_unlock(sma, locknum);
                rcu_read_unlock();
@@ -2173,13 +2191,8 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
                 */
                error = READ_ONCE(queue.status);
                if (error != -EINTR) {
-                       /*
-                        * User space could assume that semop() is a memory
-                        * barrier: Without the mb(), the cpu could
-                        * speculatively read in userspace stale data that was
-                        * overwritten by the previous owner of the semaphore.
-                        */
-                       smp_mb();
+                       /* see SEM_BARRIER_2 for purpose/pairing */
+                       smp_acquire__after_ctrl_dep();
                        goto out_free;
                }
 
@@ -2189,6 +2202,9 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
                if (!ipc_valid_object(&sma->sem_perm))
                        goto out_unlock_free;
 
+               /*
+                * No necessity for any barrier: We are protect by sem_lock()
+                */
                error = READ_ONCE(queue.status);
 
                /*
index 915eacb..fe61df5 100644 (file)
@@ -126,7 +126,7 @@ void ipc_init_ids(struct ipc_ids *ids)
 }
 
 #ifdef CONFIG_PROC_FS
-static const struct file_operations sysvipc_proc_fops;
+static const struct proc_ops sysvipc_proc_ops;
 /**
  * ipc_init_proc_interface -  create a proc interface for sysipc types using a seq_file interface.
  * @path: Path in procfs
@@ -151,7 +151,7 @@ void __init ipc_init_proc_interface(const char *path, const char *header,
        pde = proc_create_data(path,
                               S_IRUGO,        /* world readable */
                               NULL,           /* parent dir */
-                              &sysvipc_proc_fops,
+                              &sysvipc_proc_ops,
                               iface);
        if (!pde)
                kfree(iface);
@@ -884,10 +884,10 @@ static int sysvipc_proc_release(struct inode *inode, struct file *file)
        return seq_release_private(inode, file);
 }
 
-static const struct file_operations sysvipc_proc_fops = {
-       .open    = sysvipc_proc_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = sysvipc_proc_release,
+static const struct proc_ops sysvipc_proc_ops = {
+       .proc_open      = sysvipc_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = sysvipc_proc_release,
 };
 #endif /* CONFIG_PROC_FS */
index 8ad1c9e..042f955 100644 (file)
@@ -96,12 +96,11 @@ const struct bpf_prog_ops bpf_struct_ops_prog_ops = {
 
 static const struct btf_type *module_type;
 
-void bpf_struct_ops_init(struct btf *btf)
+void bpf_struct_ops_init(struct btf *btf, struct bpf_verifier_log *log)
 {
        s32 type_id, value_id, module_id;
        const struct btf_member *member;
        struct bpf_struct_ops *st_ops;
-       struct bpf_verifier_log log = {};
        const struct btf_type *t;
        char value_name[128];
        const char *mname;
@@ -172,7 +171,7 @@ void bpf_struct_ops_init(struct btf *btf)
                                                               member->type,
                                                               NULL);
                        if (func_proto &&
-                           btf_distill_func_proto(&log, btf,
+                           btf_distill_func_proto(log, btf,
                                                   func_proto, mname,
                                                   &st_ops->func_models[j])) {
                                pr_warn("Error in parsing func ptr %s in struct %s\n",
index b7c1660..805c43b 100644 (file)
@@ -3643,7 +3643,7 @@ struct btf *btf_parse_vmlinux(void)
                goto errout;
        }
 
-       bpf_struct_ops_init(btf);
+       bpf_struct_ops_init(btf, log);
 
        btf_verifier_env_free(env);
        refcount_set(&btf->refcnt, 1);
@@ -3931,6 +3931,7 @@ again:
 
                if (btf_type_is_ptr(mtype)) {
                        const struct btf_type *stype;
+                       u32 id;
 
                        if (msize != size || off != moff) {
                                bpf_log(log,
@@ -3939,12 +3940,9 @@ again:
                                return -EACCES;
                        }
 
-                       stype = btf_type_by_id(btf_vmlinux, mtype->type);
-                       /* skip modifiers */
-                       while (btf_type_is_modifier(stype))
-                               stype = btf_type_by_id(btf_vmlinux, stype->type);
+                       stype = btf_type_skip_modifiers(btf_vmlinux, mtype->type, &id);
                        if (btf_type_is_struct(stype)) {
-                               *next_btf_id = mtype->type;
+                               *next_btf_id = id;
                                return PTR_TO_BTF_ID;
                        }
                }
index bd2fd8e..5e40e7f 100644 (file)
@@ -569,16 +569,11 @@ enum {
        OPT_MODE,
 };
 
-static const struct fs_parameter_spec bpf_param_specs[] = {
+static const struct fs_parameter_spec bpf_fs_parameters[] = {
        fsparam_u32oct  ("mode",                        OPT_MODE),
        {}
 };
 
-static const struct fs_parameter_description bpf_fs_parameters = {
-       .name           = "bpf",
-       .specs          = bpf_param_specs,
-};
-
 struct bpf_mount_opts {
        umode_t mode;
 };
@@ -589,7 +584,7 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param)
        struct fs_parse_result result;
        int opt;
 
-       opt = fs_parse(fc, &bpf_fs_parameters, param, &result);
+       opt = fs_parse(fc, bpf_fs_parameters, param, &result);
        if (opt < 0)
                /* We might like to report bad mount options here, but
                 * traditionally we've ignored all mount options, so we'd
@@ -665,7 +660,7 @@ static struct file_system_type bpf_fs_type = {
        .owner          = THIS_MODULE,
        .name           = "bpf",
        .init_fs_context = bpf_init_fs_context,
-       .parameters     = &bpf_fs_parameters,
+       .parameters     = bpf_fs_parameters,
        .kill_sb        = kill_litter_super,
 };
 
index 90d1710..bfbeabc 100644 (file)
@@ -7,7 +7,7 @@
 #include <linux/workqueue.h>
 #include <linux/list.h>
 #include <linux/refcount.h>
-#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
 
 #define TRACE_CGROUP_PATH_LEN 1024
 extern spinlock_t trace_cgroup_path_lock;
@@ -265,7 +265,7 @@ extern const struct proc_ns_operations cgroupns_operations;
  */
 extern struct cftype cgroup1_base_files[];
 extern struct kernfs_syscall_ops cgroup1_kf_syscall_ops;
-extern const struct fs_parameter_description cgroup1_fs_parameters;
+extern const struct fs_parameter_spec cgroup1_fs_parameters[];
 
 int proc_cgroupstats_show(struct seq_file *m, void *v);
 bool cgroup1_ssid_disabled(int ssid);
index 09f3a41..be1a1c8 100644 (file)
@@ -18,8 +18,6 @@
 
 #include <trace/events/cgroup.h>
 
-#define cg_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__)
-
 /*
  * pidlists linger the following amount before being destroyed.  The goal
  * is avoiding frequent destruction in the middle of consecutive read calls
@@ -887,7 +885,7 @@ enum cgroup1_param {
        Opt_xattr,
 };
 
-static const struct fs_parameter_spec cgroup1_param_specs[] = {
+const struct fs_parameter_spec cgroup1_fs_parameters[] = {
        fsparam_flag  ("all",           Opt_all),
        fsparam_flag  ("clone_children", Opt_clone_children),
        fsparam_flag  ("cpuset_v2_mode", Opt_cpuset_v2_mode),
@@ -899,11 +897,6 @@ static const struct fs_parameter_spec cgroup1_param_specs[] = {
        {}
 };
 
-const struct fs_parameter_description cgroup1_fs_parameters = {
-       .name           = "cgroup1",
-       .specs          = cgroup1_param_specs,
-};
-
 int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
@@ -911,7 +904,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
        struct fs_parse_result result;
        int opt, i;
 
-       opt = fs_parse(fc, &cgroup1_fs_parameters, param, &result);
+       opt = fs_parse(fc, cgroup1_fs_parameters, param, &result);
        if (opt == -ENOPARAM) {
                if (strcmp(param->key, "source") == 0) {
                        fc->source = param->string;
@@ -924,7 +917,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
                        ctx->subsys_mask |= (1 << i);
                        return 0;
                }
-               return cg_invalf(fc, "cgroup1: Unknown subsys name '%s'", param->key);
+               return invalfc(fc, "Unknown subsys name '%s'", param->key);
        }
        if (opt < 0)
                return opt;
@@ -952,7 +945,7 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
        case Opt_release_agent:
                /* Specifying two release agents is forbidden */
                if (ctx->release_agent)
-                       return cg_invalf(fc, "cgroup1: release_agent respecified");
+                       return invalfc(fc, "release_agent respecified");
                ctx->release_agent = param->string;
                param->string = NULL;
                break;
@@ -962,9 +955,9 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
                        return -ENOENT;
                /* Can't specify an empty name */
                if (!param->size)
-                       return cg_invalf(fc, "cgroup1: Empty name");
+                       return invalfc(fc, "Empty name");
                if (param->size > MAX_CGROUP_ROOT_NAMELEN - 1)
-                       return cg_invalf(fc, "cgroup1: Name too long");
+                       return invalfc(fc, "Name too long");
                /* Must match [\w.-]+ */
                for (i = 0; i < param->size; i++) {
                        char c = param->string[i];
@@ -972,11 +965,11 @@ int cgroup1_parse_param(struct fs_context *fc, struct fs_parameter *param)
                                continue;
                        if ((c == '.') || (c == '-') || (c == '_'))
                                continue;
-                       return cg_invalf(fc, "cgroup1: Invalid name");
+                       return invalfc(fc, "Invalid name");
                }
                /* Specifying two names is forbidden */
                if (ctx->name)
-                       return cg_invalf(fc, "cgroup1: name respecified");
+                       return invalfc(fc, "name respecified");
                ctx->name = param->string;
                param->string = NULL;
                break;
@@ -1011,7 +1004,7 @@ static int check_cgroupfs_options(struct fs_context *fc)
        if (ctx->all_ss) {
                /* Mutually exclusive option 'all' + subsystem name */
                if (ctx->subsys_mask)
-                       return cg_invalf(fc, "cgroup1: subsys name conflicts with all");
+                       return invalfc(fc, "subsys name conflicts with all");
                /* 'all' => select all the subsystems */
                ctx->subsys_mask = enabled;
        }
@@ -1021,7 +1014,7 @@ static int check_cgroupfs_options(struct fs_context *fc)
         * empty hierarchies must have a name).
         */
        if (!ctx->subsys_mask && !ctx->name)
-               return cg_invalf(fc, "cgroup1: Need name or subsystem set");
+               return invalfc(fc, "Need name or subsystem set");
 
        /*
         * Option noprefix was introduced just for backward compatibility
@@ -1029,11 +1022,11 @@ static int check_cgroupfs_options(struct fs_context *fc)
         * the cpuset subsystem.
         */
        if ((ctx->flags & CGRP_ROOT_NOPREFIX) && (ctx->subsys_mask & mask))
-               return cg_invalf(fc, "cgroup1: noprefix used incorrectly");
+               return invalfc(fc, "noprefix used incorrectly");
 
        /* Can't specify "none" and some subsystems */
        if (ctx->subsys_mask && ctx->none)
-               return cg_invalf(fc, "cgroup1: none used incorrectly");
+               return invalfc(fc, "none used incorrectly");
 
        return 0;
 }
@@ -1063,7 +1056,7 @@ int cgroup1_reconfigure(struct fs_context *fc)
        /* Don't allow flags or name to change at remount */
        if ((ctx->flags ^ root->flags) ||
            (ctx->name && strcmp(ctx->name, root->name))) {
-               cg_invalf(fc, "option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"",
+               errorfc(fc, "option or name mismatch, new: 0x%x \"%s\", old: 0x%x \"%s\"",
                       ctx->flags, ctx->name ?: "", root->flags, root->name);
                ret = -EINVAL;
                goto out_unlock;
@@ -1180,7 +1173,7 @@ static int cgroup1_root_to_use(struct fs_context *fc)
         * can't create new one without subsys specification.
         */
        if (!ctx->subsys_mask && !ctx->none)
-               return cg_invalf(fc, "cgroup1: No subsys list or none specified");
+               return invalfc(fc, "No subsys list or none specified");
 
        /* Hierarchies may only be created in the initial cgroup namespace. */
        if (ctx->ns != &init_cgroup_ns)
index b374487..db552b9 100644 (file)
@@ -1816,24 +1816,19 @@ enum cgroup2_param {
        nr__cgroup2_params
 };
 
-static const struct fs_parameter_spec cgroup2_param_specs[] = {
+static const struct fs_parameter_spec cgroup2_fs_parameters[] = {
        fsparam_flag("nsdelegate",              Opt_nsdelegate),
        fsparam_flag("memory_localevents",      Opt_memory_localevents),
        {}
 };
 
-static const struct fs_parameter_description cgroup2_fs_parameters = {
-       .name           = "cgroup2",
-       .specs          = cgroup2_param_specs,
-};
-
 static int cgroup2_parse_param(struct fs_context *fc, struct fs_parameter *param)
 {
        struct cgroup_fs_context *ctx = cgroup_fc2context(fc);
        struct fs_parse_result result;
        int opt;
 
-       opt = fs_parse(fc, &cgroup2_fs_parameters, param, &result);
+       opt = fs_parse(fc, cgroup2_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -2156,7 +2151,7 @@ static void cgroup_kill_sb(struct super_block *sb)
 struct file_system_type cgroup_fs_type = {
        .name                   = "cgroup",
        .init_fs_context        = cgroup_init_fs_context,
-       .parameters             = &cgroup1_fs_parameters,
+       .parameters             = cgroup1_fs_parameters,
        .kill_sb                = cgroup_kill_sb,
        .fs_flags               = FS_USERNS_MOUNT,
 };
@@ -2164,7 +2159,7 @@ struct file_system_type cgroup_fs_type = {
 static struct file_system_type cgroup2_fs_type = {
        .name                   = "cgroup2",
        .init_fs_context        = cgroup_init_fs_context,
-       .parameters             = &cgroup2_fs_parameters,
+       .parameters             = cgroup2_fs_parameters,
        .kill_sb                = cgroup_kill_sb,
        .fs_flags               = FS_USERNS_MOUNT,
 };
index c09ea4c..a28c79c 100644 (file)
@@ -47,10 +47,9 @@ ikconfig_read_current(struct file *file, char __user *buf,
                                       &kernel_config_data);
 }
 
-static const struct file_operations ikconfig_file_ops = {
-       .owner = THIS_MODULE,
-       .read = ikconfig_read_current,
-       .llseek = default_llseek,
+static const struct proc_ops config_gz_proc_ops = {
+       .proc_read      = ikconfig_read_current,
+       .proc_lseek     = default_llseek,
 };
 
 static int __init ikconfig_init(void)
@@ -59,7 +58,7 @@ static int __init ikconfig_init(void)
 
        /* create the current config file */
        entry = proc_create("config.gz", S_IFREG | S_IRUGO, NULL,
-                           &ikconfig_file_ops);
+                           &config_gz_proc_ops);
        if (!entry)
                return -ENOMEM;
 
index 62c301a..d7ebb2c 100644 (file)
@@ -412,7 +412,6 @@ static int kdb_bc(int argc, const char **argv)
                 * assume that the breakpoint number is desired.
                 */
                if (addr < KDB_MAXBPT) {
-                       bp = &kdb_breakpoints[addr];
                        lowbp = highbp = addr;
                        highbp++;
                } else {
index 4af48ac..3de0cc7 100644 (file)
@@ -119,7 +119,6 @@ kdb_bt_cpu(unsigned long cpu)
                return;
        }
 
-       kdb_set_current_task(kdb_tsk);
        kdb_bt1(kdb_tsk, ~0UL, false);
 }
 
@@ -166,10 +165,8 @@ kdb_bt(int argc, const char **argv)
                if (diag)
                        return diag;
                p = find_task_by_pid_ns(pid, &init_pid_ns);
-               if (p) {
-                       kdb_set_current_task(p);
+               if (p)
                        return kdb_bt1(p, ~0UL, false);
-               }
                kdb_printf("No process with pid == %ld found\n", pid);
                return 0;
        } else if (strcmp(argv[0], "btt") == 0) {
@@ -178,11 +175,9 @@ kdb_bt(int argc, const char **argv)
                diag = kdbgetularg((char *)argv[1], &addr);
                if (diag)
                        return diag;
-               kdb_set_current_task((struct task_struct *)addr);
                return kdb_bt1((struct task_struct *)addr, ~0UL, false);
        } else if (strcmp(argv[0], "btc") == 0) {
                unsigned long cpu = ~0;
-               struct task_struct *save_current_task = kdb_current_task;
                if (argc > 1)
                        return KDB_ARGCOUNT;
                if (argc == 1) {
@@ -204,7 +199,6 @@ kdb_bt(int argc, const char **argv)
                                kdb_bt_cpu(cpu);
                                touch_nmi_watchdog();
                        }
-                       kdb_set_current_task(save_current_task);
                }
                return 0;
        } else {
index 8bcdded..924bc92 100644 (file)
@@ -553,7 +553,7 @@ int vkdb_printf(enum kdb_msgsrc src, const char *fmt, va_list ap)
        int this_cpu, old_cpu;
        char *cp, *cp2, *cphold = NULL, replaced_byte = ' ';
        char *moreprompt = "more> ";
-       struct console *c = console_drivers;
+       struct console *c;
        unsigned long uninitialized_var(flags);
 
        /* Serialize kdb_printf if multiple cpus try to write at once.
@@ -698,10 +698,9 @@ kdb_printit:
                                cp2++;
                        }
                }
-               while (c) {
+               for_each_console(c) {
                        c->write(c, cp, retlen - (cp - kdb_buffer));
                        touch_nmi_watchdog();
-                       c = c->next;
                }
        }
        if (logging) {
@@ -752,7 +751,6 @@ kdb_printit:
                        moreprompt = "more> ";
 
                kdb_input_flush();
-               c = console_drivers;
 
                if (dbg_io_ops && !dbg_io_ops->is_console) {
                        len = strlen(moreprompt);
@@ -762,10 +760,9 @@ kdb_printit:
                                cp++;
                        }
                }
-               while (c) {
+               for_each_console(c) {
                        c->write(c, moreprompt, strlen(moreprompt));
                        touch_nmi_watchdog();
-                       c = c->next;
                }
 
                if (logging)
index 4567fe9..ba12e9f 100644 (file)
@@ -73,7 +73,6 @@ int kdb_nextline = 1;
 int kdb_state;                 /* General KDB state */
 
 struct task_struct *kdb_current_task;
-EXPORT_SYMBOL(kdb_current_task);
 struct pt_regs *kdb_current_regs;
 
 const char *kdb_diemsg;
@@ -1139,7 +1138,7 @@ static void kdb_dumpregs(struct pt_regs *regs)
        console_loglevel = old_lvl;
 }
 
-void kdb_set_current_task(struct task_struct *p)
+static void kdb_set_current_task(struct task_struct *p)
 {
        kdb_current_task = p;
 
index 55d0520..2e296e4 100644 (file)
@@ -240,8 +240,8 @@ extern void *debug_kmalloc(size_t size, gfp_t flags);
 extern void debug_kfree(void *);
 extern void debug_kusage(void);
 
-extern void kdb_set_current_task(struct task_struct *);
 extern struct task_struct *kdb_current_task;
+extern struct pt_regs *kdb_current_regs;
 
 #ifdef CONFIG_KDB_KEYBOARD
 extern void kdb_kbd_cleanup_state(void);
index dc9c643..e453589 100644 (file)
@@ -951,9 +951,9 @@ list_update_cgroup_event(struct perf_event *event,
 
        /*
         * Because cgroup events are always per-cpu events,
-        * this will always be called from the right CPU.
+        * @ctx == &cpuctx->ctx.
         */
-       cpuctx = __get_cpu_context(ctx);
+       cpuctx = container_of(ctx, struct perf_cpu_context, ctx);
 
        /*
         * Since setting cpuctx->cgrp is conditional on the current @cgrp
@@ -979,7 +979,8 @@ list_update_cgroup_event(struct perf_event *event,
 
        cpuctx_entry = &cpuctx->cgrp_cpuctx_entry;
        if (add)
-               list_add(cpuctx_entry, this_cpu_ptr(&cgrp_cpuctx_list));
+               list_add(cpuctx_entry,
+                        per_cpu_ptr(&cgrp_cpuctx_list, event->cpu));
        else
                list_del(cpuctx_entry);
 }
@@ -4373,7 +4374,7 @@ static void free_event_rcu(struct rcu_head *head)
 }
 
 static void ring_buffer_attach(struct perf_event *event,
-                              struct ring_buffer *rb);
+                              struct perf_buffer *rb);
 
 static void detach_sb_event(struct perf_event *event)
 {
@@ -5054,7 +5055,7 @@ perf_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
 static __poll_t perf_poll(struct file *file, poll_table *wait)
 {
        struct perf_event *event = file->private_data;
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
        __poll_t events = EPOLLHUP;
 
        poll_wait(file, &event->waitq, wait);
@@ -5296,7 +5297,7 @@ static long _perf_ioctl(struct perf_event *event, unsigned int cmd, unsigned lon
                return perf_event_set_bpf_prog(event, arg);
 
        case PERF_EVENT_IOC_PAUSE_OUTPUT: {
-               struct ring_buffer *rb;
+               struct perf_buffer *rb;
 
                rcu_read_lock();
                rb = rcu_dereference(event->rb);
@@ -5432,7 +5433,7 @@ static void calc_timer_values(struct perf_event *event,
 static void perf_event_init_userpage(struct perf_event *event)
 {
        struct perf_event_mmap_page *userpg;
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
 
        rcu_read_lock();
        rb = rcu_dereference(event->rb);
@@ -5464,7 +5465,7 @@ void __weak arch_perf_update_userpage(
 void perf_event_update_userpage(struct perf_event *event)
 {
        struct perf_event_mmap_page *userpg;
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
        u64 enabled, running, now;
 
        rcu_read_lock();
@@ -5515,7 +5516,7 @@ EXPORT_SYMBOL_GPL(perf_event_update_userpage);
 static vm_fault_t perf_mmap_fault(struct vm_fault *vmf)
 {
        struct perf_event *event = vmf->vma->vm_file->private_data;
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
        vm_fault_t ret = VM_FAULT_SIGBUS;
 
        if (vmf->flags & FAULT_FLAG_MKWRITE) {
@@ -5548,9 +5549,9 @@ unlock:
 }
 
 static void ring_buffer_attach(struct perf_event *event,
-                              struct ring_buffer *rb)
+                              struct perf_buffer *rb)
 {
-       struct ring_buffer *old_rb = NULL;
+       struct perf_buffer *old_rb = NULL;
        unsigned long flags;
 
        if (event->rb) {
@@ -5608,7 +5609,7 @@ static void ring_buffer_attach(struct perf_event *event,
 
 static void ring_buffer_wakeup(struct perf_event *event)
 {
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
 
        rcu_read_lock();
        rb = rcu_dereference(event->rb);
@@ -5619,9 +5620,9 @@ static void ring_buffer_wakeup(struct perf_event *event)
        rcu_read_unlock();
 }
 
-struct ring_buffer *ring_buffer_get(struct perf_event *event)
+struct perf_buffer *ring_buffer_get(struct perf_event *event)
 {
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
 
        rcu_read_lock();
        rb = rcu_dereference(event->rb);
@@ -5634,7 +5635,7 @@ struct ring_buffer *ring_buffer_get(struct perf_event *event)
        return rb;
 }
 
-void ring_buffer_put(struct ring_buffer *rb)
+void ring_buffer_put(struct perf_buffer *rb)
 {
        if (!refcount_dec_and_test(&rb->refcount))
                return;
@@ -5672,7 +5673,7 @@ static void perf_mmap_close(struct vm_area_struct *vma)
 {
        struct perf_event *event = vma->vm_file->private_data;
 
-       struct ring_buffer *rb = ring_buffer_get(event);
+       struct perf_buffer *rb = ring_buffer_get(event);
        struct user_struct *mmap_user = rb->mmap_user;
        int mmap_locked = rb->mmap_locked;
        unsigned long size = perf_data_size(rb);
@@ -5790,8 +5791,8 @@ static int perf_mmap(struct file *file, struct vm_area_struct *vma)
        struct perf_event *event = file->private_data;
        unsigned long user_locked, user_lock_limit;
        struct user_struct *user = current_user();
+       struct perf_buffer *rb = NULL;
        unsigned long locked, lock_limit;
-       struct ring_buffer *rb = NULL;
        unsigned long vma_size;
        unsigned long nr_pages;
        long user_extra = 0, extra = 0;
@@ -5916,7 +5917,15 @@ accounting:
         */
        user_lock_limit *= num_online_cpus();
 
-       user_locked = atomic_long_read(&user->locked_vm) + user_extra;
+       user_locked = atomic_long_read(&user->locked_vm);
+
+       /*
+        * sysctl_perf_event_mlock may have changed, so that
+        *     user->locked_vm > user_lock_limit
+        */
+       if (user_locked > user_lock_limit)
+               user_locked = user_lock_limit;
+       user_locked += user_extra;
 
        if (user_locked > user_lock_limit) {
                /*
@@ -6266,7 +6275,7 @@ static unsigned long perf_prepare_sample_aux(struct perf_event *event,
                                          size_t size)
 {
        struct perf_event *sampler = event->aux_event;
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
 
        data->aux_size = 0;
 
@@ -6299,7 +6308,7 @@ out:
        return data->aux_size;
 }
 
-long perf_pmu_snapshot_aux(struct ring_buffer *rb,
+long perf_pmu_snapshot_aux(struct perf_buffer *rb,
                           struct perf_event *event,
                           struct perf_output_handle *handle,
                           unsigned long size)
@@ -6338,8 +6347,8 @@ static void perf_aux_sample_output(struct perf_event *event,
                                   struct perf_sample_data *data)
 {
        struct perf_event *sampler = event->aux_event;
+       struct perf_buffer *rb;
        unsigned long pad;
-       struct ring_buffer *rb;
        long size;
 
        if (WARN_ON_ONCE(!sampler || !data->aux_size))
@@ -6707,7 +6716,7 @@ void perf_output_sample(struct perf_output_handle *handle,
                int wakeup_events = event->attr.wakeup_events;
 
                if (wakeup_events) {
-                       struct ring_buffer *rb = handle->rb;
+                       struct perf_buffer *rb = handle->rb;
                        int events = local_inc_return(&rb->events);
 
                        if (events >= wakeup_events) {
@@ -7150,7 +7159,7 @@ void perf_event_exec(void)
 }
 
 struct remote_output {
-       struct ring_buffer      *rb;
+       struct perf_buffer      *rb;
        int                     err;
 };
 
@@ -7158,7 +7167,7 @@ static void __perf_event_output_stop(struct perf_event *event, void *data)
 {
        struct perf_event *parent = event->parent;
        struct remote_output *ro = data;
-       struct ring_buffer *rb = ro->rb;
+       struct perf_buffer *rb = ro->rb;
        struct stop_event_data sd = {
                .event  = event,
        };
@@ -10998,7 +11007,7 @@ err_size:
 static int
 perf_event_set_output(struct perf_event *event, struct perf_event *output_event)
 {
-       struct ring_buffer *rb = NULL;
+       struct perf_buffer *rb = NULL;
        int ret = -EINVAL;
 
        if (!output_event)
index 747d67f..f16f66b 100644 (file)
@@ -10,7 +10,7 @@
 
 #define RING_BUFFER_WRITABLE           0x01
 
-struct ring_buffer {
+struct perf_buffer {
        refcount_t                      refcount;
        struct rcu_head                 rcu_head;
 #ifdef CONFIG_PERF_USE_VMALLOC
@@ -58,17 +58,17 @@ struct ring_buffer {
        void                            *data_pages[0];
 };
 
-extern void rb_free(struct ring_buffer *rb);
+extern void rb_free(struct perf_buffer *rb);
 
 static inline void rb_free_rcu(struct rcu_head *rcu_head)
 {
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
 
-       rb = container_of(rcu_head, struct ring_buffer, rcu_head);
+       rb = container_of(rcu_head, struct perf_buffer, rcu_head);
        rb_free(rb);
 }
 
-static inline void rb_toggle_paused(struct ring_buffer *rb, bool pause)
+static inline void rb_toggle_paused(struct perf_buffer *rb, bool pause)
 {
        if (!pause && rb->nr_pages)
                rb->paused = 0;
@@ -76,16 +76,16 @@ static inline void rb_toggle_paused(struct ring_buffer *rb, bool pause)
                rb->paused = 1;
 }
 
-extern struct ring_buffer *
+extern struct perf_buffer *
 rb_alloc(int nr_pages, long watermark, int cpu, int flags);
 extern void perf_event_wakeup(struct perf_event *event);
-extern int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event,
+extern int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event,
                        pgoff_t pgoff, int nr_pages, long watermark, int flags);
-extern void rb_free_aux(struct ring_buffer *rb);
-extern struct ring_buffer *ring_buffer_get(struct perf_event *event);
-extern void ring_buffer_put(struct ring_buffer *rb);
+extern void rb_free_aux(struct perf_buffer *rb);
+extern struct perf_buffer *ring_buffer_get(struct perf_event *event);
+extern void ring_buffer_put(struct perf_buffer *rb);
 
-static inline bool rb_has_aux(struct ring_buffer *rb)
+static inline bool rb_has_aux(struct perf_buffer *rb)
 {
        return !!rb->aux_nr_pages;
 }
@@ -94,7 +94,7 @@ void perf_event_aux_event(struct perf_event *event, unsigned long head,
                          unsigned long size, u64 flags);
 
 extern struct page *
-perf_mmap_to_page(struct ring_buffer *rb, unsigned long pgoff);
+perf_mmap_to_page(struct perf_buffer *rb, unsigned long pgoff);
 
 #ifdef CONFIG_PERF_USE_VMALLOC
 /*
@@ -103,25 +103,25 @@ perf_mmap_to_page(struct ring_buffer *rb, unsigned long pgoff);
  * Required for architectures that have d-cache aliasing issues.
  */
 
-static inline int page_order(struct ring_buffer *rb)
+static inline int page_order(struct perf_buffer *rb)
 {
        return rb->page_order;
 }
 
 #else
 
-static inline int page_order(struct ring_buffer *rb)
+static inline int page_order(struct perf_buffer *rb)
 {
        return 0;
 }
 #endif
 
-static inline unsigned long perf_data_size(struct ring_buffer *rb)
+static inline unsigned long perf_data_size(struct perf_buffer *rb)
 {
        return rb->nr_pages << (PAGE_SHIFT + page_order(rb));
 }
 
-static inline unsigned long perf_aux_size(struct ring_buffer *rb)
+static inline unsigned long perf_aux_size(struct perf_buffer *rb)
 {
        return rb->aux_nr_pages << PAGE_SHIFT;
 }
@@ -141,7 +141,7 @@ static inline unsigned long perf_aux_size(struct ring_buffer *rb)
                        buf += written;                                 \
                handle->size -= written;                                \
                if (!handle->size) {                                    \
-                       struct ring_buffer *rb = handle->rb;            \
+                       struct perf_buffer *rb = handle->rb;    \
                                                                        \
                        handle->page++;                                 \
                        handle->page &= rb->nr_pages - 1;               \
index 7ffd5c7..192b8ab 100644 (file)
@@ -35,7 +35,7 @@ static void perf_output_wakeup(struct perf_output_handle *handle)
  */
 static void perf_output_get_handle(struct perf_output_handle *handle)
 {
-       struct ring_buffer *rb = handle->rb;
+       struct perf_buffer *rb = handle->rb;
 
        preempt_disable();
 
@@ -49,7 +49,7 @@ static void perf_output_get_handle(struct perf_output_handle *handle)
 
 static void perf_output_put_handle(struct perf_output_handle *handle)
 {
-       struct ring_buffer *rb = handle->rb;
+       struct perf_buffer *rb = handle->rb;
        unsigned long head;
        unsigned int nest;
 
@@ -150,7 +150,7 @@ __perf_output_begin(struct perf_output_handle *handle,
                    struct perf_event *event, unsigned int size,
                    bool backward)
 {
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
        unsigned long tail, offset, head;
        int have_lost, page_shift;
        struct {
@@ -301,7 +301,7 @@ void perf_output_end(struct perf_output_handle *handle)
 }
 
 static void
-ring_buffer_init(struct ring_buffer *rb, long watermark, int flags)
+ring_buffer_init(struct perf_buffer *rb, long watermark, int flags)
 {
        long max_size = perf_data_size(rb);
 
@@ -361,7 +361,7 @@ void *perf_aux_output_begin(struct perf_output_handle *handle,
 {
        struct perf_event *output_event = event;
        unsigned long aux_head, aux_tail;
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
        unsigned int nest;
 
        if (output_event->parent)
@@ -449,7 +449,7 @@ err:
 }
 EXPORT_SYMBOL_GPL(perf_aux_output_begin);
 
-static __always_inline bool rb_need_aux_wakeup(struct ring_buffer *rb)
+static __always_inline bool rb_need_aux_wakeup(struct perf_buffer *rb)
 {
        if (rb->aux_overwrite)
                return false;
@@ -475,7 +475,7 @@ static __always_inline bool rb_need_aux_wakeup(struct ring_buffer *rb)
 void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
 {
        bool wakeup = !!(handle->aux_flags & PERF_AUX_FLAG_TRUNCATED);
-       struct ring_buffer *rb = handle->rb;
+       struct perf_buffer *rb = handle->rb;
        unsigned long aux_head;
 
        /* in overwrite mode, driver provides aux_head via handle */
@@ -532,7 +532,7 @@ EXPORT_SYMBOL_GPL(perf_aux_output_end);
  */
 int perf_aux_output_skip(struct perf_output_handle *handle, unsigned long size)
 {
-       struct ring_buffer *rb = handle->rb;
+       struct perf_buffer *rb = handle->rb;
 
        if (size > handle->size)
                return -ENOSPC;
@@ -569,8 +569,8 @@ long perf_output_copy_aux(struct perf_output_handle *aux_handle,
                          struct perf_output_handle *handle,
                          unsigned long from, unsigned long to)
 {
+       struct perf_buffer *rb = aux_handle->rb;
        unsigned long tocopy, remainder, len = 0;
-       struct ring_buffer *rb = aux_handle->rb;
        void *addr;
 
        from &= (rb->aux_nr_pages << PAGE_SHIFT) - 1;
@@ -626,7 +626,7 @@ static struct page *rb_alloc_aux_page(int node, int order)
        return page;
 }
 
-static void rb_free_aux_page(struct ring_buffer *rb, int idx)
+static void rb_free_aux_page(struct perf_buffer *rb, int idx)
 {
        struct page *page = virt_to_page(rb->aux_pages[idx]);
 
@@ -635,7 +635,7 @@ static void rb_free_aux_page(struct ring_buffer *rb, int idx)
        __free_page(page);
 }
 
-static void __rb_free_aux(struct ring_buffer *rb)
+static void __rb_free_aux(struct perf_buffer *rb)
 {
        int pg;
 
@@ -662,7 +662,7 @@ static void __rb_free_aux(struct ring_buffer *rb)
        }
 }
 
-int rb_alloc_aux(struct ring_buffer *rb, struct perf_event *event,
+int rb_alloc_aux(struct perf_buffer *rb, struct perf_event *event,
                 pgoff_t pgoff, int nr_pages, long watermark, int flags)
 {
        bool overwrite = !(flags & RING_BUFFER_WRITABLE);
@@ -753,7 +753,7 @@ out:
        return ret;
 }
 
-void rb_free_aux(struct ring_buffer *rb)
+void rb_free_aux(struct perf_buffer *rb)
 {
        if (refcount_dec_and_test(&rb->aux_refcount))
                __rb_free_aux(rb);
@@ -766,7 +766,7 @@ void rb_free_aux(struct ring_buffer *rb)
  */
 
 static struct page *
-__perf_mmap_to_page(struct ring_buffer *rb, unsigned long pgoff)
+__perf_mmap_to_page(struct perf_buffer *rb, unsigned long pgoff)
 {
        if (pgoff > rb->nr_pages)
                return NULL;
@@ -798,13 +798,13 @@ static void perf_mmap_free_page(void *addr)
        __free_page(page);
 }
 
-struct ring_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags)
+struct perf_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags)
 {
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
        unsigned long size;
        int i;
 
-       size = sizeof(struct ring_buffer);
+       size = sizeof(struct perf_buffer);
        size += nr_pages * sizeof(void *);
 
        if (order_base_2(size) >= PAGE_SHIFT+MAX_ORDER)
@@ -843,7 +843,7 @@ fail:
        return NULL;
 }
 
-void rb_free(struct ring_buffer *rb)
+void rb_free(struct perf_buffer *rb)
 {
        int i;
 
@@ -854,13 +854,13 @@ void rb_free(struct ring_buffer *rb)
 }
 
 #else
-static int data_page_nr(struct ring_buffer *rb)
+static int data_page_nr(struct perf_buffer *rb)
 {
        return rb->nr_pages << page_order(rb);
 }
 
 static struct page *
-__perf_mmap_to_page(struct ring_buffer *rb, unsigned long pgoff)
+__perf_mmap_to_page(struct perf_buffer *rb, unsigned long pgoff)
 {
        /* The '>' counts in the user page. */
        if (pgoff > data_page_nr(rb))
@@ -878,11 +878,11 @@ static void perf_mmap_unmark_page(void *addr)
 
 static void rb_free_work(struct work_struct *work)
 {
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
        void *base;
        int i, nr;
 
-       rb = container_of(work, struct ring_buffer, work);
+       rb = container_of(work, struct perf_buffer, work);
        nr = data_page_nr(rb);
 
        base = rb->user_page;
@@ -894,18 +894,18 @@ static void rb_free_work(struct work_struct *work)
        kfree(rb);
 }
 
-void rb_free(struct ring_buffer *rb)
+void rb_free(struct perf_buffer *rb)
 {
        schedule_work(&rb->work);
 }
 
-struct ring_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags)
+struct perf_buffer *rb_alloc(int nr_pages, long watermark, int cpu, int flags)
 {
-       struct ring_buffer *rb;
+       struct perf_buffer *rb;
        unsigned long size;
        void *all_buf;
 
-       size = sizeof(struct ring_buffer);
+       size = sizeof(struct perf_buffer);
        size += sizeof(void *);
 
        rb = kzalloc(size, GFP_KERNEL);
@@ -939,7 +939,7 @@ fail:
 #endif
 
 struct page *
-perf_mmap_to_page(struct ring_buffer *rb, unsigned long pgoff)
+perf_mmap_to_page(struct perf_buffer *rb, unsigned long pgoff)
 {
        if (rb->aux_nr_pages) {
                /* above AUX space */
index c1eccd4..a949bd3 100644 (file)
@@ -114,6 +114,7 @@ static const struct irq_bit_descr irqdata_states[] = {
        BIT_MASK_DESCR(IRQD_AFFINITY_MANAGED),
        BIT_MASK_DESCR(IRQD_MANAGED_SHUTDOWN),
        BIT_MASK_DESCR(IRQD_CAN_RESERVE),
+       BIT_MASK_DESCR(IRQD_MSI_NOMASK_QUIRK),
 
        BIT_MASK_DESCR(IRQD_FORWARDED_TO_VCPU),
 
index 818b280..3089a60 100644 (file)
@@ -731,6 +731,13 @@ static int set_irq_wake_real(unsigned int irq, unsigned int on)
  *
  *     Wakeup mode lets this IRQ wake the system from sleep
  *     states like "suspend to RAM".
+ *
+ *     Note: irq enable/disable state is completely orthogonal
+ *     to the enable/disable state of irq wake. An irq can be
+ *     disabled with disable_irq() and still wake the system as
+ *     long as the irq has wake enabled. If this does not hold,
+ *     then the underlying irq chip and the related driver need
+ *     to be investigated.
  */
 int irq_set_irq_wake(unsigned int irq, unsigned int on)
 {
index ad26fbc..eb95f61 100644 (file)
@@ -453,8 +453,11 @@ int msi_domain_alloc_irqs(struct irq_domain *domain, struct device *dev,
                        continue;
 
                irq_data = irq_domain_get_irq_data(domain, desc->irq);
-               if (!can_reserve)
+               if (!can_reserve) {
                        irqd_clr_can_reserve(irq_data);
+                       if (domain->flags & IRQ_DOMAIN_MSI_NOMASK_QUIRK)
+                               irqd_set_msi_nomask_quirk(irq_data);
+               }
                ret = irq_domain_activate_irq(irq_data, can_reserve);
                if (ret)
                        goto cleanup;
index cfc4f08..9e5783d 100644 (file)
@@ -176,20 +176,20 @@ static int irq_affinity_list_proc_open(struct inode *inode, struct file *file)
        return single_open(file, irq_affinity_list_proc_show, PDE_DATA(inode));
 }
 
-static const struct file_operations irq_affinity_proc_fops = {
-       .open           = irq_affinity_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = irq_affinity_proc_write,
+static const struct proc_ops irq_affinity_proc_ops = {
+       .proc_open      = irq_affinity_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = irq_affinity_proc_write,
 };
 
-static const struct file_operations irq_affinity_list_proc_fops = {
-       .open           = irq_affinity_list_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = irq_affinity_list_proc_write,
+static const struct proc_ops irq_affinity_list_proc_ops = {
+       .proc_open      = irq_affinity_list_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = irq_affinity_list_proc_write,
 };
 
 #ifdef CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK
@@ -246,12 +246,12 @@ static int default_affinity_open(struct inode *inode, struct file *file)
        return single_open(file, default_affinity_show, PDE_DATA(inode));
 }
 
-static const struct file_operations default_affinity_proc_fops = {
-       .open           = default_affinity_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = default_affinity_write,
+static const struct proc_ops default_affinity_proc_ops = {
+       .proc_open      = default_affinity_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = default_affinity_write,
 };
 
 static int irq_node_proc_show(struct seq_file *m, void *v)
@@ -342,7 +342,7 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
 #ifdef CONFIG_SMP
        /* create /proc/irq/<irq>/smp_affinity */
        proc_create_data("smp_affinity", 0644, desc->dir,
-                        &irq_affinity_proc_fops, irqp);
+                        &irq_affinity_proc_ops, irqp);
 
        /* create /proc/irq/<irq>/affinity_hint */
        proc_create_single_data("affinity_hint", 0444, desc->dir,
@@ -350,7 +350,7 @@ void register_irq_proc(unsigned int irq, struct irq_desc *desc)
 
        /* create /proc/irq/<irq>/smp_affinity_list */
        proc_create_data("smp_affinity_list", 0644, desc->dir,
-                        &irq_affinity_list_proc_fops, irqp);
+                        &irq_affinity_list_proc_ops, irqp);
 
        proc_create_single_data("node", 0444, desc->dir, irq_node_proc_show,
                        irqp);
@@ -401,7 +401,7 @@ static void register_default_affinity_proc(void)
 {
 #ifdef CONFIG_SMP
        proc_create("irq/default_smp_affinity", 0644, NULL,
-                   &default_affinity_proc_fops);
+                   &default_affinity_proc_ops);
 #endif
 }
 
index 136ce04..d812b90 100644 (file)
@@ -698,16 +698,16 @@ const char *kdb_walk_kallsyms(loff_t *pos)
 }
 #endif /* CONFIG_KGDB_KDB */
 
-static const struct file_operations kallsyms_operations = {
-       .open = kallsyms_open,
-       .read = seq_read,
-       .llseek = seq_lseek,
-       .release = seq_release_private,
+static const struct proc_ops kallsyms_proc_ops = {
+       .proc_open      = kallsyms_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release_private,
 };
 
 static int __init kallsyms_init(void)
 {
-       proc_create("kallsyms", 0444, NULL, &kallsyms_operations);
+       proc_create("kallsyms", 0444, NULL, &kallsyms_proc_ops);
        return 0;
 }
 device_initcall(kallsyms_init);
index e3acead..8d1c158 100644 (file)
@@ -255,17 +255,17 @@ static int lstats_open(struct inode *inode, struct file *filp)
        return single_open(filp, lstats_show, NULL);
 }
 
-static const struct file_operations lstats_fops = {
-       .open           = lstats_open,
-       .read           = seq_read,
-       .write          = lstats_write,
-       .llseek         = seq_lseek,
-       .release        = single_release,
+static const struct proc_ops lstats_proc_ops = {
+       .proc_open      = lstats_open,
+       .proc_read      = seq_read,
+       .proc_write     = lstats_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 static int __init init_lstats_procfs(void)
 {
-       proc_create("latency_stats", 0644, NULL, &lstats_fops);
+       proc_create("latency_stats", 0644, NULL, &lstats_proc_ops);
        return 0;
 }
 
index 9bb6d24..231684c 100644 (file)
@@ -643,12 +643,12 @@ static int lock_stat_release(struct inode *inode, struct file *file)
        return seq_release(inode, file);
 }
 
-static const struct file_operations proc_lock_stat_operations = {
-       .open           = lock_stat_open,
-       .write          = lock_stat_write,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = lock_stat_release,
+static const struct proc_ops lock_stat_proc_ops = {
+       .proc_open      = lock_stat_open,
+       .proc_write     = lock_stat_write,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = lock_stat_release,
 };
 #endif /* CONFIG_LOCK_STAT */
 
@@ -660,8 +660,7 @@ static int __init lockdep_proc_init(void)
 #endif
        proc_create_single("lockdep_stats", S_IRUSR, NULL, lockdep_stats_show);
 #ifdef CONFIG_LOCK_STAT
-       proc_create("lock_stat", S_IRUSR | S_IWUSR, NULL,
-                   &proc_lock_stat_operations);
+       proc_create("lock_stat", S_IRUSR | S_IWUSR, NULL, &lock_stat_proc_ops);
 #endif
 
        return 0;
index 90ec5ab..33569a0 100644 (file)
@@ -4354,16 +4354,16 @@ static int modules_open(struct inode *inode, struct file *file)
        return err;
 }
 
-static const struct file_operations proc_modules_operations = {
-       .open           = modules_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops modules_proc_ops = {
+       .proc_open      = modules_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 static int __init proc_modules_init(void)
 {
-       proc_create("modules", 0, NULL, &proc_modules_operations);
+       proc_create("modules", 0, NULL, &modules_proc_ops);
        return 0;
 }
 module_init(proc_modules_init);
index 4b144b0..6f69a41 100644 (file)
@@ -442,18 +442,18 @@ static ssize_t prof_cpu_mask_proc_write(struct file *file,
        return err;
 }
 
-static const struct file_operations prof_cpu_mask_proc_fops = {
-       .open           = prof_cpu_mask_proc_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = single_release,
-       .write          = prof_cpu_mask_proc_write,
+static const struct proc_ops prof_cpu_mask_proc_ops = {
+       .proc_open      = prof_cpu_mask_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
+       .proc_write     = prof_cpu_mask_proc_write,
 };
 
 void create_prof_cpu_mask(void)
 {
        /* create /proc/irq/prof_cpu_mask */
-       proc_create("irq/prof_cpu_mask", 0600, NULL, &prof_cpu_mask_proc_fops);
+       proc_create("irq/prof_cpu_mask", 0600, NULL, &prof_cpu_mask_proc_ops);
 }
 
 /*
@@ -517,10 +517,10 @@ static ssize_t write_profile(struct file *file, const char __user *buf,
        return count;
 }
 
-static const struct file_operations proc_profile_operations = {
-       .read           = read_profile,
-       .write          = write_profile,
-       .llseek         = default_llseek,
+static const struct proc_ops profile_proc_ops = {
+       .proc_read      = read_profile,
+       .proc_write     = write_profile,
+       .proc_lseek     = default_llseek,
 };
 
 int __ref create_proc_profile(void)
@@ -548,7 +548,7 @@ int __ref create_proc_profile(void)
        err = 0;
 #endif
        entry = proc_create("profile", S_IWUSR | S_IRUGO,
-                           NULL, &proc_profile_operations);
+                           NULL, &profile_proc_ops);
        if (!entry)
                goto err_state_onl;
        proc_set_size(entry, (1 + prof_len) * sizeof(atomic_t));
index db7b50b..ac4bd0c 100644 (file)
@@ -1251,40 +1251,40 @@ static int psi_fop_release(struct inode *inode, struct file *file)
        return single_release(inode, file);
 }
 
-static const struct file_operations psi_io_fops = {
-       .open           = psi_io_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .write          = psi_io_write,
-       .poll           = psi_fop_poll,
-       .release        = psi_fop_release,
+static const struct proc_ops psi_io_proc_ops = {
+       .proc_open      = psi_io_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = psi_io_write,
+       .proc_poll      = psi_fop_poll,
+       .proc_release   = psi_fop_release,
 };
 
-static const struct file_operations psi_memory_fops = {
-       .open           = psi_memory_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .write          = psi_memory_write,
-       .poll           = psi_fop_poll,
-       .release        = psi_fop_release,
+static const struct proc_ops psi_memory_proc_ops = {
+       .proc_open      = psi_memory_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = psi_memory_write,
+       .proc_poll      = psi_fop_poll,
+       .proc_release   = psi_fop_release,
 };
 
-static const struct file_operations psi_cpu_fops = {
-       .open           = psi_cpu_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .write          = psi_cpu_write,
-       .poll           = psi_fop_poll,
-       .release        = psi_fop_release,
+static const struct proc_ops psi_cpu_proc_ops = {
+       .proc_open      = psi_cpu_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = psi_cpu_write,
+       .proc_poll      = psi_fop_poll,
+       .proc_release   = psi_fop_release,
 };
 
 static int __init psi_proc_init(void)
 {
        if (psi_enable) {
                proc_mkdir("pressure", NULL);
-               proc_create("pressure/io", 0, NULL, &psi_io_fops);
-               proc_create("pressure/memory", 0, NULL, &psi_memory_fops);
-               proc_create("pressure/cpu", 0, NULL, &psi_cpu_fops);
+               proc_create("pressure/io", 0, NULL, &psi_io_proc_ops);
+               proc_create("pressure/memory", 0, NULL, &psi_memory_proc_ops);
+               proc_create("pressure/cpu", 0, NULL, &psi_cpu_proc_ops);
        }
        return 0;
 }
index 3b7bedc..d0ada39 100644 (file)
@@ -435,7 +435,7 @@ static void smp_call_function_many_cond(const struct cpumask *mask,
 
        /* Fastpath: do that cpu by itself. */
        if (next_cpu >= nr_cpu_ids) {
-               if (!cond_func || (cond_func && cond_func(cpu, info)))
+               if (!cond_func || cond_func(cpu, info))
                        smp_call_function_single(cpu, func, info, wait);
                return;
        }
index fff5f64..428beb6 100644 (file)
@@ -293,8 +293,15 @@ static void clocksource_watchdog(struct timer_list *unused)
        next_cpu = cpumask_next(raw_smp_processor_id(), cpu_online_mask);
        if (next_cpu >= nr_cpu_ids)
                next_cpu = cpumask_first(cpu_online_mask);
-       watchdog_timer.expires += WATCHDOG_INTERVAL;
-       add_timer_on(&watchdog_timer, next_cpu);
+
+       /*
+        * Arm timer if not already pending: could race with concurrent
+        * pair clocksource_stop_watchdog() clocksource_start_watchdog().
+        */
+       if (!timer_pending(&watchdog_timer)) {
+               watchdog_timer.expires += WATCHDOG_INTERVAL;
+               add_timer_on(&watchdog_timer, next_cpu);
+       }
 out:
        spin_unlock(&watchdog_lock);
 }
index 25a0fcf..91e8851 100644 (file)
@@ -141,6 +141,15 @@ menuconfig FTRACE
 
 if FTRACE
 
+config BOOTTIME_TRACING
+       bool "Boot-time Tracing support"
+       depends on BOOT_CONFIG && TRACING
+       default y
+       help
+         Enable developer to setup ftrace subsystem via supplemental
+         kernel cmdline at boot time for debugging (tracing) driver
+         initialization and boot process.
+
 config FUNCTION_TRACER
        bool "Kernel Function Tracer"
        depends on HAVE_FUNCTION_TRACER
@@ -172,6 +181,77 @@ config FUNCTION_GRAPH_TRACER
          the return value. This is done by setting the current return
          address on the current task structure into a stack of calls.
 
+config DYNAMIC_FTRACE
+       bool "enable/disable function tracing dynamically"
+       depends on FUNCTION_TRACER
+       depends on HAVE_DYNAMIC_FTRACE
+       default y
+       help
+         This option will modify all the calls to function tracing
+         dynamically (will patch them out of the binary image and
+         replace them with a No-Op instruction) on boot up. During
+         compile time, a table is made of all the locations that ftrace
+         can function trace, and this table is linked into the kernel
+         image. When this is enabled, functions can be individually
+         enabled, and the functions not enabled will not affect
+         performance of the system.
+
+         See the files in /sys/kernel/debug/tracing:
+           available_filter_functions
+           set_ftrace_filter
+           set_ftrace_notrace
+
+         This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but
+         otherwise has native performance as long as no tracing is active.
+
+config DYNAMIC_FTRACE_WITH_REGS
+       def_bool y
+       depends on DYNAMIC_FTRACE
+       depends on HAVE_DYNAMIC_FTRACE_WITH_REGS
+
+config DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+       def_bool y
+       depends on DYNAMIC_FTRACE
+       depends on HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
+
+config FUNCTION_PROFILER
+       bool "Kernel function profiler"
+       depends on FUNCTION_TRACER
+       default n
+       help
+         This option enables the kernel function profiler. A file is created
+         in debugfs called function_profile_enabled which defaults to zero.
+         When a 1 is echoed into this file profiling begins, and when a
+         zero is entered, profiling stops. A "functions" file is created in
+         the trace_stat directory; this file shows the list of functions that
+         have been hit and their counters.
+
+         If in doubt, say N.
+
+config STACK_TRACER
+       bool "Trace max stack"
+       depends on HAVE_FUNCTION_TRACER
+       select FUNCTION_TRACER
+       select STACKTRACE
+       select KALLSYMS
+       help
+         This special tracer records the maximum stack footprint of the
+         kernel and displays it in /sys/kernel/debug/tracing/stack_trace.
+
+         This tracer works by hooking into every function call that the
+         kernel executes, and keeping a maximum stack depth value and
+         stack-trace saved.  If this is configured with DYNAMIC_FTRACE
+         then it will not have any overhead while the stack tracer
+         is disabled.
+
+         To enable the stack tracer on bootup, pass in 'stacktrace'
+         on the kernel command line.
+
+         The stack tracer can also be enabled or disabled via the
+         sysctl kernel.stack_tracer_enabled
+
+         Say N if unsure.
+
 config TRACE_PREEMPT_TOGGLE
        bool
        help
@@ -282,6 +362,19 @@ config HWLAT_TRACER
         file. Every time a latency is greater than tracing_thresh, it will
         be recorded into the ring buffer.
 
+config MMIOTRACE
+       bool "Memory mapped IO tracing"
+       depends on HAVE_MMIOTRACE_SUPPORT && PCI
+       select GENERIC_TRACER
+       help
+         Mmiotrace traces Memory Mapped I/O access and is meant for
+         debugging and reverse engineering. It is called from the ioremap
+         implementation and works via page faults. Tracing is disabled by
+         default and can be enabled at run-time.
+
+         See Documentation/trace/mmiotrace.rst.
+         If you are not helping to develop drivers, say N.
+
 config ENABLE_DEFAULT_TRACERS
        bool "Trace process context switches and events"
        depends on !GENERIC_TRACER
@@ -410,30 +503,6 @@ config BRANCH_TRACER
 
          Say N if unsure.
 
-config STACK_TRACER
-       bool "Trace max stack"
-       depends on HAVE_FUNCTION_TRACER
-       select FUNCTION_TRACER
-       select STACKTRACE
-       select KALLSYMS
-       help
-         This special tracer records the maximum stack footprint of the
-         kernel and displays it in /sys/kernel/debug/tracing/stack_trace.
-
-         This tracer works by hooking into every function call that the
-         kernel executes, and keeping a maximum stack depth value and
-         stack-trace saved.  If this is configured with DYNAMIC_FTRACE
-         then it will not have any overhead while the stack tracer
-         is disabled.
-
-         To enable the stack tracer on bootup, pass in 'stacktrace'
-         on the kernel command line.
-
-         The stack tracer can also be enabled or disabled via the
-         sysctl kernel.stack_tracer_enabled
-
-         Say N if unsure.
-
 config BLK_DEV_IO_TRACE
        bool "Support for tracing block IO actions"
        depends on SYSFS
@@ -531,53 +600,6 @@ config DYNAMIC_EVENTS
 config PROBE_EVENTS
        def_bool n
 
-config DYNAMIC_FTRACE
-       bool "enable/disable function tracing dynamically"
-       depends on FUNCTION_TRACER
-       depends on HAVE_DYNAMIC_FTRACE
-       default y
-       help
-         This option will modify all the calls to function tracing
-         dynamically (will patch them out of the binary image and
-         replace them with a No-Op instruction) on boot up. During
-         compile time, a table is made of all the locations that ftrace
-         can function trace, and this table is linked into the kernel
-         image. When this is enabled, functions can be individually
-         enabled, and the functions not enabled will not affect
-         performance of the system.
-
-         See the files in /sys/kernel/debug/tracing:
-           available_filter_functions
-           set_ftrace_filter
-           set_ftrace_notrace
-
-         This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but
-         otherwise has native performance as long as no tracing is active.
-
-config DYNAMIC_FTRACE_WITH_REGS
-       def_bool y
-       depends on DYNAMIC_FTRACE
-       depends on HAVE_DYNAMIC_FTRACE_WITH_REGS
-
-config DYNAMIC_FTRACE_WITH_DIRECT_CALLS
-       def_bool y
-       depends on DYNAMIC_FTRACE
-       depends on HAVE_DYNAMIC_FTRACE_WITH_DIRECT_CALLS
-
-config FUNCTION_PROFILER
-       bool "Kernel function profiler"
-       depends on FUNCTION_TRACER
-       default n
-       help
-         This option enables the kernel function profiler. A file is created
-         in debugfs called function_profile_enabled which defaults to zero.
-         When a 1 is echoed into this file profiling begins, and when a
-         zero is entered, profiling stops. A "functions" file is created in
-         the trace_stat directory; this file shows the list of functions that
-         have been hit and their counters.
-
-         If in doubt, say N.
-
 config BPF_KPROBE_OVERRIDE
        bool "Enable BPF programs to override a kprobed function"
        depends on BPF_EVENTS
@@ -592,54 +614,6 @@ config FTRACE_MCOUNT_RECORD
        depends on DYNAMIC_FTRACE
        depends on HAVE_FTRACE_MCOUNT_RECORD
 
-config FTRACE_SELFTEST
-       bool
-
-config FTRACE_STARTUP_TEST
-       bool "Perform a startup test on ftrace"
-       depends on GENERIC_TRACER
-       select FTRACE_SELFTEST
-       help
-         This option performs a series of startup tests on ftrace. On bootup
-         a series of tests are made to verify that the tracer is
-         functioning properly. It will do tests on all the configured
-         tracers of ftrace.
-
-config EVENT_TRACE_STARTUP_TEST
-       bool "Run selftest on trace events"
-       depends on FTRACE_STARTUP_TEST
-       default y
-       help
-         This option performs a test on all trace events in the system.
-         It basically just enables each event and runs some code that
-         will trigger events (not necessarily the event it enables)
-         This may take some time run as there are a lot of events.
-
-config EVENT_TRACE_TEST_SYSCALLS
-       bool "Run selftest on syscall events"
-       depends on EVENT_TRACE_STARTUP_TEST
-       help
-        This option will also enable testing every syscall event.
-        It only enables the event and disables it and runs various loads
-        with the event enabled. This adds a bit more time for kernel boot
-        up since it runs this on every system call defined.
-
-        TBD - enable a way to actually call the syscalls as we test their
-              events
-
-config MMIOTRACE
-       bool "Memory mapped IO tracing"
-       depends on HAVE_MMIOTRACE_SUPPORT && PCI
-       select GENERIC_TRACER
-       help
-         Mmiotrace traces Memory Mapped I/O access and is meant for
-         debugging and reverse engineering. It is called from the ioremap
-         implementation and works via page faults. Tracing is disabled by
-         default and can be enabled at run-time.
-
-         See Documentation/trace/mmiotrace.rst.
-         If you are not helping to develop drivers, say N.
-
 config TRACING_MAP
        bool
        depends on ARCH_HAVE_NMI_SAFE_CMPXCHG
@@ -680,16 +654,6 @@ config TRACE_EVENT_INJECT
 
          If unsure, say N.
 
-config MMIOTRACE_TEST
-       tristate "Test module for mmiotrace"
-       depends on MMIOTRACE && m
-       help
-         This is a dumb module for testing mmiotrace. It is very dangerous
-         as it will write garbage to IO memory starting at a given address.
-         However, it should be safe to use on e.g. unused portion of VRAM.
-
-         Say N, unless you absolutely know what you are doing.
-
 config TRACEPOINT_BENCHMARK
        bool "Add tracepoint that benchmarks tracepoints"
        help
@@ -736,6 +700,81 @@ config RING_BUFFER_BENCHMARK
 
          If unsure, say N.
 
+config TRACE_EVAL_MAP_FILE
+       bool "Show eval mappings for trace events"
+       depends on TRACING
+       help
+       The "print fmt" of the trace events will show the enum/sizeof names
+       instead of their values. This can cause problems for user space tools
+       that use this string to parse the raw data as user space does not know
+       how to convert the string to its value.
+
+       To fix this, there's a special macro in the kernel that can be used
+       to convert an enum/sizeof into its value. If this macro is used, then
+       the print fmt strings will be converted to their values.
+
+       If something does not get converted properly, this option can be
+       used to show what enums/sizeof the kernel tried to convert.
+
+       This option is for debugging the conversions. A file is created
+       in the tracing directory called "eval_map" that will show the
+       names matched with their values and what trace event system they
+       belong too.
+
+       Normally, the mapping of the strings to values will be freed after
+       boot up or module load. With this option, they will not be freed, as
+       they are needed for the "eval_map" file. Enabling this option will
+       increase the memory footprint of the running kernel.
+
+       If unsure, say N.
+
+config GCOV_PROFILE_FTRACE
+       bool "Enable GCOV profiling on ftrace subsystem"
+       depends on GCOV_KERNEL
+       help
+         Enable GCOV profiling on ftrace subsystem for checking
+         which functions/lines are tested.
+
+         If unsure, say N.
+
+         Note that on a kernel compiled with this config, ftrace will
+         run significantly slower.
+
+config FTRACE_SELFTEST
+       bool
+
+config FTRACE_STARTUP_TEST
+       bool "Perform a startup test on ftrace"
+       depends on GENERIC_TRACER
+       select FTRACE_SELFTEST
+       help
+         This option performs a series of startup tests on ftrace. On bootup
+         a series of tests are made to verify that the tracer is
+         functioning properly. It will do tests on all the configured
+         tracers of ftrace.
+
+config EVENT_TRACE_STARTUP_TEST
+       bool "Run selftest on trace events"
+       depends on FTRACE_STARTUP_TEST
+       default y
+       help
+         This option performs a test on all trace events in the system.
+         It basically just enables each event and runs some code that
+         will trigger events (not necessarily the event it enables)
+         This may take some time run as there are a lot of events.
+
+config EVENT_TRACE_TEST_SYSCALLS
+       bool "Run selftest on syscall events"
+       depends on EVENT_TRACE_STARTUP_TEST
+       help
+        This option will also enable testing every syscall event.
+        It only enables the event and disables it and runs various loads
+        with the event enabled. This adds a bit more time for kernel boot
+        up since it runs this on every system call defined.
+
+        TBD - enable a way to actually call the syscalls as we test their
+              events
+
 config RING_BUFFER_STARTUP_TEST
        bool "Ring buffer startup self test"
        depends on RING_BUFFER
@@ -759,8 +798,18 @@ config RING_BUFFER_STARTUP_TEST
 
         If unsure, say N
 
+config MMIOTRACE_TEST
+       tristate "Test module for mmiotrace"
+       depends on MMIOTRACE && m
+       help
+         This is a dumb module for testing mmiotrace. It is very dangerous
+         as it will write garbage to IO memory starting at a given address.
+         However, it should be safe to use on e.g. unused portion of VRAM.
+
+         Say N, unless you absolutely know what you are doing.
+
 config PREEMPTIRQ_DELAY_TEST
-       tristate "Preempt / IRQ disable delay thread to test latency tracers"
+       tristate "Test module to create a preempt / IRQ disable delay thread to test latency tracers"
        depends on m
        help
          Select this option to build a test module that can help test latency
@@ -774,45 +823,30 @@ config PREEMPTIRQ_DELAY_TEST
 
          If unsure, say N
 
-config TRACE_EVAL_MAP_FILE
-       bool "Show eval mappings for trace events"
-       depends on TRACING
-       help
-       The "print fmt" of the trace events will show the enum/sizeof names
-       instead of their values. This can cause problems for user space tools
-       that use this string to parse the raw data as user space does not know
-       how to convert the string to its value.
-
-       To fix this, there's a special macro in the kernel that can be used
-       to convert an enum/sizeof into its value. If this macro is used, then
-       the print fmt strings will be converted to their values.
-
-       If something does not get converted properly, this option can be
-       used to show what enums/sizeof the kernel tried to convert.
-
-       This option is for debugging the conversions. A file is created
-       in the tracing directory called "eval_map" that will show the
-       names matched with their values and what trace event system they
-       belong too.
+config SYNTH_EVENT_GEN_TEST
+       tristate "Test module for in-kernel synthetic event generation"
+       depends on HIST_TRIGGERS
+       help
+          This option creates a test module to check the base
+          functionality of in-kernel synthetic event definition and
+          generation.
 
-       Normally, the mapping of the strings to values will be freed after
-       boot up or module load. With this option, they will not be freed, as
-       they are needed for the "eval_map" file. Enabling this option will
-       increase the memory footprint of the running kernel.
+          To test, insert the module, and then check the trace buffer
+         for the generated sample events.
 
-       If unsure, say N.
+         If unsure, say N.
 
-config GCOV_PROFILE_FTRACE
-       bool "Enable GCOV profiling on ftrace subsystem"
-       depends on GCOV_KERNEL
+config KPROBE_EVENT_GEN_TEST
+       tristate "Test module for in-kernel kprobe event generation"
+       depends on KPROBE_EVENTS
        help
-         Enable GCOV profiling on ftrace subsystem for checking
-         which functions/lines are tested.
+          This option creates a test module to check the base
+          functionality of in-kernel kprobe event definition.
 
-         If unsure, say N.
+          To test, insert the module, and then check the trace buffer
+         for the generated kprobe events.
 
-         Note that on a kernel compiled with this config, ftrace will
-         run significantly slower.
+         If unsure, say N.
 
 endif # FTRACE
 
index 0e63db6..f9dcd19 100644 (file)
@@ -44,6 +44,8 @@ obj-$(CONFIG_TRACING) += trace_stat.o
 obj-$(CONFIG_TRACING) += trace_printk.o
 obj-$(CONFIG_TRACING_MAP) += tracing_map.o
 obj-$(CONFIG_PREEMPTIRQ_DELAY_TEST) += preemptirq_delay_test.o
+obj-$(CONFIG_SYNTH_EVENT_GEN_TEST) += synth_event_gen_test.o
+obj-$(CONFIG_KPROBE_EVENT_GEN_TEST) += kprobe_event_gen_test.o
 obj-$(CONFIG_CONTEXT_SWITCH_TRACER) += trace_sched_switch.o
 obj-$(CONFIG_FUNCTION_TRACER) += trace_functions.o
 obj-$(CONFIG_PREEMPTIRQ_TRACEPOINTS) += trace_preemptirq.o
@@ -83,6 +85,7 @@ endif
 obj-$(CONFIG_DYNAMIC_EVENTS) += trace_dynevent.o
 obj-$(CONFIG_PROBE_EVENTS) += trace_probe.o
 obj-$(CONFIG_UPROBE_EVENTS) += trace_uprobe.o
+obj-$(CONFIG_BOOTTIME_TRACING) += trace_boot.o
 
 obj-$(CONFIG_TRACEPOINT_BENCHMARK) += trace_benchmark.o
 
index 475e294..0735ae8 100644 (file)
@@ -68,14 +68,14 @@ static void trace_note(struct blk_trace *bt, pid_t pid, int action,
 {
        struct blk_io_trace *t;
        struct ring_buffer_event *event = NULL;
-       struct ring_buffer *buffer = NULL;
+       struct trace_buffer *buffer = NULL;
        int pc = 0;
        int cpu = smp_processor_id();
        bool blk_tracer = blk_tracer_enabled;
        ssize_t cgid_len = cgid ? sizeof(cgid) : 0;
 
        if (blk_tracer) {
-               buffer = blk_tr->trace_buffer.buffer;
+               buffer = blk_tr->array_buffer.buffer;
                pc = preempt_count();
                event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
                                                  sizeof(*t) + len + cgid_len,
@@ -215,7 +215,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
 {
        struct task_struct *tsk = current;
        struct ring_buffer_event *event = NULL;
-       struct ring_buffer *buffer = NULL;
+       struct trace_buffer *buffer = NULL;
        struct blk_io_trace *t;
        unsigned long flags = 0;
        unsigned long *sequence;
@@ -248,7 +248,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
        if (blk_tracer) {
                tracing_record_cmdline(current);
 
-               buffer = blk_tr->trace_buffer.buffer;
+               buffer = blk_tr->array_buffer.buffer;
                pc = preempt_count();
                event = trace_buffer_lock_reserve(buffer, TRACE_BLK,
                                                  sizeof(*t) + pdu_len + cgid_len,
index 9bf1f2c..3f7ee10 100644 (file)
@@ -62,8 +62,6 @@
        })
 
 /* hash bits for specific function selection */
-#define FTRACE_HASH_BITS 7
-#define FTRACE_FUNC_HASHSIZE (1 << FTRACE_HASH_BITS)
 #define FTRACE_HASH_DEFAULT_BITS 10
 #define FTRACE_HASH_MAX_BITS 12
 
@@ -146,7 +144,7 @@ static void ftrace_pid_func(unsigned long ip, unsigned long parent_ip,
 {
        struct trace_array *tr = op->private;
 
-       if (tr && this_cpu_read(tr->trace_buffer.data->ftrace_ignore_pid))
+       if (tr && this_cpu_read(tr->array_buffer.data->ftrace_ignore_pid))
                return;
 
        op->saved_func(ip, parent_ip, op, regs);
@@ -1103,9 +1101,6 @@ struct ftrace_page {
 #define ENTRY_SIZE sizeof(struct dyn_ftrace)
 #define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE)
 
-/* estimate from running different kernels */
-#define NR_TO_INIT             10000
-
 static struct ftrace_page      *ftrace_pages_start;
 static struct ftrace_page      *ftrace_pages;
 
@@ -5464,7 +5459,7 @@ static void __init set_ftrace_early_graph(char *buf, int enable)
        struct ftrace_hash *hash;
 
        hash = alloc_ftrace_hash(FTRACE_HASH_DEFAULT_BITS);
-       if (WARN_ON(!hash))
+       if (MEM_FAIL(!hash, "Failed to allocate hash\n"))
                return;
 
        while (buf) {
@@ -5596,8 +5591,8 @@ static const struct file_operations ftrace_notrace_fops = {
 
 static DEFINE_MUTEX(graph_lock);
 
-struct ftrace_hash *ftrace_graph_hash = EMPTY_HASH;
-struct ftrace_hash *ftrace_graph_notrace_hash = EMPTY_HASH;
+struct ftrace_hash __rcu *ftrace_graph_hash = EMPTY_HASH;
+struct ftrace_hash __rcu *ftrace_graph_notrace_hash = EMPTY_HASH;
 
 enum graph_filter_type {
        GRAPH_FILTER_NOTRACE    = 0,
@@ -5872,8 +5867,15 @@ ftrace_graph_release(struct inode *inode, struct file *file)
 
                mutex_unlock(&graph_lock);
 
-               /* Wait till all users are no longer using the old hash */
-               synchronize_rcu();
+               /*
+                * We need to do a hard force of sched synchronization.
+                * This is because we use preempt_disable() to do RCU, but
+                * the function tracers can be called where RCU is not watching
+                * (like before user_exit()). We can not rely on the RCU
+                * infrastructure to do the synchronization, thus we must do it
+                * ourselves.
+                */
+               schedule_on_each_cpu(ftrace_sync);
 
                free_ftrace_hash(old_hash);
        }
@@ -6596,7 +6598,7 @@ static void add_to_clear_hash_list(struct list_head *clear_list,
 
        func = kmalloc(sizeof(*func), GFP_KERNEL);
        if (!func) {
-               WARN_ONCE(1, "alloc failure, ftrace filter could be stale\n");
+               MEM_FAIL(1, "alloc failure, ftrace filter could be stale\n");
                return;
        }
 
@@ -6922,7 +6924,7 @@ ftrace_filter_pid_sched_switch_probe(void *data, bool preempt,
 
        pid_list = rcu_dereference_sched(tr->function_pids);
 
-       this_cpu_write(tr->trace_buffer.data->ftrace_ignore_pid,
+       this_cpu_write(tr->array_buffer.data->ftrace_ignore_pid,
                       trace_ignore_this_task(pid_list, next));
 }
 
@@ -6976,7 +6978,7 @@ static void clear_ftrace_pids(struct trace_array *tr)
        unregister_trace_sched_switch(ftrace_filter_pid_sched_switch_probe, tr);
 
        for_each_possible_cpu(cpu)
-               per_cpu_ptr(tr->trace_buffer.data, cpu)->ftrace_ignore_pid = false;
+               per_cpu_ptr(tr->array_buffer.data, cpu)->ftrace_ignore_pid = false;
 
        rcu_assign_pointer(tr->function_pids, NULL);
 
@@ -7031,9 +7033,10 @@ static void *fpid_next(struct seq_file *m, void *v, loff_t *pos)
        struct trace_array *tr = m->private;
        struct trace_pid_list *pid_list = rcu_dereference_sched(tr->function_pids);
 
-       if (v == FTRACE_NO_PIDS)
+       if (v == FTRACE_NO_PIDS) {
+               (*pos)++;
                return NULL;
-
+       }
        return trace_pid_next(pid_list, v, pos);
 }
 
@@ -7100,7 +7103,7 @@ static void ignore_task_cpu(void *data)
        pid_list = rcu_dereference_protected(tr->function_pids,
                                             mutex_is_locked(&ftrace_lock));
 
-       this_cpu_write(tr->trace_buffer.data->ftrace_ignore_pid,
+       this_cpu_write(tr->array_buffer.data->ftrace_ignore_pid,
                       trace_ignore_this_task(pid_list, current));
 }
 
diff --git a/kernel/trace/kprobe_event_gen_test.c b/kernel/trace/kprobe_event_gen_test.c
new file mode 100644 (file)
index 0000000..18b0f1c
--- /dev/null
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test module for in-kernel kprobe event creation and generation.
+ *
+ * Copyright (C) 2019 Tom Zanussi <zanussi@kernel.org>
+ */
+
+#include <linux/module.h>
+#include <linux/trace_events.h>
+
+/*
+ * This module is a simple test of basic functionality for in-kernel
+ * kprobe/kretprobe event creation.  The first test uses
+ * kprobe_event_gen_cmd_start(), kprobe_event_add_fields() and
+ * kprobe_event_gen_cmd_end() to create a kprobe event, which is then
+ * enabled in order to generate trace output.  The second creates a
+ * kretprobe event using kretprobe_event_gen_cmd_start() and
+ * kretprobe_event_gen_cmd_end(), and is also then enabled.
+ *
+ * To test, select CONFIG_KPROBE_EVENT_GEN_TEST and build the module.
+ * Then:
+ *
+ * # insmod kernel/trace/kprobe_event_gen_test.ko
+ * # cat /sys/kernel/debug/tracing/trace
+ *
+ * You should see many instances of the "gen_kprobe_test" and
+ * "gen_kretprobe_test" events in the trace buffer.
+ *
+ * To remove the events, remove the module:
+ *
+ * # rmmod kprobe_event_gen_test
+ *
+ */
+
+static struct trace_event_file *gen_kprobe_test;
+static struct trace_event_file *gen_kretprobe_test;
+
+/*
+ * Test to make sure we can create a kprobe event, then add more
+ * fields.
+ */
+static int __init test_gen_kprobe_cmd(void)
+{
+       struct dynevent_cmd cmd;
+       char *buf;
+       int ret;
+
+       /* Create a buffer to hold the generated command */
+       buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       /* Before generating the command, initialize the cmd object */
+       kprobe_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
+
+       /*
+        * Define the gen_kprobe_test event with the first 2 kprobe
+        * fields.
+        */
+       ret = kprobe_event_gen_cmd_start(&cmd, "gen_kprobe_test",
+                                        "do_sys_open",
+                                        "dfd=%ax", "filename=%dx");
+       if (ret)
+               goto free;
+
+       /* Use kprobe_event_add_fields to add the rest of the fields */
+
+       ret = kprobe_event_add_fields(&cmd, "flags=%cx", "mode=+4($stack)");
+       if (ret)
+               goto free;
+
+       /*
+        * This actually creates the event.
+        */
+       ret = kprobe_event_gen_cmd_end(&cmd);
+       if (ret)
+               goto free;
+
+       /*
+        * Now get the gen_kprobe_test event file.  We need to prevent
+        * the instance and event from disappearing from underneath
+        * us, which trace_get_event_file() does (though in this case
+        * we're using the top-level instance which never goes away).
+        */
+       gen_kprobe_test = trace_get_event_file(NULL, "kprobes",
+                                              "gen_kprobe_test");
+       if (IS_ERR(gen_kprobe_test)) {
+               ret = PTR_ERR(gen_kprobe_test);
+               goto delete;
+       }
+
+       /* Enable the event or you won't see anything */
+       ret = trace_array_set_clr_event(gen_kprobe_test->tr,
+                                       "kprobes", "gen_kprobe_test", true);
+       if (ret) {
+               trace_put_event_file(gen_kprobe_test);
+               goto delete;
+       }
+ out:
+       return ret;
+ delete:
+       /* We got an error after creating the event, delete it */
+       ret = kprobe_event_delete("gen_kprobe_test");
+ free:
+       kfree(buf);
+
+       goto out;
+}
+
+/*
+ * Test to make sure we can create a kretprobe event.
+ */
+static int __init test_gen_kretprobe_cmd(void)
+{
+       struct dynevent_cmd cmd;
+       char *buf;
+       int ret;
+
+       /* Create a buffer to hold the generated command */
+       buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       /* Before generating the command, initialize the cmd object */
+       kprobe_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
+
+       /*
+        * Define the kretprobe event.
+        */
+       ret = kretprobe_event_gen_cmd_start(&cmd, "gen_kretprobe_test",
+                                           "do_sys_open",
+                                           "$retval");
+       if (ret)
+               goto free;
+
+       /*
+        * This actually creates the event.
+        */
+       ret = kretprobe_event_gen_cmd_end(&cmd);
+       if (ret)
+               goto free;
+
+       /*
+        * Now get the gen_kretprobe_test event file.  We need to
+        * prevent the instance and event from disappearing from
+        * underneath us, which trace_get_event_file() does (though in
+        * this case we're using the top-level instance which never
+        * goes away).
+        */
+       gen_kretprobe_test = trace_get_event_file(NULL, "kprobes",
+                                                 "gen_kretprobe_test");
+       if (IS_ERR(gen_kretprobe_test)) {
+               ret = PTR_ERR(gen_kretprobe_test);
+               goto delete;
+       }
+
+       /* Enable the event or you won't see anything */
+       ret = trace_array_set_clr_event(gen_kretprobe_test->tr,
+                                       "kprobes", "gen_kretprobe_test", true);
+       if (ret) {
+               trace_put_event_file(gen_kretprobe_test);
+               goto delete;
+       }
+ out:
+       return ret;
+ delete:
+       /* We got an error after creating the event, delete it */
+       ret = kprobe_event_delete("gen_kretprobe_test");
+ free:
+       kfree(buf);
+
+       goto out;
+}
+
+static int __init kprobe_event_gen_test_init(void)
+{
+       int ret;
+
+       ret = test_gen_kprobe_cmd();
+       if (ret)
+               return ret;
+
+       ret = test_gen_kretprobe_cmd();
+       if (ret) {
+               WARN_ON(trace_array_set_clr_event(gen_kretprobe_test->tr,
+                                                 "kprobes",
+                                                 "gen_kretprobe_test", false));
+               trace_put_event_file(gen_kretprobe_test);
+               WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
+       }
+
+       return ret;
+}
+
+static void __exit kprobe_event_gen_test_exit(void)
+{
+       /* Disable the event or you can't remove it */
+       WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
+                                         "kprobes",
+                                         "gen_kprobe_test", false));
+
+       /* Now give the file and instance back */
+       trace_put_event_file(gen_kprobe_test);
+
+       /* Now unregister and free the event */
+       WARN_ON(kprobe_event_delete("gen_kprobe_test"));
+
+       /* Disable the event or you can't remove it */
+       WARN_ON(trace_array_set_clr_event(gen_kprobe_test->tr,
+                                         "kprobes",
+                                         "gen_kretprobe_test", false));
+
+       /* Now give the file and instance back */
+       trace_put_event_file(gen_kretprobe_test);
+
+       /* Now unregister and free the event */
+       WARN_ON(kprobe_event_delete("gen_kretprobe_test"));
+}
+
+module_init(kprobe_event_gen_test_init)
+module_exit(kprobe_event_gen_test_exit)
+
+MODULE_AUTHOR("Tom Zanussi");
+MODULE_DESCRIPTION("kprobe event generation test");
+MODULE_LICENSE("GPL v2");
index 3f65537..61f0e92 100644 (file)
@@ -300,8 +300,6 @@ u64 ring_buffer_event_time_stamp(struct ring_buffer_event *event)
 /* Missed count stored at end */
 #define RB_MISSED_STORED       (1 << 30)
 
-#define RB_MISSED_FLAGS                (RB_MISSED_EVENTS|RB_MISSED_STORED)
-
 struct buffer_data_page {
        u64              time_stamp;    /* page time stamp */
        local_t          commit;        /* write committed index */
@@ -443,7 +441,7 @@ enum {
 struct ring_buffer_per_cpu {
        int                             cpu;
        atomic_t                        record_disabled;
-       struct ring_buffer              *buffer;
+       struct trace_buffer     *buffer;
        raw_spinlock_t                  reader_lock;    /* serialize readers */
        arch_spinlock_t                 lock;
        struct lock_class_key           lock_key;
@@ -482,7 +480,7 @@ struct ring_buffer_per_cpu {
        struct rb_irq_work              irq_work;
 };
 
-struct ring_buffer {
+struct trace_buffer {
        unsigned                        flags;
        int                             cpus;
        atomic_t                        record_disabled;
@@ -518,7 +516,7 @@ struct ring_buffer_iter {
  *
  * Returns the number of pages used by a per_cpu buffer of the ring buffer.
  */
-size_t ring_buffer_nr_pages(struct ring_buffer *buffer, int cpu)
+size_t ring_buffer_nr_pages(struct trace_buffer *buffer, int cpu)
 {
        return buffer->buffers[cpu]->nr_pages;
 }
@@ -530,7 +528,7 @@ size_t ring_buffer_nr_pages(struct ring_buffer *buffer, int cpu)
  *
  * Returns the number of pages that have content in the ring buffer.
  */
-size_t ring_buffer_nr_dirty_pages(struct ring_buffer *buffer, int cpu)
+size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu)
 {
        size_t read;
        size_t cnt;
@@ -573,7 +571,7 @@ static void rb_wake_up_waiters(struct irq_work *work)
  * as data is added to any of the @buffer's cpu buffers. Otherwise
  * it will wait for data to be added to a specific cpu buffer.
  */
-int ring_buffer_wait(struct ring_buffer *buffer, int cpu, int full)
+int ring_buffer_wait(struct trace_buffer *buffer, int cpu, int full)
 {
        struct ring_buffer_per_cpu *uninitialized_var(cpu_buffer);
        DEFINE_WAIT(wait);
@@ -684,7 +682,7 @@ int ring_buffer_wait(struct ring_buffer *buffer, int cpu, int full)
  * Returns EPOLLIN | EPOLLRDNORM if data exists in the buffers,
  * zero otherwise.
  */
-__poll_t ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
+__poll_t ring_buffer_poll_wait(struct trace_buffer *buffer, int cpu,
                          struct file *filp, poll_table *poll_table)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
@@ -742,13 +740,13 @@ __poll_t ring_buffer_poll_wait(struct ring_buffer *buffer, int cpu,
 /* Up this if you want to test the TIME_EXTENTS and normalization */
 #define DEBUG_SHIFT 0
 
-static inline u64 rb_time_stamp(struct ring_buffer *buffer)
+static inline u64 rb_time_stamp(struct trace_buffer *buffer)
 {
        /* shift to debug/test normalization and TIME_EXTENTS */
        return buffer->clock() << DEBUG_SHIFT;
 }
 
-u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu)
+u64 ring_buffer_time_stamp(struct trace_buffer *buffer, int cpu)
 {
        u64 time;
 
@@ -760,7 +758,7 @@ u64 ring_buffer_time_stamp(struct ring_buffer *buffer, int cpu)
 }
 EXPORT_SYMBOL_GPL(ring_buffer_time_stamp);
 
-void ring_buffer_normalize_time_stamp(struct ring_buffer *buffer,
+void ring_buffer_normalize_time_stamp(struct trace_buffer *buffer,
                                      int cpu, u64 *ts)
 {
        /* Just stupid testing the normalize function and deltas */
@@ -1283,7 +1281,7 @@ static int rb_allocate_pages(struct ring_buffer_per_cpu *cpu_buffer,
 }
 
 static struct ring_buffer_per_cpu *
-rb_allocate_cpu_buffer(struct ring_buffer *buffer, long nr_pages, int cpu)
+rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct buffer_page *bpage;
@@ -1368,16 +1366,17 @@ static void rb_free_cpu_buffer(struct ring_buffer_per_cpu *cpu_buffer)
  * __ring_buffer_alloc - allocate a new ring_buffer
  * @size: the size in bytes per cpu that is needed.
  * @flags: attributes to set for the ring buffer.
+ * @key: ring buffer reader_lock_key.
  *
  * Currently the only flag that is available is the RB_FL_OVERWRITE
  * flag. This flag means that the buffer will overwrite old data
  * when the buffer wraps. If this flag is not set, the buffer will
  * drop data when the tail hits the head.
  */
-struct ring_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,
+struct trace_buffer *__ring_buffer_alloc(unsigned long size, unsigned flags,
                                        struct lock_class_key *key)
 {
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        long nr_pages;
        int bsize;
        int cpu;
@@ -1447,7 +1446,7 @@ EXPORT_SYMBOL_GPL(__ring_buffer_alloc);
  * @buffer: the buffer to free.
  */
 void
-ring_buffer_free(struct ring_buffer *buffer)
+ring_buffer_free(struct trace_buffer *buffer)
 {
        int cpu;
 
@@ -1463,18 +1462,18 @@ ring_buffer_free(struct ring_buffer *buffer)
 }
 EXPORT_SYMBOL_GPL(ring_buffer_free);
 
-void ring_buffer_set_clock(struct ring_buffer *buffer,
+void ring_buffer_set_clock(struct trace_buffer *buffer,
                           u64 (*clock)(void))
 {
        buffer->clock = clock;
 }
 
-void ring_buffer_set_time_stamp_abs(struct ring_buffer *buffer, bool abs)
+void ring_buffer_set_time_stamp_abs(struct trace_buffer *buffer, bool abs)
 {
        buffer->time_stamp_abs = abs;
 }
 
-bool ring_buffer_time_stamp_abs(struct ring_buffer *buffer)
+bool ring_buffer_time_stamp_abs(struct trace_buffer *buffer)
 {
        return buffer->time_stamp_abs;
 }
@@ -1712,7 +1711,7 @@ static void update_pages_handler(struct work_struct *work)
  *
  * Returns 0 on success and < 0 on failure.
  */
-int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,
+int ring_buffer_resize(struct trace_buffer *buffer, unsigned long size,
                        int cpu_id)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
@@ -1891,7 +1890,7 @@ int ring_buffer_resize(struct ring_buffer *buffer, unsigned long size,
 }
 EXPORT_SYMBOL_GPL(ring_buffer_resize);
 
-void ring_buffer_change_overwrite(struct ring_buffer *buffer, int val)
+void ring_buffer_change_overwrite(struct trace_buffer *buffer, int val)
 {
        mutex_lock(&buffer->mutex);
        if (val)
@@ -2206,7 +2205,7 @@ rb_move_tail(struct ring_buffer_per_cpu *cpu_buffer,
 {
        struct buffer_page *tail_page = info->tail_page;
        struct buffer_page *commit_page = cpu_buffer->commit_page;
-       struct ring_buffer *buffer = cpu_buffer->buffer;
+       struct trace_buffer *buffer = cpu_buffer->buffer;
        struct buffer_page *next_page;
        int ret;
 
@@ -2330,11 +2329,11 @@ static inline bool rb_event_is_commit(struct ring_buffer_per_cpu *cpu_buffer,
 
 /**
  * rb_update_event - update event type and data
+ * @cpu_buffer: The per cpu buffer of the @event
  * @event: the event to update
- * @type: the type of event
- * @length: the size of the event field in the ring buffer
+ * @info: The info to update the @event with (contains length and delta)
  *
- * Update the type and data fields of the event. The length
+ * Update the type and data fields of the @event. The length
  * is the actual size that is written to the ring buffer,
  * and with this, we can determine what to place into the
  * data field.
@@ -2609,7 +2608,7 @@ static void rb_commit(struct ring_buffer_per_cpu *cpu_buffer,
 }
 
 static __always_inline void
-rb_wakeups(struct ring_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
+rb_wakeups(struct trace_buffer *buffer, struct ring_buffer_per_cpu *cpu_buffer)
 {
        size_t nr_pages;
        size_t dirty;
@@ -2733,7 +2732,7 @@ trace_recursive_unlock(struct ring_buffer_per_cpu *cpu_buffer)
  * Call this function before calling another ring_buffer_lock_reserve() and
  * call ring_buffer_nest_end() after the nested ring_buffer_unlock_commit().
  */
-void ring_buffer_nest_start(struct ring_buffer *buffer)
+void ring_buffer_nest_start(struct trace_buffer *buffer)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        int cpu;
@@ -2753,7 +2752,7 @@ void ring_buffer_nest_start(struct ring_buffer *buffer)
  * Must be called after ring_buffer_nest_start() and after the
  * ring_buffer_unlock_commit().
  */
-void ring_buffer_nest_end(struct ring_buffer *buffer)
+void ring_buffer_nest_end(struct trace_buffer *buffer)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        int cpu;
@@ -2775,7 +2774,7 @@ void ring_buffer_nest_end(struct ring_buffer *buffer)
  *
  * Must be paired with ring_buffer_lock_reserve.
  */
-int ring_buffer_unlock_commit(struct ring_buffer *buffer,
+int ring_buffer_unlock_commit(struct trace_buffer *buffer,
                              struct ring_buffer_event *event)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
@@ -2868,7 +2867,7 @@ __rb_reserve_next(struct ring_buffer_per_cpu *cpu_buffer,
 }
 
 static __always_inline struct ring_buffer_event *
-rb_reserve_next_event(struct ring_buffer *buffer,
+rb_reserve_next_event(struct trace_buffer *buffer,
                      struct ring_buffer_per_cpu *cpu_buffer,
                      unsigned long length)
 {
@@ -2961,7 +2960,7 @@ rb_reserve_next_event(struct ring_buffer *buffer,
  * If NULL is returned, then nothing has been allocated or locked.
  */
 struct ring_buffer_event *
-ring_buffer_lock_reserve(struct ring_buffer *buffer, unsigned long length)
+ring_buffer_lock_reserve(struct trace_buffer *buffer, unsigned long length)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_event *event;
@@ -3062,7 +3061,7 @@ rb_decrement_entry(struct ring_buffer_per_cpu *cpu_buffer,
  * If this function is called, do not call ring_buffer_unlock_commit on
  * the event.
  */
-void ring_buffer_discard_commit(struct ring_buffer *buffer,
+void ring_buffer_discard_commit(struct trace_buffer *buffer,
                                struct ring_buffer_event *event)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
@@ -3113,7 +3112,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_discard_commit);
  * Note, like ring_buffer_lock_reserve, the length is the length of the data
  * and not the length of the event which would hold the header.
  */
-int ring_buffer_write(struct ring_buffer *buffer,
+int ring_buffer_write(struct trace_buffer *buffer,
                      unsigned long length,
                      void *data)
 {
@@ -3193,7 +3192,7 @@ static bool rb_per_cpu_empty(struct ring_buffer_per_cpu *cpu_buffer)
  *
  * The caller should call synchronize_rcu() after this.
  */
-void ring_buffer_record_disable(struct ring_buffer *buffer)
+void ring_buffer_record_disable(struct trace_buffer *buffer)
 {
        atomic_inc(&buffer->record_disabled);
 }
@@ -3206,7 +3205,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_disable);
  * Note, multiple disables will need the same number of enables
  * to truly enable the writing (much like preempt_disable).
  */
-void ring_buffer_record_enable(struct ring_buffer *buffer)
+void ring_buffer_record_enable(struct trace_buffer *buffer)
 {
        atomic_dec(&buffer->record_disabled);
 }
@@ -3223,7 +3222,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_enable);
  * it works like an on/off switch, where as the disable() version
  * must be paired with a enable().
  */
-void ring_buffer_record_off(struct ring_buffer *buffer)
+void ring_buffer_record_off(struct trace_buffer *buffer)
 {
        unsigned int rd;
        unsigned int new_rd;
@@ -3246,7 +3245,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_off);
  * it works like an on/off switch, where as the enable() version
  * must be paired with a disable().
  */
-void ring_buffer_record_on(struct ring_buffer *buffer)
+void ring_buffer_record_on(struct trace_buffer *buffer)
 {
        unsigned int rd;
        unsigned int new_rd;
@@ -3264,7 +3263,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_on);
  *
  * Returns true if the ring buffer is in a state that it accepts writes.
  */
-bool ring_buffer_record_is_on(struct ring_buffer *buffer)
+bool ring_buffer_record_is_on(struct trace_buffer *buffer)
 {
        return !atomic_read(&buffer->record_disabled);
 }
@@ -3280,7 +3279,7 @@ bool ring_buffer_record_is_on(struct ring_buffer *buffer)
  * ring_buffer_record_disable(), as that is a temporary disabling of
  * the ring buffer.
  */
-bool ring_buffer_record_is_set_on(struct ring_buffer *buffer)
+bool ring_buffer_record_is_set_on(struct trace_buffer *buffer)
 {
        return !(atomic_read(&buffer->record_disabled) & RB_BUFFER_OFF);
 }
@@ -3295,7 +3294,7 @@ bool ring_buffer_record_is_set_on(struct ring_buffer *buffer)
  *
  * The caller should call synchronize_rcu() after this.
  */
-void ring_buffer_record_disable_cpu(struct ring_buffer *buffer, int cpu)
+void ring_buffer_record_disable_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
 
@@ -3315,7 +3314,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_record_disable_cpu);
  * Note, multiple disables will need the same number of enables
  * to truly enable the writing (much like preempt_disable).
  */
-void ring_buffer_record_enable_cpu(struct ring_buffer *buffer, int cpu)
+void ring_buffer_record_enable_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
 
@@ -3345,7 +3344,7 @@ rb_num_of_entries(struct ring_buffer_per_cpu *cpu_buffer)
  * @buffer: The ring buffer
  * @cpu: The per CPU buffer to read from.
  */
-u64 ring_buffer_oldest_event_ts(struct ring_buffer *buffer, int cpu)
+u64 ring_buffer_oldest_event_ts(struct trace_buffer *buffer, int cpu)
 {
        unsigned long flags;
        struct ring_buffer_per_cpu *cpu_buffer;
@@ -3378,7 +3377,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_oldest_event_ts);
  * @buffer: The ring buffer
  * @cpu: The per CPU buffer to read from.
  */
-unsigned long ring_buffer_bytes_cpu(struct ring_buffer *buffer, int cpu)
+unsigned long ring_buffer_bytes_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        unsigned long ret;
@@ -3398,7 +3397,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_bytes_cpu);
  * @buffer: The ring buffer
  * @cpu: The per CPU buffer to get the entries from.
  */
-unsigned long ring_buffer_entries_cpu(struct ring_buffer *buffer, int cpu)
+unsigned long ring_buffer_entries_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
 
@@ -3417,7 +3416,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_entries_cpu);
  * @buffer: The ring buffer
  * @cpu: The per CPU buffer to get the number of overruns from
  */
-unsigned long ring_buffer_overrun_cpu(struct ring_buffer *buffer, int cpu)
+unsigned long ring_buffer_overrun_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        unsigned long ret;
@@ -3440,7 +3439,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_overrun_cpu);
  * @cpu: The per CPU buffer to get the number of overruns from
  */
 unsigned long
-ring_buffer_commit_overrun_cpu(struct ring_buffer *buffer, int cpu)
+ring_buffer_commit_overrun_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        unsigned long ret;
@@ -3462,7 +3461,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_commit_overrun_cpu);
  * @cpu: The per CPU buffer to get the number of overruns from
  */
 unsigned long
-ring_buffer_dropped_events_cpu(struct ring_buffer *buffer, int cpu)
+ring_buffer_dropped_events_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        unsigned long ret;
@@ -3483,7 +3482,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_dropped_events_cpu);
  * @cpu: The per CPU buffer to get the number of events read
  */
 unsigned long
-ring_buffer_read_events_cpu(struct ring_buffer *buffer, int cpu)
+ring_buffer_read_events_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
 
@@ -3502,7 +3501,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_read_events_cpu);
  * Returns the total number of entries in the ring buffer
  * (all CPU entries)
  */
-unsigned long ring_buffer_entries(struct ring_buffer *buffer)
+unsigned long ring_buffer_entries(struct trace_buffer *buffer)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        unsigned long entries = 0;
@@ -3525,7 +3524,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_entries);
  * Returns the total number of overruns in the ring buffer
  * (all CPU entries)
  */
-unsigned long ring_buffer_overruns(struct ring_buffer *buffer)
+unsigned long ring_buffer_overruns(struct trace_buffer *buffer)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        unsigned long overruns = 0;
@@ -3949,7 +3948,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_peek);
 static struct ring_buffer_event *
 rb_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
 {
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_event *event;
        int nr_loops = 0;
@@ -4077,7 +4076,7 @@ rb_reader_unlock(struct ring_buffer_per_cpu *cpu_buffer, bool locked)
  * not consume the data.
  */
 struct ring_buffer_event *
-ring_buffer_peek(struct ring_buffer *buffer, int cpu, u64 *ts,
+ring_buffer_peek(struct trace_buffer *buffer, int cpu, u64 *ts,
                 unsigned long *lost_events)
 {
        struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
@@ -4141,7 +4140,7 @@ ring_buffer_iter_peek(struct ring_buffer_iter *iter, u64 *ts)
  * and eventually empty the ring buffer if the producer is slower.
  */
 struct ring_buffer_event *
-ring_buffer_consume(struct ring_buffer *buffer, int cpu, u64 *ts,
+ring_buffer_consume(struct trace_buffer *buffer, int cpu, u64 *ts,
                    unsigned long *lost_events)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
@@ -4201,7 +4200,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_consume);
  * This overall must be paired with ring_buffer_read_finish.
  */
 struct ring_buffer_iter *
-ring_buffer_read_prepare(struct ring_buffer *buffer, int cpu, gfp_t flags)
+ring_buffer_read_prepare(struct trace_buffer *buffer, int cpu, gfp_t flags)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct ring_buffer_iter *iter;
@@ -4331,8 +4330,9 @@ EXPORT_SYMBOL_GPL(ring_buffer_read);
 /**
  * ring_buffer_size - return the size of the ring buffer (in bytes)
  * @buffer: The ring buffer.
+ * @cpu: The CPU to get ring buffer size from.
  */
-unsigned long ring_buffer_size(struct ring_buffer *buffer, int cpu)
+unsigned long ring_buffer_size(struct trace_buffer *buffer, int cpu)
 {
        /*
         * Earlier, this method returned
@@ -4398,7 +4398,7 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
  * @buffer: The ring buffer to reset a per cpu buffer of
  * @cpu: The CPU buffer to be reset
  */
-void ring_buffer_reset_cpu(struct ring_buffer *buffer, int cpu)
+void ring_buffer_reset_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
        unsigned long flags;
@@ -4435,7 +4435,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_reset_cpu);
  * ring_buffer_reset - reset a ring buffer
  * @buffer: The ring buffer to reset all cpu buffers
  */
-void ring_buffer_reset(struct ring_buffer *buffer)
+void ring_buffer_reset(struct trace_buffer *buffer)
 {
        int cpu;
 
@@ -4448,7 +4448,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_reset);
  * rind_buffer_empty - is the ring buffer empty?
  * @buffer: The ring buffer to test
  */
-bool ring_buffer_empty(struct ring_buffer *buffer)
+bool ring_buffer_empty(struct trace_buffer *buffer)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        unsigned long flags;
@@ -4478,7 +4478,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_empty);
  * @buffer: The ring buffer
  * @cpu: The CPU buffer to test
  */
-bool ring_buffer_empty_cpu(struct ring_buffer *buffer, int cpu)
+bool ring_buffer_empty_cpu(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        unsigned long flags;
@@ -4504,14 +4504,15 @@ EXPORT_SYMBOL_GPL(ring_buffer_empty_cpu);
  * ring_buffer_swap_cpu - swap a CPU buffer between two ring buffers
  * @buffer_a: One buffer to swap with
  * @buffer_b: The other buffer to swap with
+ * @cpu: the CPU of the buffers to swap
  *
  * This function is useful for tracers that want to take a "snapshot"
  * of a CPU buffer and has another back up buffer lying around.
  * it is expected that the tracer handles the cpu buffer not being
  * used at the moment.
  */
-int ring_buffer_swap_cpu(struct ring_buffer *buffer_a,
-                        struct ring_buffer *buffer_b, int cpu)
+int ring_buffer_swap_cpu(struct trace_buffer *buffer_a,
+                        struct trace_buffer *buffer_b, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer_a;
        struct ring_buffer_per_cpu *cpu_buffer_b;
@@ -4590,7 +4591,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu);
  * Returns:
  *  The page allocated, or ERR_PTR
  */
-void *ring_buffer_alloc_read_page(struct ring_buffer *buffer, int cpu)
+void *ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu)
 {
        struct ring_buffer_per_cpu *cpu_buffer;
        struct buffer_data_page *bpage = NULL;
@@ -4637,7 +4638,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
  *
  * Free a page allocated from ring_buffer_alloc_read_page.
  */
-void ring_buffer_free_read_page(struct ring_buffer *buffer, int cpu, void *data)
+void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu, void *data)
 {
        struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
        struct buffer_data_page *bpage = data;
@@ -4697,7 +4698,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_free_read_page);
  *  >=0 if data has been transferred, returns the offset of consumed data.
  *  <0 if no data has been transferred.
  */
-int ring_buffer_read_page(struct ring_buffer *buffer,
+int ring_buffer_read_page(struct trace_buffer *buffer,
                          void **data_page, size_t len, int cpu, int full)
 {
        struct ring_buffer_per_cpu *cpu_buffer = buffer->buffers[cpu];
@@ -4868,12 +4869,12 @@ EXPORT_SYMBOL_GPL(ring_buffer_read_page);
  */
 int trace_rb_cpu_prepare(unsigned int cpu, struct hlist_node *node)
 {
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        long nr_pages_same;
        int cpu_i;
        unsigned long nr_pages;
 
-       buffer = container_of(node, struct ring_buffer, node);
+       buffer = container_of(node, struct trace_buffer, node);
        if (cpumask_test_cpu(cpu, buffer->cpumask))
                return 0;
 
@@ -4923,7 +4924,7 @@ int trace_rb_cpu_prepare(unsigned int cpu, struct hlist_node *node)
 static struct task_struct *rb_threads[NR_CPUS] __initdata;
 
 struct rb_test_data {
-       struct ring_buffer      *buffer;
+       struct trace_buffer *buffer;
        unsigned long           events;
        unsigned long           bytes_written;
        unsigned long           bytes_alloc;
@@ -5065,7 +5066,7 @@ static __init int rb_hammer_test(void *arg)
 static __init int test_ringbuffer(void)
 {
        struct task_struct *rb_hammer;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        int cpu;
        int ret = 0;
 
index 32149e4..8df0aa8 100644 (file)
@@ -29,7 +29,7 @@ static int reader_finish;
 static DECLARE_COMPLETION(read_start);
 static DECLARE_COMPLETION(read_done);
 
-static struct ring_buffer *buffer;
+static struct trace_buffer *buffer;
 static struct task_struct *producer;
 static struct task_struct *consumer;
 static unsigned long read;
diff --git a/kernel/trace/synth_event_gen_test.c b/kernel/trace/synth_event_gen_test.c
new file mode 100644 (file)
index 0000000..4aefe00
--- /dev/null
@@ -0,0 +1,523 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Test module for in-kernel sythetic event creation and generation.
+ *
+ * Copyright (C) 2019 Tom Zanussi <zanussi@kernel.org>
+ */
+
+#include <linux/module.h>
+#include <linux/trace_events.h>
+
+/*
+ * This module is a simple test of basic functionality for in-kernel
+ * synthetic event creation and generation, the first and second tests
+ * using synth_event_gen_cmd_start() and synth_event_add_field(), the
+ * third uses synth_event_create() to do it all at once with a static
+ * field array.
+ *
+ * Following that are a few examples using the created events to test
+ * various ways of tracing a synthetic event.
+ *
+ * To test, select CONFIG_SYNTH_EVENT_GEN_TEST and build the module.
+ * Then:
+ *
+ * # insmod kernel/trace/synth_event_gen_test.ko
+ * # cat /sys/kernel/debug/tracing/trace
+ *
+ * You should see several events in the trace buffer -
+ * "create_synth_test", "empty_synth_test", and several instances of
+ * "gen_synth_test".
+ *
+ * To remove the events, remove the module:
+ *
+ * # rmmod synth_event_gen_test
+ *
+ */
+
+static struct trace_event_file *create_synth_test;
+static struct trace_event_file *empty_synth_test;
+static struct trace_event_file *gen_synth_test;
+
+/*
+ * Test to make sure we can create a synthetic event, then add more
+ * fields.
+ */
+static int __init test_gen_synth_cmd(void)
+{
+       struct dynevent_cmd cmd;
+       u64 vals[7];
+       char *buf;
+       int ret;
+
+       /* Create a buffer to hold the generated command */
+       buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       /* Before generating the command, initialize the cmd object */
+       synth_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
+
+       /*
+        * Create the empty gen_synth_test synthetic event with the
+        * first 4 fields.
+        */
+       ret = synth_event_gen_cmd_start(&cmd, "gen_synth_test", THIS_MODULE,
+                                       "pid_t", "next_pid_field",
+                                       "char[16]", "next_comm_field",
+                                       "u64", "ts_ns",
+                                       "u64", "ts_ms");
+       if (ret)
+               goto free;
+
+       /* Use synth_event_add_field to add the rest of the fields */
+
+       ret = synth_event_add_field(&cmd, "unsigned int", "cpu");
+       if (ret)
+               goto free;
+
+       ret = synth_event_add_field(&cmd, "char[64]", "my_string_field");
+       if (ret)
+               goto free;
+
+       ret = synth_event_add_field(&cmd, "int", "my_int_field");
+       if (ret)
+               goto free;
+
+       ret = synth_event_gen_cmd_end(&cmd);
+       if (ret)
+               goto free;
+
+       /*
+        * Now get the gen_synth_test event file.  We need to prevent
+        * the instance and event from disappearing from underneath
+        * us, which trace_get_event_file() does (though in this case
+        * we're using the top-level instance which never goes away).
+        */
+       gen_synth_test = trace_get_event_file(NULL, "synthetic",
+                                             "gen_synth_test");
+       if (IS_ERR(gen_synth_test)) {
+               ret = PTR_ERR(gen_synth_test);
+               goto delete;
+       }
+
+       /* Enable the event or you won't see anything */
+       ret = trace_array_set_clr_event(gen_synth_test->tr,
+                                       "synthetic", "gen_synth_test", true);
+       if (ret) {
+               trace_put_event_file(gen_synth_test);
+               goto delete;
+       }
+
+       /* Create some bogus values just for testing */
+
+       vals[0] = 777;                  /* next_pid_field */
+       vals[1] = (u64)"hula hoops";    /* next_comm_field */
+       vals[2] = 1000000;              /* ts_ns */
+       vals[3] = 1000;                 /* ts_ms */
+       vals[4] = smp_processor_id();   /* cpu */
+       vals[5] = (u64)"thneed";        /* my_string_field */
+       vals[6] = 598;                  /* my_int_field */
+
+       /* Now generate a gen_synth_test event */
+       ret = synth_event_trace_array(gen_synth_test, vals, ARRAY_SIZE(vals));
+ out:
+       return ret;
+ delete:
+       /* We got an error after creating the event, delete it */
+       synth_event_delete("gen_synth_test");
+ free:
+       kfree(buf);
+
+       goto out;
+}
+
+/*
+ * Test to make sure we can create an initially empty synthetic event,
+ * then add all the fields.
+ */
+static int __init test_empty_synth_event(void)
+{
+       struct dynevent_cmd cmd;
+       u64 vals[7];
+       char *buf;
+       int ret;
+
+       /* Create a buffer to hold the generated command */
+       buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       /* Before generating the command, initialize the cmd object */
+       synth_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
+
+       /*
+        * Create the empty_synth_test synthetic event with no fields.
+        */
+       ret = synth_event_gen_cmd_start(&cmd, "empty_synth_test", THIS_MODULE);
+       if (ret)
+               goto free;
+
+       /* Use synth_event_add_field to add all of the fields */
+
+       ret = synth_event_add_field(&cmd, "pid_t", "next_pid_field");
+       if (ret)
+               goto free;
+
+       ret = synth_event_add_field(&cmd, "char[16]", "next_comm_field");
+       if (ret)
+               goto free;
+
+       ret = synth_event_add_field(&cmd, "u64", "ts_ns");
+       if (ret)
+               goto free;
+
+       ret = synth_event_add_field(&cmd, "u64", "ts_ms");
+       if (ret)
+               goto free;
+
+       ret = synth_event_add_field(&cmd, "unsigned int", "cpu");
+       if (ret)
+               goto free;
+
+       ret = synth_event_add_field(&cmd, "char[64]", "my_string_field");
+       if (ret)
+               goto free;
+
+       ret = synth_event_add_field(&cmd, "int", "my_int_field");
+       if (ret)
+               goto free;
+
+       /* All fields have been added, close and register the synth event */
+
+       ret = synth_event_gen_cmd_end(&cmd);
+       if (ret)
+               goto free;
+
+       /*
+        * Now get the empty_synth_test event file.  We need to
+        * prevent the instance and event from disappearing from
+        * underneath us, which trace_get_event_file() does (though in
+        * this case we're using the top-level instance which never
+        * goes away).
+        */
+       empty_synth_test = trace_get_event_file(NULL, "synthetic",
+                                               "empty_synth_test");
+       if (IS_ERR(empty_synth_test)) {
+               ret = PTR_ERR(empty_synth_test);
+               goto delete;
+       }
+
+       /* Enable the event or you won't see anything */
+       ret = trace_array_set_clr_event(empty_synth_test->tr,
+                                       "synthetic", "empty_synth_test", true);
+       if (ret) {
+               trace_put_event_file(empty_synth_test);
+               goto delete;
+       }
+
+       /* Create some bogus values just for testing */
+
+       vals[0] = 777;                  /* next_pid_field */
+       vals[1] = (u64)"tiddlywinks";   /* next_comm_field */
+       vals[2] = 1000000;              /* ts_ns */
+       vals[3] = 1000;                 /* ts_ms */
+       vals[4] = smp_processor_id();   /* cpu */
+       vals[5] = (u64)"thneed_2.0";    /* my_string_field */
+       vals[6] = 399;                  /* my_int_field */
+
+       /* Now trace an empty_synth_test event */
+       ret = synth_event_trace_array(empty_synth_test, vals, ARRAY_SIZE(vals));
+ out:
+       return ret;
+ delete:
+       /* We got an error after creating the event, delete it */
+       synth_event_delete("empty_synth_test");
+ free:
+       kfree(buf);
+
+       goto out;
+}
+
+static struct synth_field_desc create_synth_test_fields[] = {
+       { .type = "pid_t",              .name = "next_pid_field" },
+       { .type = "char[16]",           .name = "next_comm_field" },
+       { .type = "u64",                .name = "ts_ns" },
+       { .type = "u64",                .name = "ts_ms" },
+       { .type = "unsigned int",       .name = "cpu" },
+       { .type = "char[64]",           .name = "my_string_field" },
+       { .type = "int",                .name = "my_int_field" },
+};
+
+/*
+ * Test synthetic event creation all at once from array of field
+ * descriptors.
+ */
+static int __init test_create_synth_event(void)
+{
+       u64 vals[7];
+       int ret;
+
+       /* Create the create_synth_test event with the fields above */
+       ret = synth_event_create("create_synth_test",
+                                create_synth_test_fields,
+                                ARRAY_SIZE(create_synth_test_fields),
+                                THIS_MODULE);
+       if (ret)
+               goto out;
+
+       /*
+        * Now get the create_synth_test event file.  We need to
+        * prevent the instance and event from disappearing from
+        * underneath us, which trace_get_event_file() does (though in
+        * this case we're using the top-level instance which never
+        * goes away).
+        */
+       create_synth_test = trace_get_event_file(NULL, "synthetic",
+                                                "create_synth_test");
+       if (IS_ERR(create_synth_test)) {
+               ret = PTR_ERR(create_synth_test);
+               goto delete;
+       }
+
+       /* Enable the event or you won't see anything */
+       ret = trace_array_set_clr_event(create_synth_test->tr,
+                                       "synthetic", "create_synth_test", true);
+       if (ret) {
+               trace_put_event_file(create_synth_test);
+               goto delete;
+       }
+
+       /* Create some bogus values just for testing */
+
+       vals[0] = 777;                  /* next_pid_field */
+       vals[1] = (u64)"tiddlywinks";   /* next_comm_field */
+       vals[2] = 1000000;              /* ts_ns */
+       vals[3] = 1000;                 /* ts_ms */
+       vals[4] = smp_processor_id();   /* cpu */
+       vals[5] = (u64)"thneed";        /* my_string_field */
+       vals[6] = 398;                  /* my_int_field */
+
+       /* Now generate a create_synth_test event */
+       ret = synth_event_trace_array(create_synth_test, vals, ARRAY_SIZE(vals));
+ out:
+       return ret;
+ delete:
+       /* We got an error after creating the event, delete it */
+       ret = synth_event_delete("create_synth_test");
+
+       goto out;
+}
+
+/*
+ * Test tracing a synthetic event by reserving trace buffer space,
+ * then filling in fields one after another.
+ */
+static int __init test_add_next_synth_val(void)
+{
+       struct synth_event_trace_state trace_state;
+       int ret;
+
+       /* Start by reserving space in the trace buffer */
+       ret = synth_event_trace_start(gen_synth_test, &trace_state);
+       if (ret)
+               return ret;
+
+       /* Write some bogus values into the trace buffer, one after another */
+
+       /* next_pid_field */
+       ret = synth_event_add_next_val(777, &trace_state);
+       if (ret)
+               goto out;
+
+       /* next_comm_field */
+       ret = synth_event_add_next_val((u64)"slinky", &trace_state);
+       if (ret)
+               goto out;
+
+       /* ts_ns */
+       ret = synth_event_add_next_val(1000000, &trace_state);
+       if (ret)
+               goto out;
+
+       /* ts_ms */
+       ret = synth_event_add_next_val(1000, &trace_state);
+       if (ret)
+               goto out;
+
+       /* cpu */
+       ret = synth_event_add_next_val(smp_processor_id(), &trace_state);
+       if (ret)
+               goto out;
+
+       /* my_string_field */
+       ret = synth_event_add_next_val((u64)"thneed_2.01", &trace_state);
+       if (ret)
+               goto out;
+
+       /* my_int_field */
+       ret = synth_event_add_next_val(395, &trace_state);
+ out:
+       /* Finally, commit the event */
+       ret = synth_event_trace_end(&trace_state);
+
+       return ret;
+}
+
+/*
+ * Test tracing a synthetic event by reserving trace buffer space,
+ * then filling in fields using field names, which can be done in any
+ * order.
+ */
+static int __init test_add_synth_val(void)
+{
+       struct synth_event_trace_state trace_state;
+       int ret;
+
+       /* Start by reserving space in the trace buffer */
+       ret = synth_event_trace_start(gen_synth_test, &trace_state);
+       if (ret)
+               return ret;
+
+       /* Write some bogus values into the trace buffer, using field names */
+
+       ret = synth_event_add_val("ts_ns", 1000000, &trace_state);
+       if (ret)
+               goto out;
+
+       ret = synth_event_add_val("ts_ms", 1000, &trace_state);
+       if (ret)
+               goto out;
+
+       ret = synth_event_add_val("cpu", smp_processor_id(), &trace_state);
+       if (ret)
+               goto out;
+
+       ret = synth_event_add_val("next_pid_field", 777, &trace_state);
+       if (ret)
+               goto out;
+
+       ret = synth_event_add_val("next_comm_field", (u64)"silly putty",
+                                 &trace_state);
+       if (ret)
+               goto out;
+
+       ret = synth_event_add_val("my_string_field", (u64)"thneed_9",
+                                 &trace_state);
+       if (ret)
+               goto out;
+
+       ret = synth_event_add_val("my_int_field", 3999, &trace_state);
+ out:
+       /* Finally, commit the event */
+       ret = synth_event_trace_end(&trace_state);
+
+       return ret;
+}
+
+/*
+ * Test tracing a synthetic event all at once from array of values.
+ */
+static int __init test_trace_synth_event(void)
+{
+       int ret;
+
+       /* Trace some bogus values just for testing */
+       ret = synth_event_trace(create_synth_test, 7,   /* number of values */
+                               444,                    /* next_pid_field */
+                               (u64)"clackers",        /* next_comm_field */
+                               1000000,                /* ts_ns */
+                               1000,                   /* ts_ms */
+                               smp_processor_id(),     /* cpu */
+                               (u64)"Thneed",          /* my_string_field */
+                               999);                   /* my_int_field */
+       return ret;
+}
+
+static int __init synth_event_gen_test_init(void)
+{
+       int ret;
+
+       ret = test_gen_synth_cmd();
+       if (ret)
+               return ret;
+
+       ret = test_empty_synth_event();
+       if (ret) {
+               WARN_ON(trace_array_set_clr_event(gen_synth_test->tr,
+                                                 "synthetic",
+                                                 "gen_synth_test", false));
+               trace_put_event_file(gen_synth_test);
+               WARN_ON(synth_event_delete("gen_synth_test"));
+               goto out;
+       }
+
+       ret = test_create_synth_event();
+       if (ret) {
+               WARN_ON(trace_array_set_clr_event(gen_synth_test->tr,
+                                                 "synthetic",
+                                                 "gen_synth_test", false));
+               trace_put_event_file(gen_synth_test);
+               WARN_ON(synth_event_delete("gen_synth_test"));
+
+               WARN_ON(trace_array_set_clr_event(empty_synth_test->tr,
+                                                 "synthetic",
+                                                 "empty_synth_test", false));
+               trace_put_event_file(empty_synth_test);
+               WARN_ON(synth_event_delete("empty_synth_test"));
+               goto out;
+       }
+
+       ret = test_add_next_synth_val();
+       WARN_ON(ret);
+
+       ret = test_add_synth_val();
+       WARN_ON(ret);
+
+       ret = test_trace_synth_event();
+       WARN_ON(ret);
+ out:
+       return ret;
+}
+
+static void __exit synth_event_gen_test_exit(void)
+{
+       /* Disable the event or you can't remove it */
+       WARN_ON(trace_array_set_clr_event(gen_synth_test->tr,
+                                         "synthetic",
+                                         "gen_synth_test", false));
+
+       /* Now give the file and instance back */
+       trace_put_event_file(gen_synth_test);
+
+       /* Now unregister and free the synthetic event */
+       WARN_ON(synth_event_delete("gen_synth_test"));
+
+       /* Disable the event or you can't remove it */
+       WARN_ON(trace_array_set_clr_event(empty_synth_test->tr,
+                                         "synthetic",
+                                         "empty_synth_test", false));
+
+       /* Now give the file and instance back */
+       trace_put_event_file(empty_synth_test);
+
+       /* Now unregister and free the synthetic event */
+       WARN_ON(synth_event_delete("empty_synth_test"));
+
+       /* Disable the event or you can't remove it */
+       WARN_ON(trace_array_set_clr_event(create_synth_test->tr,
+                                         "synthetic",
+                                         "create_synth_test", false));
+
+       /* Now give the file and instance back */
+       trace_put_event_file(create_synth_test);
+
+       /* Now unregister and free the synthetic event */
+       WARN_ON(synth_event_delete("create_synth_test"));
+}
+
+module_init(synth_event_gen_test_init)
+module_exit(synth_event_gen_test_exit)
+
+MODULE_AUTHOR("Tom Zanussi");
+MODULE_DESCRIPTION("synthetic event generation test");
+MODULE_LICENSE("GPL v2");
index 5b6ee4a..c797a15 100644 (file)
@@ -162,8 +162,8 @@ union trace_eval_map_item {
 static union trace_eval_map_item *trace_eval_maps;
 #endif /* CONFIG_TRACE_EVAL_MAP_FILE */
 
-static int tracing_set_tracer(struct trace_array *tr, const char *buf);
-static void ftrace_trace_userstack(struct ring_buffer *buffer,
+int tracing_set_tracer(struct trace_array *tr, const char *buf);
+static void ftrace_trace_userstack(struct trace_buffer *buffer,
                                   unsigned long flags, int pc);
 
 #define MAX_TRACER_SIZE                100
@@ -338,7 +338,7 @@ int tracing_check_open_get_tr(struct trace_array *tr)
 }
 
 int call_filter_check_discard(struct trace_event_call *call, void *rec,
-                             struct ring_buffer *buffer,
+                             struct trace_buffer *buffer,
                              struct ring_buffer_event *event)
 {
        if (unlikely(call->flags & TRACE_EVENT_FL_FILTERED) &&
@@ -603,7 +603,7 @@ int trace_pid_write(struct trace_pid_list *filtered_pids,
        return read;
 }
 
-static u64 buffer_ftrace_now(struct trace_buffer *buf, int cpu)
+static u64 buffer_ftrace_now(struct array_buffer *buf, int cpu)
 {
        u64 ts;
 
@@ -619,7 +619,7 @@ static u64 buffer_ftrace_now(struct trace_buffer *buf, int cpu)
 
 u64 ftrace_now(int cpu)
 {
-       return buffer_ftrace_now(&global_trace.trace_buffer, cpu);
+       return buffer_ftrace_now(&global_trace.array_buffer, cpu);
 }
 
 /**
@@ -747,22 +747,22 @@ static inline void trace_access_lock_init(void)
 #endif
 
 #ifdef CONFIG_STACKTRACE
-static void __ftrace_trace_stack(struct ring_buffer *buffer,
+static void __ftrace_trace_stack(struct trace_buffer *buffer,
                                 unsigned long flags,
                                 int skip, int pc, struct pt_regs *regs);
 static inline void ftrace_trace_stack(struct trace_array *tr,
-                                     struct ring_buffer *buffer,
+                                     struct trace_buffer *buffer,
                                      unsigned long flags,
                                      int skip, int pc, struct pt_regs *regs);
 
 #else
-static inline void __ftrace_trace_stack(struct ring_buffer *buffer,
+static inline void __ftrace_trace_stack(struct trace_buffer *buffer,
                                        unsigned long flags,
                                        int skip, int pc, struct pt_regs *regs)
 {
 }
 static inline void ftrace_trace_stack(struct trace_array *tr,
-                                     struct ring_buffer *buffer,
+                                     struct trace_buffer *buffer,
                                      unsigned long flags,
                                      int skip, int pc, struct pt_regs *regs)
 {
@@ -780,7 +780,7 @@ trace_event_setup(struct ring_buffer_event *event,
 }
 
 static __always_inline struct ring_buffer_event *
-__trace_buffer_lock_reserve(struct ring_buffer *buffer,
+__trace_buffer_lock_reserve(struct trace_buffer *buffer,
                          int type,
                          unsigned long len,
                          unsigned long flags, int pc)
@@ -796,8 +796,8 @@ __trace_buffer_lock_reserve(struct ring_buffer *buffer,
 
 void tracer_tracing_on(struct trace_array *tr)
 {
-       if (tr->trace_buffer.buffer)
-               ring_buffer_record_on(tr->trace_buffer.buffer);
+       if (tr->array_buffer.buffer)
+               ring_buffer_record_on(tr->array_buffer.buffer);
        /*
         * This flag is looked at when buffers haven't been allocated
         * yet, or by some tracers (like irqsoff), that just want to
@@ -825,7 +825,7 @@ EXPORT_SYMBOL_GPL(tracing_on);
 
 
 static __always_inline void
-__buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *event)
+__buffer_unlock_commit(struct trace_buffer *buffer, struct ring_buffer_event *event)
 {
        __this_cpu_write(trace_taskinfo_save, true);
 
@@ -848,7 +848,7 @@ __buffer_unlock_commit(struct ring_buffer *buffer, struct ring_buffer_event *eve
 int __trace_puts(unsigned long ip, const char *str, int size)
 {
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        struct print_entry *entry;
        unsigned long irq_flags;
        int alloc;
@@ -865,11 +865,14 @@ int __trace_puts(unsigned long ip, const char *str, int size)
        alloc = sizeof(*entry) + size + 2; /* possible \n added */
 
        local_save_flags(irq_flags);
-       buffer = global_trace.trace_buffer.buffer;
+       buffer = global_trace.array_buffer.buffer;
+       ring_buffer_nest_start(buffer);
        event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, alloc, 
                                            irq_flags, pc);
-       if (!event)
-               return 0;
+       if (!event) {
+               size = 0;
+               goto out;
+       }
 
        entry = ring_buffer_event_data(event);
        entry->ip = ip;
@@ -885,7 +888,8 @@ int __trace_puts(unsigned long ip, const char *str, int size)
 
        __buffer_unlock_commit(buffer, event);
        ftrace_trace_stack(&global_trace, buffer, irq_flags, 4, pc, NULL);
-
+ out:
+       ring_buffer_nest_end(buffer);
        return size;
 }
 EXPORT_SYMBOL_GPL(__trace_puts);
@@ -898,10 +902,11 @@ EXPORT_SYMBOL_GPL(__trace_puts);
 int __trace_bputs(unsigned long ip, const char *str)
 {
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        struct bputs_entry *entry;
        unsigned long irq_flags;
        int size = sizeof(struct bputs_entry);
+       int ret = 0;
        int pc;
 
        if (!(global_trace.trace_flags & TRACE_ITER_PRINTK))
@@ -913,11 +918,13 @@ int __trace_bputs(unsigned long ip, const char *str)
                return 0;
 
        local_save_flags(irq_flags);
-       buffer = global_trace.trace_buffer.buffer;
+       buffer = global_trace.array_buffer.buffer;
+
+       ring_buffer_nest_start(buffer);
        event = __trace_buffer_lock_reserve(buffer, TRACE_BPUTS, size,
                                            irq_flags, pc);
        if (!event)
-               return 0;
+               goto out;
 
        entry = ring_buffer_event_data(event);
        entry->ip                       = ip;
@@ -926,7 +933,10 @@ int __trace_bputs(unsigned long ip, const char *str)
        __buffer_unlock_commit(buffer, event);
        ftrace_trace_stack(&global_trace, buffer, irq_flags, 4, pc, NULL);
 
-       return 1;
+       ret = 1;
+ out:
+       ring_buffer_nest_end(buffer);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(__trace_bputs);
 
@@ -1036,9 +1046,9 @@ void *tracing_cond_snapshot_data(struct trace_array *tr)
 }
 EXPORT_SYMBOL_GPL(tracing_cond_snapshot_data);
 
-static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
-                                       struct trace_buffer *size_buf, int cpu_id);
-static void set_buffer_entries(struct trace_buffer *buf, unsigned long val);
+static int resize_buffer_duplicate_size(struct array_buffer *trace_buf,
+                                       struct array_buffer *size_buf, int cpu_id);
+static void set_buffer_entries(struct array_buffer *buf, unsigned long val);
 
 int tracing_alloc_snapshot_instance(struct trace_array *tr)
 {
@@ -1048,7 +1058,7 @@ int tracing_alloc_snapshot_instance(struct trace_array *tr)
 
                /* allocate spare buffer */
                ret = resize_buffer_duplicate_size(&tr->max_buffer,
-                                  &tr->trace_buffer, RING_BUFFER_ALL_CPUS);
+                                  &tr->array_buffer, RING_BUFFER_ALL_CPUS);
                if (ret < 0)
                        return ret;
 
@@ -1251,8 +1261,8 @@ EXPORT_SYMBOL_GPL(tracing_snapshot_cond_disable);
 
 void tracer_tracing_off(struct trace_array *tr)
 {
-       if (tr->trace_buffer.buffer)
-               ring_buffer_record_off(tr->trace_buffer.buffer);
+       if (tr->array_buffer.buffer)
+               ring_buffer_record_off(tr->array_buffer.buffer);
        /*
         * This flag is looked at when buffers haven't been allocated
         * yet, or by some tracers (like irqsoff), that just want to
@@ -1294,8 +1304,8 @@ void disable_trace_on_warning(void)
  */
 bool tracer_tracing_is_on(struct trace_array *tr)
 {
-       if (tr->trace_buffer.buffer)
-               return ring_buffer_record_is_on(tr->trace_buffer.buffer);
+       if (tr->array_buffer.buffer)
+               return ring_buffer_record_is_on(tr->array_buffer.buffer);
        return !tr->buffer_disabled;
 }
 
@@ -1590,8 +1600,8 @@ void latency_fsnotify(struct trace_array *tr)
 static void
 __update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu)
 {
-       struct trace_buffer *trace_buf = &tr->trace_buffer;
-       struct trace_buffer *max_buf = &tr->max_buffer;
+       struct array_buffer *trace_buf = &tr->array_buffer;
+       struct array_buffer *max_buf = &tr->max_buffer;
        struct trace_array_cpu *data = per_cpu_ptr(trace_buf->data, cpu);
        struct trace_array_cpu *max_data = per_cpu_ptr(max_buf->data, cpu);
 
@@ -1649,8 +1659,8 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
 
        arch_spin_lock(&tr->max_lock);
 
-       /* Inherit the recordable setting from trace_buffer */
-       if (ring_buffer_record_is_set_on(tr->trace_buffer.buffer))
+       /* Inherit the recordable setting from array_buffer */
+       if (ring_buffer_record_is_set_on(tr->array_buffer.buffer))
                ring_buffer_record_on(tr->max_buffer.buffer);
        else
                ring_buffer_record_off(tr->max_buffer.buffer);
@@ -1659,7 +1669,7 @@ update_max_tr(struct trace_array *tr, struct task_struct *tsk, int cpu,
        if (tr->cond_snapshot && !tr->cond_snapshot->update(tr, cond_data))
                goto out_unlock;
 #endif
-       swap(tr->trace_buffer.buffer, tr->max_buffer.buffer);
+       swap(tr->array_buffer.buffer, tr->max_buffer.buffer);
 
        __update_max_tr(tr, tsk, cpu);
 
@@ -1692,7 +1702,7 @@ update_max_tr_single(struct trace_array *tr, struct task_struct *tsk, int cpu)
 
        arch_spin_lock(&tr->max_lock);
 
-       ret = ring_buffer_swap_cpu(tr->max_buffer.buffer, tr->trace_buffer.buffer, cpu);
+       ret = ring_buffer_swap_cpu(tr->max_buffer.buffer, tr->array_buffer.buffer, cpu);
 
        if (ret == -EBUSY) {
                /*
@@ -1718,7 +1728,7 @@ static int wait_on_pipe(struct trace_iterator *iter, int full)
        if (trace_buffer_iter(iter, iter->cpu_file))
                return 0;
 
-       return ring_buffer_wait(iter->trace_buffer->buffer, iter->cpu_file,
+       return ring_buffer_wait(iter->array_buffer->buffer, iter->cpu_file,
                                full);
 }
 
@@ -1769,7 +1779,7 @@ static int run_tracer_selftest(struct tracer *type)
         * internal tracing to verify that everything is in order.
         * If we fail, we do not register this tracer.
         */
-       tracing_reset_online_cpus(&tr->trace_buffer);
+       tracing_reset_online_cpus(&tr->array_buffer);
 
        tr->current_trace = type;
 
@@ -1795,7 +1805,7 @@ static int run_tracer_selftest(struct tracer *type)
                return -1;
        }
        /* Only reset on passing, to avoid touching corrupted buffers */
-       tracing_reset_online_cpus(&tr->trace_buffer);
+       tracing_reset_online_cpus(&tr->array_buffer);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
        if (type->use_max_tr) {
@@ -1962,9 +1972,9 @@ int __init register_tracer(struct tracer *type)
        return ret;
 }
 
-static void tracing_reset_cpu(struct trace_buffer *buf, int cpu)
+static void tracing_reset_cpu(struct array_buffer *buf, int cpu)
 {
-       struct ring_buffer *buffer = buf->buffer;
+       struct trace_buffer *buffer = buf->buffer;
 
        if (!buffer)
                return;
@@ -1978,9 +1988,9 @@ static void tracing_reset_cpu(struct trace_buffer *buf, int cpu)
        ring_buffer_record_enable(buffer);
 }
 
-void tracing_reset_online_cpus(struct trace_buffer *buf)
+void tracing_reset_online_cpus(struct array_buffer *buf)
 {
-       struct ring_buffer *buffer = buf->buffer;
+       struct trace_buffer *buffer = buf->buffer;
        int cpu;
 
        if (!buffer)
@@ -2008,7 +2018,7 @@ void tracing_reset_all_online_cpus(void)
                if (!tr->clear_trace)
                        continue;
                tr->clear_trace = false;
-               tracing_reset_online_cpus(&tr->trace_buffer);
+               tracing_reset_online_cpus(&tr->array_buffer);
 #ifdef CONFIG_TRACER_MAX_TRACE
                tracing_reset_online_cpus(&tr->max_buffer);
 #endif
@@ -2098,7 +2108,7 @@ int is_tracing_stopped(void)
  */
 void tracing_start(void)
 {
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        unsigned long flags;
 
        if (tracing_disabled)
@@ -2117,7 +2127,7 @@ void tracing_start(void)
        /* Prevent the buffers from switching */
        arch_spin_lock(&global_trace.max_lock);
 
-       buffer = global_trace.trace_buffer.buffer;
+       buffer = global_trace.array_buffer.buffer;
        if (buffer)
                ring_buffer_record_enable(buffer);
 
@@ -2135,7 +2145,7 @@ void tracing_start(void)
 
 static void tracing_start_tr(struct trace_array *tr)
 {
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        unsigned long flags;
 
        if (tracing_disabled)
@@ -2156,7 +2166,7 @@ static void tracing_start_tr(struct trace_array *tr)
                goto out;
        }
 
-       buffer = tr->trace_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        if (buffer)
                ring_buffer_record_enable(buffer);
 
@@ -2172,7 +2182,7 @@ static void tracing_start_tr(struct trace_array *tr)
  */
 void tracing_stop(void)
 {
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        unsigned long flags;
 
        raw_spin_lock_irqsave(&global_trace.start_lock, flags);
@@ -2182,7 +2192,7 @@ void tracing_stop(void)
        /* Prevent the buffers from switching */
        arch_spin_lock(&global_trace.max_lock);
 
-       buffer = global_trace.trace_buffer.buffer;
+       buffer = global_trace.array_buffer.buffer;
        if (buffer)
                ring_buffer_record_disable(buffer);
 
@@ -2200,7 +2210,7 @@ void tracing_stop(void)
 
 static void tracing_stop_tr(struct trace_array *tr)
 {
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        unsigned long flags;
 
        /* If global, we need to also stop the max tracer */
@@ -2211,7 +2221,7 @@ static void tracing_stop_tr(struct trace_array *tr)
        if (tr->stop_count++)
                goto out;
 
-       buffer = tr->trace_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        if (buffer)
                ring_buffer_record_disable(buffer);
 
@@ -2442,7 +2452,7 @@ tracing_generic_entry_update(struct trace_entry *entry, unsigned short type,
 EXPORT_SYMBOL_GPL(tracing_generic_entry_update);
 
 struct ring_buffer_event *
-trace_buffer_lock_reserve(struct ring_buffer *buffer,
+trace_buffer_lock_reserve(struct trace_buffer *buffer,
                          int type,
                          unsigned long len,
                          unsigned long flags, int pc)
@@ -2561,10 +2571,10 @@ void trace_buffered_event_disable(void)
        preempt_enable();
 }
 
-static struct ring_buffer *temp_buffer;
+static struct trace_buffer *temp_buffer;
 
 struct ring_buffer_event *
-trace_event_buffer_lock_reserve(struct ring_buffer **current_rb,
+trace_event_buffer_lock_reserve(struct trace_buffer **current_rb,
                          struct trace_event_file *trace_file,
                          int type, unsigned long len,
                          unsigned long flags, int pc)
@@ -2572,7 +2582,7 @@ trace_event_buffer_lock_reserve(struct ring_buffer **current_rb,
        struct ring_buffer_event *entry;
        int val;
 
-       *current_rb = trace_file->tr->trace_buffer.buffer;
+       *current_rb = trace_file->tr->array_buffer.buffer;
 
        if (!ring_buffer_time_stamp_abs(*current_rb) && (trace_file->flags &
             (EVENT_FILE_FL_SOFT_DISABLED | EVENT_FILE_FL_FILTERED)) &&
@@ -2610,6 +2620,7 @@ static DEFINE_MUTEX(tracepoint_printk_mutex);
 static void output_printk(struct trace_event_buffer *fbuffer)
 {
        struct trace_event_call *event_call;
+       struct trace_event_file *file;
        struct trace_event *event;
        unsigned long flags;
        struct trace_iterator *iter = tracepoint_print_iter;
@@ -2623,6 +2634,12 @@ static void output_printk(struct trace_event_buffer *fbuffer)
            !event_call->event.funcs->trace)
                return;
 
+       file = fbuffer->trace_file;
+       if (test_bit(EVENT_FILE_FL_SOFT_DISABLED_BIT, &file->flags) ||
+           (unlikely(file->flags & EVENT_FILE_FL_FILTERED) &&
+            !filter_match_preds(file->filter, fbuffer->entry)))
+               return;
+
        event = &fbuffer->trace_file->event_call->event;
 
        spin_lock_irqsave(&tracepoint_iter_lock, flags);
@@ -2673,9 +2690,9 @@ void trace_event_buffer_commit(struct trace_event_buffer *fbuffer)
        if (static_key_false(&tracepoint_printk_key.key))
                output_printk(fbuffer);
 
-       event_trigger_unlock_commit(fbuffer->trace_file, fbuffer->buffer,
+       event_trigger_unlock_commit_regs(fbuffer->trace_file, fbuffer->buffer,
                                    fbuffer->event, fbuffer->entry,
-                                   fbuffer->flags, fbuffer->pc);
+                                   fbuffer->flags, fbuffer->pc, fbuffer->regs);
 }
 EXPORT_SYMBOL_GPL(trace_event_buffer_commit);
 
@@ -2689,7 +2706,7 @@ EXPORT_SYMBOL_GPL(trace_event_buffer_commit);
 # define STACK_SKIP 3
 
 void trace_buffer_unlock_commit_regs(struct trace_array *tr,
-                                    struct ring_buffer *buffer,
+                                    struct trace_buffer *buffer,
                                     struct ring_buffer_event *event,
                                     unsigned long flags, int pc,
                                     struct pt_regs *regs)
@@ -2710,7 +2727,7 @@ void trace_buffer_unlock_commit_regs(struct trace_array *tr,
  * Similar to trace_buffer_unlock_commit_regs() but do not dump stack.
  */
 void
-trace_buffer_unlock_commit_nostack(struct ring_buffer *buffer,
+trace_buffer_unlock_commit_nostack(struct trace_buffer *buffer,
                                   struct ring_buffer_event *event)
 {
        __buffer_unlock_commit(buffer, event);
@@ -2845,7 +2862,7 @@ trace_function(struct trace_array *tr,
               int pc)
 {
        struct trace_event_call *call = &event_function;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
        struct ring_buffer_event *event;
        struct ftrace_entry *entry;
 
@@ -2883,7 +2900,7 @@ struct ftrace_stacks {
 static DEFINE_PER_CPU(struct ftrace_stacks, ftrace_stacks);
 static DEFINE_PER_CPU(int, ftrace_stack_reserve);
 
-static void __ftrace_trace_stack(struct ring_buffer *buffer,
+static void __ftrace_trace_stack(struct trace_buffer *buffer,
                                 unsigned long flags,
                                 int skip, int pc, struct pt_regs *regs)
 {
@@ -2958,7 +2975,7 @@ static void __ftrace_trace_stack(struct ring_buffer *buffer,
 }
 
 static inline void ftrace_trace_stack(struct trace_array *tr,
-                                     struct ring_buffer *buffer,
+                                     struct trace_buffer *buffer,
                                      unsigned long flags,
                                      int skip, int pc, struct pt_regs *regs)
 {
@@ -2971,7 +2988,7 @@ static inline void ftrace_trace_stack(struct trace_array *tr,
 void __trace_stack(struct trace_array *tr, unsigned long flags, int skip,
                   int pc)
 {
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
 
        if (rcu_is_watching()) {
                __ftrace_trace_stack(buffer, flags, skip, pc, NULL);
@@ -3009,7 +3026,7 @@ void trace_dump_stack(int skip)
        /* Skip 1 to skip this function. */
        skip++;
 #endif
-       __ftrace_trace_stack(global_trace.trace_buffer.buffer,
+       __ftrace_trace_stack(global_trace.array_buffer.buffer,
                             flags, skip, preempt_count(), NULL);
 }
 EXPORT_SYMBOL_GPL(trace_dump_stack);
@@ -3018,7 +3035,7 @@ EXPORT_SYMBOL_GPL(trace_dump_stack);
 static DEFINE_PER_CPU(int, user_stack_count);
 
 static void
-ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
+ftrace_trace_userstack(struct trace_buffer *buffer, unsigned long flags, int pc)
 {
        struct trace_event_call *call = &event_user_stack;
        struct ring_buffer_event *event;
@@ -3063,7 +3080,7 @@ ftrace_trace_userstack(struct ring_buffer *buffer, unsigned long flags, int pc)
        preempt_enable();
 }
 #else /* CONFIG_USER_STACKTRACE_SUPPORT */
-static void ftrace_trace_userstack(struct ring_buffer *buffer,
+static void ftrace_trace_userstack(struct trace_buffer *buffer,
                                   unsigned long flags, int pc)
 {
 }
@@ -3109,7 +3126,7 @@ static int alloc_percpu_trace_buffer(void)
        struct trace_buffer_struct *buffers;
 
        buffers = alloc_percpu(struct trace_buffer_struct);
-       if (WARN(!buffers, "Could not allocate percpu trace_printk buffer"))
+       if (MEM_FAIL(!buffers, "Could not allocate percpu trace_printk buffer"))
                return -ENOMEM;
 
        trace_percpu_buffer = buffers;
@@ -3154,7 +3171,7 @@ void trace_printk_init_buffers(void)
         * directly here. If the global_trace.buffer is already
         * allocated here, then this was called by module code.
         */
-       if (global_trace.trace_buffer.buffer)
+       if (global_trace.array_buffer.buffer)
                tracing_start_cmdline_record();
 }
 EXPORT_SYMBOL_GPL(trace_printk_init_buffers);
@@ -3188,7 +3205,7 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
 {
        struct trace_event_call *call = &event_bprint;
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        struct trace_array *tr = &global_trace;
        struct bprint_entry *entry;
        unsigned long flags;
@@ -3213,11 +3230,12 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
        len = vbin_printf((u32 *)tbuffer, TRACE_BUF_SIZE/sizeof(int), fmt, args);
 
        if (len > TRACE_BUF_SIZE/sizeof(int) || len < 0)
-               goto out;
+               goto out_put;
 
        local_save_flags(flags);
        size = sizeof(*entry) + sizeof(u32) * len;
-       buffer = tr->trace_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
+       ring_buffer_nest_start(buffer);
        event = __trace_buffer_lock_reserve(buffer, TRACE_BPRINT, size,
                                            flags, pc);
        if (!event)
@@ -3233,6 +3251,8 @@ int trace_vbprintk(unsigned long ip, const char *fmt, va_list args)
        }
 
 out:
+       ring_buffer_nest_end(buffer);
+out_put:
        put_trace_buf();
 
 out_nobuffer:
@@ -3245,7 +3265,7 @@ EXPORT_SYMBOL_GPL(trace_vbprintk);
 
 __printf(3, 0)
 static int
-__trace_array_vprintk(struct ring_buffer *buffer,
+__trace_array_vprintk(struct trace_buffer *buffer,
                      unsigned long ip, const char *fmt, va_list args)
 {
        struct trace_event_call *call = &event_print;
@@ -3275,6 +3295,7 @@ __trace_array_vprintk(struct ring_buffer *buffer,
 
        local_save_flags(flags);
        size = sizeof(*entry) + len + 1;
+       ring_buffer_nest_start(buffer);
        event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size,
                                            flags, pc);
        if (!event)
@@ -3289,6 +3310,7 @@ __trace_array_vprintk(struct ring_buffer *buffer,
        }
 
 out:
+       ring_buffer_nest_end(buffer);
        put_trace_buf();
 
 out_nobuffer:
@@ -3302,7 +3324,7 @@ __printf(3, 0)
 int trace_array_vprintk(struct trace_array *tr,
                        unsigned long ip, const char *fmt, va_list args)
 {
-       return __trace_array_vprintk(tr->trace_buffer.buffer, ip, fmt, args);
+       return __trace_array_vprintk(tr->array_buffer.buffer, ip, fmt, args);
 }
 
 __printf(3, 0)
@@ -3326,7 +3348,7 @@ int trace_array_printk(struct trace_array *tr,
 EXPORT_SYMBOL_GPL(trace_array_printk);
 
 __printf(3, 4)
-int trace_array_printk_buf(struct ring_buffer *buffer,
+int trace_array_printk_buf(struct trace_buffer *buffer,
                           unsigned long ip, const char *fmt, ...)
 {
        int ret;
@@ -3367,7 +3389,7 @@ peek_next_entry(struct trace_iterator *iter, int cpu, u64 *ts,
        if (buf_iter)
                event = ring_buffer_iter_peek(buf_iter, ts);
        else
-               event = ring_buffer_peek(iter->trace_buffer->buffer, cpu, ts,
+               event = ring_buffer_peek(iter->array_buffer->buffer, cpu, ts,
                                         lost_events);
 
        if (event) {
@@ -3382,7 +3404,7 @@ static struct trace_entry *
 __find_next_entry(struct trace_iterator *iter, int *ent_cpu,
                  unsigned long *missing_events, u64 *ent_ts)
 {
-       struct ring_buffer *buffer = iter->trace_buffer->buffer;
+       struct trace_buffer *buffer = iter->array_buffer->buffer;
        struct trace_entry *ent, *next = NULL;
        unsigned long lost_events = 0, next_lost = 0;
        int cpu_file = iter->cpu_file;
@@ -3459,7 +3481,7 @@ void *trace_find_next_entry_inc(struct trace_iterator *iter)
 
 static void trace_consume(struct trace_iterator *iter)
 {
-       ring_buffer_consume(iter->trace_buffer->buffer, iter->cpu, &iter->ts,
+       ring_buffer_consume(iter->array_buffer->buffer, iter->cpu, &iter->ts,
                            &iter->lost_events);
 }
 
@@ -3497,7 +3519,7 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu)
        unsigned long entries = 0;
        u64 ts;
 
-       per_cpu_ptr(iter->trace_buffer->data, cpu)->skipped_entries = 0;
+       per_cpu_ptr(iter->array_buffer->data, cpu)->skipped_entries = 0;
 
        buf_iter = trace_buffer_iter(iter, cpu);
        if (!buf_iter)
@@ -3511,13 +3533,13 @@ void tracing_iter_reset(struct trace_iterator *iter, int cpu)
         * by the timestamp being before the start of the buffer.
         */
        while ((event = ring_buffer_iter_peek(buf_iter, &ts))) {
-               if (ts >= iter->trace_buffer->time_start)
+               if (ts >= iter->array_buffer->time_start)
                        break;
                entries++;
                ring_buffer_read(buf_iter, NULL);
        }
 
-       per_cpu_ptr(iter->trace_buffer->data, cpu)->skipped_entries = entries;
+       per_cpu_ptr(iter->array_buffer->data, cpu)->skipped_entries = entries;
 }
 
 /*
@@ -3602,7 +3624,7 @@ static void s_stop(struct seq_file *m, void *p)
 }
 
 static void
-get_total_entries_cpu(struct trace_buffer *buf, unsigned long *total,
+get_total_entries_cpu(struct array_buffer *buf, unsigned long *total,
                      unsigned long *entries, int cpu)
 {
        unsigned long count;
@@ -3624,7 +3646,7 @@ get_total_entries_cpu(struct trace_buffer *buf, unsigned long *total,
 }
 
 static void
-get_total_entries(struct trace_buffer *buf,
+get_total_entries(struct array_buffer *buf,
                  unsigned long *total, unsigned long *entries)
 {
        unsigned long t, e;
@@ -3647,7 +3669,7 @@ unsigned long trace_total_entries_cpu(struct trace_array *tr, int cpu)
        if (!tr)
                tr = &global_trace;
 
-       get_total_entries_cpu(&tr->trace_buffer, &total, &entries, cpu);
+       get_total_entries_cpu(&tr->array_buffer, &total, &entries, cpu);
 
        return entries;
 }
@@ -3659,7 +3681,7 @@ unsigned long trace_total_entries(struct trace_array *tr)
        if (!tr)
                tr = &global_trace;
 
-       get_total_entries(&tr->trace_buffer, &total, &entries);
+       get_total_entries(&tr->array_buffer, &total, &entries);
 
        return entries;
 }
@@ -3676,7 +3698,7 @@ static void print_lat_help_header(struct seq_file *m)
                    "#     \\   /      |||||  \\    |   /         \n");
 }
 
-static void print_event_info(struct trace_buffer *buf, struct seq_file *m)
+static void print_event_info(struct array_buffer *buf, struct seq_file *m)
 {
        unsigned long total;
        unsigned long entries;
@@ -3687,7 +3709,7 @@ static void print_event_info(struct trace_buffer *buf, struct seq_file *m)
        seq_puts(m, "#\n");
 }
 
-static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m,
+static void print_func_help_header(struct array_buffer *buf, struct seq_file *m,
                                   unsigned int flags)
 {
        bool tgid = flags & TRACE_ITER_RECORD_TGID;
@@ -3698,7 +3720,7 @@ static void print_func_help_header(struct trace_buffer *buf, struct seq_file *m,
        seq_printf(m, "#              | |     %s    |       |         |\n",      tgid ? "  |      " : "");
 }
 
-static void print_func_help_header_irq(struct trace_buffer *buf, struct seq_file *m,
+static void print_func_help_header_irq(struct array_buffer *buf, struct seq_file *m,
                                       unsigned int flags)
 {
        bool tgid = flags & TRACE_ITER_RECORD_TGID;
@@ -3720,7 +3742,7 @@ void
 print_trace_header(struct seq_file *m, struct trace_iterator *iter)
 {
        unsigned long sym_flags = (global_trace.trace_flags & TRACE_ITER_SYM_MASK);
-       struct trace_buffer *buf = iter->trace_buffer;
+       struct array_buffer *buf = iter->array_buffer;
        struct trace_array_cpu *data = per_cpu_ptr(buf->data, buf->cpu);
        struct tracer *type = iter->trace;
        unsigned long entries;
@@ -3795,7 +3817,7 @@ static void test_cpu_buff_start(struct trace_iterator *iter)
            cpumask_test_cpu(iter->cpu, iter->started))
                return;
 
-       if (per_cpu_ptr(iter->trace_buffer->data, iter->cpu)->skipped_entries)
+       if (per_cpu_ptr(iter->array_buffer->data, iter->cpu)->skipped_entries)
                return;
 
        if (cpumask_available(iter->started))
@@ -3929,7 +3951,7 @@ int trace_empty(struct trace_iterator *iter)
                        if (!ring_buffer_iter_empty(buf_iter))
                                return 0;
                } else {
-                       if (!ring_buffer_empty_cpu(iter->trace_buffer->buffer, cpu))
+                       if (!ring_buffer_empty_cpu(iter->array_buffer->buffer, cpu))
                                return 0;
                }
                return 1;
@@ -3941,7 +3963,7 @@ int trace_empty(struct trace_iterator *iter)
                        if (!ring_buffer_iter_empty(buf_iter))
                                return 0;
                } else {
-                       if (!ring_buffer_empty_cpu(iter->trace_buffer->buffer, cpu))
+                       if (!ring_buffer_empty_cpu(iter->array_buffer->buffer, cpu))
                                return 0;
                }
        }
@@ -4031,10 +4053,10 @@ void trace_default_header(struct seq_file *m)
        } else {
                if (!(trace_flags & TRACE_ITER_VERBOSE)) {
                        if (trace_flags & TRACE_ITER_IRQ_INFO)
-                               print_func_help_header_irq(iter->trace_buffer,
+                               print_func_help_header_irq(iter->array_buffer,
                                                           m, trace_flags);
                        else
-                               print_func_help_header(iter->trace_buffer, m,
+                               print_func_help_header(iter->array_buffer, m,
                                                       trace_flags);
                }
        }
@@ -4192,21 +4214,21 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
 #ifdef CONFIG_TRACER_MAX_TRACE
        /* Currently only the top directory has a snapshot */
        if (tr->current_trace->print_max || snapshot)
-               iter->trace_buffer = &tr->max_buffer;
+               iter->array_buffer = &tr->max_buffer;
        else
 #endif
-               iter->trace_buffer = &tr->trace_buffer;
+               iter->array_buffer = &tr->array_buffer;
        iter->snapshot = snapshot;
        iter->pos = -1;
        iter->cpu_file = tracing_get_cpu(inode);
        mutex_init(&iter->mutex);
 
        /* Notify the tracer early; before we stop tracing. */
-       if (iter->trace && iter->trace->open)
+       if (iter->trace->open)
                iter->trace->open(iter);
 
        /* Annotate start of buffers if we had overruns */
-       if (ring_buffer_overruns(iter->trace_buffer->buffer))
+       if (ring_buffer_overruns(iter->array_buffer->buffer))
                iter->iter_flags |= TRACE_FILE_ANNOTATE;
 
        /* Output in nanoseconds only if we are using a clock in nanoseconds. */
@@ -4220,7 +4242,7 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
        if (iter->cpu_file == RING_BUFFER_ALL_CPUS) {
                for_each_tracing_cpu(cpu) {
                        iter->buffer_iter[cpu] =
-                               ring_buffer_read_prepare(iter->trace_buffer->buffer,
+                               ring_buffer_read_prepare(iter->array_buffer->buffer,
                                                         cpu, GFP_KERNEL);
                }
                ring_buffer_read_prepare_sync();
@@ -4231,7 +4253,7 @@ __tracing_open(struct inode *inode, struct file *file, bool snapshot)
        } else {
                cpu = iter->cpu_file;
                iter->buffer_iter[cpu] =
-                       ring_buffer_read_prepare(iter->trace_buffer->buffer,
+                       ring_buffer_read_prepare(iter->array_buffer->buffer,
                                                 cpu, GFP_KERNEL);
                ring_buffer_read_prepare_sync();
                ring_buffer_read_start(iter->buffer_iter[cpu]);
@@ -4357,7 +4379,7 @@ static int tracing_open(struct inode *inode, struct file *file)
        /* If this file was open for write, then erase contents */
        if ((file->f_mode & FMODE_WRITE) && (file->f_flags & O_TRUNC)) {
                int cpu = tracing_get_cpu(inode);
-               struct trace_buffer *trace_buf = &tr->trace_buffer;
+               struct array_buffer *trace_buf = &tr->array_buffer;
 
 #ifdef CONFIG_TRACER_MAX_TRACE
                if (tr->current_trace->print_max)
@@ -4554,20 +4576,13 @@ out_err:
        return count;
 }
 
-static ssize_t
-tracing_cpumask_write(struct file *filp, const char __user *ubuf,
-                     size_t count, loff_t *ppos)
+int tracing_set_cpumask(struct trace_array *tr,
+                       cpumask_var_t tracing_cpumask_new)
 {
-       struct trace_array *tr = file_inode(filp)->i_private;
-       cpumask_var_t tracing_cpumask_new;
-       int err, cpu;
-
-       if (!alloc_cpumask_var(&tracing_cpumask_new, GFP_KERNEL))
-               return -ENOMEM;
+       int cpu;
 
-       err = cpumask_parse_user(ubuf, count, tracing_cpumask_new);
-       if (err)
-               goto err_unlock;
+       if (!tr)
+               return -EINVAL;
 
        local_irq_disable();
        arch_spin_lock(&tr->max_lock);
@@ -4578,24 +4593,47 @@ tracing_cpumask_write(struct file *filp, const char __user *ubuf,
                 */
                if (cpumask_test_cpu(cpu, tr->tracing_cpumask) &&
                                !cpumask_test_cpu(cpu, tracing_cpumask_new)) {
-                       atomic_inc(&per_cpu_ptr(tr->trace_buffer.data, cpu)->disabled);
-                       ring_buffer_record_disable_cpu(tr->trace_buffer.buffer, cpu);
+                       atomic_inc(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled);
+                       ring_buffer_record_disable_cpu(tr->array_buffer.buffer, cpu);
                }
                if (!cpumask_test_cpu(cpu, tr->tracing_cpumask) &&
                                cpumask_test_cpu(cpu, tracing_cpumask_new)) {
-                       atomic_dec(&per_cpu_ptr(tr->trace_buffer.data, cpu)->disabled);
-                       ring_buffer_record_enable_cpu(tr->trace_buffer.buffer, cpu);
+                       atomic_dec(&per_cpu_ptr(tr->array_buffer.data, cpu)->disabled);
+                       ring_buffer_record_enable_cpu(tr->array_buffer.buffer, cpu);
                }
        }
        arch_spin_unlock(&tr->max_lock);
        local_irq_enable();
 
        cpumask_copy(tr->tracing_cpumask, tracing_cpumask_new);
+
+       return 0;
+}
+
+static ssize_t
+tracing_cpumask_write(struct file *filp, const char __user *ubuf,
+                     size_t count, loff_t *ppos)
+{
+       struct trace_array *tr = file_inode(filp)->i_private;
+       cpumask_var_t tracing_cpumask_new;
+       int err;
+
+       if (!alloc_cpumask_var(&tracing_cpumask_new, GFP_KERNEL))
+               return -ENOMEM;
+
+       err = cpumask_parse_user(ubuf, count, tracing_cpumask_new);
+       if (err)
+               goto err_free;
+
+       err = tracing_set_cpumask(tr, tracing_cpumask_new);
+       if (err)
+               goto err_free;
+
        free_cpumask_var(tracing_cpumask_new);
 
        return count;
 
-err_unlock:
+err_free:
        free_cpumask_var(tracing_cpumask_new);
 
        return err;
@@ -4726,7 +4764,7 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
                ftrace_pid_follow_fork(tr, enabled);
 
        if (mask == TRACE_ITER_OVERWRITE) {
-               ring_buffer_change_overwrite(tr->trace_buffer.buffer, enabled);
+               ring_buffer_change_overwrite(tr->array_buffer.buffer, enabled);
 #ifdef CONFIG_TRACER_MAX_TRACE
                ring_buffer_change_overwrite(tr->max_buffer.buffer, enabled);
 #endif
@@ -4740,7 +4778,7 @@ int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled)
        return 0;
 }
 
-static int trace_set_options(struct trace_array *tr, char *option)
+int trace_set_options(struct trace_array *tr, char *option)
 {
        char *cmp;
        int neg = 0;
@@ -5361,14 +5399,12 @@ static void *eval_map_next(struct seq_file *m, void *v, loff_t *pos)
         * Paranoid! If ptr points to end, we don't want to increment past it.
         * This really should never happen.
         */
+       (*pos)++;
        ptr = update_eval_map(ptr);
        if (WARN_ON_ONCE(!ptr))
                return NULL;
 
        ptr++;
-
-       (*pos)++;
-
        ptr = update_eval_map(ptr);
 
        return ptr;
@@ -5534,11 +5570,11 @@ tracing_set_trace_read(struct file *filp, char __user *ubuf,
 
 int tracer_init(struct tracer *t, struct trace_array *tr)
 {
-       tracing_reset_online_cpus(&tr->trace_buffer);
+       tracing_reset_online_cpus(&tr->array_buffer);
        return t->init(tr);
 }
 
-static void set_buffer_entries(struct trace_buffer *buf, unsigned long val)
+static void set_buffer_entries(struct array_buffer *buf, unsigned long val)
 {
        int cpu;
 
@@ -5548,8 +5584,8 @@ static void set_buffer_entries(struct trace_buffer *buf, unsigned long val)
 
 #ifdef CONFIG_TRACER_MAX_TRACE
 /* resize @tr's buffer to the size of @size_tr's entries */
-static int resize_buffer_duplicate_size(struct trace_buffer *trace_buf,
-                                       struct trace_buffer *size_buf, int cpu_id)
+static int resize_buffer_duplicate_size(struct array_buffer *trace_buf,
+                                       struct array_buffer *size_buf, int cpu_id)
 {
        int cpu, ret = 0;
 
@@ -5587,10 +5623,10 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr,
        ring_buffer_expanded = true;
 
        /* May be called before buffers are initialized */
-       if (!tr->trace_buffer.buffer)
+       if (!tr->array_buffer.buffer)
                return 0;
 
-       ret = ring_buffer_resize(tr->trace_buffer.buffer, size, cpu);
+       ret = ring_buffer_resize(tr->array_buffer.buffer, size, cpu);
        if (ret < 0)
                return ret;
 
@@ -5601,8 +5637,8 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr,
 
        ret = ring_buffer_resize(tr->max_buffer.buffer, size, cpu);
        if (ret < 0) {
-               int r = resize_buffer_duplicate_size(&tr->trace_buffer,
-                                                    &tr->trace_buffer, cpu);
+               int r = resize_buffer_duplicate_size(&tr->array_buffer,
+                                                    &tr->array_buffer, cpu);
                if (r < 0) {
                        /*
                         * AARGH! We are left with different
@@ -5633,15 +5669,15 @@ static int __tracing_resize_ring_buffer(struct trace_array *tr,
 #endif /* CONFIG_TRACER_MAX_TRACE */
 
        if (cpu == RING_BUFFER_ALL_CPUS)
-               set_buffer_entries(&tr->trace_buffer, size);
+               set_buffer_entries(&tr->array_buffer, size);
        else
-               per_cpu_ptr(tr->trace_buffer.data, cpu)->entries = size;
+               per_cpu_ptr(tr->array_buffer.data, cpu)->entries = size;
 
        return ret;
 }
 
-static ssize_t tracing_resize_ring_buffer(struct trace_array *tr,
-                                         unsigned long size, int cpu_id)
+ssize_t tracing_resize_ring_buffer(struct trace_array *tr,
+                                 unsigned long size, int cpu_id)
 {
        int ret = size;
 
@@ -5720,7 +5756,7 @@ static void add_tracer_options(struct trace_array *tr, struct tracer *t)
        create_trace_option_files(tr, t);
 }
 
-static int tracing_set_tracer(struct trace_array *tr, const char *buf)
+int tracing_set_tracer(struct trace_array *tr, const char *buf)
 {
        struct tracer *t;
 #ifdef CONFIG_TRACER_MAX_TRACE
@@ -5979,7 +6015,7 @@ static int tracing_open_pipe(struct inode *inode, struct file *filp)
                iter->iter_flags |= TRACE_FILE_TIME_IN_NS;
 
        iter->tr = tr;
-       iter->trace_buffer = &tr->trace_buffer;
+       iter->array_buffer = &tr->array_buffer;
        iter->cpu_file = tracing_get_cpu(inode);
        mutex_init(&iter->mutex);
        filp->private_data = iter;
@@ -6039,7 +6075,7 @@ trace_poll(struct trace_iterator *iter, struct file *filp, poll_table *poll_tabl
                 */
                return EPOLLIN | EPOLLRDNORM;
        else
-               return ring_buffer_poll_wait(iter->trace_buffer->buffer, iter->cpu_file,
+               return ring_buffer_poll_wait(iter->array_buffer->buffer, iter->cpu_file,
                                             filp, poll_table);
 }
 
@@ -6356,8 +6392,8 @@ tracing_entries_read(struct file *filp, char __user *ubuf,
                for_each_tracing_cpu(cpu) {
                        /* fill in the size from first enabled cpu */
                        if (size == 0)
-                               size = per_cpu_ptr(tr->trace_buffer.data, cpu)->entries;
-                       if (size != per_cpu_ptr(tr->trace_buffer.data, cpu)->entries) {
+                               size = per_cpu_ptr(tr->array_buffer.data, cpu)->entries;
+                       if (size != per_cpu_ptr(tr->array_buffer.data, cpu)->entries) {
                                buf_size_same = 0;
                                break;
                        }
@@ -6373,7 +6409,7 @@ tracing_entries_read(struct file *filp, char __user *ubuf,
                } else
                        r = sprintf(buf, "X\n");
        } else
-               r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10);
+               r = sprintf(buf, "%lu\n", per_cpu_ptr(tr->array_buffer.data, cpu)->entries >> 10);
 
        mutex_unlock(&trace_types_lock);
 
@@ -6420,7 +6456,7 @@ tracing_total_entries_read(struct file *filp, char __user *ubuf,
 
        mutex_lock(&trace_types_lock);
        for_each_tracing_cpu(cpu) {
-               size += per_cpu_ptr(tr->trace_buffer.data, cpu)->entries >> 10;
+               size += per_cpu_ptr(tr->array_buffer.data, cpu)->entries >> 10;
                if (!ring_buffer_expanded)
                        expanded_size += trace_buf_size >> 10;
        }
@@ -6470,7 +6506,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
        struct trace_array *tr = filp->private_data;
        struct ring_buffer_event *event;
        enum event_trigger_type tt = ETT_NONE;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        struct print_entry *entry;
        unsigned long irq_flags;
        ssize_t written;
@@ -6499,7 +6535,7 @@ tracing_mark_write(struct file *filp, const char __user *ubuf,
        if (cnt < FAULTED_SIZE)
                size += FAULTED_SIZE - cnt;
 
-       buffer = tr->trace_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        event = __trace_buffer_lock_reserve(buffer, TRACE_PRINT, size,
                                            irq_flags, preempt_count());
        if (unlikely(!event))
@@ -6550,7 +6586,7 @@ tracing_mark_raw_write(struct file *filp, const char __user *ubuf,
 {
        struct trace_array *tr = filp->private_data;
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        struct raw_data_entry *entry;
        unsigned long irq_flags;
        ssize_t written;
@@ -6579,7 +6615,7 @@ tracing_mark_raw_write(struct file *filp, const char __user *ubuf,
        if (cnt < FAULT_SIZE_ID)
                size += FAULT_SIZE_ID - cnt;
 
-       buffer = tr->trace_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        event = __trace_buffer_lock_reserve(buffer, TRACE_RAW_DATA, size,
                                            irq_flags, preempt_count());
        if (!event)
@@ -6634,13 +6670,13 @@ int tracing_set_clock(struct trace_array *tr, const char *clockstr)
 
        tr->clock_id = i;
 
-       ring_buffer_set_clock(tr->trace_buffer.buffer, trace_clocks[i].func);
+       ring_buffer_set_clock(tr->array_buffer.buffer, trace_clocks[i].func);
 
        /*
         * New clock may not be consistent with the previous clock.
         * Reset the buffer so that it doesn't have incomparable timestamps.
         */
-       tracing_reset_online_cpus(&tr->trace_buffer);
+       tracing_reset_online_cpus(&tr->array_buffer);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
        if (tr->max_buffer.buffer)
@@ -6703,7 +6739,7 @@ static int tracing_time_stamp_mode_show(struct seq_file *m, void *v)
 
        mutex_lock(&trace_types_lock);
 
-       if (ring_buffer_time_stamp_abs(tr->trace_buffer.buffer))
+       if (ring_buffer_time_stamp_abs(tr->array_buffer.buffer))
                seq_puts(m, "delta [absolute]\n");
        else
                seq_puts(m, "[delta] absolute\n");
@@ -6748,7 +6784,7 @@ int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs)
                        goto out;
        }
 
-       ring_buffer_set_time_stamp_abs(tr->trace_buffer.buffer, abs);
+       ring_buffer_set_time_stamp_abs(tr->array_buffer.buffer, abs);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
        if (tr->max_buffer.buffer)
@@ -6797,7 +6833,7 @@ static int tracing_snapshot_open(struct inode *inode, struct file *file)
                ret = 0;
 
                iter->tr = tr;
-               iter->trace_buffer = &tr->max_buffer;
+               iter->array_buffer = &tr->max_buffer;
                iter->cpu_file = tracing_get_cpu(inode);
                m->private = iter;
                file->private_data = m;
@@ -6860,7 +6896,7 @@ tracing_snapshot_write(struct file *filp, const char __user *ubuf, size_t cnt,
 #endif
                if (tr->allocated_snapshot)
                        ret = resize_buffer_duplicate_size(&tr->max_buffer,
-                                       &tr->trace_buffer, iter->cpu_file);
+                                       &tr->array_buffer, iter->cpu_file);
                else
                        ret = tracing_alloc_snapshot_instance(tr);
                if (ret < 0)
@@ -6935,7 +6971,7 @@ static int snapshot_raw_open(struct inode *inode, struct file *filp)
        }
 
        info->iter.snapshot = true;
-       info->iter.trace_buffer = &info->iter.tr->max_buffer;
+       info->iter.array_buffer = &info->iter.tr->max_buffer;
 
        return ret;
 }
@@ -7310,7 +7346,7 @@ static int tracing_buffers_open(struct inode *inode, struct file *filp)
        info->iter.tr           = tr;
        info->iter.cpu_file     = tracing_get_cpu(inode);
        info->iter.trace        = tr->current_trace;
-       info->iter.trace_buffer = &tr->trace_buffer;
+       info->iter.array_buffer = &tr->array_buffer;
        info->spare             = NULL;
        /* Force reading ring buffer for first read */
        info->read              = (unsigned int)-1;
@@ -7355,7 +7391,7 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
 #endif
 
        if (!info->spare) {
-               info->spare = ring_buffer_alloc_read_page(iter->trace_buffer->buffer,
+               info->spare = ring_buffer_alloc_read_page(iter->array_buffer->buffer,
                                                          iter->cpu_file);
                if (IS_ERR(info->spare)) {
                        ret = PTR_ERR(info->spare);
@@ -7373,7 +7409,7 @@ tracing_buffers_read(struct file *filp, char __user *ubuf,
 
  again:
        trace_access_lock(iter->cpu_file);
-       ret = ring_buffer_read_page(iter->trace_buffer->buffer,
+       ret = ring_buffer_read_page(iter->array_buffer->buffer,
                                    &info->spare,
                                    count,
                                    iter->cpu_file, 0);
@@ -7423,7 +7459,7 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
        __trace_array_put(iter->tr);
 
        if (info->spare)
-               ring_buffer_free_read_page(iter->trace_buffer->buffer,
+               ring_buffer_free_read_page(iter->array_buffer->buffer,
                                           info->spare_cpu, info->spare);
        kfree(info);
 
@@ -7433,7 +7469,7 @@ static int tracing_buffers_release(struct inode *inode, struct file *file)
 }
 
 struct buffer_ref {
-       struct ring_buffer      *buffer;
+       struct trace_buffer     *buffer;
        void                    *page;
        int                     cpu;
        refcount_t              refcount;
@@ -7528,7 +7564,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
 
  again:
        trace_access_lock(iter->cpu_file);
-       entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file);
+       entries = ring_buffer_entries_cpu(iter->array_buffer->buffer, iter->cpu_file);
 
        for (i = 0; i < spd.nr_pages_max && len && entries; i++, len -= PAGE_SIZE) {
                struct page *page;
@@ -7541,7 +7577,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
                }
 
                refcount_set(&ref->refcount, 1);
-               ref->buffer = iter->trace_buffer->buffer;
+               ref->buffer = iter->array_buffer->buffer;
                ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
                if (IS_ERR(ref->page)) {
                        ret = PTR_ERR(ref->page);
@@ -7569,7 +7605,7 @@ tracing_buffers_splice_read(struct file *file, loff_t *ppos,
                spd.nr_pages++;
                *ppos += PAGE_SIZE;
 
-               entries = ring_buffer_entries_cpu(iter->trace_buffer->buffer, iter->cpu_file);
+               entries = ring_buffer_entries_cpu(iter->array_buffer->buffer, iter->cpu_file);
        }
 
        trace_access_unlock(iter->cpu_file);
@@ -7613,7 +7649,7 @@ tracing_stats_read(struct file *filp, char __user *ubuf,
 {
        struct inode *inode = file_inode(filp);
        struct trace_array *tr = inode->i_private;
-       struct trace_buffer *trace_buf = &tr->trace_buffer;
+       struct array_buffer *trace_buf = &tr->array_buffer;
        int cpu = tracing_get_cpu(inode);
        struct trace_seq *s;
        unsigned long cnt;
@@ -7894,7 +7930,7 @@ static struct dentry *tracing_dentry_percpu(struct trace_array *tr, int cpu)
 
        tr->percpu_dir = tracefs_create_dir("per_cpu", d_tracer);
 
-       WARN_ONCE(!tr->percpu_dir,
+       MEM_FAIL(!tr->percpu_dir,
                  "Could not create tracefs directory 'per_cpu/%d'\n", cpu);
 
        return tr->percpu_dir;
@@ -8215,7 +8251,7 @@ create_trace_option_files(struct trace_array *tr, struct tracer *tracer)
        for (cnt = 0; opts[cnt].name; cnt++) {
                create_trace_option_file(tr, &topts[cnt], flags,
                                         &opts[cnt]);
-               WARN_ONCE(topts[cnt].entry == NULL,
+               MEM_FAIL(topts[cnt].entry == NULL,
                          "Failed to create trace option: %s",
                          opts[cnt].name);
        }
@@ -8272,7 +8308,7 @@ rb_simple_write(struct file *filp, const char __user *ubuf,
                size_t cnt, loff_t *ppos)
 {
        struct trace_array *tr = filp->private_data;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
        unsigned long val;
        int ret;
 
@@ -8362,7 +8398,7 @@ static void
 init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer);
 
 static int
-allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size)
+allocate_trace_buffer(struct trace_array *tr, struct array_buffer *buf, int size)
 {
        enum ring_buffer_flags rb_flags;
 
@@ -8382,8 +8418,8 @@ allocate_trace_buffer(struct trace_array *tr, struct trace_buffer *buf, int size
        }
 
        /* Allocate the first page for all buffers */
-       set_buffer_entries(&tr->trace_buffer,
-                          ring_buffer_size(tr->trace_buffer.buffer, 0));
+       set_buffer_entries(&tr->array_buffer,
+                          ring_buffer_size(tr->array_buffer.buffer, 0));
 
        return 0;
 }
@@ -8392,18 +8428,18 @@ static int allocate_trace_buffers(struct trace_array *tr, int size)
 {
        int ret;
 
-       ret = allocate_trace_buffer(tr, &tr->trace_buffer, size);
+       ret = allocate_trace_buffer(tr, &tr->array_buffer, size);
        if (ret)
                return ret;
 
 #ifdef CONFIG_TRACER_MAX_TRACE
        ret = allocate_trace_buffer(tr, &tr->max_buffer,
                                    allocate_snapshot ? size : 1);
-       if (WARN_ON(ret)) {
-               ring_buffer_free(tr->trace_buffer.buffer);
-               tr->trace_buffer.buffer = NULL;
-               free_percpu(tr->trace_buffer.data);
-               tr->trace_buffer.data = NULL;
+       if (MEM_FAIL(ret, "Failed to allocate trace buffer\n")) {
+               ring_buffer_free(tr->array_buffer.buffer);
+               tr->array_buffer.buffer = NULL;
+               free_percpu(tr->array_buffer.data);
+               tr->array_buffer.data = NULL;
                return -ENOMEM;
        }
        tr->allocated_snapshot = allocate_snapshot;
@@ -8417,7 +8453,7 @@ static int allocate_trace_buffers(struct trace_array *tr, int size)
        return 0;
 }
 
-static void free_trace_buffer(struct trace_buffer *buf)
+static void free_trace_buffer(struct array_buffer *buf)
 {
        if (buf->buffer) {
                ring_buffer_free(buf->buffer);
@@ -8432,7 +8468,7 @@ static void free_trace_buffers(struct trace_array *tr)
        if (!tr)
                return;
 
-       free_trace_buffer(&tr->trace_buffer);
+       free_trace_buffer(&tr->array_buffer);
 
 #ifdef CONFIG_TRACER_MAX_TRACE
        free_trace_buffer(&tr->max_buffer);
@@ -8463,6 +8499,34 @@ static void update_tracer_options(struct trace_array *tr)
        mutex_unlock(&trace_types_lock);
 }
 
+/* Must have trace_types_lock held */
+struct trace_array *trace_array_find(const char *instance)
+{
+       struct trace_array *tr, *found = NULL;
+
+       list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+               if (tr->name && strcmp(tr->name, instance) == 0) {
+                       found = tr;
+                       break;
+               }
+       }
+
+       return found;
+}
+
+struct trace_array *trace_array_find_get(const char *instance)
+{
+       struct trace_array *tr;
+
+       mutex_lock(&trace_types_lock);
+       tr = trace_array_find(instance);
+       if (tr)
+               tr->ref++;
+       mutex_unlock(&trace_types_lock);
+
+       return tr;
+}
+
 static struct trace_array *trace_array_create(const char *name)
 {
        struct trace_array *tr;
@@ -8504,7 +8568,7 @@ static struct trace_array *trace_array_create(const char *name)
 
        ret = event_trace_add_tracer(tr->dir, tr);
        if (ret) {
-               tracefs_remove_recursive(tr->dir);
+               tracefs_remove(tr->dir);
                goto out_free_tr;
        }
 
@@ -8539,10 +8603,8 @@ static int instance_mkdir(const char *name)
        mutex_lock(&trace_types_lock);
 
        ret = -EEXIST;
-       list_for_each_entry(tr, &ftrace_trace_arrays, list) {
-               if (tr->name && strcmp(tr->name, name) == 0)
-                       goto out_unlock;
-       }
+       if (trace_array_find(name))
+               goto out_unlock;
 
        tr = trace_array_create(name);
 
@@ -8564,6 +8626,10 @@ out_unlock:
  * NOTE: This function increments the reference counter associated with the
  * trace array returned. This makes sure it cannot be freed while in use.
  * Use trace_array_put() once the trace array is no longer needed.
+ * If the trace_array is to be freed, trace_array_destroy() needs to
+ * be called after the trace_array_put(), or simply let user space delete
+ * it from the tracefs instances directory. But until the
+ * trace_array_put() is called, user space can not delete it.
  *
  */
 struct trace_array *trace_array_get_by_name(const char *name)
@@ -8613,7 +8679,7 @@ static int __remove_instance(struct trace_array *tr)
        event_trace_del_tracer(tr);
        ftrace_clear_pids(tr);
        ftrace_destroy_function_files(tr);
-       tracefs_remove_recursive(tr->dir);
+       tracefs_remove(tr->dir);
        free_trace_buffers(tr);
 
        for (i = 0; i < tr->nr_topts; i++) {
@@ -8666,12 +8732,9 @@ static int instance_rmdir(const char *name)
        mutex_lock(&trace_types_lock);
 
        ret = -ENODEV;
-       list_for_each_entry(tr, &ftrace_trace_arrays, list) {
-               if (tr->name && strcmp(tr->name, name) == 0) {
-                       ret = __remove_instance(tr);
-                       break;
-               }
-       }
+       tr = trace_array_find(name);
+       if (tr)
+               ret = __remove_instance(tr);
 
        mutex_unlock(&trace_types_lock);
        mutex_unlock(&event_mutex);
@@ -8684,7 +8747,7 @@ static __init void create_trace_instances(struct dentry *d_tracer)
        trace_instance_dir = tracefs_create_instance_dir("instances", d_tracer,
                                                         instance_mkdir,
                                                         instance_rmdir);
-       if (WARN_ON(!trace_instance_dir))
+       if (MEM_FAIL(!trace_instance_dir, "Failed to create instances directory\n"))
                return;
 }
 
@@ -8754,7 +8817,7 @@ init_tracer_tracefs(struct trace_array *tr, struct dentry *d_tracer)
 #endif
 
        if (ftrace_create_function_files(tr, d_tracer))
-               WARN(1, "Could not allocate function filter files");
+               MEM_FAIL(1, "Could not allocate function filter files");
 
 #ifdef CONFIG_TRACER_SNAPSHOT
        trace_create_file("snapshot", 0644, d_tracer,
@@ -9036,13 +9099,13 @@ void trace_init_global_iter(struct trace_iterator *iter)
        iter->tr = &global_trace;
        iter->trace = iter->tr->current_trace;
        iter->cpu_file = RING_BUFFER_ALL_CPUS;
-       iter->trace_buffer = &global_trace.trace_buffer;
+       iter->array_buffer = &global_trace.array_buffer;
 
        if (iter->trace && iter->trace->open)
                iter->trace->open(iter);
 
        /* Annotate start of buffers if we had overruns */
-       if (ring_buffer_overruns(iter->trace_buffer->buffer))
+       if (ring_buffer_overruns(iter->array_buffer->buffer))
                iter->iter_flags |= TRACE_FILE_ANNOTATE;
 
        /* Output in nanoseconds only if we are using a clock in nanoseconds. */
@@ -9083,7 +9146,7 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
        trace_init_global_iter(&iter);
 
        for_each_tracing_cpu(cpu) {
-               atomic_inc(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled);
+               atomic_inc(&per_cpu_ptr(iter.array_buffer->data, cpu)->disabled);
        }
 
        old_userobj = tr->trace_flags & TRACE_ITER_SYM_USEROBJ;
@@ -9151,7 +9214,7 @@ void ftrace_dump(enum ftrace_dump_mode oops_dump_mode)
        tr->trace_flags |= old_userobj;
 
        for_each_tracing_cpu(cpu) {
-               atomic_dec(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled);
+               atomic_dec(&per_cpu_ptr(iter.array_buffer->data, cpu)->disabled);
        }
        atomic_dec(&dump_running);
        printk_nmi_direct_exit();
@@ -9306,8 +9369,7 @@ __init static int tracer_alloc_buffers(void)
 
        /* TODO: make the number of buffers hot pluggable with CPUS */
        if (allocate_trace_buffers(&global_trace, ring_buf_size) < 0) {
-               printk(KERN_ERR "tracer: failed to allocate ring buffer!\n");
-               WARN_ON(1);
+               MEM_FAIL(1, "tracer: failed to allocate ring buffer!\n");
                goto out_free_savedcmd;
        }
 
@@ -9380,7 +9442,8 @@ void __init early_trace_init(void)
        if (tracepoint_printk) {
                tracepoint_print_iter =
                        kmalloc(sizeof(*tracepoint_print_iter), GFP_KERNEL);
-               if (WARN_ON(!tracepoint_print_iter))
+               if (MEM_FAIL(!tracepoint_print_iter,
+                            "Failed to allocate trace iterator\n"))
                        tracepoint_printk = 0;
                else
                        static_key_enable(&tracepoint_printk_key.key);
index a98dce1..99372dd 100644 (file)
@@ -93,6 +93,18 @@ enum trace_type {
 
 #include "trace_entries.h"
 
+/* Use this for memory failure errors */
+#define MEM_FAIL(condition, fmt, ...) ({                       \
+       static bool __section(.data.once) __warned;             \
+       int __ret_warn_once = !!(condition);                    \
+                                                               \
+       if (unlikely(__ret_warn_once && !__warned)) {           \
+               __warned = true;                                \
+               pr_err("ERROR: " fmt, ##__VA_ARGS__);           \
+       }                                                       \
+       unlikely(__ret_warn_once);                              \
+})
+
 /*
  * syscalls are special, and need special handling, this is why
  * they are not included in trace_entries.h
@@ -175,9 +187,9 @@ struct trace_array_cpu {
 struct tracer;
 struct trace_option_dentry;
 
-struct trace_buffer {
+struct array_buffer {
        struct trace_array              *tr;
-       struct ring_buffer              *buffer;
+       struct trace_buffer             *buffer;
        struct trace_array_cpu __percpu *data;
        u64                             time_start;
        int                             cpu;
@@ -248,7 +260,7 @@ struct cond_snapshot {
 struct trace_array {
        struct list_head        list;
        char                    *name;
-       struct trace_buffer     trace_buffer;
+       struct array_buffer     array_buffer;
 #ifdef CONFIG_TRACER_MAX_TRACE
        /*
         * The max_buffer is used to snapshot the trace when a maximum
@@ -256,12 +268,12 @@ struct trace_array {
         * Some tracers will use this to store a maximum trace while
         * it continues examining live traces.
         *
-        * The buffers for the max_buffer are set up the same as the trace_buffer
+        * The buffers for the max_buffer are set up the same as the array_buffer
         * When a snapshot is taken, the buffer of the max_buffer is swapped
-        * with the buffer of the trace_buffer and the buffers are reset for
-        * the trace_buffer so the tracing can continue.
+        * with the buffer of the array_buffer and the buffers are reset for
+        * the array_buffer so the tracing can continue.
         */
-       struct trace_buffer     max_buffer;
+       struct array_buffer     max_buffer;
        bool                    allocated_snapshot;
 #endif
 #if defined(CONFIG_TRACER_MAX_TRACE) || defined(CONFIG_HWLAT_TRACER)
@@ -345,6 +357,8 @@ extern struct mutex trace_types_lock;
 
 extern int trace_array_get(struct trace_array *tr);
 extern int tracing_check_open_get_tr(struct trace_array *tr);
+extern struct trace_array *trace_array_find(const char *instance);
+extern struct trace_array *trace_array_find_get(const char *instance);
 
 extern int tracing_set_time_stamp_abs(struct trace_array *tr, bool abs);
 extern int tracing_set_clock(struct trace_array *tr, const char *clockstr);
@@ -684,7 +698,7 @@ trace_buffer_iter(struct trace_iterator *iter, int cpu)
 
 int tracer_init(struct tracer *t, struct trace_array *tr);
 int tracing_is_enabled(void);
-void tracing_reset_online_cpus(struct trace_buffer *buf);
+void tracing_reset_online_cpus(struct array_buffer *buf);
 void tracing_reset_current(int cpu);
 void tracing_reset_all_online_cpus(void);
 int tracing_open_generic(struct inode *inode, struct file *filp);
@@ -704,7 +718,7 @@ struct dentry *tracing_init_dentry(void);
 struct ring_buffer_event;
 
 struct ring_buffer_event *
-trace_buffer_lock_reserve(struct ring_buffer *buffer,
+trace_buffer_lock_reserve(struct trace_buffer *buffer,
                          int type,
                          unsigned long len,
                          unsigned long flags,
@@ -716,7 +730,7 @@ struct trace_entry *tracing_get_trace_entry(struct trace_array *tr,
 struct trace_entry *trace_find_next_entry(struct trace_iterator *iter,
                                          int *ent_cpu, u64 *ent_ts);
 
-void trace_buffer_unlock_commit_nostack(struct ring_buffer *buffer,
+void trace_buffer_unlock_commit_nostack(struct trace_buffer *buffer,
                                        struct ring_buffer_event *event);
 
 int trace_empty(struct trace_iterator *iter);
@@ -872,7 +886,7 @@ trace_vprintk(unsigned long ip, const char *fmt, va_list args);
 extern int
 trace_array_vprintk(struct trace_array *tr,
                    unsigned long ip, const char *fmt, va_list args);
-int trace_array_printk_buf(struct ring_buffer *buffer,
+int trace_array_printk_buf(struct trace_buffer *buffer,
                           unsigned long ip, const char *fmt, ...);
 void trace_printk_seq(struct trace_seq *s);
 enum print_line_t print_trace_line(struct trace_iterator *iter);
@@ -949,22 +963,31 @@ extern void __trace_graph_return(struct trace_array *tr,
                                 unsigned long flags, int pc);
 
 #ifdef CONFIG_DYNAMIC_FTRACE
-extern struct ftrace_hash *ftrace_graph_hash;
-extern struct ftrace_hash *ftrace_graph_notrace_hash;
+extern struct ftrace_hash __rcu *ftrace_graph_hash;
+extern struct ftrace_hash __rcu *ftrace_graph_notrace_hash;
 
 static inline int ftrace_graph_addr(struct ftrace_graph_ent *trace)
 {
        unsigned long addr = trace->func;
        int ret = 0;
+       struct ftrace_hash *hash;
 
        preempt_disable_notrace();
 
-       if (ftrace_hash_empty(ftrace_graph_hash)) {
+       /*
+        * Have to open code "rcu_dereference_sched()" because the
+        * function graph tracer can be called when RCU is not
+        * "watching".
+        * Protected with schedule_on_each_cpu(ftrace_sync)
+        */
+       hash = rcu_dereference_protected(ftrace_graph_hash, !preemptible());
+
+       if (ftrace_hash_empty(hash)) {
                ret = 1;
                goto out;
        }
 
-       if (ftrace_lookup_ip(ftrace_graph_hash, addr)) {
+       if (ftrace_lookup_ip(hash, addr)) {
 
                /*
                 * This needs to be cleared on the return functions
@@ -1000,10 +1023,20 @@ static inline void ftrace_graph_addr_finish(struct ftrace_graph_ret *trace)
 static inline int ftrace_graph_notrace_addr(unsigned long addr)
 {
        int ret = 0;
+       struct ftrace_hash *notrace_hash;
 
        preempt_disable_notrace();
 
-       if (ftrace_lookup_ip(ftrace_graph_notrace_hash, addr))
+       /*
+        * Have to open code "rcu_dereference_sched()" because the
+        * function graph tracer can be called when RCU is not
+        * "watching".
+        * Protected with schedule_on_each_cpu(ftrace_sync)
+        */
+       notrace_hash = rcu_dereference_protected(ftrace_graph_notrace_hash,
+                                                !preemptible());
+
+       if (ftrace_lookup_ip(notrace_hash, addr))
                ret = 1;
 
        preempt_enable_notrace();
@@ -1056,7 +1089,7 @@ struct ftrace_func_command {
 extern bool ftrace_filter_param __initdata;
 static inline int ftrace_trace_task(struct trace_array *tr)
 {
-       return !this_cpu_read(tr->trace_buffer.data->ftrace_ignore_pid);
+       return !this_cpu_read(tr->array_buffer.data->ftrace_ignore_pid);
 }
 extern int ftrace_is_dead(void);
 int ftrace_create_function_files(struct trace_array *tr,
@@ -1144,6 +1177,11 @@ int unregister_ftrace_command(struct ftrace_func_command *cmd);
 void ftrace_create_filter_files(struct ftrace_ops *ops,
                                struct dentry *parent);
 void ftrace_destroy_filter_files(struct ftrace_ops *ops);
+
+extern int ftrace_set_filter(struct ftrace_ops *ops, unsigned char *buf,
+                            int len, int reset);
+extern int ftrace_set_notrace(struct ftrace_ops *ops, unsigned char *buf,
+                             int len, int reset);
 #else
 struct ftrace_func_command;
 
@@ -1366,17 +1404,17 @@ struct trace_subsystem_dir {
 };
 
 extern int call_filter_check_discard(struct trace_event_call *call, void *rec,
-                                    struct ring_buffer *buffer,
+                                    struct trace_buffer *buffer,
                                     struct ring_buffer_event *event);
 
 void trace_buffer_unlock_commit_regs(struct trace_array *tr,
-                                    struct ring_buffer *buffer,
+                                    struct trace_buffer *buffer,
                                     struct ring_buffer_event *event,
                                     unsigned long flags, int pc,
                                     struct pt_regs *regs);
 
 static inline void trace_buffer_unlock_commit(struct trace_array *tr,
-                                             struct ring_buffer *buffer,
+                                             struct trace_buffer *buffer,
                                              struct ring_buffer_event *event,
                                              unsigned long flags, int pc)
 {
@@ -1389,7 +1427,7 @@ void trace_buffered_event_disable(void);
 void trace_buffered_event_enable(void);
 
 static inline void
-__trace_event_discard_commit(struct ring_buffer *buffer,
+__trace_event_discard_commit(struct trace_buffer *buffer,
                             struct ring_buffer_event *event)
 {
        if (this_cpu_read(trace_buffered_event) == event) {
@@ -1415,7 +1453,7 @@ __trace_event_discard_commit(struct ring_buffer *buffer,
  */
 static inline bool
 __event_trigger_test_discard(struct trace_event_file *file,
-                            struct ring_buffer *buffer,
+                            struct trace_buffer *buffer,
                             struct ring_buffer_event *event,
                             void *entry,
                             enum event_trigger_type *tt)
@@ -1450,7 +1488,7 @@ __event_trigger_test_discard(struct trace_event_file *file,
  */
 static inline void
 event_trigger_unlock_commit(struct trace_event_file *file,
-                           struct ring_buffer *buffer,
+                           struct trace_buffer *buffer,
                            struct ring_buffer_event *event,
                            void *entry, unsigned long irq_flags, int pc)
 {
@@ -1481,7 +1519,7 @@ event_trigger_unlock_commit(struct trace_event_file *file,
  */
 static inline void
 event_trigger_unlock_commit_regs(struct trace_event_file *file,
-                                struct ring_buffer *buffer,
+                                struct trace_buffer *buffer,
                                 struct ring_buffer_event *event,
                                 void *entry, unsigned long irq_flags, int pc,
                                 struct pt_regs *regs)
@@ -1892,6 +1930,15 @@ void trace_printk_start_comm(void);
 int trace_keep_overwrite(struct tracer *tracer, u32 mask, int set);
 int set_tracer_flag(struct trace_array *tr, unsigned int mask, int enabled);
 
+/* Used from boot time tracer */
+extern int trace_set_options(struct trace_array *tr, char *option);
+extern int tracing_set_tracer(struct trace_array *tr, const char *buf);
+extern ssize_t tracing_resize_ring_buffer(struct trace_array *tr,
+                                         unsigned long size, int cpu_id);
+extern int tracing_set_cpumask(struct trace_array *tr,
+                               cpumask_var_t tracing_cpumask_new);
+
+
 #define MAX_EVENT_NAME_LEN     64
 
 extern int trace_run_command(const char *buf, int (*createfn)(int, char**));
@@ -1949,6 +1996,9 @@ static inline const char *get_syscall_name(int syscall)
 #ifdef CONFIG_EVENT_TRACING
 void trace_event_init(void);
 void trace_event_eval_update(struct trace_eval_map **map, int len);
+/* Used from boot time tracer */
+extern int ftrace_set_clr_event(struct trace_array *tr, char *buf, int set);
+extern int trigger_process_regex(struct trace_event_file *file, char *buff);
 #else
 static inline void __init trace_event_init(void) { }
 static inline void trace_event_eval_update(struct trace_eval_map **map, int len) { }
diff --git a/kernel/trace/trace_boot.c b/kernel/trace/trace_boot.c
new file mode 100644 (file)
index 0000000..06d7feb
--- /dev/null
@@ -0,0 +1,334 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * trace_boot.c
+ * Tracing kernel boot-time
+ */
+
+#define pr_fmt(fmt)    "trace_boot: " fmt
+
+#include <linux/bootconfig.h>
+#include <linux/cpumask.h>
+#include <linux/ftrace.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/trace.h>
+#include <linux/trace_events.h>
+
+#include "trace.h"
+
+#define MAX_BUF_LEN 256
+
+static void __init
+trace_boot_set_instance_options(struct trace_array *tr, struct xbc_node *node)
+{
+       struct xbc_node *anode;
+       const char *p;
+       char buf[MAX_BUF_LEN];
+       unsigned long v = 0;
+
+       /* Common ftrace options */
+       xbc_node_for_each_array_value(node, "options", anode, p) {
+               if (strlcpy(buf, p, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf)) {
+                       pr_err("String is too long: %s\n", p);
+                       continue;
+               }
+
+               if (trace_set_options(tr, buf) < 0)
+                       pr_err("Failed to set option: %s\n", buf);
+       }
+
+       p = xbc_node_find_value(node, "trace_clock", NULL);
+       if (p && *p != '\0') {
+               if (tracing_set_clock(tr, p) < 0)
+                       pr_err("Failed to set trace clock: %s\n", p);
+       }
+
+       p = xbc_node_find_value(node, "buffer_size", NULL);
+       if (p && *p != '\0') {
+               v = memparse(p, NULL);
+               if (v < PAGE_SIZE)
+                       pr_err("Buffer size is too small: %s\n", p);
+               if (tracing_resize_ring_buffer(tr, v, RING_BUFFER_ALL_CPUS) < 0)
+                       pr_err("Failed to resize trace buffer to %s\n", p);
+       }
+
+       p = xbc_node_find_value(node, "cpumask", NULL);
+       if (p && *p != '\0') {
+               cpumask_var_t new_mask;
+
+               if (alloc_cpumask_var(&new_mask, GFP_KERNEL)) {
+                       if (cpumask_parse(p, new_mask) < 0 ||
+                           tracing_set_cpumask(tr, new_mask) < 0)
+                               pr_err("Failed to set new CPU mask %s\n", p);
+                       free_cpumask_var(new_mask);
+               }
+       }
+}
+
+#ifdef CONFIG_EVENT_TRACING
+static void __init
+trace_boot_enable_events(struct trace_array *tr, struct xbc_node *node)
+{
+       struct xbc_node *anode;
+       char buf[MAX_BUF_LEN];
+       const char *p;
+
+       xbc_node_for_each_array_value(node, "events", anode, p) {
+               if (strlcpy(buf, p, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf)) {
+                       pr_err("String is too long: %s\n", p);
+                       continue;
+               }
+
+               if (ftrace_set_clr_event(tr, buf, 1) < 0)
+                       pr_err("Failed to enable event: %s\n", p);
+       }
+}
+
+#ifdef CONFIG_KPROBE_EVENTS
+static int __init
+trace_boot_add_kprobe_event(struct xbc_node *node, const char *event)
+{
+       struct dynevent_cmd cmd;
+       struct xbc_node *anode;
+       char buf[MAX_BUF_LEN];
+       const char *val;
+       int ret;
+
+       kprobe_event_cmd_init(&cmd, buf, MAX_BUF_LEN);
+
+       ret = kprobe_event_gen_cmd_start(&cmd, event, NULL);
+       if (ret)
+               return ret;
+
+       xbc_node_for_each_array_value(node, "probes", anode, val) {
+               ret = kprobe_event_add_field(&cmd, val);
+               if (ret)
+                       return ret;
+       }
+
+       ret = kprobe_event_gen_cmd_end(&cmd);
+       if (ret)
+               pr_err("Failed to add probe: %s\n", buf);
+
+       return ret;
+}
+#else
+static inline int __init
+trace_boot_add_kprobe_event(struct xbc_node *node, const char *event)
+{
+       pr_err("Kprobe event is not supported.\n");
+       return -ENOTSUPP;
+}
+#endif
+
+#ifdef CONFIG_HIST_TRIGGERS
+static int __init
+trace_boot_add_synth_event(struct xbc_node *node, const char *event)
+{
+       struct dynevent_cmd cmd;
+       struct xbc_node *anode;
+       char buf[MAX_BUF_LEN];
+       const char *p;
+       int ret;
+
+       synth_event_cmd_init(&cmd, buf, MAX_BUF_LEN);
+
+       ret = synth_event_gen_cmd_start(&cmd, event, NULL);
+       if (ret)
+               return ret;
+
+       xbc_node_for_each_array_value(node, "fields", anode, p) {
+               ret = synth_event_add_field_str(&cmd, p);
+               if (ret)
+                       return ret;
+       }
+
+       ret = synth_event_gen_cmd_end(&cmd);
+       if (ret < 0)
+               pr_err("Failed to add synthetic event: %s\n", buf);
+
+       return ret;
+}
+#else
+static inline int __init
+trace_boot_add_synth_event(struct xbc_node *node, const char *event)
+{
+       pr_err("Synthetic event is not supported.\n");
+       return -ENOTSUPP;
+}
+#endif
+
+static void __init
+trace_boot_init_one_event(struct trace_array *tr, struct xbc_node *gnode,
+                         struct xbc_node *enode)
+{
+       struct trace_event_file *file;
+       struct xbc_node *anode;
+       char buf[MAX_BUF_LEN];
+       const char *p, *group, *event;
+
+       group = xbc_node_get_data(gnode);
+       event = xbc_node_get_data(enode);
+
+       if (!strcmp(group, "kprobes"))
+               if (trace_boot_add_kprobe_event(enode, event) < 0)
+                       return;
+       if (!strcmp(group, "synthetic"))
+               if (trace_boot_add_synth_event(enode, event) < 0)
+                       return;
+
+       mutex_lock(&event_mutex);
+       file = find_event_file(tr, group, event);
+       if (!file) {
+               pr_err("Failed to find event: %s:%s\n", group, event);
+               goto out;
+       }
+
+       p = xbc_node_find_value(enode, "filter", NULL);
+       if (p && *p != '\0') {
+               if (strlcpy(buf, p, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf))
+                       pr_err("filter string is too long: %s\n", p);
+               else if (apply_event_filter(file, buf) < 0)
+                       pr_err("Failed to apply filter: %s\n", buf);
+       }
+
+       xbc_node_for_each_array_value(enode, "actions", anode, p) {
+               if (strlcpy(buf, p, ARRAY_SIZE(buf)) >= ARRAY_SIZE(buf))
+                       pr_err("action string is too long: %s\n", p);
+               else if (trigger_process_regex(file, buf) < 0)
+                       pr_err("Failed to apply an action: %s\n", buf);
+       }
+
+       if (xbc_node_find_value(enode, "enable", NULL)) {
+               if (trace_event_enable_disable(file, 1, 0) < 0)
+                       pr_err("Failed to enable event node: %s:%s\n",
+                               group, event);
+       }
+out:
+       mutex_unlock(&event_mutex);
+}
+
+static void __init
+trace_boot_init_events(struct trace_array *tr, struct xbc_node *node)
+{
+       struct xbc_node *gnode, *enode;
+
+       node = xbc_node_find_child(node, "event");
+       if (!node)
+               return;
+       /* per-event key starts with "event.GROUP.EVENT" */
+       xbc_node_for_each_child(node, gnode)
+               xbc_node_for_each_child(gnode, enode)
+                       trace_boot_init_one_event(tr, gnode, enode);
+}
+#else
+#define trace_boot_enable_events(tr, node) do {} while (0)
+#define trace_boot_init_events(tr, node) do {} while (0)
+#endif
+
+#ifdef CONFIG_DYNAMIC_FTRACE
+static void __init
+trace_boot_set_ftrace_filter(struct trace_array *tr, struct xbc_node *node)
+{
+       struct xbc_node *anode;
+       const char *p;
+       char *q;
+
+       xbc_node_for_each_array_value(node, "ftrace.filters", anode, p) {
+               q = kstrdup(p, GFP_KERNEL);
+               if (!q)
+                       return;
+               if (ftrace_set_filter(tr->ops, q, strlen(q), 0) < 0)
+                       pr_err("Failed to add %s to ftrace filter\n", p);
+               else
+                       ftrace_filter_param = true;
+               kfree(q);
+       }
+       xbc_node_for_each_array_value(node, "ftrace.notraces", anode, p) {
+               q = kstrdup(p, GFP_KERNEL);
+               if (!q)
+                       return;
+               if (ftrace_set_notrace(tr->ops, q, strlen(q), 0) < 0)
+                       pr_err("Failed to add %s to ftrace filter\n", p);
+               else
+                       ftrace_filter_param = true;
+               kfree(q);
+       }
+}
+#else
+#define trace_boot_set_ftrace_filter(tr, node) do {} while (0)
+#endif
+
+static void __init
+trace_boot_enable_tracer(struct trace_array *tr, struct xbc_node *node)
+{
+       const char *p;
+
+       trace_boot_set_ftrace_filter(tr, node);
+
+       p = xbc_node_find_value(node, "tracer", NULL);
+       if (p && *p != '\0') {
+               if (tracing_set_tracer(tr, p) < 0)
+                       pr_err("Failed to set given tracer: %s\n", p);
+       }
+}
+
+static void __init
+trace_boot_init_one_instance(struct trace_array *tr, struct xbc_node *node)
+{
+       trace_boot_set_instance_options(tr, node);
+       trace_boot_init_events(tr, node);
+       trace_boot_enable_events(tr, node);
+       trace_boot_enable_tracer(tr, node);
+}
+
+static void __init
+trace_boot_init_instances(struct xbc_node *node)
+{
+       struct xbc_node *inode;
+       struct trace_array *tr;
+       const char *p;
+
+       node = xbc_node_find_child(node, "instance");
+       if (!node)
+               return;
+
+       xbc_node_for_each_child(node, inode) {
+               p = xbc_node_get_data(inode);
+               if (!p || *p == '\0')
+                       continue;
+
+               tr = trace_array_get_by_name(p);
+               if (!tr) {
+                       pr_err("Failed to get trace instance %s\n", p);
+                       continue;
+               }
+               trace_boot_init_one_instance(tr, inode);
+               trace_array_put(tr);
+       }
+}
+
+static int __init trace_boot_init(void)
+{
+       struct xbc_node *trace_node;
+       struct trace_array *tr;
+
+       trace_node = xbc_find_node("ftrace");
+       if (!trace_node)
+               return 0;
+
+       tr = top_trace_array();
+       if (!tr)
+               return 0;
+
+       /* Global trace array is also one instance */
+       trace_boot_init_one_instance(tr, trace_node);
+       trace_boot_init_instances(trace_node);
+
+       return 0;
+}
+
+fs_initcall(trace_boot_init);
index 88e158d..eff0991 100644 (file)
@@ -32,10 +32,10 @@ probe_likely_condition(struct ftrace_likely_data *f, int val, int expect)
 {
        struct trace_event_call *call = &event_branch;
        struct trace_array *tr = branch_tracer;
+       struct trace_buffer *buffer;
        struct trace_array_cpu *data;
        struct ring_buffer_event *event;
        struct trace_branch *entry;
-       struct ring_buffer *buffer;
        unsigned long flags;
        int pc;
        const char *p;
@@ -55,12 +55,12 @@ probe_likely_condition(struct ftrace_likely_data *f, int val, int expect)
 
        raw_local_irq_save(flags);
        current->trace_recursion |= TRACE_BRANCH_BIT;
-       data = this_cpu_ptr(tr->trace_buffer.data);
+       data = this_cpu_ptr(tr->array_buffer.data);
        if (atomic_read(&data->disabled))
                goto out;
 
        pc = preempt_count();
-       buffer = tr->trace_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        event = trace_buffer_lock_reserve(buffer, TRACE_BRANCH,
                                          sizeof(*entry), flags, pc);
        if (!event)
index 89779eb..9f2e852 100644 (file)
@@ -223,3 +223,215 @@ static __init int init_dynamic_event(void)
        return 0;
 }
 fs_initcall(init_dynamic_event);
+
+/**
+ * dynevent_arg_add - Add an arg to a dynevent_cmd
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event cmd
+ * @arg: The argument to append to the current cmd
+ * @check_arg: An (optional) pointer to a function checking arg sanity
+ *
+ * Append an argument to a dynevent_cmd.  The argument string will be
+ * appended to the current cmd string, followed by a separator, if
+ * applicable.  Before the argument is added, the @check_arg function,
+ * if present, will be used to check the sanity of the current arg
+ * string.
+ *
+ * The cmd string and separator should be set using the
+ * dynevent_arg_init() before any arguments are added using this
+ * function.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int dynevent_arg_add(struct dynevent_cmd *cmd,
+                    struct dynevent_arg *arg,
+                    dynevent_check_arg_fn_t check_arg)
+{
+       int ret = 0;
+
+       if (check_arg) {
+               ret = check_arg(arg);
+               if (ret)
+                       return ret;
+       }
+
+       ret = seq_buf_printf(&cmd->seq, " %s%c", arg->str, arg->separator);
+       if (ret) {
+               pr_err("String is too long: %s%c\n", arg->str, arg->separator);
+               return -E2BIG;
+       }
+
+       return ret;
+}
+
+/**
+ * dynevent_arg_pair_add - Add an arg pair to a dynevent_cmd
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event cmd
+ * @arg_pair: The argument pair to append to the current cmd
+ * @check_arg: An (optional) pointer to a function checking arg sanity
+ *
+ * Append an argument pair to a dynevent_cmd.  An argument pair
+ * consists of a left-hand-side argument and a right-hand-side
+ * argument separated by an operator, which can be whitespace, all
+ * followed by a separator, if applicable.  This can be used to add
+ * arguments of the form 'type variable_name;' or 'x+y'.
+ *
+ * The lhs argument string will be appended to the current cmd string,
+ * followed by an operator, if applicable, followd by the rhs string,
+ * followed finally by a separator, if applicable.  Before the
+ * argument is added, the @check_arg function, if present, will be
+ * used to check the sanity of the current arg strings.
+ *
+ * The cmd strings, operator, and separator should be set using the
+ * dynevent_arg_pair_init() before any arguments are added using this
+ * function.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int dynevent_arg_pair_add(struct dynevent_cmd *cmd,
+                         struct dynevent_arg_pair *arg_pair,
+                         dynevent_check_arg_fn_t check_arg)
+{
+       int ret = 0;
+
+       if (check_arg) {
+               ret = check_arg(arg_pair);
+               if (ret)
+                       return ret;
+       }
+
+       ret = seq_buf_printf(&cmd->seq, " %s%c%s%c", arg_pair->lhs,
+                            arg_pair->operator, arg_pair->rhs,
+                            arg_pair->separator);
+       if (ret) {
+               pr_err("field string is too long: %s%c%s%c\n", arg_pair->lhs,
+                      arg_pair->operator, arg_pair->rhs,
+                      arg_pair->separator);
+               return -E2BIG;
+       }
+
+       return ret;
+}
+
+/**
+ * dynevent_str_add - Add a string to a dynevent_cmd
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event cmd
+ * @str: The string to append to the current cmd
+ *
+ * Append a string to a dynevent_cmd.  The string will be appended to
+ * the current cmd string as-is, with nothing prepended or appended.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int dynevent_str_add(struct dynevent_cmd *cmd, const char *str)
+{
+       int ret = 0;
+
+       ret = seq_buf_puts(&cmd->seq, str);
+       if (ret) {
+               pr_err("String is too long: %s\n", str);
+               return -E2BIG;
+       }
+
+       return ret;
+}
+
+/**
+ * dynevent_cmd_init - Initialize a dynevent_cmd object
+ * @cmd: A pointer to the dynevent_cmd struct representing the cmd
+ * @buf: A pointer to the buffer to generate the command into
+ * @maxlen: The length of the buffer the command will be generated into
+ * @type: The type of the cmd, checked against further operations
+ * @run_command: The type-specific function that will actually run the command
+ *
+ * Initialize a dynevent_cmd.  A dynevent_cmd is used to build up and
+ * run dynamic event creation commands, such as commands for creating
+ * synthetic and kprobe events.  Before calling any of the functions
+ * used to build the command, a dynevent_cmd object should be
+ * instantiated and initialized using this function.
+ *
+ * The initialization sets things up by saving a pointer to the
+ * user-supplied buffer and its length via the @buf and @maxlen
+ * params, and by saving the cmd-specific @type and @run_command
+ * params which are used to check subsequent dynevent_cmd operations
+ * and actually run the command when complete.
+ */
+void dynevent_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen,
+                      enum dynevent_type type,
+                      dynevent_create_fn_t run_command)
+{
+       memset(cmd, '\0', sizeof(*cmd));
+
+       seq_buf_init(&cmd->seq, buf, maxlen);
+       cmd->type = type;
+       cmd->run_command = run_command;
+}
+
+/**
+ * dynevent_arg_init - Initialize a dynevent_arg object
+ * @arg: A pointer to the dynevent_arg struct representing the arg
+ * @separator: An (optional) separator, appended after adding the arg
+ *
+ * Initialize a dynevent_arg object.  A dynevent_arg represents an
+ * object used to append single arguments to the current command
+ * string.  After the arg string is successfully appended to the
+ * command string, the optional @separator is appended.  If no
+ * separator was specified when initializing the arg, a space will be
+ * appended.
+ */
+void dynevent_arg_init(struct dynevent_arg *arg,
+                      char separator)
+{
+       memset(arg, '\0', sizeof(*arg));
+
+       if (!separator)
+               separator = ' ';
+       arg->separator = separator;
+}
+
+/**
+ * dynevent_arg_pair_init - Initialize a dynevent_arg_pair object
+ * @arg_pair: A pointer to the dynevent_arg_pair struct representing the arg
+ * @operator: An (optional) operator, appended after adding the first arg
+ * @separator: An (optional) separator, appended after adding the second arg
+ *
+ * Initialize a dynevent_arg_pair object.  A dynevent_arg_pair
+ * represents an object used to append argument pairs such as 'type
+ * variable_name;' or 'x+y' to the current command string.  An
+ * argument pair consists of a left-hand-side argument and a
+ * right-hand-side argument separated by an operator, which can be
+ * whitespace, all followed by a separator, if applicable.  After the
+ * first arg string is successfully appended to the command string,
+ * the optional @operator is appended, followed by the second arg and
+ * and optional @separator.  If no separator was specified when
+ * initializing the arg, a space will be appended.
+ */
+void dynevent_arg_pair_init(struct dynevent_arg_pair *arg_pair,
+                           char operator, char separator)
+{
+       memset(arg_pair, '\0', sizeof(*arg_pair));
+
+       if (!operator)
+               operator = ' ';
+       arg_pair->operator = operator;
+
+       if (!separator)
+               separator = ' ';
+       arg_pair->separator = separator;
+}
+
+/**
+ * dynevent_create - Create the dynamic event contained in dynevent_cmd
+ * @cmd: The dynevent_cmd object containing the dynamic event creation command
+ *
+ * Once a dynevent_cmd object has been successfully built up via the
+ * dynevent_cmd_init(), dynevent_arg_add() and dynevent_arg_pair_add()
+ * functions, this function runs the final command to actually create
+ * the event.
+ *
+ * Return: 0 if the event was successfully created, error otherwise.
+ */
+int dynevent_create(struct dynevent_cmd *cmd)
+{
+       return cmd->run_command(cmd);
+}
+EXPORT_SYMBOL_GPL(dynevent_create);
index 4689813..d6857a2 100644 (file)
@@ -117,4 +117,36 @@ int dyn_event_release(int argc, char **argv, struct dyn_event_operations *type);
 #define for_each_dyn_event_safe(pos, n)        \
        list_for_each_entry_safe(pos, n, &dyn_event_list, list)
 
+extern void dynevent_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen,
+                             enum dynevent_type type,
+                             dynevent_create_fn_t run_command);
+
+typedef int (*dynevent_check_arg_fn_t)(void *data);
+
+struct dynevent_arg {
+       const char              *str;
+       char                    separator; /* e.g. ';', ',', or nothing */
+};
+
+extern void dynevent_arg_init(struct dynevent_arg *arg,
+                             char separator);
+extern int dynevent_arg_add(struct dynevent_cmd *cmd,
+                           struct dynevent_arg *arg,
+                           dynevent_check_arg_fn_t check_arg);
+
+struct dynevent_arg_pair {
+       const char              *lhs;
+       const char              *rhs;
+       char                    operator; /* e.g. '=' or nothing */
+       char                    separator; /* e.g. ';', ',', or nothing */
+};
+
+extern void dynevent_arg_pair_init(struct dynevent_arg_pair *arg_pair,
+                                  char operator, char separator);
+
+extern int dynevent_arg_pair_add(struct dynevent_cmd *cmd,
+                                struct dynevent_arg_pair *arg_pair,
+                                dynevent_check_arg_fn_t check_arg);
+extern int dynevent_str_add(struct dynevent_cmd *cmd, const char *str);
+
 #endif
index 3e9d816..f22746f 100644 (file)
@@ -164,7 +164,7 @@ FTRACE_ENTRY(kernel_stack, stack_entry,
 
        F_STRUCT(
                __field(        int,            size    )
-               __dynamic_array(unsigned long,  caller  )
+               __array(        unsigned long,  caller, FTRACE_STACK_ENTRIES    )
        ),
 
        F_printk("\t=> %ps\n\t=> %ps\n\t=> %ps\n"
index c8622a4..f38234e 100644 (file)
@@ -238,7 +238,7 @@ bool trace_event_ignore_this_pid(struct trace_event_file *trace_file)
        if (!pid_list)
                return false;
 
-       data = this_cpu_ptr(tr->trace_buffer.data);
+       data = this_cpu_ptr(tr->array_buffer.data);
 
        return data->ignore_pid;
 }
@@ -273,6 +273,7 @@ void *trace_event_buffer_reserve(struct trace_event_buffer *fbuffer,
        if (!fbuffer->event)
                return NULL;
 
+       fbuffer->regs = NULL;
        fbuffer->entry = ring_buffer_event_data(fbuffer->event);
        return fbuffer->entry;
 }
@@ -547,7 +548,7 @@ event_filter_pid_sched_switch_probe_pre(void *data, bool preempt,
 
        pid_list = rcu_dereference_sched(tr->filtered_pids);
 
-       this_cpu_write(tr->trace_buffer.data->ignore_pid,
+       this_cpu_write(tr->array_buffer.data->ignore_pid,
                       trace_ignore_this_task(pid_list, prev) &&
                       trace_ignore_this_task(pid_list, next));
 }
@@ -561,7 +562,7 @@ event_filter_pid_sched_switch_probe_post(void *data, bool preempt,
 
        pid_list = rcu_dereference_sched(tr->filtered_pids);
 
-       this_cpu_write(tr->trace_buffer.data->ignore_pid,
+       this_cpu_write(tr->array_buffer.data->ignore_pid,
                       trace_ignore_this_task(pid_list, next));
 }
 
@@ -572,12 +573,12 @@ event_filter_pid_sched_wakeup_probe_pre(void *data, struct task_struct *task)
        struct trace_pid_list *pid_list;
 
        /* Nothing to do if we are already tracing */
-       if (!this_cpu_read(tr->trace_buffer.data->ignore_pid))
+       if (!this_cpu_read(tr->array_buffer.data->ignore_pid))
                return;
 
        pid_list = rcu_dereference_sched(tr->filtered_pids);
 
-       this_cpu_write(tr->trace_buffer.data->ignore_pid,
+       this_cpu_write(tr->array_buffer.data->ignore_pid,
                       trace_ignore_this_task(pid_list, task));
 }
 
@@ -588,13 +589,13 @@ event_filter_pid_sched_wakeup_probe_post(void *data, struct task_struct *task)
        struct trace_pid_list *pid_list;
 
        /* Nothing to do if we are not tracing */
-       if (this_cpu_read(tr->trace_buffer.data->ignore_pid))
+       if (this_cpu_read(tr->array_buffer.data->ignore_pid))
                return;
 
        pid_list = rcu_dereference_sched(tr->filtered_pids);
 
        /* Set tracing if current is enabled */
-       this_cpu_write(tr->trace_buffer.data->ignore_pid,
+       this_cpu_write(tr->array_buffer.data->ignore_pid,
                       trace_ignore_this_task(pid_list, current));
 }
 
@@ -626,7 +627,7 @@ static void __ftrace_clear_event_pids(struct trace_array *tr)
        }
 
        for_each_possible_cpu(cpu)
-               per_cpu_ptr(tr->trace_buffer.data, cpu)->ignore_pid = false;
+               per_cpu_ptr(tr->array_buffer.data, cpu)->ignore_pid = false;
 
        rcu_assign_pointer(tr->filtered_pids, NULL);
 
@@ -698,7 +699,7 @@ static void remove_subsystem(struct trace_subsystem_dir *dir)
                return;
 
        if (!--dir->nr_events) {
-               tracefs_remove_recursive(dir->entry);
+               tracefs_remove(dir->entry);
                list_del(&dir->list);
                __put_system_dir(dir);
        }
@@ -717,7 +718,7 @@ static void remove_event_file_dir(struct trace_event_file *file)
                }
                spin_unlock(&dir->d_lock);
 
-               tracefs_remove_recursive(dir);
+               tracefs_remove(dir);
        }
 
        list_del(&file->list);
@@ -1595,7 +1596,7 @@ static void ignore_task_cpu(void *data)
        pid_list = rcu_dereference_protected(tr->filtered_pids,
                                             mutex_is_locked(&event_mutex));
 
-       this_cpu_write(tr->trace_buffer.data->ignore_pid,
+       this_cpu_write(tr->array_buffer.data->ignore_pid,
                       trace_ignore_this_task(pid_list, current));
 }
 
@@ -2553,6 +2554,91 @@ find_event_file(struct trace_array *tr, const char *system, const char *event)
        return file;
 }
 
+/**
+ * trace_get_event_file - Find and return a trace event file
+ * @instance: The name of the trace instance containing the event
+ * @system: The name of the system containing the event
+ * @event: The name of the event
+ *
+ * Return a trace event file given the trace instance name, trace
+ * system, and trace event name.  If the instance name is NULL, it
+ * refers to the top-level trace array.
+ *
+ * This function will look it up and return it if found, after calling
+ * trace_array_get() to prevent the instance from going away, and
+ * increment the event's module refcount to prevent it from being
+ * removed.
+ *
+ * To release the file, call trace_put_event_file(), which will call
+ * trace_array_put() and decrement the event's module refcount.
+ *
+ * Return: The trace event on success, ERR_PTR otherwise.
+ */
+struct trace_event_file *trace_get_event_file(const char *instance,
+                                             const char *system,
+                                             const char *event)
+{
+       struct trace_array *tr = top_trace_array();
+       struct trace_event_file *file = NULL;
+       int ret = -EINVAL;
+
+       if (instance) {
+               tr = trace_array_find_get(instance);
+               if (!tr)
+                       return ERR_PTR(-ENOENT);
+       } else {
+               ret = trace_array_get(tr);
+               if (ret)
+                       return ERR_PTR(ret);
+       }
+
+       mutex_lock(&event_mutex);
+
+       file = find_event_file(tr, system, event);
+       if (!file) {
+               trace_array_put(tr);
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* Don't let event modules unload while in use */
+       ret = try_module_get(file->event_call->mod);
+       if (!ret) {
+               trace_array_put(tr);
+               ret = -EBUSY;
+               goto out;
+       }
+
+       ret = 0;
+ out:
+       mutex_unlock(&event_mutex);
+
+       if (ret)
+               file = ERR_PTR(ret);
+
+       return file;
+}
+EXPORT_SYMBOL_GPL(trace_get_event_file);
+
+/**
+ * trace_put_event_file - Release a file from trace_get_event_file()
+ * @file: The trace event file
+ *
+ * If a file was retrieved using trace_get_event_file(), this should
+ * be called when it's no longer needed.  It will cancel the previous
+ * trace_array_get() called by that function, and decrement the
+ * event's module refcount.
+ */
+void trace_put_event_file(struct trace_event_file *file)
+{
+       mutex_lock(&event_mutex);
+       module_put(file->event_call->mod);
+       mutex_unlock(&event_mutex);
+
+       trace_array_put(file->tr);
+}
+EXPORT_SYMBOL_GPL(trace_put_event_file);
+
 #ifdef CONFIG_DYNAMIC_FTRACE
 
 /* Avoid typos */
@@ -3082,7 +3168,7 @@ int event_trace_del_tracer(struct trace_array *tr)
 
        down_write(&trace_event_sem);
        __trace_remove_event_dirs(tr);
-       tracefs_remove_recursive(tr->event_dir);
+       tracefs_remove(tr->event_dir);
        up_write(&trace_event_sem);
 
        tr->event_dir = NULL;
@@ -3409,8 +3495,8 @@ static void __init
 function_test_events_call(unsigned long ip, unsigned long parent_ip,
                          struct ftrace_ops *op, struct pt_regs *pt_regs)
 {
+       struct trace_buffer *buffer;
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
        struct ftrace_entry *entry;
        unsigned long flags;
        long disabled;
index f2896d1..e7ce7cd 100644 (file)
        C(INVALID_SUBSYS_EVENT, "Invalid subsystem or event name"),     \
        C(INVALID_REF_KEY,      "Using variable references in keys not supported"), \
        C(VAR_NOT_FOUND,        "Couldn't find variable"),              \
-       C(FIELD_NOT_FOUND,      "Couldn't find field"),
+       C(FIELD_NOT_FOUND,      "Couldn't find field"),                 \
+       C(EMPTY_ASSIGNMENT,     "Empty assignment"),                    \
+       C(INVALID_SORT_MODIFIER,"Invalid sort modifier"),               \
+       C(EMPTY_SORT_FIELD,     "Empty sort field"),                    \
+       C(TOO_MANY_SORT_FIELDS, "Too many sort fields (Max = 2)"),      \
+       C(INVALID_SORT_FIELD,   "Sort field must be a key or a val"),
 
 #undef C
 #define C(a, b)                HIST_ERR_##a
@@ -375,7 +380,7 @@ struct hist_trigger_data {
        unsigned int                    n_save_var_str;
 };
 
-static int synth_event_create(int argc, const char **argv);
+static int create_synth_event(int argc, const char **argv);
 static int synth_event_show(struct seq_file *m, struct dyn_event *ev);
 static int synth_event_release(struct dyn_event *ev);
 static bool synth_event_is_busy(struct dyn_event *ev);
@@ -383,7 +388,7 @@ static bool synth_event_match(const char *system, const char *event,
                        int argc, const char **argv, struct dyn_event *ev);
 
 static struct dyn_event_operations synth_event_ops = {
-       .create = synth_event_create,
+       .create = create_synth_event,
        .show = synth_event_show,
        .is_busy = synth_event_is_busy,
        .free = synth_event_release,
@@ -394,6 +399,7 @@ struct synth_field {
        char *type;
        char *name;
        size_t size;
+       unsigned int offset;
        bool is_signed;
        bool is_string;
 };
@@ -408,6 +414,7 @@ struct synth_event {
        struct trace_event_class                class;
        struct trace_event_call                 call;
        struct tracepoint                       *tp;
+       struct module                           *mod;
 };
 
 static bool is_synth_event(struct dyn_event *ev)
@@ -470,11 +477,12 @@ struct action_data {
         * When a histogram trigger is hit, the values of any
         * references to variables, including variables being passed
         * as parameters to synthetic events, are collected into a
-        * var_ref_vals array.  This var_ref_idx is the index of the
-        * first param in the array to be passed to the synthetic
-        * event invocation.
+        * var_ref_vals array.  This var_ref_idx array is an array of
+        * indices into the var_ref_vals array, one for each synthetic
+        * event param, and is passed to the synthetic event
+        * invocation.
         */
-       unsigned int            var_ref_idx;
+       unsigned int            var_ref_idx[TRACING_MAP_VARS_MAX];
        struct synth_event      *synth_event;
        bool                    use_trace_keyword;
        char                    *synth_event_name;
@@ -608,7 +616,8 @@ static void last_cmd_set(struct trace_event_file *file, char *str)
        if (!str)
                return;
 
-       strncpy(last_cmd, str, MAX_FILTER_STR_VAL - 1);
+       strcpy(last_cmd, "hist:");
+       strncat(last_cmd, str, MAX_FILTER_STR_VAL - 1 - sizeof("hist:"));
 
        if (file) {
                call = file->event_call;
@@ -662,6 +671,8 @@ static int synth_event_define_fields(struct trace_event_call *call)
                if (ret)
                        break;
 
+               event->fields[i]->offset = n_u64;
+
                if (event->fields[i]->is_string) {
                        offset += STR_VAR_LEN_MAX;
                        n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
@@ -834,7 +845,7 @@ static enum print_line_t print_synth_event(struct trace_iterator *iter,
                fmt = synth_field_fmt(se->fields[i]->type);
 
                /* parameter types */
-               if (tr->trace_flags & TRACE_ITER_VERBOSE)
+               if (tr && tr->trace_flags & TRACE_ITER_VERBOSE)
                        trace_seq_printf(s, "%s ", fmt);
 
                snprintf(print_fmt, sizeof(print_fmt), "%%s=%s%%s", fmt);
@@ -875,14 +886,14 @@ static struct trace_event_functions synth_event_funcs = {
 
 static notrace void trace_event_raw_event_synth(void *__data,
                                                u64 *var_ref_vals,
-                                               unsigned int var_ref_idx)
+                                               unsigned int *var_ref_idx)
 {
        struct trace_event_file *trace_file = __data;
        struct synth_trace_event *entry;
        struct trace_event_buffer fbuffer;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        struct synth_event *event;
-       unsigned int i, n_u64;
+       unsigned int i, n_u64, val_idx;
        int fields_size = 0;
 
        event = trace_file->event_call->data;
@@ -896,7 +907,7 @@ static notrace void trace_event_raw_event_synth(void *__data,
         * Avoid ring buffer recursion detection, as this event
         * is being performed within another event.
         */
-       buffer = trace_file->tr->trace_buffer.buffer;
+       buffer = trace_file->tr->array_buffer.buffer;
        ring_buffer_nest_start(buffer);
 
        entry = trace_event_buffer_reserve(&fbuffer, trace_file,
@@ -905,15 +916,16 @@ static notrace void trace_event_raw_event_synth(void *__data,
                goto out;
 
        for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
+               val_idx = var_ref_idx[i];
                if (event->fields[i]->is_string) {
-                       char *str_val = (char *)(long)var_ref_vals[var_ref_idx + i];
+                       char *str_val = (char *)(long)var_ref_vals[val_idx];
                        char *str_field = (char *)&entry->fields[n_u64];
 
                        strscpy(str_field, str_val, STR_VAR_LEN_MAX);
                        n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
                } else {
                        struct synth_field *field = event->fields[i];
-                       u64 val = var_ref_vals[var_ref_idx + i];
+                       u64 val = var_ref_vals[val_idx];
 
                        switch (field->size) {
                        case 1:
@@ -1113,10 +1125,10 @@ static struct tracepoint *alloc_synth_tracepoint(char *name)
 }
 
 typedef void (*synth_probe_func_t) (void *__data, u64 *var_ref_vals,
-                                   unsigned int var_ref_idx);
+                                   unsigned int *var_ref_idx);
 
 static inline void trace_synth(struct synth_event *event, u64 *var_ref_vals,
-                              unsigned int var_ref_idx)
+                              unsigned int *var_ref_idx)
 {
        struct tracepoint *tp = event->tp;
 
@@ -1293,6 +1305,273 @@ struct hist_var_data {
        struct hist_trigger_data *hist_data;
 };
 
+static int synth_event_check_arg_fn(void *data)
+{
+       struct dynevent_arg_pair *arg_pair = data;
+       int size;
+
+       size = synth_field_size((char *)arg_pair->lhs);
+
+       return size ? 0 : -EINVAL;
+}
+
+/**
+ * synth_event_add_field - Add a new field to a synthetic event cmd
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @type: The type of the new field to add
+ * @name: The name of the new field to add
+ *
+ * Add a new field to a synthetic event cmd object.  Field ordering is in
+ * the same order the fields are added.
+ *
+ * See synth_field_size() for available types. If field_name contains
+ * [n] the field is considered to be an array.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int synth_event_add_field(struct dynevent_cmd *cmd, const char *type,
+                         const char *name)
+{
+       struct dynevent_arg_pair arg_pair;
+       int ret;
+
+       if (cmd->type != DYNEVENT_TYPE_SYNTH)
+               return -EINVAL;
+
+       if (!type || !name)
+               return -EINVAL;
+
+       dynevent_arg_pair_init(&arg_pair, 0, ';');
+
+       arg_pair.lhs = type;
+       arg_pair.rhs = name;
+
+       ret = dynevent_arg_pair_add(cmd, &arg_pair, synth_event_check_arg_fn);
+       if (ret)
+               return ret;
+
+       if (++cmd->n_fields > SYNTH_FIELDS_MAX)
+               ret = -EINVAL;
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_add_field);
+
+/**
+ * synth_event_add_field_str - Add a new field to a synthetic event cmd
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @type_name: The type and name of the new field to add, as a single string
+ *
+ * Add a new field to a synthetic event cmd object, as a single
+ * string.  The @type_name string is expected to be of the form 'type
+ * name', which will be appended by ';'.  No sanity checking is done -
+ * what's passed in is assumed to already be well-formed.  Field
+ * ordering is in the same order the fields are added.
+ *
+ * See synth_field_size() for available types. If field_name contains
+ * [n] the field is considered to be an array.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int synth_event_add_field_str(struct dynevent_cmd *cmd, const char *type_name)
+{
+       struct dynevent_arg arg;
+       int ret;
+
+       if (cmd->type != DYNEVENT_TYPE_SYNTH)
+               return -EINVAL;
+
+       if (!type_name)
+               return -EINVAL;
+
+       dynevent_arg_init(&arg, ';');
+
+       arg.str = type_name;
+
+       ret = dynevent_arg_add(cmd, &arg, NULL);
+       if (ret)
+               return ret;
+
+       if (++cmd->n_fields > SYNTH_FIELDS_MAX)
+               ret = -EINVAL;
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_add_field_str);
+
+/**
+ * synth_event_add_fields - Add multiple fields to a synthetic event cmd
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @fields: An array of type/name field descriptions
+ * @n_fields: The number of field descriptions contained in the fields array
+ *
+ * Add a new set of fields to a synthetic event cmd object.  The event
+ * fields that will be defined for the event should be passed in as an
+ * array of struct synth_field_desc, and the number of elements in the
+ * array passed in as n_fields.  Field ordering will retain the
+ * ordering given in the fields array.
+ *
+ * See synth_field_size() for available types. If field_name contains
+ * [n] the field is considered to be an array.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int synth_event_add_fields(struct dynevent_cmd *cmd,
+                          struct synth_field_desc *fields,
+                          unsigned int n_fields)
+{
+       unsigned int i;
+       int ret = 0;
+
+       for (i = 0; i < n_fields; i++) {
+               if (fields[i].type == NULL || fields[i].name == NULL) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               ret = synth_event_add_field(cmd, fields[i].type, fields[i].name);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_add_fields);
+
+/**
+ * __synth_event_gen_cmd_start - Start a synthetic event command from arg list
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @name: The name of the synthetic event
+ * @mod: The module creating the event, NULL if not created from a module
+ * @args: Variable number of arg (pairs), one pair for each field
+ *
+ * NOTE: Users normally won't want to call this function directly, but
+ * rather use the synth_event_gen_cmd_start() wrapper, which
+ * automatically adds a NULL to the end of the arg list.  If this
+ * function is used directly, make sure the last arg in the variable
+ * arg list is NULL.
+ *
+ * Generate a synthetic event command to be executed by
+ * synth_event_gen_cmd_end().  This function can be used to generate
+ * the complete command or only the first part of it; in the latter
+ * case, synth_event_add_field(), synth_event_add_field_str(), or
+ * synth_event_add_fields() can be used to add more fields following
+ * this.
+ *
+ * There should be an even number variable args, each pair consisting
+ * of a type followed by a field name.
+ *
+ * See synth_field_size() for available types. If field_name contains
+ * [n] the field is considered to be an array.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int __synth_event_gen_cmd_start(struct dynevent_cmd *cmd, const char *name,
+                               struct module *mod, ...)
+{
+       struct dynevent_arg arg;
+       va_list args;
+       int ret;
+
+       cmd->event_name = name;
+       cmd->private_data = mod;
+
+       if (cmd->type != DYNEVENT_TYPE_SYNTH)
+               return -EINVAL;
+
+       dynevent_arg_init(&arg, 0);
+       arg.str = name;
+       ret = dynevent_arg_add(cmd, &arg, NULL);
+       if (ret)
+               return ret;
+
+       va_start(args, mod);
+       for (;;) {
+               const char *type, *name;
+
+               type = va_arg(args, const char *);
+               if (!type)
+                       break;
+               name = va_arg(args, const char *);
+               if (!name)
+                       break;
+
+               if (++cmd->n_fields > SYNTH_FIELDS_MAX) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               ret = synth_event_add_field(cmd, type, name);
+               if (ret)
+                       break;
+       }
+       va_end(args);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__synth_event_gen_cmd_start);
+
+/**
+ * synth_event_gen_cmd_array_start - Start synthetic event command from an array
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @name: The name of the synthetic event
+ * @fields: An array of type/name field descriptions
+ * @n_fields: The number of field descriptions contained in the fields array
+ *
+ * Generate a synthetic event command to be executed by
+ * synth_event_gen_cmd_end().  This function can be used to generate
+ * the complete command or only the first part of it; in the latter
+ * case, synth_event_add_field(), synth_event_add_field_str(), or
+ * synth_event_add_fields() can be used to add more fields following
+ * this.
+ *
+ * The event fields that will be defined for the event should be
+ * passed in as an array of struct synth_field_desc, and the number of
+ * elements in the array passed in as n_fields.  Field ordering will
+ * retain the ordering given in the fields array.
+ *
+ * See synth_field_size() for available types. If field_name contains
+ * [n] the field is considered to be an array.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int synth_event_gen_cmd_array_start(struct dynevent_cmd *cmd, const char *name,
+                                   struct module *mod,
+                                   struct synth_field_desc *fields,
+                                   unsigned int n_fields)
+{
+       struct dynevent_arg arg;
+       unsigned int i;
+       int ret = 0;
+
+       cmd->event_name = name;
+       cmd->private_data = mod;
+
+       if (cmd->type != DYNEVENT_TYPE_SYNTH)
+               return -EINVAL;
+
+       if (n_fields > SYNTH_FIELDS_MAX)
+               return -EINVAL;
+
+       dynevent_arg_init(&arg, 0);
+       arg.str = name;
+       ret = dynevent_arg_add(cmd, &arg, NULL);
+       if (ret)
+               return ret;
+
+       for (i = 0; i < n_fields; i++) {
+               if (fields[i].type == NULL || fields[i].name == NULL)
+                       return -EINVAL;
+
+               ret = synth_event_add_field(cmd, fields[i].type, fields[i].name);
+               if (ret)
+                       break;
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_gen_cmd_array_start);
+
 static int __create_synth_event(int argc, const char *name, const char **argv)
 {
        struct synth_field *field, *fields[SYNTH_FIELDS_MAX];
@@ -1361,29 +1640,123 @@ static int __create_synth_event(int argc, const char *name, const char **argv)
        goto out;
 }
 
+/**
+ * synth_event_create - Create a new synthetic event
+ * @name: The name of the new sythetic event
+ * @fields: An array of type/name field descriptions
+ * @n_fields: The number of field descriptions contained in the fields array
+ * @mod: The module creating the event, NULL if not created from a module
+ *
+ * Create a new synthetic event with the given name under the
+ * trace/events/synthetic/ directory.  The event fields that will be
+ * defined for the event should be passed in as an array of struct
+ * synth_field_desc, and the number elements in the array passed in as
+ * n_fields. Field ordering will retain the ordering given in the
+ * fields array.
+ *
+ * If the new synthetic event is being created from a module, the mod
+ * param must be non-NULL.  This will ensure that the trace buffer
+ * won't contain unreadable events.
+ *
+ * The new synth event should be deleted using synth_event_delete()
+ * function.  The new synthetic event can be generated from modules or
+ * other kernel code using trace_synth_event() and related functions.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int synth_event_create(const char *name, struct synth_field_desc *fields,
+                      unsigned int n_fields, struct module *mod)
+{
+       struct dynevent_cmd cmd;
+       char *buf;
+       int ret;
+
+       buf = kzalloc(MAX_DYNEVENT_CMD_LEN, GFP_KERNEL);
+       if (!buf)
+               return -ENOMEM;
+
+       synth_event_cmd_init(&cmd, buf, MAX_DYNEVENT_CMD_LEN);
+
+       ret = synth_event_gen_cmd_array_start(&cmd, name, mod,
+                                             fields, n_fields);
+       if (ret)
+               goto out;
+
+       ret = synth_event_gen_cmd_end(&cmd);
+ out:
+       kfree(buf);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_create);
+
+static int destroy_synth_event(struct synth_event *se)
+{
+       int ret;
+
+       if (se->ref)
+               ret = -EBUSY;
+       else {
+               ret = unregister_synth_event(se);
+               if (!ret) {
+                       dyn_event_remove(&se->devent);
+                       free_synth_event(se);
+               }
+       }
+
+       return ret;
+}
+
+/**
+ * synth_event_delete - Delete a synthetic event
+ * @event_name: The name of the new sythetic event
+ *
+ * Delete a synthetic event that was created with synth_event_create().
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int synth_event_delete(const char *event_name)
+{
+       struct synth_event *se = NULL;
+       struct module *mod = NULL;
+       int ret = -ENOENT;
+
+       mutex_lock(&event_mutex);
+       se = find_synth_event(event_name);
+       if (se) {
+               mod = se->mod;
+               ret = destroy_synth_event(se);
+       }
+       mutex_unlock(&event_mutex);
+
+       if (mod) {
+               mutex_lock(&trace_types_lock);
+               /*
+                * It is safest to reset the ring buffer if the module
+                * being unloaded registered any events that were
+                * used. The only worry is if a new module gets
+                * loaded, and takes on the same id as the events of
+                * this module. When printing out the buffer, traced
+                * events left over from this module may be passed to
+                * the new module events and unexpected results may
+                * occur.
+                */
+               tracing_reset_all_online_cpus();
+               mutex_unlock(&trace_types_lock);
+       }
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_delete);
+
 static int create_or_delete_synth_event(int argc, char **argv)
 {
        const char *name = argv[0];
-       struct synth_event *event = NULL;
        int ret;
 
        /* trace_run_command() ensures argc != 0 */
        if (name[0] == '!') {
-               mutex_lock(&event_mutex);
-               event = find_synth_event(name + 1);
-               if (event) {
-                       if (event->ref)
-                               ret = -EBUSY;
-                       else {
-                               ret = unregister_synth_event(event);
-                               if (!ret) {
-                                       dyn_event_remove(&event->devent);
-                                       free_synth_event(event);
-                               }
-                       }
-               } else
-                       ret = -ENOENT;
-               mutex_unlock(&event_mutex);
+               ret = synth_event_delete(name + 1);
                return ret;
        }
 
@@ -1391,7 +1764,474 @@ static int create_or_delete_synth_event(int argc, char **argv)
        return ret == -ECANCELED ? -EINVAL : ret;
 }
 
-static int synth_event_create(int argc, const char **argv)
+static int synth_event_run_command(struct dynevent_cmd *cmd)
+{
+       struct synth_event *se;
+       int ret;
+
+       ret = trace_run_command(cmd->seq.buffer, create_or_delete_synth_event);
+       if (ret)
+               return ret;
+
+       se = find_synth_event(cmd->event_name);
+       if (WARN_ON(!se))
+               return -ENOENT;
+
+       se->mod = cmd->private_data;
+
+       return ret;
+}
+
+/**
+ * synth_event_cmd_init - Initialize a synthetic event command object
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @buf: A pointer to the buffer used to build the command
+ * @maxlen: The length of the buffer passed in @buf
+ *
+ * Initialize a synthetic event command object.  Use this before
+ * calling any of the other dyenvent_cmd functions.
+ */
+void synth_event_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen)
+{
+       dynevent_cmd_init(cmd, buf, maxlen, DYNEVENT_TYPE_SYNTH,
+                         synth_event_run_command);
+}
+EXPORT_SYMBOL_GPL(synth_event_cmd_init);
+
+/**
+ * synth_event_trace - Trace a synthetic event
+ * @file: The trace_event_file representing the synthetic event
+ * @n_vals: The number of values in vals
+ * @args: Variable number of args containing the event values
+ *
+ * Trace a synthetic event using the values passed in the variable
+ * argument list.
+ *
+ * The argument list should be a list 'n_vals' u64 values.  The number
+ * of vals must match the number of field in the synthetic event, and
+ * must be in the same order as the synthetic event fields.
+ *
+ * All vals should be cast to u64, and string vals are just pointers
+ * to strings, cast to u64.  Strings will be copied into space
+ * reserved in the event for the string, using these pointers.
+ *
+ * Return: 0 on success, err otherwise.
+ */
+int synth_event_trace(struct trace_event_file *file, unsigned int n_vals, ...)
+{
+       struct trace_event_buffer fbuffer;
+       struct synth_trace_event *entry;
+       struct trace_buffer *buffer;
+       struct synth_event *event;
+       unsigned int i, n_u64;
+       int fields_size = 0;
+       va_list args;
+       int ret = 0;
+
+       /*
+        * Normal event generation doesn't get called at all unless
+        * the ENABLED bit is set (which attaches the probe thus
+        * allowing this code to be called, etc).  Because this is
+        * called directly by the user, we don't have that but we
+        * still need to honor not logging when disabled.
+        */
+       if (!(file->flags & EVENT_FILE_FL_ENABLED))
+               return 0;
+
+       event = file->event_call->data;
+
+       if (n_vals != event->n_fields)
+               return -EINVAL;
+
+       if (trace_trigger_soft_disabled(file))
+               return -EINVAL;
+
+       fields_size = event->n_u64 * sizeof(u64);
+
+       /*
+        * Avoid ring buffer recursion detection, as this event
+        * is being performed within another event.
+        */
+       buffer = file->tr->array_buffer.buffer;
+       ring_buffer_nest_start(buffer);
+
+       entry = trace_event_buffer_reserve(&fbuffer, file,
+                                          sizeof(*entry) + fields_size);
+       if (!entry) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       va_start(args, n_vals);
+       for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
+               u64 val;
+
+               val = va_arg(args, u64);
+
+               if (event->fields[i]->is_string) {
+                       char *str_val = (char *)(long)val;
+                       char *str_field = (char *)&entry->fields[n_u64];
+
+                       strscpy(str_field, str_val, STR_VAR_LEN_MAX);
+                       n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
+               } else {
+                       entry->fields[n_u64] = val;
+                       n_u64++;
+               }
+       }
+       va_end(args);
+
+       trace_event_buffer_commit(&fbuffer);
+out:
+       ring_buffer_nest_end(buffer);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_trace);
+
+/**
+ * synth_event_trace_array - Trace a synthetic event from an array
+ * @file: The trace_event_file representing the synthetic event
+ * @vals: Array of values
+ * @n_vals: The number of values in vals
+ *
+ * Trace a synthetic event using the values passed in as 'vals'.
+ *
+ * The 'vals' array is just an array of 'n_vals' u64.  The number of
+ * vals must match the number of field in the synthetic event, and
+ * must be in the same order as the synthetic event fields.
+ *
+ * All vals should be cast to u64, and string vals are just pointers
+ * to strings, cast to u64.  Strings will be copied into space
+ * reserved in the event for the string, using these pointers.
+ *
+ * Return: 0 on success, err otherwise.
+ */
+int synth_event_trace_array(struct trace_event_file *file, u64 *vals,
+                           unsigned int n_vals)
+{
+       struct trace_event_buffer fbuffer;
+       struct synth_trace_event *entry;
+       struct trace_buffer *buffer;
+       struct synth_event *event;
+       unsigned int i, n_u64;
+       int fields_size = 0;
+       int ret = 0;
+
+       /*
+        * Normal event generation doesn't get called at all unless
+        * the ENABLED bit is set (which attaches the probe thus
+        * allowing this code to be called, etc).  Because this is
+        * called directly by the user, we don't have that but we
+        * still need to honor not logging when disabled.
+        */
+       if (!(file->flags & EVENT_FILE_FL_ENABLED))
+               return 0;
+
+       event = file->event_call->data;
+
+       if (n_vals != event->n_fields)
+               return -EINVAL;
+
+       if (trace_trigger_soft_disabled(file))
+               return -EINVAL;
+
+       fields_size = event->n_u64 * sizeof(u64);
+
+       /*
+        * Avoid ring buffer recursion detection, as this event
+        * is being performed within another event.
+        */
+       buffer = file->tr->array_buffer.buffer;
+       ring_buffer_nest_start(buffer);
+
+       entry = trace_event_buffer_reserve(&fbuffer, file,
+                                          sizeof(*entry) + fields_size);
+       if (!entry) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       for (i = 0, n_u64 = 0; i < event->n_fields; i++) {
+               if (event->fields[i]->is_string) {
+                       char *str_val = (char *)(long)vals[i];
+                       char *str_field = (char *)&entry->fields[n_u64];
+
+                       strscpy(str_field, str_val, STR_VAR_LEN_MAX);
+                       n_u64 += STR_VAR_LEN_MAX / sizeof(u64);
+               } else {
+                       entry->fields[n_u64] = vals[i];
+                       n_u64++;
+               }
+       }
+
+       trace_event_buffer_commit(&fbuffer);
+out:
+       ring_buffer_nest_end(buffer);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_trace_array);
+
+/**
+ * synth_event_trace_start - Start piecewise synthetic event trace
+ * @file: The trace_event_file representing the synthetic event
+ * @trace_state: A pointer to object tracking the piecewise trace state
+ *
+ * Start the trace of a synthetic event field-by-field rather than all
+ * at once.
+ *
+ * This function 'opens' an event trace, which means space is reserved
+ * for the event in the trace buffer, after which the event's
+ * individual field values can be set through either
+ * synth_event_add_next_val() or synth_event_add_val().
+ *
+ * A pointer to a trace_state object is passed in, which will keep
+ * track of the current event trace state until the event trace is
+ * closed (and the event finally traced) using
+ * synth_event_trace_end().
+ *
+ * Note that synth_event_trace_end() must be called after all values
+ * have been added for each event trace, regardless of whether adding
+ * all field values succeeded or not.
+ *
+ * Note also that for a given event trace, all fields must be added
+ * using either synth_event_add_next_val() or synth_event_add_val()
+ * but not both together or interleaved.
+ *
+ * Return: 0 on success, err otherwise.
+ */
+int synth_event_trace_start(struct trace_event_file *file,
+                           struct synth_event_trace_state *trace_state)
+{
+       struct synth_trace_event *entry;
+       int fields_size = 0;
+       int ret = 0;
+
+       if (!trace_state) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       memset(trace_state, '\0', sizeof(*trace_state));
+
+       /*
+        * Normal event tracing doesn't get called at all unless the
+        * ENABLED bit is set (which attaches the probe thus allowing
+        * this code to be called, etc).  Because this is called
+        * directly by the user, we don't have that but we still need
+        * to honor not logging when disabled.  For the the iterated
+        * trace case, we save the enabed state upon start and just
+        * ignore the following data calls.
+        */
+       if (!(file->flags & EVENT_FILE_FL_ENABLED)) {
+               trace_state->enabled = false;
+               goto out;
+       }
+
+       trace_state->enabled = true;
+
+       trace_state->event = file->event_call->data;
+
+       if (trace_trigger_soft_disabled(file)) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       fields_size = trace_state->event->n_u64 * sizeof(u64);
+
+       /*
+        * Avoid ring buffer recursion detection, as this event
+        * is being performed within another event.
+        */
+       trace_state->buffer = file->tr->array_buffer.buffer;
+       ring_buffer_nest_start(trace_state->buffer);
+
+       entry = trace_event_buffer_reserve(&trace_state->fbuffer, file,
+                                          sizeof(*entry) + fields_size);
+       if (!entry) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       trace_state->entry = entry;
+out:
+       return ret;
+}
+EXPORT_SYMBOL_GPL(synth_event_trace_start);
+
+static int __synth_event_add_val(const char *field_name, u64 val,
+                                struct synth_event_trace_state *trace_state)
+{
+       struct synth_field *field = NULL;
+       struct synth_trace_event *entry;
+       struct synth_event *event;
+       int i, ret = 0;
+
+       if (!trace_state) {
+               ret = -EINVAL;
+               goto out;
+       }
+
+       /* can't mix add_next_synth_val() with add_synth_val() */
+       if (field_name) {
+               if (trace_state->add_next) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+               trace_state->add_name = true;
+       } else {
+               if (trace_state->add_name) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+               trace_state->add_next = true;
+       }
+
+       if (!trace_state->enabled)
+               goto out;
+
+       event = trace_state->event;
+       if (trace_state->add_name) {
+               for (i = 0; i < event->n_fields; i++) {
+                       field = event->fields[i];
+                       if (strcmp(field->name, field_name) == 0)
+                               break;
+               }
+               if (!field) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+       } else {
+               if (trace_state->cur_field >= event->n_fields) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+               field = event->fields[trace_state->cur_field++];
+       }
+
+       entry = trace_state->entry;
+       if (field->is_string) {
+               char *str_val = (char *)(long)val;
+               char *str_field;
+
+               if (!str_val) {
+                       ret = -EINVAL;
+                       goto out;
+               }
+
+               str_field = (char *)&entry->fields[field->offset];
+               strscpy(str_field, str_val, STR_VAR_LEN_MAX);
+       } else
+               entry->fields[field->offset] = val;
+ out:
+       return ret;
+}
+
+/**
+ * synth_event_add_next_val - Add the next field's value to an open synth trace
+ * @val: The value to set the next field to
+ * @trace_state: A pointer to object tracking the piecewise trace state
+ *
+ * Set the value of the next field in an event that's been opened by
+ * synth_event_trace_start().
+ *
+ * The val param should be the value cast to u64.  If the value points
+ * to a string, the val param should be a char * cast to u64.
+ *
+ * This function assumes all the fields in an event are to be set one
+ * after another - successive calls to this function are made, one for
+ * each field, in the order of the fields in the event, until all
+ * fields have been set.  If you'd rather set each field individually
+ * without regard to ordering, synth_event_add_val() can be used
+ * instead.
+ *
+ * Note however that synth_event_add_next_val() and
+ * synth_event_add_val() can't be intermixed for a given event trace -
+ * one or the other but not both can be used at the same time.
+ *
+ * Note also that synth_event_trace_end() must be called after all
+ * values have been added for each event trace, regardless of whether
+ * adding all field values succeeded or not.
+ *
+ * Return: 0 on success, err otherwise.
+ */
+int synth_event_add_next_val(u64 val,
+                            struct synth_event_trace_state *trace_state)
+{
+       return __synth_event_add_val(NULL, val, trace_state);
+}
+EXPORT_SYMBOL_GPL(synth_event_add_next_val);
+
+/**
+ * synth_event_add_val - Add a named field's value to an open synth trace
+ * @field_name: The name of the synthetic event field value to set
+ * @val: The value to set the next field to
+ * @trace_state: A pointer to object tracking the piecewise trace state
+ *
+ * Set the value of the named field in an event that's been opened by
+ * synth_event_trace_start().
+ *
+ * The val param should be the value cast to u64.  If the value points
+ * to a string, the val param should be a char * cast to u64.
+ *
+ * This function looks up the field name, and if found, sets the field
+ * to the specified value.  This lookup makes this function more
+ * expensive than synth_event_add_next_val(), so use that or the
+ * none-piecewise synth_event_trace() instead if efficiency is more
+ * important.
+ *
+ * Note however that synth_event_add_next_val() and
+ * synth_event_add_val() can't be intermixed for a given event trace -
+ * one or the other but not both can be used at the same time.
+ *
+ * Note also that synth_event_trace_end() must be called after all
+ * values have been added for each event trace, regardless of whether
+ * adding all field values succeeded or not.
+ *
+ * Return: 0 on success, err otherwise.
+ */
+int synth_event_add_val(const char *field_name, u64 val,
+                       struct synth_event_trace_state *trace_state)
+{
+       return __synth_event_add_val(field_name, val, trace_state);
+}
+EXPORT_SYMBOL_GPL(synth_event_add_val);
+
+/**
+ * synth_event_trace_end - End piecewise synthetic event trace
+ * @trace_state: A pointer to object tracking the piecewise trace state
+ *
+ * End the trace of a synthetic event opened by
+ * synth_event_trace__start().
+ *
+ * This function 'closes' an event trace, which basically means that
+ * it commits the reserved event and cleans up other loose ends.
+ *
+ * A pointer to a trace_state object is passed in, which will keep
+ * track of the current event trace state opened with
+ * synth_event_trace_start().
+ *
+ * Note that this function must be called after all values have been
+ * added for each event trace, regardless of whether adding all field
+ * values succeeded or not.
+ *
+ * Return: 0 on success, err otherwise.
+ */
+int synth_event_trace_end(struct synth_event_trace_state *trace_state)
+{
+       if (!trace_state)
+               return -EINVAL;
+
+       trace_event_buffer_commit(&trace_state->fbuffer);
+
+       ring_buffer_nest_end(trace_state->buffer);
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(synth_event_trace_end);
+
+static int create_synth_event(int argc, const char **argv)
 {
        const char *name = argv[0];
        int len;
@@ -2041,12 +2881,6 @@ static int parse_map_size(char *str)
        unsigned long size, map_bits;
        int ret;
 
-       strsep(&str, "=");
-       if (!str) {
-               ret = -EINVAL;
-               goto out;
-       }
-
        ret = kstrtoul(str, 0, &size);
        if (ret)
                goto out;
@@ -2106,25 +2940,25 @@ static int parse_action(char *str, struct hist_trigger_attrs *attrs)
 static int parse_assignment(struct trace_array *tr,
                            char *str, struct hist_trigger_attrs *attrs)
 {
-       int ret = 0;
+       int len, ret = 0;
 
-       if ((str_has_prefix(str, "key=")) ||
-           (str_has_prefix(str, "keys="))) {
-               attrs->keys_str = kstrdup(str, GFP_KERNEL);
+       if ((len = str_has_prefix(str, "key=")) ||
+           (len = str_has_prefix(str, "keys="))) {
+               attrs->keys_str = kstrdup(str + len, GFP_KERNEL);
                if (!attrs->keys_str) {
                        ret = -ENOMEM;
                        goto out;
                }
-       } else if ((str_has_prefix(str, "val=")) ||
-                  (str_has_prefix(str, "vals=")) ||
-                  (str_has_prefix(str, "values="))) {
-               attrs->vals_str = kstrdup(str, GFP_KERNEL);
+       } else if ((len = str_has_prefix(str, "val=")) ||
+                  (len = str_has_prefix(str, "vals=")) ||
+                  (len = str_has_prefix(str, "values="))) {
+               attrs->vals_str = kstrdup(str + len, GFP_KERNEL);
                if (!attrs->vals_str) {
                        ret = -ENOMEM;
                        goto out;
                }
-       } else if (str_has_prefix(str, "sort=")) {
-               attrs->sort_key_str = kstrdup(str, GFP_KERNEL);
+       } else if ((len = str_has_prefix(str, "sort="))) {
+               attrs->sort_key_str = kstrdup(str + len, GFP_KERNEL);
                if (!attrs->sort_key_str) {
                        ret = -ENOMEM;
                        goto out;
@@ -2135,12 +2969,8 @@ static int parse_assignment(struct trace_array *tr,
                        ret = -ENOMEM;
                        goto out;
                }
-       } else if (str_has_prefix(str, "clock=")) {
-               strsep(&str, "=");
-               if (!str) {
-                       ret = -EINVAL;
-                       goto out;
-               }
+       } else if ((len = str_has_prefix(str, "clock="))) {
+               str += len;
 
                str = strstrip(str);
                attrs->clock = kstrdup(str, GFP_KERNEL);
@@ -2148,8 +2978,8 @@ static int parse_assignment(struct trace_array *tr,
                        ret = -ENOMEM;
                        goto out;
                }
-       } else if (str_has_prefix(str, "size=")) {
-               int map_bits = parse_map_size(str);
+       } else if ((len = str_has_prefix(str, "size="))) {
+               int map_bits = parse_map_size(str + len);
 
                if (map_bits < 0) {
                        ret = map_bits;
@@ -2189,8 +3019,15 @@ parse_hist_trigger_attrs(struct trace_array *tr, char *trigger_str)
 
        while (trigger_str) {
                char *str = strsep(&trigger_str, ":");
+               char *rhs;
 
-               if (strchr(str, '=')) {
+               rhs = strchr(str, '=');
+               if (rhs) {
+                       if (!strlen(++rhs)) {
+                               ret = -EINVAL;
+                               hist_err(tr, HIST_ERR_EMPTY_ASSIGNMENT, errpos(str));
+                               goto free;
+                       }
                        ret = parse_assignment(tr, str, attrs);
                        if (ret)
                                goto free;
@@ -2661,6 +3498,22 @@ static int init_var_ref(struct hist_field *ref_field,
        goto out;
 }
 
+static int find_var_ref_idx(struct hist_trigger_data *hist_data,
+                           struct hist_field *var_field)
+{
+       struct hist_field *ref_field;
+       int i;
+
+       for (i = 0; i < hist_data->n_var_refs; i++) {
+               ref_field = hist_data->var_refs[i];
+               if (ref_field->var.idx == var_field->var.idx &&
+                   ref_field->var.hist_data == var_field->hist_data)
+                       return i;
+       }
+
+       return -ENOENT;
+}
+
 /**
  * create_var_ref - Create a variable reference and attach it to trigger
  * @hist_data: The trigger that will be referencing the variable
@@ -4146,8 +4999,11 @@ static int check_synth_field(struct synth_event *event,
 
        field = event->fields[field_pos];
 
-       if (strcmp(field->type, hist_field->type) != 0)
-               return -EINVAL;
+       if (strcmp(field->type, hist_field->type) != 0) {
+               if (field->size != hist_field->size ||
+                   field->is_signed != hist_field->is_signed)
+                       return -EINVAL;
+       }
 
        return 0;
 }
@@ -4234,11 +5090,11 @@ static int trace_action_create(struct hist_trigger_data *hist_data,
        struct trace_array *tr = hist_data->event_file->tr;
        char *event_name, *param, *system = NULL;
        struct hist_field *hist_field, *var_ref;
-       unsigned int i, var_ref_idx;
+       unsigned int i;
        unsigned int field_pos = 0;
        struct synth_event *event;
        char *synth_event_name;
-       int ret = 0;
+       int var_ref_idx, ret = 0;
 
        lockdep_assert_held(&event_mutex);
 
@@ -4255,8 +5111,6 @@ static int trace_action_create(struct hist_trigger_data *hist_data,
 
        event->ref++;
 
-       var_ref_idx = hist_data->n_var_refs;
-
        for (i = 0; i < data->n_params; i++) {
                char *p;
 
@@ -4305,6 +5159,14 @@ static int trace_action_create(struct hist_trigger_data *hist_data,
                                goto err;
                        }
 
+                       var_ref_idx = find_var_ref_idx(hist_data, var_ref);
+                       if (WARN_ON(var_ref_idx < 0)) {
+                               ret = var_ref_idx;
+                               goto err;
+                       }
+
+                       data->var_ref_idx[i] = var_ref_idx;
+
                        field_pos++;
                        kfree(p);
                        continue;
@@ -4323,7 +5185,6 @@ static int trace_action_create(struct hist_trigger_data *hist_data,
        }
 
        data->synth_event = event;
-       data->var_ref_idx = var_ref_idx;
  out:
        return ret;
  err:
@@ -4542,10 +5403,6 @@ static int create_val_fields(struct hist_trigger_data *hist_data,
        if (!fields_str)
                goto out;
 
-       strsep(&fields_str, "=");
-       if (!fields_str)
-               goto out;
-
        for (i = 0, j = 1; i < TRACING_MAP_VALS_MAX &&
                     j < TRACING_MAP_VALS_MAX; i++) {
                field_str = strsep(&fields_str, ",");
@@ -4640,10 +5497,6 @@ static int create_key_fields(struct hist_trigger_data *hist_data,
        if (!fields_str)
                goto out;
 
-       strsep(&fields_str, "=");
-       if (!fields_str)
-               goto out;
-
        for (i = n_vals; i < n_vals + TRACING_MAP_KEYS_MAX; i++) {
                field_str = strsep(&fields_str, ",");
                if (!field_str)
@@ -4775,7 +5628,7 @@ static int create_hist_fields(struct hist_trigger_data *hist_data,
        return ret;
 }
 
-static int is_descending(const char *str)
+static int is_descending(struct trace_array *tr, const char *str)
 {
        if (!str)
                return 0;
@@ -4786,11 +5639,14 @@ static int is_descending(const char *str)
        if (strcmp(str, "ascending") == 0)
                return 0;
 
+       hist_err(tr, HIST_ERR_INVALID_SORT_MODIFIER, errpos((char *)str));
+
        return -EINVAL;
 }
 
 static int create_sort_keys(struct hist_trigger_data *hist_data)
 {
+       struct trace_array *tr = hist_data->event_file->tr;
        char *fields_str = hist_data->attrs->sort_key_str;
        struct tracing_map_sort_key *sort_key;
        int descending, ret = 0;
@@ -4801,12 +5657,6 @@ static int create_sort_keys(struct hist_trigger_data *hist_data)
        if (!fields_str)
                goto out;
 
-       strsep(&fields_str, "=");
-       if (!fields_str) {
-               ret = -EINVAL;
-               goto out;
-       }
-
        for (i = 0; i < TRACING_MAP_SORT_KEYS_MAX; i++) {
                struct hist_field *hist_field;
                char *field_str, *field_name;
@@ -4815,25 +5665,30 @@ static int create_sort_keys(struct hist_trigger_data *hist_data)
                sort_key = &hist_data->sort_keys[i];
 
                field_str = strsep(&fields_str, ",");
-               if (!field_str) {
-                       if (i == 0)
-                               ret = -EINVAL;
+               if (!field_str)
+                       break;
+
+               if (!*field_str) {
+                       ret = -EINVAL;
+                       hist_err(tr, HIST_ERR_EMPTY_SORT_FIELD, errpos("sort="));
                        break;
                }
 
                if ((i == TRACING_MAP_SORT_KEYS_MAX - 1) && fields_str) {
+                       hist_err(tr, HIST_ERR_TOO_MANY_SORT_FIELDS, errpos("sort="));
                        ret = -EINVAL;
                        break;
                }
 
                field_name = strsep(&field_str, ".");
-               if (!field_name) {
+               if (!field_name || !*field_name) {
                        ret = -EINVAL;
+                       hist_err(tr, HIST_ERR_EMPTY_SORT_FIELD, errpos("sort="));
                        break;
                }
 
                if (strcmp(field_name, "hitcount") == 0) {
-                       descending = is_descending(field_str);
+                       descending = is_descending(tr, field_str);
                        if (descending < 0) {
                                ret = descending;
                                break;
@@ -4855,7 +5710,7 @@ static int create_sort_keys(struct hist_trigger_data *hist_data)
 
                        if (strcmp(field_name, test_name) == 0) {
                                sort_key->field_idx = idx;
-                               descending = is_descending(field_str);
+                               descending = is_descending(tr, field_str);
                                if (descending < 0) {
                                        ret = descending;
                                        goto out;
@@ -4866,6 +5721,7 @@ static int create_sort_keys(struct hist_trigger_data *hist_data)
                }
                if (j == hist_data->n_fields) {
                        ret = -EINVAL;
+                       hist_err(tr, HIST_ERR_INVALID_SORT_FIELD, errpos(field_name));
                        break;
                }
        }
index 40106ff..dd34a1b 100644 (file)
@@ -116,9 +116,10 @@ static void *trigger_next(struct seq_file *m, void *t, loff_t *pos)
 {
        struct trace_event_file *event_file = event_file_data(m->private);
 
-       if (t == SHOW_AVAILABLE_TRIGGERS)
+       if (t == SHOW_AVAILABLE_TRIGGERS) {
+               (*pos)++;
                return NULL;
-
+       }
        return seq_list_next(t, &event_file->triggers, pos);
 }
 
@@ -213,7 +214,7 @@ static int event_trigger_regex_open(struct inode *inode, struct file *file)
        return ret;
 }
 
-static int trigger_process_regex(struct trace_event_file *file, char *buff)
+int trigger_process_regex(struct trace_event_file *file, char *buff)
 {
        char *command, *next = buff;
        struct event_command *p;
index b611cd3..8a4c8d5 100644 (file)
@@ -101,7 +101,7 @@ static int function_trace_init(struct trace_array *tr)
 
        ftrace_init_array_ops(tr, func);
 
-       tr->trace_buffer.cpu = get_cpu();
+       tr->array_buffer.cpu = get_cpu();
        put_cpu();
 
        tracing_start_cmdline_record();
@@ -118,7 +118,7 @@ static void function_trace_reset(struct trace_array *tr)
 
 static void function_trace_start(struct trace_array *tr)
 {
-       tracing_reset_online_cpus(&tr->trace_buffer);
+       tracing_reset_online_cpus(&tr->array_buffer);
 }
 
 static void
@@ -143,7 +143,7 @@ function_trace_call(unsigned long ip, unsigned long parent_ip,
                goto out;
 
        cpu = smp_processor_id();
-       data = per_cpu_ptr(tr->trace_buffer.data, cpu);
+       data = per_cpu_ptr(tr->array_buffer.data, cpu);
        if (!atomic_read(&data->disabled)) {
                local_save_flags(flags);
                trace_function(tr, ip, parent_ip, flags, pc);
@@ -192,7 +192,7 @@ function_stack_trace_call(unsigned long ip, unsigned long parent_ip,
         */
        local_irq_save(flags);
        cpu = raw_smp_processor_id();
-       data = per_cpu_ptr(tr->trace_buffer.data, cpu);
+       data = per_cpu_ptr(tr->array_buffer.data, cpu);
        disabled = atomic_inc_return(&data->disabled);
 
        if (likely(disabled == 1)) {
index 78af971..7d71546 100644 (file)
@@ -101,7 +101,7 @@ int __trace_graph_entry(struct trace_array *tr,
 {
        struct trace_event_call *call = &event_funcgraph_entry;
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
        struct ftrace_graph_ent_entry *entry;
 
        event = trace_buffer_lock_reserve(buffer, TRACE_GRAPH_ENT,
@@ -171,7 +171,7 @@ int trace_graph_entry(struct ftrace_graph_ent *trace)
 
        local_irq_save(flags);
        cpu = raw_smp_processor_id();
-       data = per_cpu_ptr(tr->trace_buffer.data, cpu);
+       data = per_cpu_ptr(tr->array_buffer.data, cpu);
        disabled = atomic_inc_return(&data->disabled);
        if (likely(disabled == 1)) {
                pc = preempt_count();
@@ -221,7 +221,7 @@ void __trace_graph_return(struct trace_array *tr,
 {
        struct trace_event_call *call = &event_funcgraph_exit;
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
        struct ftrace_graph_ret_entry *entry;
 
        event = trace_buffer_lock_reserve(buffer, TRACE_GRAPH_RET,
@@ -252,7 +252,7 @@ void trace_graph_return(struct ftrace_graph_ret *trace)
 
        local_irq_save(flags);
        cpu = raw_smp_processor_id();
-       data = per_cpu_ptr(tr->trace_buffer.data, cpu);
+       data = per_cpu_ptr(tr->array_buffer.data, cpu);
        disabled = atomic_inc_return(&data->disabled);
        if (likely(disabled == 1)) {
                pc = preempt_count();
@@ -444,9 +444,9 @@ get_return_for_leaf(struct trace_iterator *iter,
                         * We need to consume the current entry to see
                         * the next one.
                         */
-                       ring_buffer_consume(iter->trace_buffer->buffer, iter->cpu,
+                       ring_buffer_consume(iter->array_buffer->buffer, iter->cpu,
                                            NULL, NULL);
-                       event = ring_buffer_peek(iter->trace_buffer->buffer, iter->cpu,
+                       event = ring_buffer_peek(iter->array_buffer->buffer, iter->cpu,
                                                 NULL, NULL);
                }
 
@@ -503,7 +503,7 @@ print_graph_rel_time(struct trace_iterator *iter, struct trace_seq *s)
 {
        unsigned long long usecs;
 
-       usecs = iter->ts - iter->trace_buffer->time_start;
+       usecs = iter->ts - iter->array_buffer->time_start;
        do_div(usecs, NSEC_PER_USEC);
 
        trace_seq_printf(s, "%9llu us |  ", usecs);
index 6638d63..a48808c 100644 (file)
@@ -104,7 +104,7 @@ static void trace_hwlat_sample(struct hwlat_sample *sample)
 {
        struct trace_array *tr = hwlat_trace;
        struct trace_event_call *call = &event_hwlat;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
        struct ring_buffer_event *event;
        struct hwlat_entry *entry;
        unsigned long flags;
@@ -556,7 +556,7 @@ static int init_tracefs(void)
        return 0;
 
  err:
-       tracefs_remove_recursive(top_dir);
+       tracefs_remove(top_dir);
        return -ENOMEM;
 }
 
index a745b0c..10bbb0f 100644 (file)
@@ -122,7 +122,7 @@ static int func_prolog_dec(struct trace_array *tr,
        if (!irqs_disabled_flags(*flags) && !preempt_count())
                return 0;
 
-       *data = per_cpu_ptr(tr->trace_buffer.data, cpu);
+       *data = per_cpu_ptr(tr->array_buffer.data, cpu);
        disabled = atomic_inc_return(&(*data)->disabled);
 
        if (likely(disabled == 1))
@@ -167,7 +167,7 @@ static int irqsoff_display_graph(struct trace_array *tr, int set)
                per_cpu(tracing_cpu, cpu) = 0;
 
        tr->max_latency = 0;
-       tracing_reset_online_cpus(&irqsoff_trace->trace_buffer);
+       tracing_reset_online_cpus(&irqsoff_trace->array_buffer);
 
        return start_irqsoff_tracer(irqsoff_trace, set);
 }
@@ -382,7 +382,7 @@ start_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
        if (per_cpu(tracing_cpu, cpu))
                return;
 
-       data = per_cpu_ptr(tr->trace_buffer.data, cpu);
+       data = per_cpu_ptr(tr->array_buffer.data, cpu);
 
        if (unlikely(!data) || atomic_read(&data->disabled))
                return;
@@ -420,7 +420,7 @@ stop_critical_timing(unsigned long ip, unsigned long parent_ip, int pc)
        if (!tracer_enabled || !tracing_is_enabled())
                return;
 
-       data = per_cpu_ptr(tr->trace_buffer.data, cpu);
+       data = per_cpu_ptr(tr->array_buffer.data, cpu);
 
        if (unlikely(!data) ||
            !data->critical_start || atomic_read(&data->disabled))
index cca6504..9da7610 100644 (file)
@@ -43,7 +43,7 @@ static void ftrace_dump_buf(int skip_entries, long cpu_file)
        if (cpu_file == RING_BUFFER_ALL_CPUS) {
                for_each_tracing_cpu(cpu) {
                        iter.buffer_iter[cpu] =
-                       ring_buffer_read_prepare(iter.trace_buffer->buffer,
+                       ring_buffer_read_prepare(iter.array_buffer->buffer,
                                                 cpu, GFP_ATOMIC);
                        ring_buffer_read_start(iter.buffer_iter[cpu]);
                        tracing_iter_reset(&iter, cpu);
@@ -51,7 +51,7 @@ static void ftrace_dump_buf(int skip_entries, long cpu_file)
        } else {
                iter.cpu_file = cpu_file;
                iter.buffer_iter[cpu_file] =
-                       ring_buffer_read_prepare(iter.trace_buffer->buffer,
+                       ring_buffer_read_prepare(iter.array_buffer->buffer,
                                                 cpu_file, GFP_ATOMIC);
                ring_buffer_read_start(iter.buffer_iter[cpu_file]);
                tracing_iter_reset(&iter, cpu_file);
@@ -124,7 +124,7 @@ static int kdb_ftdump(int argc, const char **argv)
        iter.buffer_iter = buffer_iter;
 
        for_each_tracing_cpu(cpu) {
-               atomic_inc(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled);
+               atomic_inc(&per_cpu_ptr(iter.array_buffer->data, cpu)->disabled);
        }
 
        /* A negative skip_entries means skip all but the last entries */
@@ -139,7 +139,7 @@ static int kdb_ftdump(int argc, const char **argv)
        ftrace_dump_buf(skip_entries, cpu_file);
 
        for_each_tracing_cpu(cpu) {
-               atomic_dec(&per_cpu_ptr(iter.trace_buffer->data, cpu)->disabled);
+               atomic_dec(&per_cpu_ptr(iter.array_buffer->data, cpu)->disabled);
        }
 
        kdb_trap_printk--;
index aa515d5..d8264eb 100644 (file)
@@ -22,7 +22,6 @@
 
 #define KPROBE_EVENT_SYSTEM "kprobes"
 #define KRETPROBE_MAXACTIVE_MAX 4096
-#define MAX_KPROBE_CMDLINE_SIZE 1024
 
 /* Kprobe early definition from command line */
 static char kprobe_boot_events_buf[COMMAND_LINE_SIZE] __initdata;
@@ -902,6 +901,167 @@ static int create_or_delete_trace_kprobe(int argc, char **argv)
        return ret == -ECANCELED ? -EINVAL : ret;
 }
 
+static int trace_kprobe_run_command(struct dynevent_cmd *cmd)
+{
+       return trace_run_command(cmd->seq.buffer, create_or_delete_trace_kprobe);
+}
+
+/**
+ * kprobe_event_cmd_init - Initialize a kprobe event command object
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @buf: A pointer to the buffer used to build the command
+ * @maxlen: The length of the buffer passed in @buf
+ *
+ * Initialize a synthetic event command object.  Use this before
+ * calling any of the other kprobe_event functions.
+ */
+void kprobe_event_cmd_init(struct dynevent_cmd *cmd, char *buf, int maxlen)
+{
+       dynevent_cmd_init(cmd, buf, maxlen, DYNEVENT_TYPE_KPROBE,
+                         trace_kprobe_run_command);
+}
+EXPORT_SYMBOL_GPL(kprobe_event_cmd_init);
+
+/**
+ * __kprobe_event_gen_cmd_start - Generate a kprobe event command from arg list
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @name: The name of the kprobe event
+ * @loc: The location of the kprobe event
+ * @kretprobe: Is this a return probe?
+ * @args: Variable number of arg (pairs), one pair for each field
+ *
+ * NOTE: Users normally won't want to call this function directly, but
+ * rather use the kprobe_event_gen_cmd_start() wrapper, which automatically
+ * adds a NULL to the end of the arg list.  If this function is used
+ * directly, make sure the last arg in the variable arg list is NULL.
+ *
+ * Generate a kprobe event command to be executed by
+ * kprobe_event_gen_cmd_end().  This function can be used to generate the
+ * complete command or only the first part of it; in the latter case,
+ * kprobe_event_add_fields() can be used to add more fields following this.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int __kprobe_event_gen_cmd_start(struct dynevent_cmd *cmd, bool kretprobe,
+                                const char *name, const char *loc, ...)
+{
+       char buf[MAX_EVENT_NAME_LEN];
+       struct dynevent_arg arg;
+       va_list args;
+       int ret;
+
+       if (cmd->type != DYNEVENT_TYPE_KPROBE)
+               return -EINVAL;
+
+       if (kretprobe)
+               snprintf(buf, MAX_EVENT_NAME_LEN, "r:kprobes/%s", name);
+       else
+               snprintf(buf, MAX_EVENT_NAME_LEN, "p:kprobes/%s", name);
+
+       ret = dynevent_str_add(cmd, buf);
+       if (ret)
+               return ret;
+
+       dynevent_arg_init(&arg, 0);
+       arg.str = loc;
+       ret = dynevent_arg_add(cmd, &arg, NULL);
+       if (ret)
+               return ret;
+
+       va_start(args, loc);
+       for (;;) {
+               const char *field;
+
+               field = va_arg(args, const char *);
+               if (!field)
+                       break;
+
+               if (++cmd->n_fields > MAX_TRACE_ARGS) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               arg.str = field;
+               ret = dynevent_arg_add(cmd, &arg, NULL);
+               if (ret)
+                       break;
+       }
+       va_end(args);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__kprobe_event_gen_cmd_start);
+
+/**
+ * __kprobe_event_add_fields - Add probe fields to a kprobe command from arg list
+ * @cmd: A pointer to the dynevent_cmd struct representing the new event
+ * @args: Variable number of arg (pairs), one pair for each field
+ *
+ * NOTE: Users normally won't want to call this function directly, but
+ * rather use the kprobe_event_add_fields() wrapper, which
+ * automatically adds a NULL to the end of the arg list.  If this
+ * function is used directly, make sure the last arg in the variable
+ * arg list is NULL.
+ *
+ * Add probe fields to an existing kprobe command using a variable
+ * list of args.  Fields are added in the same order they're listed.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int __kprobe_event_add_fields(struct dynevent_cmd *cmd, ...)
+{
+       struct dynevent_arg arg;
+       va_list args;
+       int ret;
+
+       if (cmd->type != DYNEVENT_TYPE_KPROBE)
+               return -EINVAL;
+
+       dynevent_arg_init(&arg, 0);
+
+       va_start(args, cmd);
+       for (;;) {
+               const char *field;
+
+               field = va_arg(args, const char *);
+               if (!field)
+                       break;
+
+               if (++cmd->n_fields > MAX_TRACE_ARGS) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               arg.str = field;
+               ret = dynevent_arg_add(cmd, &arg, NULL);
+               if (ret)
+                       break;
+       }
+       va_end(args);
+
+       return ret;
+}
+EXPORT_SYMBOL_GPL(__kprobe_event_add_fields);
+
+/**
+ * kprobe_event_delete - Delete a kprobe event
+ * @name: The name of the kprobe event to delete
+ *
+ * Delete a kprobe event with the give @name from kernel code rather
+ * than directly from the command line.
+ *
+ * Return: 0 if successful, error otherwise.
+ */
+int kprobe_event_delete(const char *name)
+{
+       char buf[MAX_EVENT_NAME_LEN];
+
+       snprintf(buf, MAX_EVENT_NAME_LEN, "-:%s", name);
+
+       return trace_run_command(buf, create_or_delete_trace_kprobe);
+}
+EXPORT_SYMBOL_GPL(kprobe_event_delete);
+
 static int trace_kprobe_release(struct dyn_event *ev)
 {
        struct trace_kprobe *tk = to_trace_kprobe(ev);
@@ -1175,35 +1335,35 @@ __kprobe_trace_func(struct trace_kprobe *tk, struct pt_regs *regs,
                    struct trace_event_file *trace_file)
 {
        struct kprobe_trace_entry_head *entry;
-       struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
-       int size, dsize, pc;
-       unsigned long irq_flags;
        struct trace_event_call *call = trace_probe_event_call(&tk->tp);
+       struct trace_event_buffer fbuffer;
+       int dsize;
 
        WARN_ON(call != trace_file->event_call);
 
        if (trace_trigger_soft_disabled(trace_file))
                return;
 
-       local_save_flags(irq_flags);
-       pc = preempt_count();
+       local_save_flags(fbuffer.flags);
+       fbuffer.pc = preempt_count();
+       fbuffer.trace_file = trace_file;
 
        dsize = __get_data_size(&tk->tp, regs);
-       size = sizeof(*entry) + tk->tp.size + dsize;
 
-       event = trace_event_buffer_lock_reserve(&buffer, trace_file,
-                                               call->event.type,
-                                               size, irq_flags, pc);
-       if (!event)
+       fbuffer.event =
+               trace_event_buffer_lock_reserve(&fbuffer.buffer, trace_file,
+                                       call->event.type,
+                                       sizeof(*entry) + tk->tp.size + dsize,
+                                       fbuffer.flags, fbuffer.pc);
+       if (!fbuffer.event)
                return;
 
-       entry = ring_buffer_event_data(event);
+       fbuffer.regs = regs;
+       entry = fbuffer.entry = ring_buffer_event_data(fbuffer.event);
        entry->ip = (unsigned long)tk->rp.kp.addr;
        store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
 
-       event_trigger_unlock_commit_regs(trace_file, buffer, event,
-                                        entry, irq_flags, pc, regs);
+       trace_event_buffer_commit(&fbuffer);
 }
 
 static void
@@ -1223,36 +1383,35 @@ __kretprobe_trace_func(struct trace_kprobe *tk, struct kretprobe_instance *ri,
                       struct trace_event_file *trace_file)
 {
        struct kretprobe_trace_entry_head *entry;
-       struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
-       int size, pc, dsize;
-       unsigned long irq_flags;
+       struct trace_event_buffer fbuffer;
        struct trace_event_call *call = trace_probe_event_call(&tk->tp);
+       int dsize;
 
        WARN_ON(call != trace_file->event_call);
 
        if (trace_trigger_soft_disabled(trace_file))
                return;
 
-       local_save_flags(irq_flags);
-       pc = preempt_count();
+       local_save_flags(fbuffer.flags);
+       fbuffer.pc = preempt_count();
+       fbuffer.trace_file = trace_file;
 
        dsize = __get_data_size(&tk->tp, regs);
-       size = sizeof(*entry) + tk->tp.size + dsize;
-
-       event = trace_event_buffer_lock_reserve(&buffer, trace_file,
-                                               call->event.type,
-                                               size, irq_flags, pc);
-       if (!event)
+       fbuffer.event =
+               trace_event_buffer_lock_reserve(&fbuffer.buffer, trace_file,
+                                       call->event.type,
+                                       sizeof(*entry) + tk->tp.size + dsize,
+                                       fbuffer.flags, fbuffer.pc);
+       if (!fbuffer.event)
                return;
 
-       entry = ring_buffer_event_data(event);
+       fbuffer.regs = regs;
+       entry = fbuffer.entry = ring_buffer_event_data(fbuffer.event);
        entry->func = (unsigned long)tk->rp.kp.addr;
        entry->ret_ip = (unsigned long)ri->ret_addr;
        store_trace_args(&entry[1], &tk->tp, regs, sizeof(*entry), dsize);
 
-       event_trigger_unlock_commit_regs(trace_file, buffer, event,
-                                        entry, irq_flags, pc, regs);
+       trace_event_buffer_commit(&fbuffer);
 }
 
 static void
@@ -1698,11 +1857,12 @@ static __init void setup_boot_kprobe_events(void)
        enable_boot_kprobe_events();
 }
 
-/* Make a tracefs interface for controlling probe points */
-static __init int init_kprobe_trace(void)
+/*
+ * Register dynevent at subsys_initcall. This allows kernel to setup kprobe
+ * events in fs_initcall without tracefs.
+ */
+static __init int init_kprobe_trace_early(void)
 {
-       struct dentry *d_tracer;
-       struct dentry *entry;
        int ret;
 
        ret = dyn_event_register(&trace_kprobe_ops);
@@ -1712,6 +1872,16 @@ static __init int init_kprobe_trace(void)
        if (register_module_notifier(&trace_kprobe_module_nb))
                return -EINVAL;
 
+       return 0;
+}
+subsys_initcall(init_kprobe_trace_early);
+
+/* Make a tracefs interface for controlling probe points */
+static __init int init_kprobe_trace(void)
+{
+       struct dentry *d_tracer;
+       struct dentry *entry;
+
        d_tracer = tracing_init_dentry();
        if (IS_ERR(d_tracer))
                return 0;
index b038801..84582bf 100644 (file)
@@ -32,7 +32,7 @@ static void mmio_reset_data(struct trace_array *tr)
        overrun_detected = false;
        prev_overruns = 0;
 
-       tracing_reset_online_cpus(&tr->trace_buffer);
+       tracing_reset_online_cpus(&tr->array_buffer);
 }
 
 static int mmio_trace_init(struct trace_array *tr)
@@ -122,7 +122,7 @@ static void mmio_close(struct trace_iterator *iter)
 static unsigned long count_overruns(struct trace_iterator *iter)
 {
        unsigned long cnt = atomic_xchg(&dropped_count, 0);
-       unsigned long over = ring_buffer_overruns(iter->trace_buffer->buffer);
+       unsigned long over = ring_buffer_overruns(iter->array_buffer->buffer);
 
        if (over > prev_overruns)
                cnt += over - prev_overruns;
@@ -297,7 +297,7 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
                                struct mmiotrace_rw *rw)
 {
        struct trace_event_call *call = &event_mmiotrace_rw;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
        struct ring_buffer_event *event;
        struct trace_mmiotrace_rw *entry;
        int pc = preempt_count();
@@ -318,7 +318,7 @@ static void __trace_mmiotrace_rw(struct trace_array *tr,
 void mmio_trace_rw(struct mmiotrace_rw *rw)
 {
        struct trace_array *tr = mmio_trace_array;
-       struct trace_array_cpu *data = per_cpu_ptr(tr->trace_buffer.data, smp_processor_id());
+       struct trace_array_cpu *data = per_cpu_ptr(tr->array_buffer.data, smp_processor_id());
        __trace_mmiotrace_rw(tr, data, rw);
 }
 
@@ -327,7 +327,7 @@ static void __trace_mmiotrace_map(struct trace_array *tr,
                                struct mmiotrace_map *map)
 {
        struct trace_event_call *call = &event_mmiotrace_map;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
        struct ring_buffer_event *event;
        struct trace_mmiotrace_map *entry;
        int pc = preempt_count();
@@ -351,7 +351,7 @@ void mmio_trace_mapping(struct mmiotrace_map *map)
        struct trace_array_cpu *data;
 
        preempt_disable();
-       data = per_cpu_ptr(tr->trace_buffer.data, smp_processor_id());
+       data = per_cpu_ptr(tr->array_buffer.data, smp_processor_id());
        __trace_mmiotrace_map(tr, data, map);
        preempt_enable();
 }
index d9b4b7c..b490908 100644 (file)
@@ -538,7 +538,7 @@ lat_print_timestamp(struct trace_iterator *iter, u64 next_ts)
        struct trace_array *tr = iter->tr;
        unsigned long verbose = tr->trace_flags & TRACE_ITER_VERBOSE;
        unsigned long in_ns = iter->iter_flags & TRACE_FILE_TIME_IN_NS;
-       unsigned long long abs_ts = iter->ts - iter->trace_buffer->time_start;
+       unsigned long long abs_ts = iter->ts - iter->array_buffer->time_start;
        unsigned long long rel_ts = next_ts - iter->ts;
        struct trace_seq *s = &iter->seq;
 
index e288168..e304196 100644 (file)
@@ -89,8 +89,10 @@ static void tracing_sched_unregister(void)
 
 static void tracing_start_sched_switch(int ops)
 {
-       bool sched_register = (!sched_cmdline_ref && !sched_tgid_ref);
+       bool sched_register;
+
        mutex_lock(&sched_register_mutex);
+       sched_register = (!sched_cmdline_ref && !sched_tgid_ref);
 
        switch (ops) {
        case RECORD_CMDLINE:
index 617e297..97b10bb 100644 (file)
@@ -82,7 +82,7 @@ func_prolog_preempt_disable(struct trace_array *tr,
        if (cpu != wakeup_current_cpu)
                goto out_enable;
 
-       *data = per_cpu_ptr(tr->trace_buffer.data, cpu);
+       *data = per_cpu_ptr(tr->array_buffer.data, cpu);
        disabled = atomic_inc_return(&(*data)->disabled);
        if (unlikely(disabled != 1))
                goto out;
@@ -378,7 +378,7 @@ tracing_sched_switch_trace(struct trace_array *tr,
                           unsigned long flags, int pc)
 {
        struct trace_event_call *call = &event_context_switch;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
        struct ring_buffer_event *event;
        struct ctx_switch_entry *entry;
 
@@ -408,7 +408,7 @@ tracing_sched_wakeup_trace(struct trace_array *tr,
        struct trace_event_call *call = &event_wakeup;
        struct ring_buffer_event *event;
        struct ctx_switch_entry *entry;
-       struct ring_buffer *buffer = tr->trace_buffer.buffer;
+       struct trace_buffer *buffer = tr->array_buffer.buffer;
 
        event = trace_buffer_lock_reserve(buffer, TRACE_WAKE,
                                          sizeof(*entry), flags, pc);
@@ -459,7 +459,7 @@ probe_wakeup_sched_switch(void *ignore, bool preempt,
 
        /* disable local data, not wakeup_cpu data */
        cpu = raw_smp_processor_id();
-       disabled = atomic_inc_return(&per_cpu_ptr(wakeup_trace->trace_buffer.data, cpu)->disabled);
+       disabled = atomic_inc_return(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
        if (likely(disabled != 1))
                goto out;
 
@@ -471,7 +471,7 @@ probe_wakeup_sched_switch(void *ignore, bool preempt,
                goto out_unlock;
 
        /* The task we are waiting for is waking up */
-       data = per_cpu_ptr(wakeup_trace->trace_buffer.data, wakeup_cpu);
+       data = per_cpu_ptr(wakeup_trace->array_buffer.data, wakeup_cpu);
 
        __trace_function(wakeup_trace, CALLER_ADDR0, CALLER_ADDR1, flags, pc);
        tracing_sched_switch_trace(wakeup_trace, prev, next, flags, pc);
@@ -494,7 +494,7 @@ out_unlock:
        arch_spin_unlock(&wakeup_lock);
        local_irq_restore(flags);
 out:
-       atomic_dec(&per_cpu_ptr(wakeup_trace->trace_buffer.data, cpu)->disabled);
+       atomic_dec(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
 }
 
 static void __wakeup_reset(struct trace_array *tr)
@@ -513,7 +513,7 @@ static void wakeup_reset(struct trace_array *tr)
 {
        unsigned long flags;
 
-       tracing_reset_online_cpus(&tr->trace_buffer);
+       tracing_reset_online_cpus(&tr->array_buffer);
 
        local_irq_save(flags);
        arch_spin_lock(&wakeup_lock);
@@ -551,7 +551,7 @@ probe_wakeup(void *ignore, struct task_struct *p)
                return;
 
        pc = preempt_count();
-       disabled = atomic_inc_return(&per_cpu_ptr(wakeup_trace->trace_buffer.data, cpu)->disabled);
+       disabled = atomic_inc_return(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
        if (unlikely(disabled != 1))
                goto out;
 
@@ -583,7 +583,7 @@ probe_wakeup(void *ignore, struct task_struct *p)
 
        local_save_flags(flags);
 
-       data = per_cpu_ptr(wakeup_trace->trace_buffer.data, wakeup_cpu);
+       data = per_cpu_ptr(wakeup_trace->array_buffer.data, wakeup_cpu);
        data->preempt_timestamp = ftrace_now(cpu);
        tracing_sched_wakeup_trace(wakeup_trace, p, current, flags, pc);
        __trace_stack(wakeup_trace, flags, 0, pc);
@@ -598,7 +598,7 @@ probe_wakeup(void *ignore, struct task_struct *p)
 out_locked:
        arch_spin_unlock(&wakeup_lock);
 out:
-       atomic_dec(&per_cpu_ptr(wakeup_trace->trace_buffer.data, cpu)->disabled);
+       atomic_dec(&per_cpu_ptr(wakeup_trace->array_buffer.data, cpu)->disabled);
 }
 
 static void start_wakeup_tracer(struct trace_array *tr)
index 69ee8ef..b5e3496 100644 (file)
@@ -23,7 +23,7 @@ static inline int trace_valid_entry(struct trace_entry *entry)
        return 0;
 }
 
-static int trace_test_buffer_cpu(struct trace_buffer *buf, int cpu)
+static int trace_test_buffer_cpu(struct array_buffer *buf, int cpu)
 {
        struct ring_buffer_event *event;
        struct trace_entry *entry;
@@ -60,7 +60,7 @@ static int trace_test_buffer_cpu(struct trace_buffer *buf, int cpu)
  * Test the trace buffer to see if all the elements
  * are still sane.
  */
-static int __maybe_unused trace_test_buffer(struct trace_buffer *buf, unsigned long *count)
+static int __maybe_unused trace_test_buffer(struct array_buffer *buf, unsigned long *count)
 {
        unsigned long flags, cnt = 0;
        int cpu, ret = 0;
@@ -362,7 +362,7 @@ static int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
        msleep(100);
 
        /* we should have nothing in the buffer */
-       ret = trace_test_buffer(&tr->trace_buffer, &count);
+       ret = trace_test_buffer(&tr->array_buffer, &count);
        if (ret)
                goto out;
 
@@ -383,7 +383,7 @@ static int trace_selftest_startup_dynamic_tracing(struct tracer *trace,
        ftrace_enabled = 0;
 
        /* check the trace buffer */
-       ret = trace_test_buffer(&tr->trace_buffer, &count);
+       ret = trace_test_buffer(&tr->array_buffer, &count);
 
        ftrace_enabled = 1;
        tracing_start();
@@ -682,7 +682,7 @@ trace_selftest_startup_function(struct tracer *trace, struct trace_array *tr)
        ftrace_enabled = 0;
 
        /* check the trace buffer */
-       ret = trace_test_buffer(&tr->trace_buffer, &count);
+       ret = trace_test_buffer(&tr->array_buffer, &count);
 
        ftrace_enabled = 1;
        trace->reset(tr);
@@ -768,7 +768,7 @@ trace_selftest_startup_function_graph(struct tracer *trace,
         * Simulate the init() callback but we attach a watchdog callback
         * to detect and recover from possible hangs
         */
-       tracing_reset_online_cpus(&tr->trace_buffer);
+       tracing_reset_online_cpus(&tr->array_buffer);
        set_graph_array(tr);
        ret = register_ftrace_graph(&fgraph_ops);
        if (ret) {
@@ -790,7 +790,7 @@ trace_selftest_startup_function_graph(struct tracer *trace,
        tracing_stop();
 
        /* check the trace buffer */
-       ret = trace_test_buffer(&tr->trace_buffer, &count);
+       ret = trace_test_buffer(&tr->array_buffer, &count);
 
        /* Need to also simulate the tr->reset to remove this fgraph_ops */
        tracing_stop_cmdline_record();
@@ -848,7 +848,7 @@ trace_selftest_startup_irqsoff(struct tracer *trace, struct trace_array *tr)
        /* stop the tracing. */
        tracing_stop();
        /* check both trace buffers */
-       ret = trace_test_buffer(&tr->trace_buffer, NULL);
+       ret = trace_test_buffer(&tr->array_buffer, NULL);
        if (!ret)
                ret = trace_test_buffer(&tr->max_buffer, &count);
        trace->reset(tr);
@@ -910,7 +910,7 @@ trace_selftest_startup_preemptoff(struct tracer *trace, struct trace_array *tr)
        /* stop the tracing. */
        tracing_stop();
        /* check both trace buffers */
-       ret = trace_test_buffer(&tr->trace_buffer, NULL);
+       ret = trace_test_buffer(&tr->array_buffer, NULL);
        if (!ret)
                ret = trace_test_buffer(&tr->max_buffer, &count);
        trace->reset(tr);
@@ -976,7 +976,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
        /* stop the tracing. */
        tracing_stop();
        /* check both trace buffers */
-       ret = trace_test_buffer(&tr->trace_buffer, NULL);
+       ret = trace_test_buffer(&tr->array_buffer, NULL);
        if (ret)
                goto out;
 
@@ -1006,7 +1006,7 @@ trace_selftest_startup_preemptirqsoff(struct tracer *trace, struct trace_array *
        /* stop the tracing. */
        tracing_stop();
        /* check both trace buffers */
-       ret = trace_test_buffer(&tr->trace_buffer, NULL);
+       ret = trace_test_buffer(&tr->array_buffer, NULL);
        if (ret)
                goto out;
 
@@ -1136,7 +1136,7 @@ trace_selftest_startup_wakeup(struct tracer *trace, struct trace_array *tr)
        /* stop the tracing. */
        tracing_stop();
        /* check both trace buffers */
-       ret = trace_test_buffer(&tr->trace_buffer, NULL);
+       ret = trace_test_buffer(&tr->array_buffer, NULL);
        if (!ret)
                ret = trace_test_buffer(&tr->max_buffer, &count);
 
@@ -1177,7 +1177,7 @@ trace_selftest_startup_branch(struct tracer *trace, struct trace_array *tr)
        /* stop the tracing. */
        tracing_stop();
        /* check the trace buffer */
-       ret = trace_test_buffer(&tr->trace_buffer, &count);
+       ret = trace_test_buffer(&tr->array_buffer, &count);
        trace->reset(tr);
        tracing_start();
 
index 87de6ed..1d84fcc 100644 (file)
@@ -30,9 +30,6 @@
 /* How much buffer is left on the trace_seq? */
 #define TRACE_SEQ_BUF_LEFT(s) seq_buf_buffer_left(&(s)->seq)
 
-/* How much buffer is written? */
-#define TRACE_SEQ_BUF_USED(s) seq_buf_used(&(s)->seq)
-
 /*
  * trace_seq should work with being initialized with 0s.
  */
index 874f127..d1fa197 100644 (file)
@@ -280,18 +280,22 @@ static int tracing_stat_init(void)
 
        d_tracing = tracing_init_dentry();
        if (IS_ERR(d_tracing))
-               return 0;
+               return -ENODEV;
 
        stat_dir = tracefs_create_dir("trace_stat", d_tracing);
-       if (!stat_dir)
+       if (!stat_dir) {
                pr_warn("Could not create tracefs 'trace_stat' entry\n");
+               return -ENOMEM;
+       }
        return 0;
 }
 
 static int init_stat_file(struct stat_session *session)
 {
-       if (!stat_dir && tracing_stat_init())
-               return -ENODEV;
+       int ret;
+
+       if (!stat_dir && (ret = tracing_stat_init()))
+               return ret;
 
        session->file = tracefs_create_file(session->ts->name, 0644,
                                            stat_dir,
@@ -304,7 +308,7 @@ static int init_stat_file(struct stat_session *session)
 int register_stat_tracer(struct tracer_stat *trace)
 {
        struct stat_session *session, *node;
-       int ret;
+       int ret = -EINVAL;
 
        if (!trace)
                return -EINVAL;
@@ -315,17 +319,15 @@ int register_stat_tracer(struct tracer_stat *trace)
        /* Already registered? */
        mutex_lock(&all_stat_sessions_mutex);
        list_for_each_entry(node, &all_stat_sessions, session_list) {
-               if (node->ts == trace) {
-                       mutex_unlock(&all_stat_sessions_mutex);
-                       return -EINVAL;
-               }
+               if (node->ts == trace)
+                       goto out;
        }
-       mutex_unlock(&all_stat_sessions_mutex);
 
+       ret = -ENOMEM;
        /* Init the session */
        session = kzalloc(sizeof(*session), GFP_KERNEL);
        if (!session)
-               return -ENOMEM;
+               goto out;
 
        session->ts = trace;
        INIT_LIST_HEAD(&session->session_list);
@@ -334,15 +336,16 @@ int register_stat_tracer(struct tracer_stat *trace)
        ret = init_stat_file(session);
        if (ret) {
                destroy_session(session);
-               return ret;
+               goto out;
        }
 
+       ret = 0;
        /* Register */
-       mutex_lock(&all_stat_sessions_mutex);
        list_add_tail(&session->session_list, &all_stat_sessions);
+ out:
        mutex_unlock(&all_stat_sessions_mutex);
 
-       return 0;
+       return ret;
 }
 
 void unregister_stat_tracer(struct tracer_stat *trace)
index 2978c29..d85a2f0 100644 (file)
@@ -297,7 +297,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
        struct syscall_trace_enter *entry;
        struct syscall_metadata *sys_data;
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        unsigned long irq_flags;
        unsigned long args[6];
        int pc;
@@ -325,7 +325,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
        local_save_flags(irq_flags);
        pc = preempt_count();
 
-       buffer = tr->trace_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        event = trace_buffer_lock_reserve(buffer,
                        sys_data->enter_event->event.type, size, irq_flags, pc);
        if (!event)
@@ -347,7 +347,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
        struct syscall_trace_exit *entry;
        struct syscall_metadata *sys_data;
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
+       struct trace_buffer *buffer;
        unsigned long irq_flags;
        int pc;
        int syscall_nr;
@@ -371,7 +371,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
        local_save_flags(irq_flags);
        pc = preempt_count();
 
-       buffer = tr->trace_buffer.buffer;
+       buffer = tr->array_buffer.buffer;
        event = trace_buffer_lock_reserve(buffer,
                        sys_data->exit_event->event.type, sizeof(*entry),
                        irq_flags, pc);
index 7885ebd..18d16f3 100644 (file)
@@ -931,8 +931,8 @@ static void __uprobe_trace_func(struct trace_uprobe *tu,
                                struct trace_event_file *trace_file)
 {
        struct uprobe_trace_entry_head *entry;
+       struct trace_buffer *buffer;
        struct ring_buffer_event *event;
-       struct ring_buffer *buffer;
        void *data;
        int size, esize;
        struct trace_event_call *call = trace_probe_event_call(&tu->tp);
index 53144d0..c6f323d 100644 (file)
@@ -14,7 +14,8 @@ int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
 {
        unsigned long flags;
 
-       WARN_ON(cpu != 0);
+       if (cpu != 0)
+               return -ENXIO;
 
        local_irq_save(flags);
        func(info);
index bc7e563..0cf875f 100644 (file)
@@ -573,6 +573,9 @@ config DIMLIB
 config LIBFDT
        bool
 
+config LIBXBC
+       bool
+
 config OID_REGISTRY
        tristate
        help
index 23ca78d..8bb9117 100644 (file)
@@ -230,6 +230,8 @@ $(foreach file, $(libfdt_files), \
        $(eval CFLAGS_$(file) = -I $(srctree)/scripts/dtc/libfdt))
 lib-$(CONFIG_LIBFDT) += $(libfdt_files)
 
+lib-$(CONFIG_LIBXBC) += bootconfig.o
+
 obj-$(CONFIG_RBTREE_TEST) += rbtree_test.o
 obj-$(CONFIG_INTERVAL_TREE_TEST) += interval_tree_test.o
 
index 6e175fb..89260aa 100644 (file)
@@ -431,97 +431,6 @@ EXPORT_SYMBOL(bitmap_find_next_zero_area_off);
  * second version by Paul Jackson, third by Joe Korty.
  */
 
-#define CHUNKSZ                                32
-#define nbits_to_hold_value(val)       fls(val)
-#define BASEDEC 10             /* fancier cpuset lists input in decimal */
-
-/**
- * __bitmap_parse - convert an ASCII hex string into a bitmap.
- * @buf: pointer to buffer containing string.
- * @buflen: buffer size in bytes.  If string is smaller than this
- *    then it must be terminated with a \0.
- * @is_user: location of buffer, 0 indicates kernel space
- * @maskp: pointer to bitmap array that will contain result.
- * @nmaskbits: size of bitmap, in bits.
- *
- * Commas group hex digits into chunks.  Each chunk defines exactly 32
- * bits of the resultant bitmask.  No chunk may specify a value larger
- * than 32 bits (%-EOVERFLOW), and if a chunk specifies a smaller value
- * then leading 0-bits are prepended.  %-EINVAL is returned for illegal
- * characters and for grouping errors such as "1,,5", ",44", "," and "".
- * Leading and trailing whitespace accepted, but not embedded whitespace.
- */
-int __bitmap_parse(const char *buf, unsigned int buflen,
-               int is_user, unsigned long *maskp,
-               int nmaskbits)
-{
-       int c, old_c, totaldigits, ndigits, nchunks, nbits;
-       u32 chunk;
-       const char __user __force *ubuf = (const char __user __force *)buf;
-
-       bitmap_zero(maskp, nmaskbits);
-
-       nchunks = nbits = totaldigits = c = 0;
-       do {
-               chunk = 0;
-               ndigits = totaldigits;
-
-               /* Get the next chunk of the bitmap */
-               while (buflen) {
-                       old_c = c;
-                       if (is_user) {
-                               if (__get_user(c, ubuf++))
-                                       return -EFAULT;
-                       }
-                       else
-                               c = *buf++;
-                       buflen--;
-                       if (isspace(c))
-                               continue;
-
-                       /*
-                        * If the last character was a space and the current
-                        * character isn't '\0', we've got embedded whitespace.
-                        * This is a no-no, so throw an error.
-                        */
-                       if (totaldigits && c && isspace(old_c))
-                               return -EINVAL;
-
-                       /* A '\0' or a ',' signal the end of the chunk */
-                       if (c == '\0' || c == ',')
-                               break;
-
-                       if (!isxdigit(c))
-                               return -EINVAL;
-
-                       /*
-                        * Make sure there are at least 4 free bits in 'chunk'.
-                        * If not, this hexdigit will overflow 'chunk', so
-                        * throw an error.
-                        */
-                       if (chunk & ~((1UL << (CHUNKSZ - 4)) - 1))
-                               return -EOVERFLOW;
-
-                       chunk = (chunk << 4) | hex_to_bin(c);
-                       totaldigits++;
-               }
-               if (ndigits == totaldigits)
-                       return -EINVAL;
-               if (nchunks == 0 && chunk == 0)
-                       continue;
-
-               __bitmap_shift_left(maskp, maskp, CHUNKSZ, nmaskbits);
-               *maskp |= chunk;
-               nchunks++;
-               nbits += (nchunks == 1) ? nbits_to_hold_value(chunk) : CHUNKSZ;
-               if (nbits > nmaskbits)
-                       return -EOVERFLOW;
-       } while (buflen && c == ',');
-
-       return 0;
-}
-EXPORT_SYMBOL(__bitmap_parse);
-
 /**
  * bitmap_parse_user - convert an ASCII hex string in a user buffer into a bitmap
  *
@@ -530,22 +439,22 @@ EXPORT_SYMBOL(__bitmap_parse);
  *    then it must be terminated with a \0.
  * @maskp: pointer to bitmap array that will contain result.
  * @nmaskbits: size of bitmap, in bits.
- *
- * Wrapper for __bitmap_parse(), providing it with user buffer.
- *
- * We cannot have this as an inline function in bitmap.h because it needs
- * linux/uaccess.h to get the access_ok() declaration and this causes
- * cyclic dependencies.
  */
 int bitmap_parse_user(const char __user *ubuf,
                        unsigned int ulen, unsigned long *maskp,
                        int nmaskbits)
 {
-       if (!access_ok(ubuf, ulen))
-               return -EFAULT;
-       return __bitmap_parse((const char __force *)ubuf,
-                               ulen, 1, maskp, nmaskbits);
+       char *buf;
+       int ret;
 
+       buf = memdup_user_nul(ubuf, ulen);
+       if (IS_ERR(buf))
+               return PTR_ERR(buf);
+
+       ret = bitmap_parse(buf, UINT_MAX, maskp, nmaskbits);
+
+       kfree(buf);
+       return ret;
 }
 EXPORT_SYMBOL(bitmap_parse_user);
 
@@ -653,6 +562,14 @@ static const char *bitmap_find_region(const char *str)
        return end_of_str(*str) ? NULL : str;
 }
 
+static const char *bitmap_find_region_reverse(const char *start, const char *end)
+{
+       while (start <= end && __end_of_region(*end))
+               end--;
+
+       return end;
+}
+
 static const char *bitmap_parse_region(const char *str, struct region *r)
 {
        str = bitmap_getnum(str, &r->start);
@@ -776,6 +693,80 @@ int bitmap_parselist_user(const char __user *ubuf,
 }
 EXPORT_SYMBOL(bitmap_parselist_user);
 
+static const char *bitmap_get_x32_reverse(const char *start,
+                                       const char *end, u32 *num)
+{
+       u32 ret = 0;
+       int c, i;
+
+       for (i = 0; i < 32; i += 4) {
+               c = hex_to_bin(*end--);
+               if (c < 0)
+                       return ERR_PTR(-EINVAL);
+
+               ret |= c << i;
+
+               if (start > end || __end_of_region(*end))
+                       goto out;
+       }
+
+       if (hex_to_bin(*end--) >= 0)
+               return ERR_PTR(-EOVERFLOW);
+out:
+       *num = ret;
+       return end;
+}
+
+/**
+ * bitmap_parse - convert an ASCII hex string into a bitmap.
+ * @start: pointer to buffer containing string.
+ * @buflen: buffer size in bytes.  If string is smaller than this
+ *    then it must be terminated with a \0 or \n. In that case,
+ *    UINT_MAX may be provided instead of string length.
+ * @maskp: pointer to bitmap array that will contain result.
+ * @nmaskbits: size of bitmap, in bits.
+ *
+ * Commas group hex digits into chunks.  Each chunk defines exactly 32
+ * bits of the resultant bitmask.  No chunk may specify a value larger
+ * than 32 bits (%-EOVERFLOW), and if a chunk specifies a smaller value
+ * then leading 0-bits are prepended.  %-EINVAL is returned for illegal
+ * characters. Grouping such as "1,,5", ",44", "," or "" is allowed.
+ * Leading, embedded and trailing whitespace accepted.
+ */
+int bitmap_parse(const char *start, unsigned int buflen,
+               unsigned long *maskp, int nmaskbits)
+{
+       const char *end = strnchrnul(start, buflen, '\n') - 1;
+       int chunks = BITS_TO_U32(nmaskbits);
+       u32 *bitmap = (u32 *)maskp;
+       int unset_bit;
+
+       while (1) {
+               end = bitmap_find_region_reverse(start, end);
+               if (start > end)
+                       break;
+
+               if (!chunks--)
+                       return -EOVERFLOW;
+
+               end = bitmap_get_x32_reverse(start, end, bitmap++);
+               if (IS_ERR(end))
+                       return PTR_ERR(end);
+       }
+
+       unset_bit = (BITS_TO_U32(nmaskbits) - chunks) * 32;
+       if (unset_bit < nmaskbits) {
+               bitmap_clear(maskp, unset_bit, nmaskbits - unset_bit);
+               return 0;
+       }
+
+       if (find_next_bit(maskp, unset_bit, nmaskbits) != unset_bit)
+               return -EOVERFLOW;
+
+       return 0;
+}
+EXPORT_SYMBOL(bitmap_parse);
+
 
 #ifdef CONFIG_NUMA
 /**
diff --git a/lib/bootconfig.c b/lib/bootconfig.c
new file mode 100644 (file)
index 0000000..afb2e76
--- /dev/null
@@ -0,0 +1,814 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Extra Boot Config
+ * Masami Hiramatsu <mhiramat@kernel.org>
+ */
+
+#define pr_fmt(fmt)    "bootconfig: " fmt
+
+#include <linux/bug.h>
+#include <linux/ctype.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/printk.h>
+#include <linux/bootconfig.h>
+#include <linux/string.h>
+
+/*
+ * Extra Boot Config (XBC) is given as tree-structured ascii text of
+ * key-value pairs on memory.
+ * xbc_parse() parses the text to build a simple tree. Each tree node is
+ * simply a key word or a value. A key node may have a next key node or/and
+ * a child node (both key and value). A value node may have a next value
+ * node (for array).
+ */
+
+static struct xbc_node xbc_nodes[XBC_NODE_MAX] __initdata;
+static int xbc_node_num __initdata;
+static char *xbc_data __initdata;
+static size_t xbc_data_size __initdata;
+static struct xbc_node *last_parent __initdata;
+
+static int __init xbc_parse_error(const char *msg, const char *p)
+{
+       int pos = p - xbc_data;
+
+       pr_err("Parse error at pos %d: %s\n", pos, msg);
+       return -EINVAL;
+}
+
+/**
+ * xbc_root_node() - Get the root node of extended boot config
+ *
+ * Return the address of root node of extended boot config. If the
+ * extended boot config is not initiized, return NULL.
+ */
+struct xbc_node * __init xbc_root_node(void)
+{
+       if (unlikely(!xbc_data))
+               return NULL;
+
+       return xbc_nodes;
+}
+
+/**
+ * xbc_node_index() - Get the index of XBC node
+ * @node: A target node of getting index.
+ *
+ * Return the index number of @node in XBC node list.
+ */
+int __init xbc_node_index(struct xbc_node *node)
+{
+       return node - &xbc_nodes[0];
+}
+
+/**
+ * xbc_node_get_parent() - Get the parent XBC node
+ * @node: An XBC node.
+ *
+ * Return the parent node of @node. If the node is top node of the tree,
+ * return NULL.
+ */
+struct xbc_node * __init xbc_node_get_parent(struct xbc_node *node)
+{
+       return node->parent == XBC_NODE_MAX ? NULL : &xbc_nodes[node->parent];
+}
+
+/**
+ * xbc_node_get_child() - Get the child XBC node
+ * @node: An XBC node.
+ *
+ * Return the first child node of @node. If the node has no child, return
+ * NULL.
+ */
+struct xbc_node * __init xbc_node_get_child(struct xbc_node *node)
+{
+       return node->child ? &xbc_nodes[node->child] : NULL;
+}
+
+/**
+ * xbc_node_get_next() - Get the next sibling XBC node
+ * @node: An XBC node.
+ *
+ * Return the NEXT sibling node of @node. If the node has no next sibling,
+ * return NULL. Note that even if this returns NULL, it doesn't mean @node
+ * has no siblings. (You also has to check whether the parent's child node
+ * is @node or not.)
+ */
+struct xbc_node * __init xbc_node_get_next(struct xbc_node *node)
+{
+       return node->next ? &xbc_nodes[node->next] : NULL;
+}
+
+/**
+ * xbc_node_get_data() - Get the data of XBC node
+ * @node: An XBC node.
+ *
+ * Return the data (which is always a null terminated string) of @node.
+ * If the node has invalid data, warn and return NULL.
+ */
+const char * __init xbc_node_get_data(struct xbc_node *node)
+{
+       int offset = node->data & ~XBC_VALUE;
+
+       if (WARN_ON(offset >= xbc_data_size))
+               return NULL;
+
+       return xbc_data + offset;
+}
+
+static bool __init
+xbc_node_match_prefix(struct xbc_node *node, const char **prefix)
+{
+       const char *p = xbc_node_get_data(node);
+       int len = strlen(p);
+
+       if (strncmp(*prefix, p, len))
+               return false;
+
+       p = *prefix + len;
+       if (*p == '.')
+               p++;
+       else if (*p != '\0')
+               return false;
+       *prefix = p;
+
+       return true;
+}
+
+/**
+ * xbc_node_find_child() - Find a child node which matches given key
+ * @parent: An XBC node.
+ * @key: A key string.
+ *
+ * Search a node under @parent which matches @key. The @key can contain
+ * several words jointed with '.'. If @parent is NULL, this searches the
+ * node from whole tree. Return NULL if no node is matched.
+ */
+struct xbc_node * __init
+xbc_node_find_child(struct xbc_node *parent, const char *key)
+{
+       struct xbc_node *node;
+
+       if (parent)
+               node = xbc_node_get_child(parent);
+       else
+               node = xbc_root_node();
+
+       while (node && xbc_node_is_key(node)) {
+               if (!xbc_node_match_prefix(node, &key))
+                       node = xbc_node_get_next(node);
+               else if (*key != '\0')
+                       node = xbc_node_get_child(node);
+               else
+                       break;
+       }
+
+       return node;
+}
+
+/**
+ * xbc_node_find_value() - Find a value node which matches given key
+ * @parent: An XBC node.
+ * @key: A key string.
+ * @vnode: A container pointer of found XBC node.
+ *
+ * Search a value node under @parent whose (parent) key node matches @key,
+ * store it in *@vnode, and returns the value string.
+ * The @key can contain several words jointed with '.'. If @parent is NULL,
+ * this searches the node from whole tree. Return the value string if a
+ * matched key found, return NULL if no node is matched.
+ * Note that this returns 0-length string and stores NULL in *@vnode if the
+ * key has no value. And also it will return the value of the first entry if
+ * the value is an array.
+ */
+const char * __init
+xbc_node_find_value(struct xbc_node *parent, const char *key,
+                   struct xbc_node **vnode)
+{
+       struct xbc_node *node = xbc_node_find_child(parent, key);
+
+       if (!node || !xbc_node_is_key(node))
+               return NULL;
+
+       node = xbc_node_get_child(node);
+       if (node && !xbc_node_is_value(node))
+               return NULL;
+
+       if (vnode)
+               *vnode = node;
+
+       return node ? xbc_node_get_data(node) : "";
+}
+
+/**
+ * xbc_node_compose_key_after() - Compose partial key string of the XBC node
+ * @root: Root XBC node
+ * @node: Target XBC node.
+ * @buf: A buffer to store the key.
+ * @size: The size of the @buf.
+ *
+ * Compose the partial key of the @node into @buf, which is starting right
+ * after @root (@root is not included.) If @root is NULL, this returns full
+ * key words of @node.
+ * Returns the total length of the key stored in @buf. Returns -EINVAL
+ * if @node is NULL or @root is not the ancestor of @node or @root is @node,
+ * or returns -ERANGE if the key depth is deeper than max depth.
+ * This is expected to be used with xbc_find_node() to list up all (child)
+ * keys under given key.
+ */
+int __init xbc_node_compose_key_after(struct xbc_node *root,
+                                     struct xbc_node *node,
+                                     char *buf, size_t size)
+{
+       u16 keys[XBC_DEPTH_MAX];
+       int depth = 0, ret = 0, total = 0;
+
+       if (!node || node == root)
+               return -EINVAL;
+
+       if (xbc_node_is_value(node))
+               node = xbc_node_get_parent(node);
+
+       while (node && node != root) {
+               keys[depth++] = xbc_node_index(node);
+               if (depth == XBC_DEPTH_MAX)
+                       return -ERANGE;
+               node = xbc_node_get_parent(node);
+       }
+       if (!node && root)
+               return -EINVAL;
+
+       while (--depth >= 0) {
+               node = xbc_nodes + keys[depth];
+               ret = snprintf(buf, size, "%s%s", xbc_node_get_data(node),
+                              depth ? "." : "");
+               if (ret < 0)
+                       return ret;
+               if (ret > size) {
+                       size = 0;
+               } else {
+                       size -= ret;
+                       buf += ret;
+               }
+               total += ret;
+       }
+
+       return total;
+}
+
+/**
+ * xbc_node_find_next_leaf() - Find the next leaf node under given node
+ * @root: An XBC root node
+ * @node: An XBC node which starts from.
+ *
+ * Search the next leaf node (which means the terminal key node) of @node
+ * under @root node (including @root node itself).
+ * Return the next node or NULL if next leaf node is not found.
+ */
+struct xbc_node * __init xbc_node_find_next_leaf(struct xbc_node *root,
+                                                struct xbc_node *node)
+{
+       if (unlikely(!xbc_data))
+               return NULL;
+
+       if (!node) {    /* First try */
+               node = root;
+               if (!node)
+                       node = xbc_nodes;
+       } else {
+               if (node == root)       /* @root was a leaf, no child node. */
+                       return NULL;
+
+               while (!node->next) {
+                       node = xbc_node_get_parent(node);
+                       if (node == root)
+                               return NULL;
+                       /* User passed a node which is not uder parent */
+                       if (WARN_ON(!node))
+                               return NULL;
+               }
+               node = xbc_node_get_next(node);
+       }
+
+       while (node && !xbc_node_is_leaf(node))
+               node = xbc_node_get_child(node);
+
+       return node;
+}
+
+/**
+ * xbc_node_find_next_key_value() - Find the next key-value pair nodes
+ * @root: An XBC root node
+ * @leaf: A container pointer of XBC node which starts from.
+ *
+ * Search the next leaf node (which means the terminal key node) of *@leaf
+ * under @root node. Returns the value and update *@leaf if next leaf node
+ * is found, or NULL if no next leaf node is found.
+ * Note that this returns 0-length string if the key has no value, or
+ * the value of the first entry if the value is an array.
+ */
+const char * __init xbc_node_find_next_key_value(struct xbc_node *root,
+                                                struct xbc_node **leaf)
+{
+       /* tip must be passed */
+       if (WARN_ON(!leaf))
+               return NULL;
+
+       *leaf = xbc_node_find_next_leaf(root, *leaf);
+       if (!*leaf)
+               return NULL;
+       if ((*leaf)->child)
+               return xbc_node_get_data(xbc_node_get_child(*leaf));
+       else
+               return "";      /* No value key */
+}
+
+/* XBC parse and tree build */
+
+static struct xbc_node * __init xbc_add_node(char *data, u32 flag)
+{
+       struct xbc_node *node;
+       unsigned long offset;
+
+       if (xbc_node_num == XBC_NODE_MAX)
+               return NULL;
+
+       node = &xbc_nodes[xbc_node_num++];
+       offset = data - xbc_data;
+       node->data = (u16)offset;
+       if (WARN_ON(offset >= XBC_DATA_MAX))
+               return NULL;
+       node->data |= flag;
+       node->child = 0;
+       node->next = 0;
+
+       return node;
+}
+
+static inline __init struct xbc_node *xbc_last_sibling(struct xbc_node *node)
+{
+       while (node->next)
+               node = xbc_node_get_next(node);
+
+       return node;
+}
+
+static struct xbc_node * __init xbc_add_sibling(char *data, u32 flag)
+{
+       struct xbc_node *sib, *node = xbc_add_node(data, flag);
+
+       if (node) {
+               if (!last_parent) {
+                       node->parent = XBC_NODE_MAX;
+                       sib = xbc_last_sibling(xbc_nodes);
+                       sib->next = xbc_node_index(node);
+               } else {
+                       node->parent = xbc_node_index(last_parent);
+                       if (!last_parent->child) {
+                               last_parent->child = xbc_node_index(node);
+                       } else {
+                               sib = xbc_node_get_child(last_parent);
+                               sib = xbc_last_sibling(sib);
+                               sib->next = xbc_node_index(node);
+                       }
+               }
+       } else
+               xbc_parse_error("Too many nodes", data);
+
+       return node;
+}
+
+static inline __init struct xbc_node *xbc_add_child(char *data, u32 flag)
+{
+       struct xbc_node *node = xbc_add_sibling(data, flag);
+
+       if (node)
+               last_parent = node;
+
+       return node;
+}
+
+static inline __init bool xbc_valid_keyword(char *key)
+{
+       if (key[0] == '\0')
+               return false;
+
+       while (isalnum(*key) || *key == '-' || *key == '_')
+               key++;
+
+       return *key == '\0';
+}
+
+static char *skip_comment(char *p)
+{
+       char *ret;
+
+       ret = strchr(p, '\n');
+       if (!ret)
+               ret = p + strlen(p);
+       else
+               ret++;
+
+       return ret;
+}
+
+static char *skip_spaces_until_newline(char *p)
+{
+       while (isspace(*p) && *p != '\n')
+               p++;
+       return p;
+}
+
+static int __init __xbc_open_brace(void)
+{
+       /* Mark the last key as open brace */
+       last_parent->next = XBC_NODE_MAX;
+
+       return 0;
+}
+
+static int __init __xbc_close_brace(char *p)
+{
+       struct xbc_node *node;
+
+       if (!last_parent || last_parent->next != XBC_NODE_MAX)
+               return xbc_parse_error("Unexpected closing brace", p);
+
+       node = last_parent;
+       node->next = 0;
+       do {
+               node = xbc_node_get_parent(node);
+       } while (node && node->next != XBC_NODE_MAX);
+       last_parent = node;
+
+       return 0;
+}
+
+/*
+ * Return delimiter or error, no node added. As same as lib/cmdline.c,
+ * you can use " around spaces, but can't escape " for value.
+ */
+static int __init __xbc_parse_value(char **__v, char **__n)
+{
+       char *p, *v = *__v;
+       int c, quotes = 0;
+
+       v = skip_spaces(v);
+       while (*v == '#') {
+               v = skip_comment(v);
+               v = skip_spaces(v);
+       }
+       if (*v == '"' || *v == '\'') {
+               quotes = *v;
+               v++;
+       }
+       p = v - 1;
+       while ((c = *++p)) {
+               if (!isprint(c) && !isspace(c))
+                       return xbc_parse_error("Non printable value", p);
+               if (quotes) {
+                       if (c != quotes)
+                               continue;
+                       quotes = 0;
+                       *p++ = '\0';
+                       p = skip_spaces_until_newline(p);
+                       c = *p;
+                       if (c && !strchr(",;\n#}", c))
+                               return xbc_parse_error("No value delimiter", p);
+                       if (*p)
+                               p++;
+                       break;
+               }
+               if (strchr(",;\n#}", c)) {
+                       v = strim(v);
+                       *p++ = '\0';
+                       break;
+               }
+       }
+       if (quotes)
+               return xbc_parse_error("No closing quotes", p);
+       if (c == '#') {
+               p = skip_comment(p);
+               c = '\n';       /* A comment must be treated as a newline */
+       }
+       *__n = p;
+       *__v = v;
+
+       return c;
+}
+
+static int __init xbc_parse_array(char **__v)
+{
+       struct xbc_node *node;
+       char *next;
+       int c = 0;
+
+       do {
+               c = __xbc_parse_value(__v, &next);
+               if (c < 0)
+                       return c;
+
+               node = xbc_add_sibling(*__v, XBC_VALUE);
+               if (!node)
+                       return -ENOMEM;
+               *__v = next;
+       } while (c == ',');
+       node->next = 0;
+
+       return c;
+}
+
+static inline __init
+struct xbc_node *find_match_node(struct xbc_node *node, char *k)
+{
+       while (node) {
+               if (!strcmp(xbc_node_get_data(node), k))
+                       break;
+               node = xbc_node_get_next(node);
+       }
+       return node;
+}
+
+static int __init __xbc_add_key(char *k)
+{
+       struct xbc_node *node;
+
+       if (!xbc_valid_keyword(k))
+               return xbc_parse_error("Invalid keyword", k);
+
+       if (unlikely(xbc_node_num == 0))
+               goto add_node;
+
+       if (!last_parent)       /* the first level */
+               node = find_match_node(xbc_nodes, k);
+       else
+               node = find_match_node(xbc_node_get_child(last_parent), k);
+
+       if (node)
+               last_parent = node;
+       else {
+add_node:
+               node = xbc_add_child(k, XBC_KEY);
+               if (!node)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+static int __init __xbc_parse_keys(char *k)
+{
+       char *p;
+       int ret;
+
+       k = strim(k);
+       while ((p = strchr(k, '.'))) {
+               *p++ = '\0';
+               ret = __xbc_add_key(k);
+               if (ret)
+                       return ret;
+               k = p;
+       }
+
+       return __xbc_add_key(k);
+}
+
+static int __init xbc_parse_kv(char **k, char *v)
+{
+       struct xbc_node *prev_parent = last_parent;
+       struct xbc_node *node;
+       char *next;
+       int c, ret;
+
+       ret = __xbc_parse_keys(*k);
+       if (ret)
+               return ret;
+
+       c = __xbc_parse_value(&v, &next);
+       if (c < 0)
+               return c;
+
+       node = xbc_add_sibling(v, XBC_VALUE);
+       if (!node)
+               return -ENOMEM;
+
+       if (c == ',') { /* Array */
+               c = xbc_parse_array(&next);
+               if (c < 0)
+                       return c;
+       }
+
+       last_parent = prev_parent;
+
+       if (c == '}') {
+               ret = __xbc_close_brace(next - 1);
+               if (ret < 0)
+                       return ret;
+       }
+
+       *k = next;
+
+       return 0;
+}
+
+static int __init xbc_parse_key(char **k, char *n)
+{
+       struct xbc_node *prev_parent = last_parent;
+       int ret;
+
+       *k = strim(*k);
+       if (**k != '\0') {
+               ret = __xbc_parse_keys(*k);
+               if (ret)
+                       return ret;
+               last_parent = prev_parent;
+       }
+       *k = n;
+
+       return 0;
+}
+
+static int __init xbc_open_brace(char **k, char *n)
+{
+       int ret;
+
+       ret = __xbc_parse_keys(*k);
+       if (ret)
+               return ret;
+       *k = n;
+
+       return __xbc_open_brace();
+}
+
+static int __init xbc_close_brace(char **k, char *n)
+{
+       int ret;
+
+       ret = xbc_parse_key(k, n);
+       if (ret)
+               return ret;
+       /* k is updated in xbc_parse_key() */
+
+       return __xbc_close_brace(n - 1);
+}
+
+static int __init xbc_verify_tree(void)
+{
+       int i, depth, len, wlen;
+       struct xbc_node *n, *m;
+
+       /* Empty tree */
+       if (xbc_node_num == 0) {
+               xbc_parse_error("Empty config", xbc_data);
+               return -ENOENT;
+       }
+
+       for (i = 0; i < xbc_node_num; i++) {
+               if (xbc_nodes[i].next > xbc_node_num) {
+                       return xbc_parse_error("No closing brace",
+                               xbc_node_get_data(xbc_nodes + i));
+               }
+       }
+
+       /* Key tree limitation check */
+       n = &xbc_nodes[0];
+       depth = 1;
+       len = 0;
+
+       while (n) {
+               wlen = strlen(xbc_node_get_data(n)) + 1;
+               len += wlen;
+               if (len > XBC_KEYLEN_MAX)
+                       return xbc_parse_error("Too long key length",
+                               xbc_node_get_data(n));
+
+               m = xbc_node_get_child(n);
+               if (m && xbc_node_is_key(m)) {
+                       n = m;
+                       depth++;
+                       if (depth > XBC_DEPTH_MAX)
+                               return xbc_parse_error("Too many key words",
+                                               xbc_node_get_data(n));
+                       continue;
+               }
+               len -= wlen;
+               m = xbc_node_get_next(n);
+               while (!m) {
+                       n = xbc_node_get_parent(n);
+                       if (!n)
+                               break;
+                       len -= strlen(xbc_node_get_data(n)) + 1;
+                       depth--;
+                       m = xbc_node_get_next(n);
+               }
+               n = m;
+       }
+
+       return 0;
+}
+
+/**
+ * xbc_destroy_all() - Clean up all parsed bootconfig
+ *
+ * This clears all data structures of parsed bootconfig on memory.
+ * If you need to reuse xbc_init() with new boot config, you can
+ * use this.
+ */
+void __init xbc_destroy_all(void)
+{
+       xbc_data = NULL;
+       xbc_data_size = 0;
+       xbc_node_num = 0;
+       memset(xbc_nodes, 0, sizeof(xbc_nodes));
+}
+
+/**
+ * xbc_init() - Parse given XBC file and build XBC internal tree
+ * @buf: boot config text
+ *
+ * This parses the boot config text in @buf. @buf must be a
+ * null terminated string and smaller than XBC_DATA_MAX.
+ * Return the number of stored nodes (>0) if succeeded, or -errno
+ * if there is any error.
+ */
+int __init xbc_init(char *buf)
+{
+       char *p, *q;
+       int ret, c;
+
+       if (xbc_data) {
+               pr_err("Error: bootconfig is already initialized.\n");
+               return -EBUSY;
+       }
+
+       ret = strlen(buf);
+       if (ret > XBC_DATA_MAX - 1 || ret == 0) {
+               pr_err("Error: Config data is %s.\n",
+                       ret ? "too big" : "empty");
+               return -ERANGE;
+       }
+
+       xbc_data = buf;
+       xbc_data_size = ret + 1;
+       last_parent = NULL;
+
+       p = buf;
+       do {
+               q = strpbrk(p, "{}=;\n#");
+               if (!q) {
+                       p = skip_spaces(p);
+                       if (*p != '\0')
+                               ret = xbc_parse_error("No delimiter", p);
+                       break;
+               }
+
+               c = *q;
+               *q++ = '\0';
+               switch (c) {
+               case '=':
+                       ret = xbc_parse_kv(&p, q);
+                       break;
+               case '{':
+                       ret = xbc_open_brace(&p, q);
+                       break;
+               case '#':
+                       q = skip_comment(q);
+                       /* fall through */
+               case ';':
+               case '\n':
+                       ret = xbc_parse_key(&p, q);
+                       break;
+               case '}':
+                       ret = xbc_close_brace(&p, q);
+                       break;
+               }
+       } while (!ret);
+
+       if (!ret)
+               ret = xbc_verify_tree();
+
+       if (ret < 0)
+               xbc_destroy_all();
+       else
+               ret = xbc_node_num;
+
+       return ret;
+}
+
+/**
+ * xbc_debug_dump() - Dump current XBC node list
+ *
+ * Dump the current XBC node list on printk buffer for debug.
+ */
+void __init xbc_debug_dump(void)
+{
+       int i;
+
+       for (i = 0; i < xbc_node_num; i++) {
+               pr_debug("[%d] %s (%s) .next=%d, .child=%d .parent=%d\n", i,
+                       xbc_node_get_data(xbc_nodes + i),
+                       xbc_node_is_value(xbc_nodes + i) ? "value" : "key",
+                       xbc_nodes[i].next, xbc_nodes[i].child,
+                       xbc_nodes[i].parent);
+       }
+}
index 08ec58c..f607b96 100644 (file)
@@ -434,6 +434,23 @@ char *strchrnul(const char *s, int c)
 EXPORT_SYMBOL(strchrnul);
 #endif
 
+/**
+ * strnchrnul - Find and return a character in a length limited string,
+ * or end of string
+ * @s: The string to be searched
+ * @count: The number of characters to be searched
+ * @c: The character to search for
+ *
+ * Returns pointer to the first occurrence of 'c' in s. If c is not found,
+ * then return a pointer to the last character of the string.
+ */
+char *strnchrnul(const char *s, size_t count, int c)
+{
+       while (count-- && *s && *s != (char)c)
+               s++;
+       return (char *)s;
+}
+
 #ifndef __HAVE_ARCH_STRRCHR
 /**
  * strrchr - Find the last occurrence of a character in a string
index 71ec3af..61ed71c 100644 (file)
@@ -295,7 +295,8 @@ static void __init test_replace(void)
        expect_eq_bitmap(bmap, exp3_1_0, nbits);
 }
 
-#define PARSE_TIME 0x1
+#define PARSE_TIME     0x1
+#define NO_LEN         0x2
 
 struct test_bitmap_parselist{
        const int errno;
@@ -349,7 +350,6 @@ static const struct test_bitmap_parselist parselist_tests[] __initconst = {
        {-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)
@@ -401,6 +401,95 @@ static void __init __test_bitmap_parselist(int is_user)
        }
 }
 
+static const unsigned long parse_test[] __initconst = {
+       BITMAP_FROM_U64(0),
+       BITMAP_FROM_U64(1),
+       BITMAP_FROM_U64(0xdeadbeef),
+       BITMAP_FROM_U64(0x100000000ULL),
+};
+
+static const unsigned long parse_test2[] __initconst = {
+       BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xdeadbeef),
+       BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0xbaadf00ddeadbeef),
+       BITMAP_FROM_U64(0x100000000ULL), BITMAP_FROM_U64(0x0badf00ddeadbeef),
+};
+
+static const struct test_bitmap_parselist parse_tests[] __initconst = {
+       {0, "",                         &parse_test[0 * step], 32, 0},
+       {0, " ",                        &parse_test[0 * step], 32, 0},
+       {0, "0",                        &parse_test[0 * step], 32, 0},
+       {0, "0\n",                      &parse_test[0 * step], 32, 0},
+       {0, "1",                        &parse_test[1 * step], 32, 0},
+       {0, "deadbeef",                 &parse_test[2 * step], 32, 0},
+       {0, "1,0",                      &parse_test[3 * step], 33, 0},
+       {0, "deadbeef,\n,0,1",          &parse_test[2 * step], 96, 0},
+
+       {0, "deadbeef,1,0",             &parse_test2[0 * 2 * step], 96, 0},
+       {0, "baadf00d,deadbeef,1,0",    &parse_test2[1 * 2 * step], 128, 0},
+       {0, "badf00d,deadbeef,1,0",     &parse_test2[2 * 2 * step], 124, 0},
+       {0, "badf00d,deadbeef,1,0",     &parse_test2[2 * 2 * step], 124, NO_LEN},
+       {0, "  badf00d,deadbeef,1,0  ", &parse_test2[2 * 2 * step], 124, 0},
+       {0, " , badf00d,deadbeef,1,0 , ",       &parse_test2[2 * 2 * step], 124, 0},
+       {0, " , badf00d, ,, ,,deadbeef,1,0 , ", &parse_test2[2 * 2 * step], 124, 0},
+
+       {-EINVAL,    "goodfood,deadbeef,1,0",   NULL, 128, 0},
+       {-EOVERFLOW, "3,0",                     NULL, 33, 0},
+       {-EOVERFLOW, "123badf00d,deadbeef,1,0", NULL, 128, 0},
+       {-EOVERFLOW, "badf00d,deadbeef,1,0",    NULL, 90, 0},
+       {-EOVERFLOW, "fbadf00d,deadbeef,1,0",   NULL, 95, 0},
+       {-EOVERFLOW, "badf00d,deadbeef,1,0",    NULL, 100, 0},
+#undef step
+};
+
+static void __init __test_bitmap_parse(int is_user)
+{
+       int i;
+       int err;
+       ktime_t time;
+       DECLARE_BITMAP(bmap, 2048);
+       char *mode = is_user ? "_user"  : "";
+
+       for (i = 0; i < ARRAY_SIZE(parse_tests); i++) {
+               struct test_bitmap_parselist test = parse_tests[i];
+
+               if (is_user) {
+                       size_t len = strlen(test.in);
+                       mm_segment_t orig_fs = get_fs();
+
+                       set_fs(KERNEL_DS);
+                       time = ktime_get();
+                       err = bitmap_parse_user((__force const char __user *)test.in, len,
+                                               bmap, test.nbits);
+                       time = ktime_get() - time;
+                       set_fs(orig_fs);
+               } else {
+                       size_t len = test.flags & NO_LEN ?
+                               UINT_MAX : strlen(test.in);
+                       time = ktime_get();
+                       err = bitmap_parse(test.in, len, bmap, test.nbits);
+                       time = ktime_get() - time;
+               }
+
+               if (err != test.errno) {
+                       pr_err("parse%s: %d: input is %s, errno is %d, expected %d\n",
+                                       mode, i, test.in, err, test.errno);
+                       continue;
+               }
+
+               if (!err && test.expected
+                        && !__bitmap_equal(bmap, test.expected, test.nbits)) {
+                       pr_err("parse%s: %d: input is %s, result is 0x%lx, expected 0x%lx\n",
+                                       mode, i, test.in, bmap[0],
+                                       *test.expected);
+                       continue;
+               }
+
+               if (test.flags & PARSE_TIME)
+                       pr_err("parse%s: %d: input is '%s' OK, Time: %llu\n",
+                                       mode, i, test.in, time);
+       }
+}
+
 static void __init test_bitmap_parselist(void)
 {
        __test_bitmap_parselist(0);
@@ -411,6 +500,16 @@ static void __init test_bitmap_parselist_user(void)
        __test_bitmap_parselist(1);
 }
 
+static void __init test_bitmap_parse(void)
+{
+       __test_bitmap_parse(0);
+}
+
+static void __init test_bitmap_parse_user(void)
+{
+       __test_bitmap_parse(1);
+}
+
 #define EXP1_IN_BITS   (sizeof(exp1) * 8)
 
 static void __init test_bitmap_arr32(void)
@@ -516,6 +615,8 @@ static void __init selftest(void)
        test_copy();
        test_replace();
        test_bitmap_arr32();
+       test_bitmap_parse();
+       test_bitmap_parse_user();
        test_bitmap_parselist();
        test_bitmap_parselist_user();
        test_mem_optimisations();
index 327b3eb..0271b22 100644 (file)
@@ -117,3 +117,24 @@ config DEBUG_RODATA_TEST
     depends on STRICT_KERNEL_RWX
     ---help---
       This option enables a testcase for the setting rodata read-only.
+
+config GENERIC_PTDUMP
+       bool
+
+config PTDUMP_CORE
+       bool
+
+config PTDUMP_DEBUGFS
+       bool "Export kernel pagetable layout to userspace via debugfs"
+       depends on DEBUG_KERNEL
+       depends on DEBUG_FS
+       depends on GENERIC_PTDUMP
+       select PTDUMP_CORE
+       help
+         Say Y here if you want to show the kernel pagetable layout in a
+         debugfs file. This information is only useful for kernel developers
+         who are working in architecture specific areas of the kernel.
+         It is probably not a good idea to enable this feature in a production
+         kernel.
+
+         If in doubt, say N.
index 32f08e2..272e660 100644 (file)
@@ -109,3 +109,4 @@ obj-$(CONFIG_ZONE_DEVICE) += memremap.o
 obj-$(CONFIG_HMM_MIRROR) += hmm.o
 obj-$(CONFIG_MEMFD_CREATE) += memfd.o
 obj-$(CONFIG_MAPPING_DIRTY_HELPERS) += mapping_dirty_helpers.o
+obj-$(CONFIG_PTDUMP_CORE) += ptdump.o
index e13f4d2..1b521e0 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -1792,7 +1792,7 @@ EXPORT_SYMBOL(get_user_pages_unlocked);
  * Before activating this code, please be aware that the following assumptions
  * are currently made:
  *
- *  *) Either HAVE_RCU_TABLE_FREE is enabled, and tlb_remove_table() is used to
+ *  *) Either MMU_GATHER_RCU_TABLE_FREE is enabled, and tlb_remove_table() is used to
  *  free pages containing page tables or TLB flushing requires IPI broadcast.
  *
  *  *) ptes can be read atomically by the architecture.
index d379cb6..72e5a6d 100644 (file)
--- a/mm/hmm.c
+++ b/mm/hmm.c
@@ -186,7 +186,7 @@ static void hmm_range_need_fault(const struct hmm_vma_walk *hmm_vma_walk,
 }
 
 static int hmm_vma_walk_hole(unsigned long addr, unsigned long end,
-                            struct mm_walk *walk)
+                            __always_unused int depth, struct mm_walk *walk)
 {
        struct hmm_vma_walk *hmm_vma_walk = walk->private;
        struct hmm_range *range = hmm_vma_walk->range;
@@ -380,7 +380,7 @@ static int hmm_vma_walk_pmd(pmd_t *pmdp,
 again:
        pmd = READ_ONCE(*pmdp);
        if (pmd_none(pmd))
-               return hmm_vma_walk_hole(start, end, walk);
+               return hmm_vma_walk_hole(start, end, -1, walk);
 
        if (thp_migration_supported() && is_pmd_migration_entry(pmd)) {
                bool fault, write_fault;
@@ -474,23 +474,32 @@ static int hmm_vma_walk_pud(pud_t *pudp, unsigned long start, unsigned long end,
 {
        struct hmm_vma_walk *hmm_vma_walk = walk->private;
        struct hmm_range *range = hmm_vma_walk->range;
-       unsigned long addr = start, next;
-       pmd_t *pmdp;
+       unsigned long addr = start;
        pud_t pud;
-       int ret;
+       int ret = 0;
+       spinlock_t *ptl = pud_trans_huge_lock(pudp, walk->vma);
+
+       if (!ptl)
+               return 0;
+
+       /* Normally we don't want to split the huge page */
+       walk->action = ACTION_CONTINUE;
 
-again:
        pud = READ_ONCE(*pudp);
-       if (pud_none(pud))
-               return hmm_vma_walk_hole(start, end, walk);
+       if (pud_none(pud)) {
+               ret = hmm_vma_walk_hole(start, end, -1, walk);
+               goto out_unlock;
+       }
 
        if (pud_huge(pud) && pud_devmap(pud)) {
                unsigned long i, npages, pfn;
                uint64_t *pfns, cpu_flags;
                bool fault, write_fault;
 
-               if (!pud_present(pud))
-                       return hmm_vma_walk_hole(start, end, walk);
+               if (!pud_present(pud)) {
+                       ret = hmm_vma_walk_hole(start, end, -1, walk);
+                       goto out_unlock;
+               }
 
                i = (addr - range->start) >> PAGE_SHIFT;
                npages = (end - addr) >> PAGE_SHIFT;
@@ -499,16 +508,20 @@ again:
                cpu_flags = pud_to_hmm_pfn_flags(range, pud);
                hmm_range_need_fault(hmm_vma_walk, pfns, npages,
                                     cpu_flags, &fault, &write_fault);
-               if (fault || write_fault)
-                       return hmm_vma_walk_hole_(addr, end, fault,
-                                               write_fault, walk);
+               if (fault || write_fault) {
+                       ret = hmm_vma_walk_hole_(addr, end, fault,
+                                                write_fault, walk);
+                       goto out_unlock;
+               }
 
                pfn = pud_pfn(pud) + ((addr & ~PUD_MASK) >> PAGE_SHIFT);
                for (i = 0; i < npages; ++i, ++pfn) {
                        hmm_vma_walk->pgmap = get_dev_pagemap(pfn,
                                              hmm_vma_walk->pgmap);
-                       if (unlikely(!hmm_vma_walk->pgmap))
-                               return -EBUSY;
+                       if (unlikely(!hmm_vma_walk->pgmap)) {
+                               ret = -EBUSY;
+                               goto out_unlock;
+                       }
                        pfns[i] = hmm_device_entry_from_pfn(range, pfn) |
                                  cpu_flags;
                }
@@ -517,22 +530,15 @@ again:
                        hmm_vma_walk->pgmap = NULL;
                }
                hmm_vma_walk->last = end;
-               return 0;
+               goto out_unlock;
        }
 
-       split_huge_pud(walk->vma, pudp, addr);
-       if (pud_none(*pudp))
-               goto again;
+       /* Ask for the PUD to be split */
+       walk->action = ACTION_SUBTREE;
 
-       pmdp = pmd_offset(pudp, addr);
-       do {
-               next = pmd_addr_end(addr, end);
-               ret = hmm_vma_walk_pmd(pmdp, addr, next, walk);
-               if (ret)
-                       return ret;
-       } while (pmdp++, addr = next, addr != end);
-
-       return 0;
+out_unlock:
+       spin_unlock(ptl);
+       return ret;
 }
 #else
 #define hmm_vma_walk_pud       NULL
index 1c4be87..0bccc62 100644 (file)
@@ -1664,6 +1664,9 @@ out_unlock:
  * vmf_insert_pfn_prot should only be used if using multiple VMAs is
  * impractical.
  *
+ * See vmf_insert_mixed_prot() for a discussion of the implication of using
+ * a value of @pgprot different from that of @vma->vm_page_prot.
+ *
  * Context: Process context.  May allocate using %GFP_KERNEL.
  * Return: vm_fault_t value.
  */
@@ -1737,9 +1740,9 @@ static bool vm_mixed_ok(struct vm_area_struct *vma, pfn_t pfn)
 }
 
 static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma,
-               unsigned long addr, pfn_t pfn, bool mkwrite)
+               unsigned long addr, pfn_t pfn, pgprot_t pgprot,
+               bool mkwrite)
 {
-       pgprot_t pgprot = vma->vm_page_prot;
        int err;
 
        BUG_ON(!vm_mixed_ok(vma, pfn));
@@ -1782,10 +1785,43 @@ static vm_fault_t __vm_insert_mixed(struct vm_area_struct *vma,
        return VM_FAULT_NOPAGE;
 }
 
+/**
+ * vmf_insert_mixed_prot - insert single pfn into user vma with specified pgprot
+ * @vma: user vma to map to
+ * @addr: target user address of this page
+ * @pfn: source kernel pfn
+ * @pgprot: pgprot flags for the inserted page
+ *
+ * This is exactly like vmf_insert_mixed(), except that it allows drivers to
+ * to override pgprot on a per-page basis.
+ *
+ * Typically this function should be used by drivers to set caching- and
+ * encryption bits different than those of @vma->vm_page_prot, because
+ * the caching- or encryption mode may not be known at mmap() time.
+ * This is ok as long as @vma->vm_page_prot is not used by the core vm
+ * to set caching and encryption bits for those vmas (except for COW pages).
+ * This is ensured by core vm only modifying these page table entries using
+ * functions that don't touch caching- or encryption bits, using pte_modify()
+ * if needed. (See for example mprotect()).
+ * Also when new page-table entries are created, this is only done using the
+ * fault() callback, and never using the value of vma->vm_page_prot,
+ * except for page-table entries that point to anonymous pages as the result
+ * of COW.
+ *
+ * Context: Process context.  May allocate using %GFP_KERNEL.
+ * Return: vm_fault_t value.
+ */
+vm_fault_t vmf_insert_mixed_prot(struct vm_area_struct *vma, unsigned long addr,
+                                pfn_t pfn, pgprot_t pgprot)
+{
+       return __vm_insert_mixed(vma, addr, pfn, pgprot, false);
+}
+EXPORT_SYMBOL(vmf_insert_mixed_prot);
+
 vm_fault_t vmf_insert_mixed(struct vm_area_struct *vma, unsigned long addr,
                pfn_t pfn)
 {
-       return __vm_insert_mixed(vma, addr, pfn, false);
+       return __vm_insert_mixed(vma, addr, pfn, vma->vm_page_prot, false);
 }
 EXPORT_SYMBOL(vmf_insert_mixed);
 
@@ -1797,7 +1833,7 @@ EXPORT_SYMBOL(vmf_insert_mixed);
 vm_fault_t vmf_insert_mixed_mkwrite(struct vm_area_struct *vma,
                unsigned long addr, pfn_t pfn)
 {
-       return __vm_insert_mixed(vma, addr, pfn, true);
+       return __vm_insert_mixed(vma, addr, pfn, vma->vm_page_prot, true);
 }
 EXPORT_SYMBOL(vmf_insert_mixed_mkwrite);
 
index 36d8091..0a54ffa 100644 (file)
@@ -355,7 +355,7 @@ static unsigned long find_smallest_section_pfn(int nid, struct zone *zone,
                if (unlikely(pfn_to_nid(start_pfn) != nid))
                        continue;
 
-               if (zone && zone != page_zone(pfn_to_page(start_pfn)))
+               if (zone != page_zone(pfn_to_page(start_pfn)))
                        continue;
 
                return start_pfn;
@@ -380,7 +380,7 @@ static unsigned long find_biggest_section_pfn(int nid, struct zone *zone,
                if (unlikely(pfn_to_nid(pfn) != nid))
                        continue;
 
-               if (zone && zone != page_zone(pfn_to_page(pfn)))
+               if (zone != page_zone(pfn_to_page(pfn)))
                        continue;
 
                return pfn;
@@ -392,14 +392,11 @@ static unsigned long find_biggest_section_pfn(int nid, struct zone *zone,
 static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
                             unsigned long end_pfn)
 {
-       unsigned long zone_start_pfn = zone->zone_start_pfn;
-       unsigned long z = zone_end_pfn(zone); /* zone_end_pfn namespace clash */
-       unsigned long zone_end_pfn = z;
        unsigned long pfn;
        int nid = zone_to_nid(zone);
 
        zone_span_writelock(zone);
-       if (zone_start_pfn == start_pfn) {
+       if (zone->zone_start_pfn == start_pfn) {
                /*
                 * If the section is smallest section in the zone, it need
                 * shrink zone->zone_start_pfn and zone->zone_spanned_pages.
@@ -407,50 +404,30 @@ static void shrink_zone_span(struct zone *zone, unsigned long start_pfn,
                 * for shrinking zone.
                 */
                pfn = find_smallest_section_pfn(nid, zone, end_pfn,
-                                               zone_end_pfn);
+                                               zone_end_pfn(zone));
                if (pfn) {
+                       zone->spanned_pages = zone_end_pfn(zone) - pfn;
                        zone->zone_start_pfn = pfn;
-                       zone->spanned_pages = zone_end_pfn - pfn;
+               } else {
+                       zone->zone_start_pfn = 0;
+                       zone->spanned_pages = 0;
                }
-       } else if (zone_end_pfn == end_pfn) {
+       } else if (zone_end_pfn(zone) == end_pfn) {
                /*
                 * If the section is biggest section in the zone, it need
                 * shrink zone->spanned_pages.
                 * In this case, we find second biggest valid mem_section for
                 * shrinking zone.
                 */
-               pfn = find_biggest_section_pfn(nid, zone, zone_start_pfn,
+               pfn = find_biggest_section_pfn(nid, zone, zone->zone_start_pfn,
                                               start_pfn);
                if (pfn)
-                       zone->spanned_pages = pfn - zone_start_pfn + 1;
-       }
-
-       /*
-        * The section is not biggest or smallest mem_section in the zone, it
-        * only creates a hole in the zone. So in this case, we need not
-        * change the zone. But perhaps, the zone has only hole data. Thus
-        * it check the zone has only hole or not.
-        */
-       pfn = zone_start_pfn;
-       for (; pfn < zone_end_pfn; pfn += PAGES_PER_SUBSECTION) {
-               if (unlikely(!pfn_to_online_page(pfn)))
-                       continue;
-
-               if (page_zone(pfn_to_page(pfn)) != zone)
-                       continue;
-
-               /* Skip range to be removed */
-               if (pfn >= start_pfn && pfn < end_pfn)
-                       continue;
-
-               /* If we find valid section, we have nothing to do */
-               zone_span_writeunlock(zone);
-               return;
+                       zone->spanned_pages = pfn - zone->zone_start_pfn + 1;
+               else {
+                       zone->zone_start_pfn = 0;
+                       zone->spanned_pages = 0;
+               }
        }
-
-       /* The zone has no valid section */
-       zone->zone_start_pfn = 0;
-       zone->spanned_pages = 0;
        zone_span_writeunlock(zone);
 }
 
@@ -490,6 +467,9 @@ void __ref remove_pfn_range_from_zone(struct zone *zone,
        struct pglist_data *pgdat = zone->zone_pgdat;
        unsigned long flags;
 
+       /* Poison struct pages because they are now uninitialized again. */
+       page_init_poison(pfn_to_page(start_pfn), sizeof(struct page) * nr_pages);
+
 #ifdef CONFIG_ZONE_DEVICE
        /*
         * Zone shrinking code cannot properly deal with ZONE_DEVICE. So
@@ -536,25 +516,20 @@ static void __remove_section(unsigned long pfn, unsigned long nr_pages,
 void __remove_pages(unsigned long pfn, unsigned long nr_pages,
                    struct vmem_altmap *altmap)
 {
+       const unsigned long end_pfn = pfn + nr_pages;
+       unsigned long cur_nr_pages;
        unsigned long map_offset = 0;
-       unsigned long nr, start_sec, end_sec;
 
        map_offset = vmem_altmap_offset(altmap);
 
        if (check_pfn_span(pfn, nr_pages, "remove"))
                return;
 
-       start_sec = pfn_to_section_nr(pfn);
-       end_sec = pfn_to_section_nr(pfn + nr_pages - 1);
-       for (nr = start_sec; nr <= end_sec; nr++) {
-               unsigned long pfns;
-
+       for (; pfn < end_pfn; pfn += cur_nr_pages) {
                cond_resched();
-               pfns = min(nr_pages, PAGES_PER_SECTION
-                               - (pfn & ~PAGE_SECTION_MASK));
-               __remove_section(pfn, pfns, map_offset, altmap);
-               pfn += pfns;
-               nr_pages -= pfns;
+               /* Select all remaining pages up to the next section boundary */
+               cur_nr_pages = min(end_pfn - pfn, -(pfn | PAGE_SECTION_MASK));
+               __remove_section(pfn, cur_nr_pages, map_offset, altmap);
                map_offset = 0;
        }
 }
@@ -1197,14 +1172,13 @@ bool is_mem_section_removable(unsigned long start_pfn, unsigned long nr_pages)
 }
 
 /*
- * Confirm all pages in a range [start, end) belong to the same zone.
- * When true, return its valid [start, end).
+ * Confirm all pages in a range [start, end) belong to the same zone (skipping
+ * memory holes). When true, return the zone.
  */
-int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,
-                        unsigned long *valid_start, unsigned long *valid_end)
+struct zone *test_pages_in_a_zone(unsigned long start_pfn,
+                                 unsigned long end_pfn)
 {
        unsigned long pfn, sec_end_pfn;
-       unsigned long start, end;
        struct zone *zone = NULL;
        struct page *page;
        int i;
@@ -1225,24 +1199,15 @@ int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn,
                                continue;
                        /* Check if we got outside of the zone */
                        if (zone && !zone_spans_pfn(zone, pfn + i))
-                               return 0;
+                               return NULL;
                        page = pfn_to_page(pfn + i);
                        if (zone && page_zone(page) != zone)
-                               return 0;
-                       if (!zone)
-                               start = pfn + i;
+                               return NULL;
                        zone = page_zone(page);
-                       end = pfn + MAX_ORDER_NR_PAGES;
                }
        }
 
-       if (zone) {
-               *valid_start = start;
-               *valid_end = min(end, end_pfn);
-               return 1;
-       } else {
-               return 0;
-       }
+       return zone;
 }
 
 /*
@@ -1487,7 +1452,6 @@ static int __ref __offline_pages(unsigned long start_pfn,
        unsigned long offlined_pages = 0;
        int ret, node, nr_isolate_pageblock;
        unsigned long flags;
-       unsigned long valid_start, valid_end;
        struct zone *zone;
        struct memory_notify arg;
        char *reason;
@@ -1512,14 +1476,12 @@ static int __ref __offline_pages(unsigned long start_pfn,
 
        /* This makes hotplug much easier...and readable.
           we assume this for now. .*/
-       if (!test_pages_in_a_zone(start_pfn, end_pfn, &valid_start,
-                                 &valid_end)) {
+       zone = test_pages_in_a_zone(start_pfn, end_pfn);
+       if (!zone) {
                ret = -EINVAL;
                reason = "multizone range";
                goto failed_removal;
        }
-
-       zone = page_zone(pfn_to_page(valid_start));
        node = zone_to_nid(zone);
 
        /* set above range as isolated */
index 4c723d2..09b5b7a 100644 (file)
@@ -120,6 +120,8 @@ void memunmap_pages(struct dev_pagemap *pgmap)
        nid = page_to_nid(first_page);
 
        mem_hotplug_begin();
+       remove_pfn_range_from_zone(page_zone(first_page), PHYS_PFN(res->start),
+                                  PHYS_PFN(resource_size(res)));
        if (pgmap->type == MEMORY_DEVICE_PRIVATE) {
                __remove_pages(PHYS_PFN(res->start),
                               PHYS_PFN(resource_size(res)), NULL);
index edf42ed..b109287 100644 (file)
@@ -2151,6 +2151,7 @@ out_unlock:
 #ifdef CONFIG_DEVICE_PRIVATE
 static int migrate_vma_collect_hole(unsigned long start,
                                    unsigned long end,
+                                   __always_unused int depth,
                                    struct mm_walk *walk)
 {
        struct migrate_vma *migrate = walk->private;
@@ -2195,7 +2196,7 @@ static int migrate_vma_collect_pmd(pmd_t *pmdp,
 
 again:
        if (pmd_none(*pmdp))
-               return migrate_vma_collect_hole(start, end, walk);
+               return migrate_vma_collect_hole(start, end, -1, walk);
 
        if (pmd_trans_huge(*pmdp)) {
                struct page *page;
@@ -2228,7 +2229,7 @@ again:
                                return migrate_vma_collect_skip(start, end,
                                                                walk);
                        if (pmd_none(*pmdp))
-                               return migrate_vma_collect_hole(start, end,
+                               return migrate_vma_collect_hole(start, end, -1,
                                                                walk);
                }
        }
index 49b6fa2..0e6dd99 100644 (file)
@@ -112,6 +112,7 @@ static int __mincore_unmapped_range(unsigned long addr, unsigned long end,
 }
 
 static int mincore_unmapped_range(unsigned long addr, unsigned long end,
+                                  __always_unused int depth,
                                   struct mm_walk *walk)
 {
        walk->private += __mincore_unmapped_range(addr, end,
index 7d70e5c..a3538cb 100644 (file)
@@ -11,7 +11,7 @@
 #include <asm/pgalloc.h>
 #include <asm/tlb.h>
 
-#ifndef CONFIG_HAVE_MMU_GATHER_NO_GATHER
+#ifndef CONFIG_MMU_GATHER_NO_GATHER
 
 static bool tlb_next_batch(struct mmu_gather *tlb)
 {
@@ -69,7 +69,7 @@ bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page, int page_
 
        VM_BUG_ON(!tlb->end);
 
-#ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
+#ifdef CONFIG_MMU_GATHER_PAGE_SIZE
        VM_WARN_ON(tlb->page_size != page_size);
 #endif
 
@@ -89,58 +89,108 @@ bool __tlb_remove_page_size(struct mmu_gather *tlb, struct page *page, int page_
        return false;
 }
 
-#endif /* HAVE_MMU_GATHER_NO_GATHER */
+#endif /* MMU_GATHER_NO_GATHER */
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
+#ifdef CONFIG_MMU_GATHER_TABLE_FREE
 
-/*
- * See the comment near struct mmu_table_batch.
- */
+static void __tlb_remove_table_free(struct mmu_table_batch *batch)
+{
+       int i;
+
+       for (i = 0; i < batch->nr; i++)
+               __tlb_remove_table(batch->tables[i]);
+
+       free_page((unsigned long)batch);
+}
+
+#ifdef CONFIG_MMU_GATHER_RCU_TABLE_FREE
 
 /*
- * If we want tlb_remove_table() to imply TLB invalidates.
+ * Semi RCU freeing of the page directories.
+ *
+ * This is needed by some architectures to implement software pagetable walkers.
+ *
+ * gup_fast() and other software pagetable walkers do a lockless page-table
+ * walk and therefore needs some synchronization with the freeing of the page
+ * directories. The chosen means to accomplish that is by disabling IRQs over
+ * the walk.
+ *
+ * Architectures that use IPIs to flush TLBs will then automagically DTRT,
+ * since we unlink the page, flush TLBs, free the page. Since the disabling of
+ * IRQs delays the completion of the TLB flush we can never observe an already
+ * freed page.
+ *
+ * Architectures that do not have this (PPC) need to delay the freeing by some
+ * other means, this is that means.
+ *
+ * What we do is batch the freed directory pages (tables) and RCU free them.
+ * We use the sched RCU variant, as that guarantees that IRQ/preempt disabling
+ * holds off grace periods.
+ *
+ * However, in order to batch these pages we need to allocate storage, this
+ * allocation is deep inside the MM code and can thus easily fail on memory
+ * pressure. To guarantee progress we fall back to single table freeing, see
+ * the implementation of tlb_remove_table_one().
+ *
  */
-static inline void tlb_table_invalidate(struct mmu_gather *tlb)
-{
-#ifndef CONFIG_HAVE_RCU_TABLE_NO_INVALIDATE
-       /*
-        * Invalidate page-table caches used by hardware walkers. Then we still
-        * need to RCU-sched wait while freeing the pages because software
-        * walkers can still be in-flight.
-        */
-       tlb_flush_mmu_tlbonly(tlb);
-#endif
-}
 
 static void tlb_remove_table_smp_sync(void *arg)
 {
        /* Simply deliver the interrupt */
 }
 
-static void tlb_remove_table_one(void *table)
+static void tlb_remove_table_sync_one(void)
 {
        /*
         * This isn't an RCU grace period and hence the page-tables cannot be
         * assumed to be actually RCU-freed.
         *
         * It is however sufficient for software page-table walkers that rely on
-        * IRQ disabling. See the comment near struct mmu_table_batch.
+        * IRQ disabling.
         */
        smp_call_function(tlb_remove_table_smp_sync, NULL, 1);
-       __tlb_remove_table(table);
 }
 
 static void tlb_remove_table_rcu(struct rcu_head *head)
 {
-       struct mmu_table_batch *batch;
-       int i;
+       __tlb_remove_table_free(container_of(head, struct mmu_table_batch, rcu));
+}
+
+static void tlb_remove_table_free(struct mmu_table_batch *batch)
+{
+       call_rcu(&batch->rcu, tlb_remove_table_rcu);
+}
 
-       batch = container_of(head, struct mmu_table_batch, rcu);
+#else /* !CONFIG_MMU_GATHER_RCU_TABLE_FREE */
 
-       for (i = 0; i < batch->nr; i++)
-               __tlb_remove_table(batch->tables[i]);
+static void tlb_remove_table_sync_one(void) { }
 
-       free_page((unsigned long)batch);
+static void tlb_remove_table_free(struct mmu_table_batch *batch)
+{
+       __tlb_remove_table_free(batch);
+}
+
+#endif /* CONFIG_MMU_GATHER_RCU_TABLE_FREE */
+
+/*
+ * If we want tlb_remove_table() to imply TLB invalidates.
+ */
+static inline void tlb_table_invalidate(struct mmu_gather *tlb)
+{
+       if (tlb_needs_table_invalidate()) {
+               /*
+                * Invalidate page-table caches used by hardware walkers. Then
+                * we still need to RCU-sched wait while freeing the pages
+                * because software walkers can still be in-flight.
+                */
+               tlb_flush_mmu_tlbonly(tlb);
+       }
+}
+
+static void tlb_remove_table_one(void *table)
+{
+       tlb_remove_table_sync_one();
+       __tlb_remove_table(table);
 }
 
 static void tlb_table_flush(struct mmu_gather *tlb)
@@ -149,7 +199,7 @@ static void tlb_table_flush(struct mmu_gather *tlb)
 
        if (*batch) {
                tlb_table_invalidate(tlb);
-               call_rcu(&(*batch)->rcu, tlb_remove_table_rcu);
+               tlb_remove_table_free(*batch);
                *batch = NULL;
        }
 }
@@ -173,14 +223,22 @@ void tlb_remove_table(struct mmu_gather *tlb, void *table)
                tlb_table_flush(tlb);
 }
 
-#endif /* CONFIG_HAVE_RCU_TABLE_FREE */
+static inline void tlb_table_init(struct mmu_gather *tlb)
+{
+       tlb->batch = NULL;
+}
+
+#else /* !CONFIG_MMU_GATHER_TABLE_FREE */
+
+static inline void tlb_table_flush(struct mmu_gather *tlb) { }
+static inline void tlb_table_init(struct mmu_gather *tlb) { }
+
+#endif /* CONFIG_MMU_GATHER_TABLE_FREE */
 
 static void tlb_flush_mmu_free(struct mmu_gather *tlb)
 {
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
        tlb_table_flush(tlb);
-#endif
-#ifndef CONFIG_HAVE_MMU_GATHER_NO_GATHER
+#ifndef CONFIG_MMU_GATHER_NO_GATHER
        tlb_batch_pages_flush(tlb);
 #endif
 }
@@ -211,7 +269,7 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
        /* Is it from 0 to ~0? */
        tlb->fullmm     = !(start | (end+1));
 
-#ifndef CONFIG_HAVE_MMU_GATHER_NO_GATHER
+#ifndef CONFIG_MMU_GATHER_NO_GATHER
        tlb->need_flush_all = 0;
        tlb->local.next = NULL;
        tlb->local.nr   = 0;
@@ -220,10 +278,8 @@ void tlb_gather_mmu(struct mmu_gather *tlb, struct mm_struct *mm,
        tlb->batch_count = 0;
 #endif
 
-#ifdef CONFIG_HAVE_RCU_TABLE_FREE
-       tlb->batch = NULL;
-#endif
-#ifdef CONFIG_HAVE_MMU_GATHER_PAGE_SIZE
+       tlb_table_init(tlb);
+#ifdef CONFIG_MMU_GATHER_PAGE_SIZE
        tlb->page_size = 0;
 #endif
 
@@ -271,7 +327,7 @@ void tlb_finish_mmu(struct mmu_gather *tlb,
 
        tlb_flush_mmu(tlb);
 
-#ifndef CONFIG_HAVE_MMU_GATHER_NO_GATHER
+#ifndef CONFIG_MMU_GATHER_NO_GATHER
        tlb_batch_list_free(tlb);
 #endif
        dec_tlb_flush_pending(tlb->mm);
index 15e908a..3c4eb75 100644 (file)
@@ -5852,18 +5852,11 @@ overlap_memmap_init(unsigned long zone, unsigned long *pfn)
 /* Skip PFNs that belong to non-present sections */
 static inline __meminit unsigned long next_pfn(unsigned long pfn)
 {
-       unsigned long section_nr;
+       const unsigned long section_nr = pfn_to_section_nr(++pfn);
 
-       section_nr = pfn_to_section_nr(++pfn);
        if (present_section_nr(section_nr))
                return pfn;
-
-       while (++section_nr <= __highest_present_section_nr) {
-               if (present_section_nr(section_nr))
-                       return section_nr_to_pfn(section_nr);
-       }
-
-       return -1;
+       return section_nr_to_pfn(next_present_section_nr(section_nr));
 }
 #else
 static inline __meminit unsigned long next_pfn(unsigned long pfn)
@@ -5905,18 +5898,20 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
        }
 #endif
 
-       for (pfn = start_pfn; pfn < end_pfn; pfn++) {
+       for (pfn = start_pfn; pfn < end_pfn; ) {
                /*
                 * There can be holes in boot-time mem_map[]s handed to this
                 * function.  They do not exist on hotplugged memory.
                 */
                if (context == MEMMAP_EARLY) {
                        if (!early_pfn_valid(pfn)) {
-                               pfn = next_pfn(pfn) - 1;
+                               pfn = next_pfn(pfn);
                                continue;
                        }
-                       if (!early_pfn_in_nid(pfn, nid))
+                       if (!early_pfn_in_nid(pfn, nid)) {
+                               pfn++;
                                continue;
+                       }
                        if (overlap_memmap_init(zone, &pfn))
                                continue;
                        if (defer_init(nid, pfn, end_pfn))
@@ -5944,16 +5939,17 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
                        set_pageblock_migratetype(page, MIGRATE_MOVABLE);
                        cond_resched();
                }
+               pfn++;
        }
 }
 
 #ifdef CONFIG_ZONE_DEVICE
 void __ref memmap_init_zone_device(struct zone *zone,
                                   unsigned long start_pfn,
-                                  unsigned long size,
+                                  unsigned long nr_pages,
                                   struct dev_pagemap *pgmap)
 {
-       unsigned long pfn, end_pfn = start_pfn + size;
+       unsigned long pfn, end_pfn = start_pfn + nr_pages;
        struct pglist_data *pgdat = zone->zone_pgdat;
        struct vmem_altmap *altmap = pgmap_altmap(pgmap);
        unsigned long zone_idx = zone_idx(zone);
@@ -5970,7 +5966,7 @@ void __ref memmap_init_zone_device(struct zone *zone,
         */
        if (altmap) {
                start_pfn = altmap->base_pfn + vmem_altmap_offset(altmap);
-               size = end_pfn - start_pfn;
+               nr_pages = end_pfn - start_pfn;
        }
 
        for (pfn = start_pfn; pfn < end_pfn; pfn++) {
@@ -6017,7 +6013,7 @@ void __ref memmap_init_zone_device(struct zone *zone,
        }
 
        pr_info("%s initialised %lu pages in %ums\n", __func__,
-               size, jiffies_to_msecs(jiffies - start));
+               nr_pages, jiffies_to_msecs(jiffies - start));
 }
 
 #endif
@@ -6916,10 +6912,10 @@ void __init free_area_init_node(int nid, unsigned long *zones_size,
 
 #if !defined(CONFIG_FLAT_NODE_MEM_MAP)
 /*
- * Zero all valid struct pages in range [spfn, epfn), return number of struct
- * pages zeroed
+ * Initialize all valid struct pages in the range [spfn, epfn) and mark them
+ * PageReserved(). Return the number of struct pages that were initialized.
  */
-static u64 zero_pfn_range(unsigned long spfn, unsigned long epfn)
+static u64 __init init_unavailable_range(unsigned long spfn, unsigned long epfn)
 {
        unsigned long pfn;
        u64 pgcnt = 0;
@@ -6930,7 +6926,13 @@ static u64 zero_pfn_range(unsigned long spfn, unsigned long epfn)
                                + pageblock_nr_pages - 1;
                        continue;
                }
-               mm_zero_struct_page(pfn_to_page(pfn));
+               /*
+                * Use a fake node/zone (0) for now. Some of these pages
+                * (in memblock.reserved but not in memblock.memory) will
+                * get re-initialized via reserve_bootmem_region() later.
+                */
+               __init_single_page(pfn_to_page(pfn), pfn, 0, 0);
+               __SetPageReserved(pfn_to_page(pfn));
                pgcnt++;
        }
 
@@ -6942,14 +6944,15 @@ static u64 zero_pfn_range(unsigned long spfn, unsigned long epfn)
  * initialized by going through __init_single_page(). But, there are some
  * struct pages which are reserved in memblock allocator and their fields
  * may be accessed (for example page_to_pfn() on some configuration accesses
- * flags). We must explicitly zero those struct pages.
+ * flags). We must explicitly initialize those struct pages.
  *
  * This function also addresses a similar issue where struct pages are left
  * uninitialized because the physical address range is not covered by
  * memblock.memory or memblock.reserved. That could happen when memblock
- * layout is manually configured via memmap=.
+ * layout is manually configured via memmap=, or when the highest physical
+ * address (max_pfn) does not end on a section boundary.
  */
-void __init zero_resv_unavail(void)
+static void __init init_unavailable_mem(void)
 {
        phys_addr_t start, end;
        u64 i, pgcnt;
@@ -6962,10 +6965,20 @@ void __init zero_resv_unavail(void)
        for_each_mem_range(i, &memblock.memory, NULL,
                        NUMA_NO_NODE, MEMBLOCK_NONE, &start, &end, NULL) {
                if (next < start)
-                       pgcnt += zero_pfn_range(PFN_DOWN(next), PFN_UP(start));
+                       pgcnt += init_unavailable_range(PFN_DOWN(next),
+                                                       PFN_UP(start));
                next = end;
        }
-       pgcnt += zero_pfn_range(PFN_DOWN(next), max_pfn);
+
+       /*
+        * Early sections always have a fully populated memmap for the whole
+        * section - see pfn_valid(). If the last section has holes at the
+        * end and that section is marked "online", the memmap will be
+        * considered initialized. Make sure that memmap has a well defined
+        * state.
+        */
+       pgcnt += init_unavailable_range(PFN_DOWN(next),
+                                       round_up(max_pfn, PAGES_PER_SECTION));
 
        /*
         * Struct pages that do not have backing memory. This could be because
@@ -6974,6 +6987,10 @@ void __init zero_resv_unavail(void)
        if (pgcnt)
                pr_info("Zeroed struct page in unavailable ranges: %lld pages", pgcnt);
 }
+#else
+static inline void __init init_unavailable_mem(void)
+{
+}
 #endif /* !CONFIG_FLAT_NODE_MEM_MAP */
 
 #ifdef CONFIG_HAVE_MEMBLOCK_NODE_MAP
@@ -7403,7 +7420,7 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
        /* Initialise every node */
        mminit_verify_pageflags_layout();
        setup_nr_node_ids();
-       zero_resv_unavail();
+       init_unavailable_mem();
        for_each_online_node(nid) {
                pg_data_t *pgdat = NODE_DATA(nid);
                free_area_init_node(nid, NULL,
@@ -7598,7 +7615,7 @@ void __init set_dma_reserve(unsigned long new_dma_reserve)
 
 void __init free_area_init(unsigned long *zones_size)
 {
-       zero_resv_unavail();
+       init_unavailable_mem();
        free_area_init_node(0, zones_size,
                        __pa(PAGE_OFFSET) >> PAGE_SHIFT, NULL);
 }
index 3a198de..76965be 100644 (file)
@@ -177,8 +177,9 @@ int generic_swapfile_activate(struct swap_info_struct *sis,
 
                cond_resched();
 
-               first_block = bmap(inode, probe_block);
-               if (first_block == 0)
+               first_block = probe_block;
+               ret = bmap(inode, &first_block);
+               if (ret || !first_block)
                        goto bad_bmap;
 
                /*
@@ -193,9 +194,11 @@ int generic_swapfile_activate(struct swap_info_struct *sis,
                                        block_in_page++) {
                        sector_t block;
 
-                       block = bmap(inode, probe_block + block_in_page);
-                       if (block == 0)
+                       block = probe_block + block_in_page;
+                       ret = bmap(inode, &block);
+                       if (ret || !block)
                                goto bad_bmap;
+
                        if (block != first_block + block_in_page) {
                                /* Discontiguity */
                                probe_block++;
index ea0b9e6..928df16 100644 (file)
@@ -4,26 +4,57 @@
 #include <linux/sched.h>
 #include <linux/hugetlb.h>
 
-static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
-                         struct mm_walk *walk)
+/*
+ * We want to know the real level where a entry is located ignoring any
+ * folding of levels which may be happening. For example if p4d is folded then
+ * a missing entry found at level 1 (p4d) is actually at level 0 (pgd).
+ */
+static int real_depth(int depth)
+{
+       if (depth == 3 && PTRS_PER_PMD == 1)
+               depth = 2;
+       if (depth == 2 && PTRS_PER_PUD == 1)
+               depth = 1;
+       if (depth == 1 && PTRS_PER_P4D == 1)
+               depth = 0;
+       return depth;
+}
+
+static int walk_pte_range_inner(pte_t *pte, unsigned long addr,
+                               unsigned long end, struct mm_walk *walk)
 {
-       pte_t *pte;
-       int err = 0;
        const struct mm_walk_ops *ops = walk->ops;
-       spinlock_t *ptl;
+       int err = 0;
 
-       pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
        for (;;) {
                err = ops->pte_entry(pte, addr, addr + PAGE_SIZE, walk);
                if (err)
                       break;
-               addr += PAGE_SIZE;
-               if (addr == end)
+               if (addr >= end - PAGE_SIZE)
                        break;
+               addr += PAGE_SIZE;
                pte++;
        }
+       return err;
+}
+
+static int walk_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
+                         struct mm_walk *walk)
+{
+       pte_t *pte;
+       int err = 0;
+       spinlock_t *ptl;
+
+       if (walk->no_vma) {
+               pte = pte_offset_map(pmd, addr);
+               err = walk_pte_range_inner(pte, addr, end, walk);
+               pte_unmap(pte);
+       } else {
+               pte = pte_offset_map_lock(walk->mm, pmd, addr, &ptl);
+               err = walk_pte_range_inner(pte, addr, end, walk);
+               pte_unmap_unlock(pte, ptl);
+       }
 
-       pte_unmap_unlock(pte, ptl);
        return err;
 }
 
@@ -34,18 +65,22 @@ static int walk_pmd_range(pud_t *pud, unsigned long addr, unsigned long end,
        unsigned long next;
        const struct mm_walk_ops *ops = walk->ops;
        int err = 0;
+       int depth = real_depth(3);
 
        pmd = pmd_offset(pud, addr);
        do {
 again:
                next = pmd_addr_end(addr, end);
-               if (pmd_none(*pmd) || !walk->vma) {
+               if (pmd_none(*pmd) || (!walk->vma && !walk->no_vma)) {
                        if (ops->pte_hole)
-                               err = ops->pte_hole(addr, next, walk);
+                               err = ops->pte_hole(addr, next, depth, walk);
                        if (err)
                                break;
                        continue;
                }
+
+               walk->action = ACTION_SUBTREE;
+
                /*
                 * This implies that each ->pmd_entry() handler
                 * needs to know about pmd_trans_huge() pmds
@@ -55,16 +90,24 @@ again:
                if (err)
                        break;
 
+               if (walk->action == ACTION_AGAIN)
+                       goto again;
+
                /*
                 * Check this here so we only break down trans_huge
                 * pages when we _need_ to
                 */
-               if (!ops->pte_entry)
+               if ((!walk->vma && (pmd_leaf(*pmd) || !pmd_present(*pmd))) ||
+                   walk->action == ACTION_CONTINUE ||
+                   !(ops->pte_entry))
                        continue;
 
-               split_huge_pmd(walk->vma, pmd, addr);
-               if (pmd_trans_unstable(pmd))
-                       goto again;
+               if (walk->vma) {
+                       split_huge_pmd(walk->vma, pmd, addr);
+                       if (pmd_trans_unstable(pmd))
+                               goto again;
+               }
+
                err = walk_pte_range(pmd, addr, next, walk);
                if (err)
                        break;
@@ -80,37 +123,41 @@ static int walk_pud_range(p4d_t *p4d, unsigned long addr, unsigned long end,
        unsigned long next;
        const struct mm_walk_ops *ops = walk->ops;
        int err = 0;
+       int depth = real_depth(2);
 
        pud = pud_offset(p4d, addr);
        do {
  again:
                next = pud_addr_end(addr, end);
-               if (pud_none(*pud) || !walk->vma) {
+               if (pud_none(*pud) || (!walk->vma && !walk->no_vma)) {
                        if (ops->pte_hole)
-                               err = ops->pte_hole(addr, next, walk);
+                               err = ops->pte_hole(addr, next, depth, walk);
                        if (err)
                                break;
                        continue;
                }
 
-               if (ops->pud_entry) {
-                       spinlock_t *ptl = pud_trans_huge_lock(pud, walk->vma);
+               walk->action = ACTION_SUBTREE;
 
-                       if (ptl) {
-                               err = ops->pud_entry(pud, addr, next, walk);
-                               spin_unlock(ptl);
-                               if (err)
-                                       break;
-                               continue;
-                       }
-               }
+               if (ops->pud_entry)
+                       err = ops->pud_entry(pud, addr, next, walk);
+               if (err)
+                       break;
+
+               if (walk->action == ACTION_AGAIN)
+                       goto again;
 
-               split_huge_pud(walk->vma, pud, addr);
+               if ((!walk->vma && (pud_leaf(*pud) || !pud_present(*pud))) ||
+                   walk->action == ACTION_CONTINUE ||
+                   !(ops->pmd_entry || ops->pte_entry))
+                       continue;
+
+               if (walk->vma)
+                       split_huge_pud(walk->vma, pud, addr);
                if (pud_none(*pud))
                        goto again;
 
-               if (ops->pmd_entry || ops->pte_entry)
-                       err = walk_pmd_range(pud, addr, next, walk);
+               err = walk_pmd_range(pud, addr, next, walk);
                if (err)
                        break;
        } while (pud++, addr = next, addr != end);
@@ -125,18 +172,24 @@ static int walk_p4d_range(pgd_t *pgd, unsigned long addr, unsigned long end,
        unsigned long next;
        const struct mm_walk_ops *ops = walk->ops;
        int err = 0;
+       int depth = real_depth(1);
 
        p4d = p4d_offset(pgd, addr);
        do {
                next = p4d_addr_end(addr, end);
                if (p4d_none_or_clear_bad(p4d)) {
                        if (ops->pte_hole)
-                               err = ops->pte_hole(addr, next, walk);
+                               err = ops->pte_hole(addr, next, depth, walk);
                        if (err)
                                break;
                        continue;
                }
-               if (ops->pmd_entry || ops->pte_entry)
+               if (ops->p4d_entry) {
+                       err = ops->p4d_entry(p4d, addr, next, walk);
+                       if (err)
+                               break;
+               }
+               if (ops->pud_entry || ops->pmd_entry || ops->pte_entry)
                        err = walk_pud_range(p4d, addr, next, walk);
                if (err)
                        break;
@@ -153,17 +206,26 @@ static int walk_pgd_range(unsigned long addr, unsigned long end,
        const struct mm_walk_ops *ops = walk->ops;
        int err = 0;
 
-       pgd = pgd_offset(walk->mm, addr);
+       if (walk->pgd)
+               pgd = walk->pgd + pgd_index(addr);
+       else
+               pgd = pgd_offset(walk->mm, addr);
        do {
                next = pgd_addr_end(addr, end);
                if (pgd_none_or_clear_bad(pgd)) {
                        if (ops->pte_hole)
-                               err = ops->pte_hole(addr, next, walk);
+                               err = ops->pte_hole(addr, next, 0, walk);
                        if (err)
                                break;
                        continue;
                }
-               if (ops->pmd_entry || ops->pte_entry)
+               if (ops->pgd_entry) {
+                       err = ops->pgd_entry(pgd, addr, next, walk);
+                       if (err)
+                               break;
+               }
+               if (ops->p4d_entry || ops->pud_entry || ops->pmd_entry ||
+                   ops->pte_entry)
                        err = walk_p4d_range(pgd, addr, next, walk);
                if (err)
                        break;
@@ -199,7 +261,7 @@ static int walk_hugetlb_range(unsigned long addr, unsigned long end,
                if (pte)
                        err = ops->hugetlb_entry(pte, hmask, addr, next, walk);
                else if (ops->pte_hole)
-                       err = ops->pte_hole(addr, next, walk);
+                       err = ops->pte_hole(addr, next, -1, walk);
 
                if (err)
                        break;
@@ -243,7 +305,7 @@ static int walk_page_test(unsigned long start, unsigned long end,
        if (vma->vm_flags & VM_PFNMAP) {
                int err = 1;
                if (ops->pte_hole)
-                       err = ops->pte_hole(start, end, walk);
+                       err = ops->pte_hole(start, end, -1, walk);
                return err ? err : 1;
        }
        return 0;
@@ -369,6 +431,33 @@ int walk_page_range(struct mm_struct *mm, unsigned long start,
        return err;
 }
 
+/*
+ * Similar to walk_page_range() but can walk any page tables even if they are
+ * not backed by VMAs. Because 'unusual' entries may be walked this function
+ * will also not lock the PTEs for the pte_entry() callback. This is useful for
+ * walking the kernel pages tables or page tables for firmware.
+ */
+int walk_page_range_novma(struct mm_struct *mm, unsigned long start,
+                         unsigned long end, const struct mm_walk_ops *ops,
+                         pgd_t *pgd,
+                         void *private)
+{
+       struct mm_walk walk = {
+               .ops            = ops,
+               .mm             = mm,
+               .pgd            = pgd,
+               .private        = private,
+               .no_vma         = true
+       };
+
+       if (start >= end || !walk.mm)
+               return -EINVAL;
+
+       lockdep_assert_held(&walk.mm->mmap_sem);
+
+       return __walk_page_range(start, end, &walk);
+}
+
 int walk_page_vma(struct vm_area_struct *vma, const struct mm_walk_ops *ops,
                void *private)
 {
diff --git a/mm/ptdump.c b/mm/ptdump.c
new file mode 100644 (file)
index 0000000..26208d0
--- /dev/null
@@ -0,0 +1,139 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/pagewalk.h>
+#include <linux/ptdump.h>
+#include <linux/kasan.h>
+
+#ifdef CONFIG_KASAN
+/*
+ * This is an optimization for KASAN=y case. Since all kasan page tables
+ * eventually point to the kasan_early_shadow_page we could call note_page()
+ * right away without walking through lower level page tables. This saves
+ * us dozens of seconds (minutes for 5-level config) while checking for
+ * W+X mapping or reading kernel_page_tables debugfs file.
+ */
+static inline int note_kasan_page_table(struct mm_walk *walk,
+                                       unsigned long addr)
+{
+       struct ptdump_state *st = walk->private;
+
+       st->note_page(st, addr, 4, pte_val(kasan_early_shadow_pte[0]));
+
+       walk->action = ACTION_CONTINUE;
+
+       return 0;
+}
+#endif
+
+static int ptdump_pgd_entry(pgd_t *pgd, unsigned long addr,
+                           unsigned long next, struct mm_walk *walk)
+{
+       struct ptdump_state *st = walk->private;
+       pgd_t val = READ_ONCE(*pgd);
+
+#if CONFIG_PGTABLE_LEVELS > 4 && defined(CONFIG_KASAN)
+       if (pgd_page(val) == virt_to_page(lm_alias(kasan_early_shadow_p4d)))
+               return note_kasan_page_table(walk, addr);
+#endif
+
+       if (pgd_leaf(val))
+               st->note_page(st, addr, 0, pgd_val(val));
+
+       return 0;
+}
+
+static int ptdump_p4d_entry(p4d_t *p4d, unsigned long addr,
+                           unsigned long next, struct mm_walk *walk)
+{
+       struct ptdump_state *st = walk->private;
+       p4d_t val = READ_ONCE(*p4d);
+
+#if CONFIG_PGTABLE_LEVELS > 3 && defined(CONFIG_KASAN)
+       if (p4d_page(val) == virt_to_page(lm_alias(kasan_early_shadow_pud)))
+               return note_kasan_page_table(walk, addr);
+#endif
+
+       if (p4d_leaf(val))
+               st->note_page(st, addr, 1, p4d_val(val));
+
+       return 0;
+}
+
+static int ptdump_pud_entry(pud_t *pud, unsigned long addr,
+                           unsigned long next, struct mm_walk *walk)
+{
+       struct ptdump_state *st = walk->private;
+       pud_t val = READ_ONCE(*pud);
+
+#if CONFIG_PGTABLE_LEVELS > 2 && defined(CONFIG_KASAN)
+       if (pud_page(val) == virt_to_page(lm_alias(kasan_early_shadow_pmd)))
+               return note_kasan_page_table(walk, addr);
+#endif
+
+       if (pud_leaf(val))
+               st->note_page(st, addr, 2, pud_val(val));
+
+       return 0;
+}
+
+static int ptdump_pmd_entry(pmd_t *pmd, unsigned long addr,
+                           unsigned long next, struct mm_walk *walk)
+{
+       struct ptdump_state *st = walk->private;
+       pmd_t val = READ_ONCE(*pmd);
+
+#if defined(CONFIG_KASAN)
+       if (pmd_page(val) == virt_to_page(lm_alias(kasan_early_shadow_pte)))
+               return note_kasan_page_table(walk, addr);
+#endif
+
+       if (pmd_leaf(val))
+               st->note_page(st, addr, 3, pmd_val(val));
+
+       return 0;
+}
+
+static int ptdump_pte_entry(pte_t *pte, unsigned long addr,
+                           unsigned long next, struct mm_walk *walk)
+{
+       struct ptdump_state *st = walk->private;
+
+       st->note_page(st, addr, 4, pte_val(READ_ONCE(*pte)));
+
+       return 0;
+}
+
+static int ptdump_hole(unsigned long addr, unsigned long next,
+                      int depth, struct mm_walk *walk)
+{
+       struct ptdump_state *st = walk->private;
+
+       st->note_page(st, addr, depth, 0);
+
+       return 0;
+}
+
+static const struct mm_walk_ops ptdump_ops = {
+       .pgd_entry      = ptdump_pgd_entry,
+       .p4d_entry      = ptdump_p4d_entry,
+       .pud_entry      = ptdump_pud_entry,
+       .pmd_entry      = ptdump_pmd_entry,
+       .pte_entry      = ptdump_pte_entry,
+       .pte_hole       = ptdump_hole,
+};
+
+void ptdump_walk_pgd(struct ptdump_state *st, struct mm_struct *mm, pgd_t *pgd)
+{
+       const struct ptdump_range *range = st->range;
+
+       down_read(&mm->mmap_sem);
+       while (range->start != range->end) {
+               walk_page_range_novma(mm, range->start, range->end,
+                                     &ptdump_ops, pgd, st);
+               range++;
+       }
+       up_read(&mm->mmap_sem);
+
+       /* Flush out the last page */
+       st->note_page(st, 0, -1, 0);
+}
index 8793e8c..c8f7540 100644 (file)
@@ -3381,9 +3381,19 @@ enum shmem_param {
        Opt_uid,
 };
 
-static const struct fs_parameter_spec shmem_param_specs[] = {
+static const struct constant_table shmem_param_enums_huge[] = {
+       {"never",       SHMEM_HUGE_NEVER },
+       {"always",      SHMEM_HUGE_ALWAYS },
+       {"within_size", SHMEM_HUGE_WITHIN_SIZE },
+       {"advise",      SHMEM_HUGE_ADVISE },
+       {"deny",        SHMEM_HUGE_DENY },
+       {"force",       SHMEM_HUGE_FORCE },
+       {}
+};
+
+const struct fs_parameter_spec shmem_fs_parameters[] = {
        fsparam_u32   ("gid",           Opt_gid),
-       fsparam_enum  ("huge",          Opt_huge),
+       fsparam_enum  ("huge",          Opt_huge,  shmem_param_enums_huge),
        fsparam_u32oct("mode",          Opt_mode),
        fsparam_string("mpol",          Opt_mpol),
        fsparam_string("nr_blocks",     Opt_nr_blocks),
@@ -3393,20 +3403,6 @@ static const struct fs_parameter_spec shmem_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_enum shmem_param_enums[] = {
-       { Opt_huge,     "never",        SHMEM_HUGE_NEVER },
-       { Opt_huge,     "always",       SHMEM_HUGE_ALWAYS },
-       { Opt_huge,     "within_size",  SHMEM_HUGE_WITHIN_SIZE },
-       { Opt_huge,     "advise",       SHMEM_HUGE_ADVISE },
-       {}
-};
-
-const struct fs_parameter_description shmem_fs_parameters = {
-       .name           = "tmpfs",
-       .specs          = shmem_param_specs,
-       .enums          = shmem_param_enums,
-};
-
 static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
 {
        struct shmem_options *ctx = fc->fs_private;
@@ -3415,7 +3411,7 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
        char *rest;
        int opt;
 
-       opt = fs_parse(fc, &shmem_fs_parameters, param, &result);
+       opt = fs_parse(fc, shmem_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -3479,9 +3475,9 @@ static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param)
        return 0;
 
 unsupported_parameter:
-       return invalf(fc, "tmpfs: Unsupported parameter '%s'", param->key);
+       return invalfc(fc, "Unsupported parameter '%s'", param->key);
 bad_value:
-       return invalf(fc, "tmpfs: Bad value for '%s'", param->key);
+       return invalfc(fc, "Bad value for '%s'", param->key);
 }
 
 static int shmem_parse_options(struct fs_context *fc, void *data)
@@ -3587,7 +3583,7 @@ static int shmem_reconfigure(struct fs_context *fc)
        return 0;
 out:
        spin_unlock(&sbinfo->stat_lock);
-       return invalf(fc, "tmpfs: %s", err);
+       return invalfc(fc, "%s", err);
 }
 
 static int shmem_show_options(struct seq_file *seq, struct dentry *root)
@@ -3889,7 +3885,7 @@ static struct file_system_type shmem_fs_type = {
        .name           = "tmpfs",
        .init_fs_context = shmem_init_fs_context,
 #ifdef CONFIG_TMPFS
-       .parameters     = &shmem_fs_parameters,
+       .parameters     = shmem_fs_parameters,
 #endif
        .kill_sb        = kill_litter_super,
        .fs_flags       = FS_USERNS_MOUNT,
@@ -4035,7 +4031,7 @@ bool shmem_huge_enabled(struct vm_area_struct *vma)
 static struct file_system_type shmem_fs_type = {
        .name           = "tmpfs",
        .init_fs_context = ramfs_init_fs_context,
-       .parameters     = &ramfs_fs_parameters,
+       .parameters     = ramfs_fs_parameters,
        .kill_sb        = kill_litter_super,
        .fs_flags       = FS_USERNS_MOUNT,
 };
index 0d95dde..1907cb2 100644 (file)
@@ -1580,18 +1580,17 @@ static int slabinfo_open(struct inode *inode, struct file *file)
        return seq_open(file, &slabinfo_op);
 }
 
-static const struct file_operations proc_slabinfo_operations = {
-       .open           = slabinfo_open,
-       .read           = seq_read,
-       .write          = slabinfo_write,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
+static const struct proc_ops slabinfo_proc_ops = {
+       .proc_open      = slabinfo_open,
+       .proc_read      = seq_read,
+       .proc_write     = slabinfo_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 static int __init slab_proc_init(void)
 {
-       proc_create("slabinfo", SLABINFO_RIGHTS, NULL,
-                                               &proc_slabinfo_operations);
+       proc_create("slabinfo", SLABINFO_RIGHTS, NULL, &slabinfo_proc_ops);
        return 0;
 }
 module_init(slab_proc_init);
@@ -1677,28 +1676,6 @@ static __always_inline void *__do_krealloc(const void *p, size_t new_size,
 }
 
 /**
- * __krealloc - like krealloc() but don't free @p.
- * @p: object to reallocate memory for.
- * @new_size: how many bytes of memory are required.
- * @flags: the type of memory to allocate.
- *
- * This function is like krealloc() except it never frees the originally
- * allocated buffer. Use this if you don't want to free the buffer immediately
- * like, for example, with RCU.
- *
- * Return: pointer to the allocated memory or %NULL in case of error
- */
-void *__krealloc(const void *p, size_t new_size, gfp_t flags)
-{
-       if (unlikely(!new_size))
-               return ZERO_SIZE_PTR;
-
-       return __do_krealloc(p, new_size, flags);
-
-}
-EXPORT_SYMBOL(__krealloc);
-
-/**
  * krealloc - reallocate memory. The contents will remain unchanged.
  * @p: object to reallocate memory for.
  * @new_size: how many bytes of memory are required.
index 3918fc3..c184b69 100644 (file)
@@ -198,16 +198,6 @@ static void section_mark_present(struct mem_section *ms)
        ms->section_mem_map |= SECTION_MARKED_PRESENT;
 }
 
-static inline unsigned long next_present_section_nr(unsigned long section_nr)
-{
-       do {
-               section_nr++;
-               if (present_section_nr(section_nr))
-                       return section_nr;
-       } while ((section_nr <= __highest_present_section_nr));
-
-       return -1;
-}
 #define for_each_present_section_nr(start, section_nr)         \
        for (section_nr = next_present_section_nr(start-1);     \
             ((section_nr != -1) &&                             \
index 6febae9..2c33ff4 100644 (file)
@@ -2796,17 +2796,17 @@ static int swaps_open(struct inode *inode, struct file *file)
        return 0;
 }
 
-static const struct file_operations proc_swaps_operations = {
-       .open           = swaps_open,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = seq_release,
-       .poll           = swaps_poll,
+static const struct proc_ops swaps_proc_ops = {
+       .proc_open      = swaps_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
+       .proc_poll      = swaps_poll,
 };
 
 static int __init procswaps_init(void)
 {
-       proc_create("swaps", 0, NULL, &proc_swaps_operations);
+       proc_create("swaps", 0, NULL, &swaps_proc_ops);
        return 0;
 }
 __initcall(procswaps_init);
index 46d6cd9..829db9e 100644 (file)
@@ -53,15 +53,12 @@ static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
 
 static int parse_qos(const char *buff);
 
-/*
- *   Define allowed FILE OPERATIONS
- */
-static const struct file_operations mpc_file_operations = {
-       .open =         proc_mpc_open,
-       .read =         seq_read,
-       .llseek =       seq_lseek,
-       .write =        proc_mpc_write,
-       .release =      seq_release,
+static const struct proc_ops mpc_proc_ops = {
+       .proc_open      = proc_mpc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = proc_mpc_write,
+       .proc_release   = seq_release,
 };
 
 /*
@@ -290,7 +287,7 @@ int mpc_proc_init(void)
 {
        struct proc_dir_entry *p;
 
-       p = proc_create(STAT_FILE_NAME, 0, atm_proc_root, &mpc_file_operations);
+       p = proc_create(STAT_FILE_NAME, 0, atm_proc_root, &mpc_proc_ops);
        if (!p) {
                pr_err("Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
                return -ENOMEM;
index c318967..4369ffa 100644 (file)
@@ -36,9 +36,9 @@
 static ssize_t proc_dev_atm_read(struct file *file, char __user *buf,
                                 size_t count, loff_t *pos);
 
-static const struct file_operations proc_atm_dev_ops = {
-       .read =         proc_dev_atm_read,
-       .llseek =       noop_llseek,
+static const struct proc_ops atm_dev_proc_ops = {
+       .proc_read      = proc_dev_atm_read,
+       .proc_lseek     = noop_llseek,
 };
 
 static void add_stats(struct seq_file *seq, const char *aal,
@@ -359,7 +359,7 @@ int atm_proc_dev_register(struct atm_dev *dev)
                goto err_out;
 
        dev->proc_entry = proc_create_data(dev->proc_name, 0, atm_proc_root,
-                                          &proc_atm_dev_ops, dev);
+                                          &atm_dev_proc_ops, dev);
        if (!dev->proc_entry)
                goto err_free_name;
        return 0;
index 59d0ba2..ce09bb4 100644 (file)
@@ -13,5 +13,5 @@ libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
        auth.o auth_none.o \
        crypto.o armor.o \
        auth_x.o \
-       ceph_fs.o ceph_strings.o ceph_hash.o \
+       ceph_strings.o ceph_hash.o \
        pagevec.o snapshot.o string_table.o
index a9d6c97..a0e97f6 100644 (file)
@@ -269,7 +269,7 @@ enum {
        Opt_abort_on_full,
 };
 
-static const struct fs_parameter_spec ceph_param_specs[] = {
+static const struct fs_parameter_spec ceph_parameters[] = {
        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),
@@ -283,18 +283,13 @@ static const struct fs_parameter_spec ceph_param_specs[] = {
        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),
+                        fs_param_deprecated, NULL),
        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;
@@ -337,7 +332,7 @@ EXPORT_SYMBOL(ceph_destroy_options);
 
 /* get secret from key store */
 static int get_secret(struct ceph_crypto_key *dst, const char *name,
-                     struct fs_context *fc)
+                     struct p_log *log)
 {
        struct key *ukey;
        int key_err;
@@ -351,19 +346,19 @@ static int get_secret(struct ceph_crypto_key *dst, const char *name,
                key_err = PTR_ERR(ukey);
                switch (key_err) {
                case -ENOKEY:
-                       errorf(fc, "libceph: Failed due to key not found: %s",
+                       error_plog(log, "Failed due to key not found: %s",
                               name);
                        break;
                case -EKEYEXPIRED:
-                       errorf(fc, "libceph: Failed due to expired key: %s",
+                       error_plog(log, "Failed due to expired key: %s",
                               name);
                        break;
                case -EKEYREVOKED:
-                       errorf(fc, "libceph: Failed due to revoked key: %s",
+                       error_plog(log, "Failed due to revoked key: %s",
                               name);
                        break;
                default:
-                       errorf(fc, "libceph: Failed due to key error %d: %s",
+                       error_plog(log, "Failed due to key error %d: %s",
                               key_err, name);
                }
                err = -EPERM;
@@ -383,15 +378,16 @@ out:
 }
 
 int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
-                      struct fs_context *fc)
+                      struct fc_log *l)
 {
+       struct p_log log = {.prefix = "libceph", .log = l};
        int ret;
 
        /* ip1[:port1][,ip2[:port2]...] */
        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);
+               error_plog(&log, "Failed to parse monitor IPs: %d", ret);
                return ret;
        }
 
@@ -400,12 +396,13 @@ int ceph_parse_mon_ips(const char *buf, size_t len, struct ceph_options *opt,
 EXPORT_SYMBOL(ceph_parse_mon_ips);
 
 int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
-                    struct fs_context *fc)
+                    struct fc_log *l)
 {
        struct fs_parse_result result;
        int token, err;
+       struct p_log log = {.prefix = "libceph", .log = l};
 
-       token = fs_parse(fc, &ceph_parameters, param, &result);
+       token = __fs_parse(&log, ceph_parameters, param, &result);
        dout("%s fs_parse '%s' token %d\n", __func__, param->key, token);
        if (token < 0)
                return token;
@@ -417,7 +414,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
                                     &opt->my_addr,
                                     1, NULL);
                if (err) {
-                       errorf(fc, "libceph: Failed to parse ip: %d", err);
+                       error_plog(&log, "Failed to parse ip: %d", err);
                        return err;
                }
                opt->flags |= CEPH_OPT_MYIP;
@@ -426,7 +423,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
        case Opt_fsid:
                err = parse_fsid(param->string, &opt->fsid);
                if (err) {
-                       errorf(fc, "libceph: Failed to parse fsid: %d", err);
+                       error_plog(&log, "Failed to parse fsid: %d", err);
                        return err;
                }
                opt->flags |= CEPH_OPT_FSID;
@@ -445,7 +442,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
                        return -ENOMEM;
                err = ceph_crypto_key_unarmor(opt->key, param->string);
                if (err) {
-                       errorf(fc, "libceph: Failed to parse secret: %d", err);
+                       error_plog(&log, "Failed to parse secret: %d", err);
                        return err;
                }
                break;
@@ -456,10 +453,10 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
                opt->key = kzalloc(sizeof(*opt->key), GFP_KERNEL);
                if (!opt->key)
                        return -ENOMEM;
-               return get_secret(opt->key, param->string, fc);
+               return get_secret(opt->key, param->string, &log);
 
        case Opt_osdtimeout:
-               warnf(fc, "libceph: Ignoring osdtimeout");
+               warn_plog(&log, "Ignoring osdtimeout");
                break;
        case Opt_osdkeepalivetimeout:
                /* 0 isn't well defined right now, reject it */
@@ -530,7 +527,7 @@ int ceph_parse_param(struct fs_parameter *param, struct ceph_options *opt,
        return 0;
 
 out_of_range:
-       return invalf(fc, "libceph: %s out of range", param->key);
+       return inval_plog(&log, "%s out of range", param->key);
 }
 EXPORT_SYMBOL(ceph_parse_param);
 
index ba45b07..b68b376 100644 (file)
@@ -402,7 +402,7 @@ static void osd_req_op_data_release(struct ceph_osd_request *osd_req,
        case CEPH_OSD_OP_LIST_WATCHERS:
                ceph_osd_data_release(&op->list_watchers.response_data);
                break;
-       case CEPH_OSD_OP_COPY_FROM:
+       case CEPH_OSD_OP_COPY_FROM2:
                ceph_osd_data_release(&op->copy_from.osd_data);
                break;
        default:
@@ -697,7 +697,7 @@ static void get_num_data_items(struct ceph_osd_request *req,
                case CEPH_OSD_OP_SETXATTR:
                case CEPH_OSD_OP_CMPXATTR:
                case CEPH_OSD_OP_NOTIFY_ACK:
-               case CEPH_OSD_OP_COPY_FROM:
+               case CEPH_OSD_OP_COPY_FROM2:
                        *num_request_data_items += 1;
                        break;
 
@@ -1029,7 +1029,7 @@ static u32 osd_req_encode_op(struct ceph_osd_op *dst,
        case CEPH_OSD_OP_CREATE:
        case CEPH_OSD_OP_DELETE:
                break;
-       case CEPH_OSD_OP_COPY_FROM:
+       case CEPH_OSD_OP_COPY_FROM2:
                dst->copy_from.snapid = cpu_to_le64(src->copy_from.snapid);
                dst->copy_from.src_version =
                        cpu_to_le64(src->copy_from.src_version);
@@ -1966,7 +1966,7 @@ static void setup_request_data(struct ceph_osd_request *req)
                        ceph_osdc_msg_data_add(request_msg,
                                               &op->notify_ack.request_data);
                        break;
-               case CEPH_OSD_OP_COPY_FROM:
+               case CEPH_OSD_OP_COPY_FROM2:
                        ceph_osdc_msg_data_add(request_msg,
                                               &op->copy_from.osd_data);
                        break;
@@ -5315,6 +5315,7 @@ static int osd_req_op_copy_from_init(struct ceph_osd_request *req,
                                     struct ceph_object_locator *src_oloc,
                                     u32 src_fadvise_flags,
                                     u32 dst_fadvise_flags,
+                                    u32 truncate_seq, u64 truncate_size,
                                     u8 copy_from_flags)
 {
        struct ceph_osd_req_op *op;
@@ -5325,7 +5326,8 @@ static int osd_req_op_copy_from_init(struct ceph_osd_request *req,
        if (IS_ERR(pages))
                return PTR_ERR(pages);
 
-       op = _osd_req_op_init(req, 0, CEPH_OSD_OP_COPY_FROM, dst_fadvise_flags);
+       op = _osd_req_op_init(req, 0, CEPH_OSD_OP_COPY_FROM2,
+                             dst_fadvise_flags);
        op->copy_from.snapid = src_snapid;
        op->copy_from.src_version = src_version;
        op->copy_from.flags = copy_from_flags;
@@ -5335,6 +5337,8 @@ static int osd_req_op_copy_from_init(struct ceph_osd_request *req,
        end = p + PAGE_SIZE;
        ceph_encode_string(&p, end, src_oid->name, src_oid->name_len);
        encode_oloc(&p, end, src_oloc);
+       ceph_encode_32(&p, truncate_seq);
+       ceph_encode_64(&p, truncate_size);
        op->indata_len = PAGE_SIZE - (end - p);
 
        ceph_osd_data_pages_init(&op->copy_from.osd_data, pages,
@@ -5350,6 +5354,7 @@ int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
                        struct ceph_object_id *dst_oid,
                        struct ceph_object_locator *dst_oloc,
                        u32 dst_fadvise_flags,
+                       u32 truncate_seq, u64 truncate_size,
                        u8 copy_from_flags)
 {
        struct ceph_osd_request *req;
@@ -5366,7 +5371,8 @@ int ceph_osdc_copy_from(struct ceph_osd_client *osdc,
 
        ret = osd_req_op_copy_from_init(req, src_snapid, src_version, src_oid,
                                        src_oloc, src_fadvise_flags,
-                                       dst_fadvise_flags, copy_from_flags);
+                                       dst_fadvise_flags, truncate_seq,
+                                       truncate_size, copy_from_flags);
        if (ret)
                goto out;
 
index 458be6b..3ab23f6 100644 (file)
@@ -643,9 +643,10 @@ static struct bpf_map *bpf_sk_storage_map_alloc(union bpf_attr *attr)
                return ERR_PTR(-ENOMEM);
        bpf_map_init_from_attr(&smap->map, attr);
 
+       nbuckets = roundup_pow_of_two(num_possible_cpus());
        /* Use at least 2 buckets, select_bucket() is undefined behavior with 1 bucket */
-       smap->bucket_log = max_t(u32, 1, ilog2(roundup_pow_of_two(num_possible_cpus())));
-       nbuckets = 1U << smap->bucket_log;
+       nbuckets = max_t(u32, 2, nbuckets);
+       smap->bucket_log = ilog2(nbuckets);
        cost = sizeof(*smap->buckets) * nbuckets + sizeof(*smap);
 
        ret = bpf_map_charge_init(&smap->map.memory, cost);
index 17529d4..a69e8bd 100644 (file)
@@ -5792,7 +5792,7 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
        if (&ptype->list == head)
                goto normal;
 
-       if (IS_ERR(pp) && PTR_ERR(pp) == -EINPROGRESS) {
+       if (PTR_ERR(pp) == -EINPROGRESS) {
                ret = GRO_CONSUMED;
                goto ok;
        }
index ca1df0e..549ee56 100644 (file)
@@ -3986,6 +3986,12 @@ static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
                goto out_unlock;
        }
 
+       /* return 0 if there is no further data to read */
+       if (start_offset >= region->size) {
+               err = 0;
+               goto out_unlock;
+       }
+
        hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
                          &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
                          DEVLINK_CMD_REGION_READ);
index ea46fc6..31700e0 100644 (file)
@@ -1000,8 +1000,10 @@ static void net_dm_hw_monitor_stop(struct netlink_ext_ack *extack)
 {
        int cpu;
 
-       if (!monitor_hw)
+       if (!monitor_hw) {
                NL_SET_ERR_MSG_MOD(extack, "Hardware monitoring already disabled");
+               return;
+       }
 
        monitor_hw = false;
 
index 792e374..c180871 100644 (file)
@@ -1573,7 +1573,7 @@ int sk_reuseport_attach_bpf(u32 ufd, struct sock *sk)
                return -EPERM;
 
        prog = bpf_prog_get_type(ufd, BPF_PROG_TYPE_SOCKET_FILTER);
-       if (IS_ERR(prog) && PTR_ERR(prog) == -EINVAL)
+       if (PTR_ERR(prog) == -EINVAL)
                prog = bpf_prog_get_type(ufd, BPF_PROG_TYPE_SK_REUSEPORT);
        if (IS_ERR(prog))
                return PTR_ERR(prog);
index 294bfcf..acc849d 100644 (file)
@@ -535,12 +535,12 @@ static int pgctrl_open(struct inode *inode, struct file *file)
        return single_open(file, pgctrl_show, PDE_DATA(inode));
 }
 
-static const struct file_operations pktgen_fops = {
-       .open    = pgctrl_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .write   = pgctrl_write,
-       .release = single_release,
+static const struct proc_ops pktgen_proc_ops = {
+       .proc_open      = pgctrl_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = pgctrl_write,
+       .proc_release   = single_release,
 };
 
 static int pktgen_if_show(struct seq_file *seq, void *v)
@@ -1707,12 +1707,12 @@ static int pktgen_if_open(struct inode *inode, struct file *file)
        return single_open(file, pktgen_if_show, PDE_DATA(inode));
 }
 
-static const struct file_operations pktgen_if_fops = {
-       .open    = pktgen_if_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .write   = pktgen_if_write,
-       .release = single_release,
+static const struct proc_ops pktgen_if_proc_ops = {
+       .proc_open      = pktgen_if_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = pktgen_if_write,
+       .proc_release   = single_release,
 };
 
 static int pktgen_thread_show(struct seq_file *seq, void *v)
@@ -1844,12 +1844,12 @@ static int pktgen_thread_open(struct inode *inode, struct file *file)
        return single_open(file, pktgen_thread_show, PDE_DATA(inode));
 }
 
-static const struct file_operations pktgen_thread_fops = {
-       .open    = pktgen_thread_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .write   = pktgen_thread_write,
-       .release = single_release,
+static const struct proc_ops pktgen_thread_proc_ops = {
+       .proc_open      = pktgen_thread_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_write     = pktgen_thread_write,
+       .proc_release   = single_release,
 };
 
 /* Think find or remove for NN */
@@ -1926,7 +1926,7 @@ static void pktgen_change_name(const struct pktgen_net *pn, struct net_device *d
 
                        pkt_dev->entry = proc_create_data(dev->name, 0600,
                                                          pn->proc_dir,
-                                                         &pktgen_if_fops,
+                                                         &pktgen_if_proc_ops,
                                                          pkt_dev);
                        if (!pkt_dev->entry)
                                pr_err("can't move proc entry for '%s'\n",
@@ -3638,7 +3638,7 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
                pkt_dev->clone_skb = pg_clone_skb_d;
 
        pkt_dev->entry = proc_create_data(ifname, 0600, t->net->proc_dir,
-                                         &pktgen_if_fops, pkt_dev);
+                                         &pktgen_if_proc_ops, pkt_dev);
        if (!pkt_dev->entry) {
                pr_err("cannot create %s/%s procfs entry\n",
                       PG_PROC_DIR, ifname);
@@ -3708,7 +3708,7 @@ static int __net_init pktgen_create_thread(int cpu, struct pktgen_net *pn)
        t->tsk = p;
 
        pe = proc_create_data(t->tsk->comm, 0600, pn->proc_dir,
-                             &pktgen_thread_fops, t);
+                             &pktgen_thread_proc_ops, t);
        if (!pe) {
                pr_err("cannot create %s/%s procfs entry\n",
                       PG_PROC_DIR, t->tsk->comm);
@@ -3793,7 +3793,7 @@ static int __net_init pg_net_init(struct net *net)
                pr_warn("cannot create /proc/net/%s\n", PG_PROC_DIR);
                return -ENODEV;
        }
-       pe = proc_create(PGCTRL, 0600, pn->proc_dir, &pktgen_fops);
+       pe = proc_create(PGCTRL, 0600, pn->proc_dir, &pktgen_proc_ops);
        if (pe == NULL) {
                pr_err("cannot create %s procfs entry\n", PGCTRL);
                ret = -EINVAL;
index 8998e35..085cef5 100644 (file)
@@ -234,7 +234,6 @@ static void sock_map_free(struct bpf_map *map)
        int i;
 
        synchronize_rcu();
-       rcu_read_lock();
        raw_spin_lock_bh(&stab->lock);
        for (i = 0; i < stab->map.max_entries; i++) {
                struct sock **psk = &stab->sks[i];
@@ -243,13 +242,15 @@ static void sock_map_free(struct bpf_map *map)
                sk = xchg(psk, NULL);
                if (sk) {
                        lock_sock(sk);
+                       rcu_read_lock();
                        sock_map_unref(sk, psk);
+                       rcu_read_unlock();
                        release_sock(sk);
                }
        }
        raw_spin_unlock_bh(&stab->lock);
-       rcu_read_unlock();
 
+       /* wait for psock readers accessing its map link */
        synchronize_rcu();
 
        bpf_map_area_free(stab->sks);
@@ -416,14 +417,16 @@ static int sock_map_update_elem(struct bpf_map *map, void *key,
                ret = -EINVAL;
                goto out;
        }
-       if (!sock_map_sk_is_suitable(sk) ||
-           sk->sk_state != TCP_ESTABLISHED) {
+       if (!sock_map_sk_is_suitable(sk)) {
                ret = -EOPNOTSUPP;
                goto out;
        }
 
        sock_map_sk_acquire(sk);
-       ret = sock_map_update_common(map, idx, sk, flags);
+       if (sk->sk_state != TCP_ESTABLISHED)
+               ret = -EOPNOTSUPP;
+       else
+               ret = sock_map_update_common(map, idx, sk, flags);
        sock_map_sk_release(sk);
 out:
        fput(sock->file);
@@ -739,14 +742,16 @@ static int sock_hash_update_elem(struct bpf_map *map, void *key,
                ret = -EINVAL;
                goto out;
        }
-       if (!sock_map_sk_is_suitable(sk) ||
-           sk->sk_state != TCP_ESTABLISHED) {
+       if (!sock_map_sk_is_suitable(sk)) {
                ret = -EOPNOTSUPP;
                goto out;
        }
 
        sock_map_sk_acquire(sk);
-       ret = sock_hash_update_common(map, key, sk, flags);
+       if (sk->sk_state != TCP_ESTABLISHED)
+               ret = -EOPNOTSUPP;
+       else
+               ret = sock_hash_update_common(map, key, sk, flags);
        sock_map_sk_release(sk);
 out:
        fput(sock->file);
@@ -859,19 +864,22 @@ static void sock_hash_free(struct bpf_map *map)
        int i;
 
        synchronize_rcu();
-       rcu_read_lock();
        for (i = 0; i < htab->buckets_num; i++) {
                bucket = sock_hash_select_bucket(htab, i);
                raw_spin_lock_bh(&bucket->lock);
                hlist_for_each_entry_safe(elem, node, &bucket->head, node) {
                        hlist_del_rcu(&elem->node);
                        lock_sock(elem->sk);
+                       rcu_read_lock();
                        sock_map_unref(elem->sk, elem);
+                       rcu_read_unlock();
                        release_sock(elem->sk);
                }
                raw_spin_unlock_bh(&bucket->lock);
        }
-       rcu_read_unlock();
+
+       /* wait for psock readers accessing its map link */
+       synchronize_rcu();
 
        bpf_map_area_free(htab->buckets);
        kfree(htab);
index ee56129..fbfd0db 100644 (file)
@@ -27,6 +27,8 @@ static rx_handler_result_t hsr_handle_frame(struct sk_buff **pskb)
 
        rcu_read_lock(); /* hsr->node_db, hsr->ports */
        port = hsr_port_get_rcu(skb->dev);
+       if (!port)
+               goto finish_pass;
 
        if (hsr_addr_is_self(port->hsr, eth_hdr(skb)->h_source)) {
                /* Directly kill frames sent by ourselves */
index f35308f..4438f6b 100644 (file)
@@ -1334,7 +1334,7 @@ static int __init ipconfig_proc_net_init(void)
 
 /* Create a new file under /proc/net/ipconfig */
 static int ipconfig_proc_net_create(const char *name,
-                                   const struct file_operations *fops)
+                                   const struct proc_ops *proc_ops)
 {
        char *pname;
        struct proc_dir_entry *p;
@@ -1346,7 +1346,7 @@ static int ipconfig_proc_net_create(const char *name,
        if (!pname)
                return -ENOMEM;
 
-       p = proc_create(pname, 0444, init_net.proc_net, fops);
+       p = proc_create(pname, 0444, init_net.proc_net, proc_ops);
        kfree(pname);
        if (!p)
                return -ENOMEM;
@@ -1355,7 +1355,7 @@ static int ipconfig_proc_net_create(const char *name,
 }
 
 /* Write NTP server IP addresses to /proc/net/ipconfig/ntp_servers */
-static int ntp_servers_seq_show(struct seq_file *seq, void *v)
+static int ntp_servers_show(struct seq_file *seq, void *v)
 {
        int i;
 
@@ -1365,7 +1365,7 @@ static int ntp_servers_seq_show(struct seq_file *seq, void *v)
        }
        return 0;
 }
-DEFINE_SHOW_ATTRIBUTE(ntp_servers_seq);
+DEFINE_PROC_SHOW_ATTRIBUTE(ntp_servers);
 #endif /* CONFIG_PROC_FS */
 
 /*
@@ -1456,7 +1456,7 @@ static int __init ip_auto_config(void)
        proc_create_single("pnp", 0444, init_net.proc_net, pnp_seq_show);
 
        if (ipconfig_proc_net_init() == 0)
-               ipconfig_proc_net_create("ntp_servers", &ntp_servers_seq_fops);
+               ipconfig_proc_net_create("ntp_servers", &ntp_servers_proc_ops);
 #endif /* CONFIG_PROC_FS */
 
        if (!ic_enable)
index 6bdb1ab..f8755a4 100644 (file)
@@ -58,7 +58,7 @@ struct clusterip_config {
 };
 
 #ifdef CONFIG_PROC_FS
-static const struct file_operations clusterip_proc_fops;
+static const struct proc_ops clusterip_proc_ops;
 #endif
 
 struct clusterip_net {
@@ -280,7 +280,7 @@ clusterip_config_init(struct net *net, const struct ipt_clusterip_tgt_info *i,
                mutex_lock(&cn->mutex);
                c->pde = proc_create_data(buffer, 0600,
                                          cn->procdir,
-                                         &clusterip_proc_fops, c);
+                                         &clusterip_proc_ops, c);
                mutex_unlock(&cn->mutex);
                if (!c->pde) {
                        err = -ENOMEM;
@@ -804,12 +804,12 @@ static ssize_t clusterip_proc_write(struct file *file, const char __user *input,
        return size;
 }
 
-static const struct file_operations clusterip_proc_fops = {
-       .open    = clusterip_proc_open,
-       .read    = seq_read,
-       .write   = clusterip_proc_write,
-       .llseek  = seq_lseek,
-       .release = clusterip_proc_release,
+static const struct proc_ops clusterip_proc_ops = {
+       .proc_open      = clusterip_proc_open,
+       .proc_read      = seq_read,
+       .proc_write     = clusterip_proc_write,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = clusterip_proc_release,
 };
 
 #endif /* CONFIG_PROC_FS */
index d5c57b3..ebe7060 100644 (file)
@@ -237,11 +237,11 @@ static int rt_cache_seq_open(struct inode *inode, struct file *file)
        return seq_open(file, &rt_cache_seq_ops);
 }
 
-static const struct file_operations rt_cache_seq_fops = {
-       .open    = rt_cache_seq_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = seq_release,
+static const struct proc_ops rt_cache_proc_ops = {
+       .proc_open      = rt_cache_seq_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 
@@ -328,11 +328,11 @@ static int rt_cpu_seq_open(struct inode *inode, struct file *file)
        return seq_open(file, &rt_cpu_seq_ops);
 }
 
-static const struct file_operations rt_cpu_seq_fops = {
-       .open    = rt_cpu_seq_open,
-       .read    = seq_read,
-       .llseek  = seq_lseek,
-       .release = seq_release,
+static const struct proc_ops rt_cpu_proc_ops = {
+       .proc_open      = rt_cpu_seq_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = seq_release,
 };
 
 #ifdef CONFIG_IP_ROUTE_CLASSID
@@ -366,12 +366,12 @@ static int __net_init ip_rt_do_proc_init(struct net *net)
        struct proc_dir_entry *pde;
 
        pde = proc_create("rt_cache", 0444, net->proc_net,
-                         &rt_cache_seq_fops);
+                         &rt_cache_proc_ops);
        if (!pde)
                goto err1;
 
        pde = proc_create("rt_cache", 0444,
-                         net->proc_net_stat, &rt_cpu_seq_fops);
+                         net->proc_net_stat, &rt_cpu_proc_ops);
        if (!pde)
                goto err2;
 
index 484485a..eb2d805 100644 (file)
@@ -2622,10 +2622,12 @@ int tcp_disconnect(struct sock *sk, int flags)
        tp->snd_cwnd = TCP_INIT_CWND;
        tp->snd_cwnd_cnt = 0;
        tp->window_clamp = 0;
+       tp->delivered = 0;
        tp->delivered_ce = 0;
        tcp_set_ca_state(sk, TCP_CA_Open);
        tp->is_sack_reneg = 0;
        tcp_clear_retrans(tp);
+       tp->total_retrans = 0;
        inet_csk_delack_init(sk);
        /* Initialize rcv_mss to TCP_MIN_MSS to avoid division by 0
         * issue in __tcp_select_window()
@@ -2637,10 +2639,14 @@ int tcp_disconnect(struct sock *sk, int flags)
        sk->sk_rx_dst = NULL;
        tcp_saved_syn_free(tp);
        tp->compressed_ack = 0;
+       tp->segs_in = 0;
+       tp->segs_out = 0;
        tp->bytes_sent = 0;
        tp->bytes_acked = 0;
        tp->bytes_received = 0;
        tp->bytes_retrans = 0;
+       tp->data_segs_in = 0;
+       tp->data_segs_out = 0;
        tp->duplicate_sack[0].start_seq = 0;
        tp->duplicate_sack[0].end_seq = 0;
        tp->dsack_dups = 0;
index e325b45..316ebdf 100644 (file)
@@ -5908,8 +5908,14 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
                 *        the segment and return)"
                 */
                if (!after(TCP_SKB_CB(skb)->ack_seq, tp->snd_una) ||
-                   after(TCP_SKB_CB(skb)->ack_seq, tp->snd_nxt))
+                   after(TCP_SKB_CB(skb)->ack_seq, tp->snd_nxt)) {
+                       /* Previous FIN/ACK or RST/ACK might be ignored. */
+                       if (icsk->icsk_retransmits == 0)
+                               inet_csk_reset_xmit_timer(sk,
+                                               ICSK_TIME_RETRANS,
+                                               TCP_TIMEOUT_MIN, TCP_RTO_MAX);
                        goto reset_and_undo;
+               }
 
                if (tp->rx_opt.saw_tstamp && tp->rx_opt.rcv_tsecr &&
                    !between(tp->rx_opt.rcv_tsecr, tp->retrans_stamp,
index 39d861d..cb493e1 100644 (file)
@@ -5718,6 +5718,9 @@ static int inet6_set_link_af(struct net_device *dev, const struct nlattr *nla)
        struct nlattr *tb[IFLA_INET6_MAX + 1];
        int err;
 
+       if (!idev)
+               return -EAFNOSUPPORT;
+
        if (nla_parse_nested_deprecated(tb, IFLA_INET6_MAX, nla, NULL, NULL) < 0)
                BUG();
 
index c99223c..fcb53ed 100644 (file)
@@ -320,8 +320,13 @@ int l2tp_session_register(struct l2tp_session *session,
 
                spin_lock_bh(&pn->l2tp_session_hlist_lock);
 
+               /* IP encap expects session IDs to be globally unique, while
+                * UDP encap doesn't.
+                */
                hlist_for_each_entry(session_walk, g_head, global_hlist)
-                       if (session_walk->session_id == session->session_id) {
+                       if (session_walk->session_id == session->session_id &&
+                           (session_walk->tunnel->encap == L2TP_ENCAPTYPE_IP ||
+                            tunnel->encap == L2TP_ENCAPTYPE_IP)) {
                                err = -EEXIST;
                                goto err_tlock_pnlock;
                        }
index 3bccee4..73780b4 100644 (file)
 
 #define MPTCP_SAME_STATE TCP_MAX_STATES
 
-static void __mptcp_close(struct sock *sk, long timeout);
-
-static const struct proto_ops *tcp_proto_ops(struct sock *sk)
-{
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
-       if (sk->sk_family == AF_INET6)
-               return &inet6_stream_ops;
+struct mptcp6_sock {
+       struct mptcp_sock msk;
+       struct ipv6_pinfo np;
+};
 #endif
-       return &inet_stream_ops;
-}
-
-/* MP_CAPABLE handshake failed, convert msk to plain tcp, replacing
- * socket->sk and stream ops and destroying msk
- * return the msk socket, as we can't access msk anymore after this function
- * completes
- * Called with msk lock held, releases such lock before returning
- */
-static struct socket *__mptcp_fallback_to_tcp(struct mptcp_sock *msk,
-                                             struct sock *ssk)
-{
-       struct mptcp_subflow_context *subflow;
-       struct socket *sock;
-       struct sock *sk;
-
-       sk = (struct sock *)msk;
-       sock = sk->sk_socket;
-       subflow = mptcp_subflow_ctx(ssk);
-
-       /* detach the msk socket */
-       list_del_init(&subflow->node);
-       sock_orphan(sk);
-       sock->sk = NULL;
-
-       /* socket is now TCP */
-       lock_sock(ssk);
-       sock_graft(ssk, sock);
-       if (subflow->conn) {
-               /* We can't release the ULP data on a live socket,
-                * restore the tcp callback
-                */
-               mptcp_subflow_tcp_fallback(ssk, subflow);
-               sock_put(subflow->conn);
-               subflow->conn = NULL;
-       }
-       release_sock(ssk);
-       sock->ops = tcp_proto_ops(ssk);
-
-       /* destroy the left-over msk sock */
-       __mptcp_close(sk, 0);
-       return sock;
-}
 
 /* If msk has an initial subflow socket, and the MP_CAPABLE handshake has not
  * completed yet or has failed, return the subflow socket.
@@ -93,10 +48,6 @@ static bool __mptcp_needs_tcp_fallback(const struct mptcp_sock *msk)
        return msk->first && !sk_is_mptcp(msk->first);
 }
 
-/* if the mp_capable handshake has failed, it fallbacks msk to plain TCP,
- * releases the socket lock and returns a reference to the now TCP socket.
- * Otherwise returns NULL
- */
 static struct socket *__mptcp_tcp_fallback(struct mptcp_sock *msk)
 {
        sock_owned_by_me((const struct sock *)msk);
@@ -105,15 +56,11 @@ static struct socket *__mptcp_tcp_fallback(struct mptcp_sock *msk)
                return NULL;
 
        if (msk->subflow) {
-               /* the first subflow is an active connection, discart the
-                * paired socket
-                */
-               msk->subflow->sk = NULL;
-               sock_release(msk->subflow);
-               msk->subflow = NULL;
+               release_sock((struct sock *)msk);
+               return msk->subflow;
        }
 
-       return __mptcp_fallback_to_tcp(msk, msk->first);
+       return NULL;
 }
 
 static bool __mptcp_can_create_subflow(const struct mptcp_sock *msk)
@@ -640,12 +587,14 @@ static void mptcp_subflow_shutdown(struct sock *ssk, int how)
 }
 
 /* Called with msk lock held, releases such lock before returning */
-static void __mptcp_close(struct sock *sk, long timeout)
+static void mptcp_close(struct sock *sk, long timeout)
 {
        struct mptcp_subflow_context *subflow, *tmp;
        struct mptcp_sock *msk = mptcp_sk(sk);
        LIST_HEAD(conn_list);
 
+       lock_sock(sk);
+
        mptcp_token_destroy(msk->token);
        inet_sk_state_store(sk, TCP_CLOSE);
 
@@ -662,12 +611,6 @@ static void __mptcp_close(struct sock *sk, long timeout)
        sk_common_release(sk);
 }
 
-static void mptcp_close(struct sock *sk, long timeout)
-{
-       lock_sock(sk);
-       __mptcp_close(sk, timeout);
-}
-
 static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
 {
 #if IS_ENABLED(CONFIG_MPTCP_IPV6)
@@ -691,6 +634,30 @@ static void mptcp_copy_inaddrs(struct sock *msk, const struct sock *ssk)
        inet_sk(msk)->inet_rcv_saddr = inet_sk(ssk)->inet_rcv_saddr;
 }
 
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+static struct ipv6_pinfo *mptcp_inet6_sk(const struct sock *sk)
+{
+       unsigned int offset = sizeof(struct mptcp6_sock) - sizeof(struct ipv6_pinfo);
+
+       return (struct ipv6_pinfo *)(((u8 *)sk) + offset);
+}
+#endif
+
+struct sock *mptcp_sk_clone_lock(const struct sock *sk)
+{
+       struct sock *nsk = sk_clone_lock(sk, GFP_ATOMIC);
+
+       if (!nsk)
+               return NULL;
+
+#if IS_ENABLED(CONFIG_MPTCP_IPV6)
+       if (nsk->sk_family == AF_INET6)
+               inet_sk(nsk)->pinet6 = mptcp_inet6_sk(nsk);
+#endif
+
+       return nsk;
+}
+
 static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
                                 bool kern)
 {
@@ -721,7 +688,7 @@ static struct sock *mptcp_accept(struct sock *sk, int flags, int *err,
                lock_sock(sk);
 
                local_bh_disable();
-               new_mptcp_sock = sk_clone_lock(sk, GFP_ATOMIC);
+               new_mptcp_sock = mptcp_sk_clone_lock(sk);
                if (!new_mptcp_sock) {
                        *err = -ENOBUFS;
                        local_bh_enable();
@@ -1270,8 +1237,7 @@ int mptcp_proto_v6_init(void)
        strcpy(mptcp_v6_prot.name, "MPTCPv6");
        mptcp_v6_prot.slab = NULL;
        mptcp_v6_prot.destroy = mptcp_v6_destroy;
-       mptcp_v6_prot.obj_size = sizeof(struct mptcp_sock) +
-                                sizeof(struct ipv6_pinfo);
+       mptcp_v6_prot.obj_size = sizeof(struct mptcp6_sock);
 
        err = proto_register(&mptcp_v6_prot, 1);
        if (err)
index cf895bc..69c107f 100644 (file)
@@ -1483,31 +1483,34 @@ ip_set_dump_policy[IPSET_ATTR_CMD_MAX + 1] = {
 };
 
 static int
-dump_init(struct netlink_callback *cb, struct ip_set_net *inst)
+ip_set_dump_start(struct netlink_callback *cb)
 {
        struct nlmsghdr *nlh = nlmsg_hdr(cb->skb);
        int min_len = nlmsg_total_size(sizeof(struct nfgenmsg));
        struct nlattr *cda[IPSET_ATTR_CMD_MAX + 1];
        struct nlattr *attr = (void *)nlh + min_len;
+       struct sk_buff *skb = cb->skb;
+       struct ip_set_net *inst = ip_set_pernet(sock_net(skb->sk));
        u32 dump_type;
-       ip_set_id_t index;
        int ret;
 
        ret = nla_parse(cda, IPSET_ATTR_CMD_MAX, attr,
                        nlh->nlmsg_len - min_len,
                        ip_set_dump_policy, NULL);
        if (ret)
-               return ret;
+               goto error;
 
        cb->args[IPSET_CB_PROTO] = nla_get_u8(cda[IPSET_ATTR_PROTOCOL]);
        if (cda[IPSET_ATTR_SETNAME]) {
+               ip_set_id_t index;
                struct ip_set *set;
 
                set = find_set_and_id(inst, nla_data(cda[IPSET_ATTR_SETNAME]),
                                      &index);
-               if (!set)
-                       return -ENOENT;
-
+               if (!set) {
+                       ret = -ENOENT;
+                       goto error;
+               }
                dump_type = DUMP_ONE;
                cb->args[IPSET_CB_INDEX] = index;
        } else {
@@ -1523,10 +1526,17 @@ dump_init(struct netlink_callback *cb, struct ip_set_net *inst)
        cb->args[IPSET_CB_DUMP] = dump_type;
 
        return 0;
+
+error:
+       /* We have to create and send the error message manually :-( */
+       if (nlh->nlmsg_flags & NLM_F_ACK) {
+               netlink_ack(cb->skb, nlh, ret, NULL);
+       }
+       return ret;
 }
 
 static int
-ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
+ip_set_dump_do(struct sk_buff *skb, struct netlink_callback *cb)
 {
        ip_set_id_t index = IPSET_INVALID_ID, max;
        struct ip_set *set = NULL;
@@ -1537,18 +1547,8 @@ ip_set_dump_start(struct sk_buff *skb, struct netlink_callback *cb)
        bool is_destroyed;
        int ret = 0;
 
-       if (!cb->args[IPSET_CB_DUMP]) {
-               ret = dump_init(cb, inst);
-               if (ret < 0) {
-                       nlh = nlmsg_hdr(cb->skb);
-                       /* We have to create and send the error message
-                        * manually :-(
-                        */
-                       if (nlh->nlmsg_flags & NLM_F_ACK)
-                               netlink_ack(cb->skb, nlh, ret, NULL);
-                       return ret;
-               }
-       }
+       if (!cb->args[IPSET_CB_DUMP])
+               return -EINVAL;
 
        if (cb->args[IPSET_CB_INDEX] >= inst->ip_set_max)
                goto out;
@@ -1684,7 +1684,8 @@ static int ip_set_dump(struct net *net, struct sock *ctnl, struct sk_buff *skb,
 
        {
                struct netlink_dump_control c = {
-                       .dump = ip_set_dump_start,
+                       .start = ip_set_dump_start,
+                       .dump = ip_set_dump_do,
                        .done = ip_set_dump_done,
                };
                return netlink_dump_start(ctnl, skb, nlh, &c);
index f4c4b46..d130542 100644 (file)
@@ -2248,8 +2248,7 @@ void *nf_ct_alloc_hashtable(unsigned int *sizep, int nulls)
        BUILD_BUG_ON(sizeof(struct hlist_nulls_head) != sizeof(struct hlist_head));
        nr_slots = *sizep = roundup(*sizep, PAGE_SIZE / sizeof(struct hlist_nulls_head));
 
-       hash = kvmalloc_array(nr_slots, sizeof(struct hlist_nulls_head),
-                             GFP_KERNEL | __GFP_ZERO);
+       hash = kvcalloc(nr_slots, sizeof(struct hlist_nulls_head), GFP_KERNEL);
 
        if (hash && nulls)
                for (i = 0; i < nr_slots; i++)
index 7e91989..8af28e1 100644 (file)
@@ -529,9 +529,9 @@ static void nf_flow_table_do_cleanup(struct flow_offload *flow, void *data)
 static void nf_flow_table_iterate_cleanup(struct nf_flowtable *flowtable,
                                          struct net_device *dev)
 {
-       nf_flow_table_offload_flush(flowtable);
        nf_flow_table_iterate(flowtable, nf_flow_table_do_cleanup, dev);
        flush_delayed_work(&flowtable->gc_work);
+       nf_flow_table_offload_flush(flowtable);
 }
 
 void nf_flow_table_cleanup(struct net_device *dev)
@@ -553,6 +553,7 @@ void nf_flow_table_free(struct nf_flowtable *flow_table)
        cancel_delayed_work_sync(&flow_table->gc_work);
        nf_flow_table_iterate(flow_table, nf_flow_table_do_cleanup, NULL);
        nf_flow_table_iterate(flow_table, nf_flow_offload_gc_step, flow_table);
+       nf_flow_table_offload_flush(flow_table);
        rhashtable_destroy(&flow_table->rhashtable);
 }
 EXPORT_SYMBOL_GPL(nf_flow_table_free);
index c8b70ff..83e1db3 100644 (file)
@@ -675,6 +675,7 @@ static void flow_offload_work_del(struct flow_offload_work *offload)
 {
        flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_ORIGINAL);
        flow_offload_tuple_del(offload, FLOW_OFFLOAD_DIR_REPLY);
+       set_bit(NF_FLOW_HW_DEAD, &offload->flow->flags);
 }
 
 static void flow_offload_tuple_stats(struct flow_offload_work *offload,
index ce70c25..e27c6c5 100644 (file)
@@ -939,14 +939,14 @@ EXPORT_SYMBOL(xt_check_entry_offsets);
  *
  * @size: number of entries
  *
- * Return: NULL or kmalloc'd or vmalloc'd array
+ * Return: NULL or zeroed kmalloc'd or vmalloc'd array
  */
 unsigned int *xt_alloc_entry_offsets(unsigned int size)
 {
        if (size > XT_MAX_TABLE_SIZE / sizeof(unsigned int))
                return NULL;
 
-       return kvmalloc_array(size, sizeof(unsigned int), GFP_KERNEL | __GFP_ZERO);
+       return kvcalloc(size, sizeof(unsigned int), GFP_KERNEL);
 
 }
 EXPORT_SYMBOL(xt_alloc_entry_offsets);
index 781e0b4..0a97080 100644 (file)
@@ -103,7 +103,7 @@ static DEFINE_SPINLOCK(recent_lock);
 static DEFINE_MUTEX(recent_mutex);
 
 #ifdef CONFIG_PROC_FS
-static const struct file_operations recent_mt_fops;
+static const struct proc_ops recent_mt_proc_ops;
 #endif
 
 static u_int32_t hash_rnd __read_mostly;
@@ -405,7 +405,7 @@ static int recent_mt_check(const struct xt_mtchk_param *par,
                goto out;
        }
        pde = proc_create_data(t->name, ip_list_perms, recent_net->xt_recent,
-                 &recent_mt_fops, t);
+                              &recent_mt_proc_ops, t);
        if (pde == NULL) {
                recent_table_free(t);
                ret = -ENOMEM;
@@ -616,13 +616,12 @@ recent_mt_proc_write(struct file *file, const char __user *input,
        return size + 1;
 }
 
-static const struct file_operations recent_mt_fops = {
-       .open    = recent_seq_open,
-       .read    = seq_read,
-       .write   = recent_mt_proc_write,
-       .release = seq_release_private,
-       .owner   = THIS_MODULE,
-       .llseek = seq_lseek,
+static const struct proc_ops recent_mt_proc_ops = {
+       .proc_open      = recent_seq_open,
+       .proc_read      = seq_read,
+       .proc_write     = recent_mt_proc_write,
+       .proc_release   = seq_release_private,
+       .proc_lseek     = seq_lseek,
 };
 
 static int __net_init recent_proc_net_init(struct net *net)
index 9d3c4d2..fe42f98 100644 (file)
@@ -194,6 +194,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len)
 service_in_use:
        write_unlock(&local->services_lock);
        rxrpc_unuse_local(local);
+       rxrpc_put_local(local);
        ret = -EADDRINUSE;
 error_unlock:
        release_sock(&rx->sk);
@@ -899,6 +900,7 @@ static int rxrpc_release_sock(struct sock *sk)
        rxrpc_purge_queue(&sk->sk_receive_queue);
 
        rxrpc_unuse_local(rx->local);
+       rxrpc_put_local(rx->local);
        rx->local = NULL;
        key_put(rx->key);
        rx->key = NULL;
index 5e99df8..7d730c4 100644 (file)
@@ -490,6 +490,7 @@ enum rxrpc_call_flag {
        RXRPC_CALL_RX_HEARD,            /* The peer responded at least once to this call */
        RXRPC_CALL_RX_UNDERRUN,         /* Got data underrun */
        RXRPC_CALL_IS_INTR,             /* The call is interruptible */
+       RXRPC_CALL_DISCONNECTED,        /* The call has been disconnected */
 };
 
 /*
@@ -1021,6 +1022,16 @@ void rxrpc_unuse_local(struct rxrpc_local *);
 void rxrpc_queue_local(struct rxrpc_local *);
 void rxrpc_destroy_all_locals(struct rxrpc_net *);
 
+static inline bool __rxrpc_unuse_local(struct rxrpc_local *local)
+{
+       return atomic_dec_return(&local->active_users) == 0;
+}
+
+static inline bool __rxrpc_use_local(struct rxrpc_local *local)
+{
+       return atomic_fetch_add_unless(&local->active_users, 1, 0) != 0;
+}
+
 /*
  * misc.c
  */
index a31c18c..c9f34b0 100644 (file)
@@ -493,7 +493,7 @@ void rxrpc_release_call(struct rxrpc_sock *rx, struct rxrpc_call *call)
 
        _debug("RELEASE CALL %p (%d CONN %p)", call, call->debug_id, conn);
 
-       if (conn)
+       if (conn && !test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
                rxrpc_disconnect_call(call);
        if (call->security)
                call->security->free_call_crypto(call);
@@ -562,13 +562,14 @@ void rxrpc_put_call(struct rxrpc_call *call, enum rxrpc_call_trace op)
 }
 
 /*
- * Final call destruction under RCU.
+ * Final call destruction - but must be done in process context.
  */
-static void rxrpc_rcu_destroy_call(struct rcu_head *rcu)
+static void rxrpc_destroy_call(struct work_struct *work)
 {
-       struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu);
+       struct rxrpc_call *call = container_of(work, struct rxrpc_call, processor);
        struct rxrpc_net *rxnet = call->rxnet;
 
+       rxrpc_put_connection(call->conn);
        rxrpc_put_peer(call->peer);
        kfree(call->rxtx_buffer);
        kfree(call->rxtx_annotations);
@@ -578,6 +579,22 @@ static void rxrpc_rcu_destroy_call(struct rcu_head *rcu)
 }
 
 /*
+ * Final call destruction under RCU.
+ */
+static void rxrpc_rcu_destroy_call(struct rcu_head *rcu)
+{
+       struct rxrpc_call *call = container_of(rcu, struct rxrpc_call, rcu);
+
+       if (in_softirq()) {
+               INIT_WORK(&call->processor, rxrpc_destroy_call);
+               if (!rxrpc_queue_work(&call->processor))
+                       BUG();
+       } else {
+               rxrpc_destroy_call(&call->processor);
+       }
+}
+
+/*
  * clean up a call
  */
 void rxrpc_cleanup_call(struct rxrpc_call *call)
@@ -590,7 +607,6 @@ void rxrpc_cleanup_call(struct rxrpc_call *call)
 
        ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
        ASSERT(test_bit(RXRPC_CALL_RELEASED, &call->flags));
-       ASSERTCMP(call->conn, ==, NULL);
 
        rxrpc_cleanup_ring(call);
        rxrpc_free_skb(call->tx_pending, rxrpc_skb_cleaned);
index 376370c..ea7d4c2 100644 (file)
@@ -785,6 +785,7 @@ void rxrpc_disconnect_client_call(struct rxrpc_call *call)
        u32 cid;
 
        spin_lock(&conn->channel_lock);
+       set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
 
        cid = call->cid;
        if (cid) {
@@ -792,7 +793,6 @@ void rxrpc_disconnect_client_call(struct rxrpc_call *call)
                chan = &conn->channels[channel];
        }
        trace_rxrpc_client(conn, channel, rxrpc_client_chan_disconnect);
-       call->conn = NULL;
 
        /* Calls that have never actually been assigned a channel can simply be
         * discarded.  If the conn didn't get used either, it will follow
@@ -908,7 +908,6 @@ out:
        spin_unlock(&rxnet->client_conn_cache_lock);
 out_2:
        spin_unlock(&conn->channel_lock);
-       rxrpc_put_connection(conn);
        _leave("");
        return;
 
index 808a472..06fcff2 100644 (file)
@@ -438,16 +438,12 @@ again:
 /*
  * connection-level event processor
  */
-void rxrpc_process_connection(struct work_struct *work)
+static void rxrpc_do_process_connection(struct rxrpc_connection *conn)
 {
-       struct rxrpc_connection *conn =
-               container_of(work, struct rxrpc_connection, processor);
        struct sk_buff *skb;
        u32 abort_code = RX_PROTOCOL_ERROR;
        int ret;
 
-       rxrpc_see_connection(conn);
-
        if (test_and_clear_bit(RXRPC_CONN_EV_CHALLENGE, &conn->events))
                rxrpc_secure_connection(conn);
 
@@ -475,18 +471,32 @@ void rxrpc_process_connection(struct work_struct *work)
                }
        }
 
-out:
-       rxrpc_put_connection(conn);
-       _leave("");
        return;
 
 requeue_and_leave:
        skb_queue_head(&conn->rx_queue, skb);
-       goto out;
+       return;
 
 protocol_error:
        if (rxrpc_abort_connection(conn, ret, abort_code) < 0)
                goto requeue_and_leave;
        rxrpc_free_skb(skb, rxrpc_skb_freed);
-       goto out;
+       return;
+}
+
+void rxrpc_process_connection(struct work_struct *work)
+{
+       struct rxrpc_connection *conn =
+               container_of(work, struct rxrpc_connection, processor);
+
+       rxrpc_see_connection(conn);
+
+       if (__rxrpc_use_local(conn->params.local)) {
+               rxrpc_do_process_connection(conn);
+               rxrpc_unuse_local(conn->params.local);
+       }
+
+       rxrpc_put_connection(conn);
+       _leave("");
+       return;
 }
index 38d718e..19e141e 100644 (file)
@@ -223,9 +223,8 @@ void rxrpc_disconnect_call(struct rxrpc_call *call)
        __rxrpc_disconnect_call(conn, call);
        spin_unlock(&conn->channel_lock);
 
-       call->conn = NULL;
+       set_bit(RXRPC_CALL_DISCONNECTED, &call->flags);
        conn->idle_timestamp = jiffies;
-       rxrpc_put_connection(conn);
 }
 
 /*
index 96d54e5..ef10fbf 100644 (file)
@@ -599,10 +599,8 @@ ack:
                                  false, true,
                                  rxrpc_propose_ack_input_data);
 
-       if (seq0 == READ_ONCE(call->rx_hard_ack) + 1) {
-               trace_rxrpc_notify_socket(call->debug_id, serial);
-               rxrpc_notify_socket(call);
-       }
+       trace_rxrpc_notify_socket(call->debug_id, serial);
+       rxrpc_notify_socket(call);
 
 unlock:
        spin_unlock(&call->input_lock);
index 3658726..a6c1349 100644 (file)
@@ -364,11 +364,14 @@ void rxrpc_queue_local(struct rxrpc_local *local)
 void rxrpc_put_local(struct rxrpc_local *local)
 {
        const void *here = __builtin_return_address(0);
+       unsigned int debug_id;
        int n;
 
        if (local) {
+               debug_id = local->debug_id;
+
                n = atomic_dec_return(&local->usage);
-               trace_rxrpc_local(local->debug_id, rxrpc_local_put, n, here);
+               trace_rxrpc_local(debug_id, rxrpc_local_put, n, here);
 
                if (n == 0)
                        call_rcu(&local->rcu, rxrpc_local_rcu);
@@ -380,14 +383,11 @@ void rxrpc_put_local(struct rxrpc_local *local)
  */
 struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *local)
 {
-       unsigned int au;
-
        local = rxrpc_get_local_maybe(local);
        if (!local)
                return NULL;
 
-       au = atomic_fetch_add_unless(&local->active_users, 1, 0);
-       if (au == 0) {
+       if (!__rxrpc_use_local(local)) {
                rxrpc_put_local(local);
                return NULL;
        }
@@ -401,14 +401,11 @@ struct rxrpc_local *rxrpc_use_local(struct rxrpc_local *local)
  */
 void rxrpc_unuse_local(struct rxrpc_local *local)
 {
-       unsigned int au;
-
        if (local) {
-               au = atomic_dec_return(&local->active_users);
-               if (au == 0)
+               if (__rxrpc_unuse_local(local)) {
+                       rxrpc_get_local(local);
                        rxrpc_queue_local(local);
-               else
-                       rxrpc_put_local(local);
+               }
        }
 }
 
@@ -465,7 +462,7 @@ static void rxrpc_local_processor(struct work_struct *work)
 
        do {
                again = false;
-               if (atomic_read(&local->active_users) == 0) {
+               if (!__rxrpc_use_local(local)) {
                        rxrpc_local_destroyer(local);
                        break;
                }
@@ -479,6 +476,8 @@ static void rxrpc_local_processor(struct work_struct *work)
                        rxrpc_process_local_events(local);
                        again = true;
                }
+
+               __rxrpc_unuse_local(local);
        } while (again);
 
        rxrpc_put_local(local);
index 935bb60..bad3d24 100644 (file)
@@ -129,7 +129,7 @@ static size_t rxrpc_fill_out_ack(struct rxrpc_connection *conn,
 int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
                          rxrpc_serial_t *_serial)
 {
-       struct rxrpc_connection *conn = NULL;
+       struct rxrpc_connection *conn;
        struct rxrpc_ack_buffer *pkt;
        struct msghdr msg;
        struct kvec iov[2];
@@ -139,18 +139,14 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
        int ret;
        u8 reason;
 
-       spin_lock_bh(&call->lock);
-       if (call->conn)
-               conn = rxrpc_get_connection_maybe(call->conn);
-       spin_unlock_bh(&call->lock);
-       if (!conn)
+       if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
                return -ECONNRESET;
 
        pkt = kzalloc(sizeof(*pkt), GFP_KERNEL);
-       if (!pkt) {
-               rxrpc_put_connection(conn);
+       if (!pkt)
                return -ENOMEM;
-       }
+
+       conn = call->conn;
 
        msg.msg_name    = &call->peer->srx.transport;
        msg.msg_namelen = call->peer->srx.transport_len;
@@ -244,7 +240,6 @@ int rxrpc_send_ack_packet(struct rxrpc_call *call, bool ping,
        }
 
 out:
-       rxrpc_put_connection(conn);
        kfree(pkt);
        return ret;
 }
@@ -254,7 +249,7 @@ out:
  */
 int rxrpc_send_abort_packet(struct rxrpc_call *call)
 {
-       struct rxrpc_connection *conn = NULL;
+       struct rxrpc_connection *conn;
        struct rxrpc_abort_buffer pkt;
        struct msghdr msg;
        struct kvec iov[1];
@@ -271,13 +266,11 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
            test_bit(RXRPC_CALL_TX_LAST, &call->flags))
                return 0;
 
-       spin_lock_bh(&call->lock);
-       if (call->conn)
-               conn = rxrpc_get_connection_maybe(call->conn);
-       spin_unlock_bh(&call->lock);
-       if (!conn)
+       if (test_bit(RXRPC_CALL_DISCONNECTED, &call->flags))
                return -ECONNRESET;
 
+       conn = call->conn;
+
        msg.msg_name    = &call->peer->srx.transport;
        msg.msg_namelen = call->peer->srx.transport_len;
        msg.msg_control = NULL;
@@ -312,8 +305,6 @@ int rxrpc_send_abort_packet(struct rxrpc_call *call)
                trace_rxrpc_tx_packet(call->debug_id, &pkt.whdr,
                                      rxrpc_tx_point_call_abort);
        rxrpc_tx_backoff(call, ret);
-
-       rxrpc_put_connection(conn);
        return ret;
 }
 
index 48f67a9..923b263 100644 (file)
@@ -364,27 +364,31 @@ static void rxrpc_peer_keepalive_dispatch(struct rxrpc_net *rxnet,
                if (!rxrpc_get_peer_maybe(peer))
                        continue;
 
-               spin_unlock_bh(&rxnet->peer_hash_lock);
-
-               keepalive_at = peer->last_tx_at + RXRPC_KEEPALIVE_TIME;
-               slot = keepalive_at - base;
-               _debug("%02x peer %u t=%d {%pISp}",
-                      cursor, peer->debug_id, slot, &peer->srx.transport);
+               if (__rxrpc_use_local(peer->local)) {
+                       spin_unlock_bh(&rxnet->peer_hash_lock);
+
+                       keepalive_at = peer->last_tx_at + RXRPC_KEEPALIVE_TIME;
+                       slot = keepalive_at - base;
+                       _debug("%02x peer %u t=%d {%pISp}",
+                              cursor, peer->debug_id, slot, &peer->srx.transport);
+
+                       if (keepalive_at <= base ||
+                           keepalive_at > base + RXRPC_KEEPALIVE_TIME) {
+                               rxrpc_send_keepalive(peer);
+                               slot = RXRPC_KEEPALIVE_TIME;
+                       }
 
-               if (keepalive_at <= base ||
-                   keepalive_at > base + RXRPC_KEEPALIVE_TIME) {
-                       rxrpc_send_keepalive(peer);
-                       slot = RXRPC_KEEPALIVE_TIME;
+                       /* A transmission to this peer occurred since last we
+                        * examined it so put it into the appropriate future
+                        * bucket.
+                        */
+                       slot += cursor;
+                       slot &= mask;
+                       spin_lock_bh(&rxnet->peer_hash_lock);
+                       list_add_tail(&peer->keepalive_link,
+                                     &rxnet->peer_keepalive[slot & mask]);
+                       rxrpc_unuse_local(peer->local);
                }
-
-               /* A transmission to this peer occurred since last we examined
-                * it so put it into the appropriate future bucket.
-                */
-               slot += cursor;
-               slot &= mask;
-               spin_lock_bh(&rxnet->peer_hash_lock);
-               list_add_tail(&peer->keepalive_link,
-                             &rxnet->peer_keepalive[slot & mask]);
                rxrpc_put_peer_locked(peer);
        }
 
index c226241..d36949d 100644 (file)
@@ -463,10 +463,8 @@ static u32 gen_tunnel(struct rsvp_head *data)
 
 static const struct nla_policy rsvp_policy[TCA_RSVP_MAX + 1] = {
        [TCA_RSVP_CLASSID]      = { .type = NLA_U32 },
-       [TCA_RSVP_DST]          = { .type = NLA_BINARY,
-                                   .len = RSVP_DST_LEN * sizeof(u32) },
-       [TCA_RSVP_SRC]          = { .type = NLA_BINARY,
-                                   .len = RSVP_DST_LEN * sizeof(u32) },
+       [TCA_RSVP_DST]          = { .len = RSVP_DST_LEN * sizeof(u32) },
+       [TCA_RSVP_SRC]          = { .len = RSVP_DST_LEN * sizeof(u32) },
        [TCA_RSVP_PINFO]        = { .len = sizeof(struct tc_rsvp_pinfo) },
 };
 
index 3d4a128..09b7dc5 100644 (file)
@@ -333,12 +333,31 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
        cp->fall_through = p->fall_through;
        cp->tp = tp;
 
+       if (tb[TCA_TCINDEX_HASH])
+               cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
+
+       if (tb[TCA_TCINDEX_MASK])
+               cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
+
+       if (tb[TCA_TCINDEX_SHIFT])
+               cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
+
+       if (!cp->hash) {
+               /* Hash not specified, use perfect hash if the upper limit
+                * of the hashing index is below the threshold.
+                */
+               if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD)
+                       cp->hash = (cp->mask >> cp->shift) + 1;
+               else
+                       cp->hash = DEFAULT_HASH_SIZE;
+       }
+
        if (p->perfect) {
                int i;
 
                if (tcindex_alloc_perfect_hash(net, cp) < 0)
                        goto errout;
-               for (i = 0; i < cp->hash; i++)
+               for (i = 0; i < min(cp->hash, p->hash); i++)
                        cp->perfect[i].res = p->perfect[i].res;
                balloc = 1;
        }
@@ -346,19 +365,10 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
 
        err = tcindex_filter_result_init(&new_filter_result, net);
        if (err < 0)
-               goto errout1;
+               goto errout_alloc;
        if (old_r)
                cr = r->res;
 
-       if (tb[TCA_TCINDEX_HASH])
-               cp->hash = nla_get_u32(tb[TCA_TCINDEX_HASH]);
-
-       if (tb[TCA_TCINDEX_MASK])
-               cp->mask = nla_get_u16(tb[TCA_TCINDEX_MASK]);
-
-       if (tb[TCA_TCINDEX_SHIFT])
-               cp->shift = nla_get_u32(tb[TCA_TCINDEX_SHIFT]);
-
        err = -EBUSY;
 
        /* Hash already allocated, make sure that we still meet the
@@ -376,16 +386,6 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
        if (tb[TCA_TCINDEX_FALL_THROUGH])
                cp->fall_through = nla_get_u32(tb[TCA_TCINDEX_FALL_THROUGH]);
 
-       if (!cp->hash) {
-               /* Hash not specified, use perfect hash if the upper limit
-                * of the hashing index is below the threshold.
-                */
-               if ((cp->mask >> cp->shift) < PERFECT_HASH_THRESHOLD)
-                       cp->hash = (cp->mask >> cp->shift) + 1;
-               else
-                       cp->hash = DEFAULT_HASH_SIZE;
-       }
-
        if (!cp->perfect && !cp->h)
                cp->alloc_hash = cp->hash;
 
@@ -484,7 +484,6 @@ errout_alloc:
                tcindex_free_perfect_hash(cp);
        else if (balloc == 2)
                kfree(cp->h);
-errout1:
        tcf_exts_destroy(&new_filter_result.exts);
 errout:
        kfree(cp);
index bbd0dea..214657e 100644 (file)
@@ -349,9 +349,9 @@ static int fq_pie_change(struct Qdisc *sch, struct nlattr *opt,
        while (sch->q.qlen > sch->limit) {
                struct sk_buff *skb = fq_pie_qdisc_dequeue(sch);
 
-               kfree_skb(skb);
                len_dropped += qdisc_pkt_len(skb);
                num_dropped += 1;
+               rtnl_kfree_skbs(skb, skb);
        }
        qdisc_tree_reduce_backlog(sch, num_dropped, len_dropped);
 
index c609373..660fc45 100644 (file)
@@ -31,6 +31,7 @@ static DEFINE_SPINLOCK(taprio_list_lock);
 
 #define TXTIME_ASSIST_IS_ENABLED(flags) ((flags) & TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST)
 #define FULL_OFFLOAD_IS_ENABLED(flags) ((flags) & TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD)
+#define TAPRIO_FLAGS_INVALID U32_MAX
 
 struct sched_entry {
        struct list_head list;
@@ -766,6 +767,7 @@ static const struct nla_policy taprio_policy[TCA_TAPRIO_ATTR_MAX + 1] = {
        [TCA_TAPRIO_ATTR_SCHED_CLOCKID]              = { .type = NLA_S32 },
        [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME]           = { .type = NLA_S64 },
        [TCA_TAPRIO_ATTR_SCHED_CYCLE_TIME_EXTENSION] = { .type = NLA_S64 },
+       [TCA_TAPRIO_ATTR_FLAGS]                      = { .type = NLA_U32 },
 };
 
 static int fill_sched_entry(struct nlattr **tb, struct sched_entry *entry,
@@ -1367,6 +1369,33 @@ static int taprio_mqprio_cmp(const struct net_device *dev,
        return 0;
 }
 
+/* The semantics of the 'flags' argument in relation to 'change()'
+ * requests, are interpreted following two rules (which are applied in
+ * this order): (1) an omitted 'flags' argument is interpreted as
+ * zero; (2) the 'flags' of a "running" taprio instance cannot be
+ * changed.
+ */
+static int taprio_new_flags(const struct nlattr *attr, u32 old,
+                           struct netlink_ext_ack *extack)
+{
+       u32 new = 0;
+
+       if (attr)
+               new = nla_get_u32(attr);
+
+       if (old != TAPRIO_FLAGS_INVALID && old != new) {
+               NL_SET_ERR_MSG_MOD(extack, "Changing 'flags' of a running schedule is not supported");
+               return -EOPNOTSUPP;
+       }
+
+       if (!taprio_flags_valid(new)) {
+               NL_SET_ERR_MSG_MOD(extack, "Specified 'flags' are not valid");
+               return -EINVAL;
+       }
+
+       return new;
+}
+
 static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
                         struct netlink_ext_ack *extack)
 {
@@ -1375,7 +1404,6 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
        struct taprio_sched *q = qdisc_priv(sch);
        struct net_device *dev = qdisc_dev(sch);
        struct tc_mqprio_qopt *mqprio = NULL;
-       u32 taprio_flags = 0;
        unsigned long flags;
        ktime_t start;
        int i, err;
@@ -1388,21 +1416,14 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
        if (tb[TCA_TAPRIO_ATTR_PRIOMAP])
                mqprio = nla_data(tb[TCA_TAPRIO_ATTR_PRIOMAP]);
 
-       if (tb[TCA_TAPRIO_ATTR_FLAGS]) {
-               taprio_flags = nla_get_u32(tb[TCA_TAPRIO_ATTR_FLAGS]);
-
-               if (q->flags != 0 && q->flags != taprio_flags) {
-                       NL_SET_ERR_MSG_MOD(extack, "Changing 'flags' of a running schedule is not supported");
-                       return -EOPNOTSUPP;
-               } else if (!taprio_flags_valid(taprio_flags)) {
-                       NL_SET_ERR_MSG_MOD(extack, "Specified 'flags' are not valid");
-                       return -EINVAL;
-               }
+       err = taprio_new_flags(tb[TCA_TAPRIO_ATTR_FLAGS],
+                              q->flags, extack);
+       if (err < 0)
+               return err;
 
-               q->flags = taprio_flags;
-       }
+       q->flags = err;
 
-       err = taprio_parse_mqprio_opt(dev, mqprio, extack, taprio_flags);
+       err = taprio_parse_mqprio_opt(dev, mqprio, extack, q->flags);
        if (err < 0)
                return err;
 
@@ -1444,7 +1465,20 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
 
        taprio_set_picos_per_byte(dev, q);
 
-       if (FULL_OFFLOAD_IS_ENABLED(taprio_flags))
+       if (mqprio) {
+               netdev_set_num_tc(dev, mqprio->num_tc);
+               for (i = 0; i < mqprio->num_tc; i++)
+                       netdev_set_tc_queue(dev, i,
+                                           mqprio->count[i],
+                                           mqprio->offset[i]);
+
+               /* Always use supplied priority mappings */
+               for (i = 0; i <= TC_BITMASK; i++)
+                       netdev_set_prio_tc_map(dev, i,
+                                              mqprio->prio_tc_map[i]);
+       }
+
+       if (FULL_OFFLOAD_IS_ENABLED(q->flags))
                err = taprio_enable_offload(dev, mqprio, q, new_admin, extack);
        else
                err = taprio_disable_offload(dev, q, extack);
@@ -1464,27 +1498,14 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
                q->txtime_delay = nla_get_u32(tb[TCA_TAPRIO_ATTR_TXTIME_DELAY]);
        }
 
-       if (!TXTIME_ASSIST_IS_ENABLED(taprio_flags) &&
-           !FULL_OFFLOAD_IS_ENABLED(taprio_flags) &&
+       if (!TXTIME_ASSIST_IS_ENABLED(q->flags) &&
+           !FULL_OFFLOAD_IS_ENABLED(q->flags) &&
            !hrtimer_active(&q->advance_timer)) {
                hrtimer_init(&q->advance_timer, q->clockid, HRTIMER_MODE_ABS);
                q->advance_timer.function = advance_sched;
        }
 
-       if (mqprio) {
-               netdev_set_num_tc(dev, mqprio->num_tc);
-               for (i = 0; i < mqprio->num_tc; i++)
-                       netdev_set_tc_queue(dev, i,
-                                           mqprio->count[i],
-                                           mqprio->offset[i]);
-
-               /* Always use supplied priority mappings */
-               for (i = 0; i <= TC_BITMASK; i++)
-                       netdev_set_prio_tc_map(dev, i,
-                                              mqprio->prio_tc_map[i]);
-       }
-
-       if (FULL_OFFLOAD_IS_ENABLED(taprio_flags)) {
+       if (FULL_OFFLOAD_IS_ENABLED(q->flags)) {
                q->dequeue = taprio_dequeue_offload;
                q->peek = taprio_peek_offload;
        } else {
@@ -1501,9 +1522,9 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
                goto unlock;
        }
 
-       if (TXTIME_ASSIST_IS_ENABLED(taprio_flags)) {
-               setup_txtime(q, new_admin, start);
+       setup_txtime(q, new_admin, start);
 
+       if (TXTIME_ASSIST_IS_ENABLED(q->flags)) {
                if (!oper) {
                        rcu_assign_pointer(q->oper_sched, new_admin);
                        err = 0;
@@ -1528,7 +1549,7 @@ static int taprio_change(struct Qdisc *sch, struct nlattr *opt,
 
                spin_unlock_irqrestore(&q->current_entry_lock, flags);
 
-               if (FULL_OFFLOAD_IS_ENABLED(taprio_flags))
+               if (FULL_OFFLOAD_IS_ENABLED(q->flags))
                        taprio_offload_config_changed(q);
        }
 
@@ -1567,7 +1588,7 @@ static void taprio_destroy(struct Qdisc *sch)
        }
        q->qdiscs = NULL;
 
-       netdev_set_num_tc(dev, 0);
+       netdev_reset_tc(dev);
 
        if (q->oper_sched)
                call_rcu(&q->oper_sched->rcu, taprio_free_sched_cb);
@@ -1597,6 +1618,7 @@ static int taprio_init(struct Qdisc *sch, struct nlattr *opt,
         * and get the valid one on taprio_change().
         */
        q->clockid = -1;
+       q->flags = TAPRIO_FLAGS_INVALID;
 
        spin_lock(&taprio_list_lock);
        list_add(&q->taprio_list, &taprio_list);
index d024af4..8b4d72b 100644 (file)
@@ -175,7 +175,7 @@ static int rpc_parse_scope_id(struct net *net, const char *buf,
                return 0;
 
        len = (buf + buflen) - delim - 1;
-       p = kstrndup(delim + 1, len, GFP_KERNEL);
+       p = kmemdup_nul(delim + 1, len, GFP_KERNEL);
        if (p) {
                u32 scope_id = 0;
                struct net_device *dev;
index cdb05b4..5748ad0 100644 (file)
@@ -221,55 +221,6 @@ rpcauth_get_gssinfo(rpc_authflavor_t pseudoflavor, struct rpcsec_gss_info *info)
 }
 EXPORT_SYMBOL_GPL(rpcauth_get_gssinfo);
 
-/**
- * rpcauth_list_flavors - discover registered flavors and pseudoflavors
- * @array: array to fill in
- * @size: size of "array"
- *
- * Returns the number of array items filled in, or a negative errno.
- *
- * The returned array is not sorted by any policy.  Callers should not
- * rely on the order of the items in the returned array.
- */
-int
-rpcauth_list_flavors(rpc_authflavor_t *array, int size)
-{
-       const struct rpc_authops *ops;
-       rpc_authflavor_t flavor, pseudos[4];
-       int i, len, result = 0;
-
-       rcu_read_lock();
-       for (flavor = 0; flavor < RPC_AUTH_MAXFLAVOR; flavor++) {
-               ops = rcu_dereference(auth_flavors[flavor]);
-               if (result >= size) {
-                       result = -ENOMEM;
-                       break;
-               }
-
-               if (ops == NULL)
-                       continue;
-               if (ops->list_pseudoflavors == NULL) {
-                       array[result++] = ops->au_flavor;
-                       continue;
-               }
-               len = ops->list_pseudoflavors(pseudos, ARRAY_SIZE(pseudos));
-               if (len < 0) {
-                       result = len;
-                       break;
-               }
-               for (i = 0; i < len; i++) {
-                       if (result >= size) {
-                               result = -ENOMEM;
-                               break;
-                       }
-                       array[result++] = pseudos[i];
-               }
-       }
-       rcu_read_unlock();
-       return result;
-}
-EXPORT_SYMBOL_GPL(rpcauth_list_flavors);
-
 struct rpc_auth *
 rpcauth_create(const struct rpc_auth_create_args *args, struct rpc_clnt *clnt)
 {
index d75fddc..24ca861 100644 (file)
@@ -2118,7 +2118,6 @@ static const struct rpc_authops authgss_ops = {
        .hash_cred      = gss_hash_cred,
        .lookup_cred    = gss_lookup_cred,
        .crcreate       = gss_create_cred,
-       .list_pseudoflavors = gss_mech_list_pseudoflavors,
        .info2flavor    = gss_mech_info2flavor,
        .flavor2info    = gss_mech_flavor2info,
 };
index d3685d4..db550bf 100644 (file)
@@ -220,35 +220,6 @@ gss_mech_get_by_pseudoflavor(u32 pseudoflavor)
 }
 
 /**
- * gss_mech_list_pseudoflavors - Discover registered GSS pseudoflavors
- * @array_ptr: array to fill in
- * @size: size of "array"
- *
- * Returns the number of array items filled in, or a negative errno.
- *
- * The returned array is not sorted by any policy.  Callers should not
- * rely on the order of the items in the returned array.
- */
-int gss_mech_list_pseudoflavors(rpc_authflavor_t *array_ptr, int size)
-{
-       struct gss_api_mech *pos = NULL;
-       int j, i = 0;
-
-       rcu_read_lock();
-       list_for_each_entry_rcu(pos, &registered_mechs, gm_list) {
-               for (j = 0; j < pos->gm_pf_num; j++) {
-                       if (i >= size) {
-                               spin_unlock(&registered_mechs_lock);
-                               return -ENOMEM;
-                       }
-                       array_ptr[i++] = pos->gm_pfs[j].pseudoflavor;
-               }
-       }
-       rcu_read_unlock();
-       return i;
-}
-
-/**
  * gss_svc_to_pseudoflavor - map a GSS service number to a pseudoflavor
  * @gm: GSS mechanism handle
  * @qop: GSS quality-of-protection value
index 3111817..65b67b2 100644 (file)
@@ -1248,6 +1248,7 @@ static int gss_proxy_save_rsc(struct cache_detail *cd,
                dprintk("RPC:       No creds found!\n");
                goto out;
        } else {
+               struct timespec64 boot;
 
                /* steal creds */
                rsci.cred = ud->creds;
@@ -1268,6 +1269,9 @@ static int gss_proxy_save_rsc(struct cache_detail *cd,
                                                &expiry, GFP_KERNEL);
                if (status)
                        goto out;
+
+               getboottime64(&boot);
+               expiry -= boot.tv_sec;
        }
 
        rsci.h.expiry_time = expiry;
@@ -1428,10 +1432,10 @@ static ssize_t read_gssp(struct file *file, char __user *buf,
        return len;
 }
 
-static const struct file_operations use_gss_proxy_ops = {
-       .open = nonseekable_open,
-       .write = write_gssp,
-       .read = read_gssp,
+static const struct proc_ops use_gss_proxy_proc_ops = {
+       .proc_open      = nonseekable_open,
+       .proc_write     = write_gssp,
+       .proc_read      = read_gssp,
 };
 
 static int create_use_gss_proxy_proc_entry(struct net *net)
@@ -1442,7 +1446,7 @@ static int create_use_gss_proxy_proc_entry(struct net *net)
        sn->use_gss_proxy = -1;
        *p = proc_create_data("use-gss-proxy", S_IFREG | 0600,
                              sn->proc_net_rpc,
-                             &use_gss_proxy_ops, net);
+                             &use_gss_proxy_proc_ops, net);
        if (!*p)
                return -ENOMEM;
        init_gssp_clnt(sn);
index d996bf8..bd843a8 100644 (file)
@@ -77,6 +77,22 @@ static struct cache_head *sunrpc_cache_find_rcu(struct cache_detail *detail,
        return NULL;
 }
 
+static void sunrpc_begin_cache_remove_entry(struct cache_head *ch,
+                                           struct cache_detail *cd)
+{
+       /* Must be called under cd->hash_lock */
+       hlist_del_init_rcu(&ch->cache_list);
+       set_bit(CACHE_CLEANED, &ch->flags);
+       cd->entries --;
+}
+
+static void sunrpc_end_cache_remove_entry(struct cache_head *ch,
+                                         struct cache_detail *cd)
+{
+       cache_fresh_unlocked(ch, cd);
+       cache_put(ch, cd);
+}
+
 static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
                                                 struct cache_head *key,
                                                 int hash)
@@ -100,8 +116,7 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
        hlist_for_each_entry_rcu(tmp, head, cache_list) {
                if (detail->match(tmp, key)) {
                        if (cache_is_expired(detail, tmp)) {
-                               hlist_del_init_rcu(&tmp->cache_list);
-                               detail->entries --;
+                               sunrpc_begin_cache_remove_entry(tmp, detail);
                                freeme = tmp;
                                break;
                        }
@@ -117,10 +132,8 @@ static struct cache_head *sunrpc_cache_add_entry(struct cache_detail *detail,
        cache_get(new);
        spin_unlock(&detail->hash_lock);
 
-       if (freeme) {
-               cache_fresh_unlocked(freeme, detail);
-               cache_put(freeme, detail);
-       }
+       if (freeme)
+               sunrpc_end_cache_remove_entry(freeme, detail);
        return new;
 }
 
@@ -454,8 +467,7 @@ static int cache_clean(void)
                        if (!cache_is_expired(current_detail, ch))
                                continue;
 
-                       hlist_del_init_rcu(&ch->cache_list);
-                       current_detail->entries--;
+                       sunrpc_begin_cache_remove_entry(ch, current_detail);
                        rv = 1;
                        break;
                }
@@ -465,11 +477,8 @@ static int cache_clean(void)
                if (!ch)
                        current_index ++;
                spin_unlock(&cache_list_lock);
-               if (ch) {
-                       set_bit(CACHE_CLEANED, &ch->flags);
-                       cache_fresh_unlocked(ch, d);
-                       cache_put(ch, d);
-               }
+               if (ch)
+                       sunrpc_end_cache_remove_entry(ch, d);
        } else
                spin_unlock(&cache_list_lock);
 
@@ -525,13 +534,9 @@ void cache_purge(struct cache_detail *detail)
        for (i = 0; i < detail->hash_size; i++) {
                head = &detail->hash_table[i];
                hlist_for_each_entry_safe(ch, tmp, head, cache_list) {
-                       hlist_del_init_rcu(&ch->cache_list);
-                       detail->entries--;
-
-                       set_bit(CACHE_CLEANED, &ch->flags);
+                       sunrpc_begin_cache_remove_entry(ch, detail);
                        spin_unlock(&detail->hash_lock);
-                       cache_fresh_unlocked(ch, detail);
-                       cache_put(ch, detail);
+                       sunrpc_end_cache_remove_entry(ch, detail);
                        spin_lock(&detail->hash_lock);
                }
        }
@@ -1571,15 +1576,14 @@ static int cache_release_procfs(struct inode *inode, struct file *filp)
        return cache_release(inode, filp, cd);
 }
 
-static const struct file_operations cache_file_operations_procfs = {
-       .owner          = THIS_MODULE,
-       .llseek         = no_llseek,
-       .read           = cache_read_procfs,
-       .write          = cache_write_procfs,
-       .poll           = cache_poll_procfs,
-       .unlocked_ioctl = cache_ioctl_procfs, /* for FIONREAD */
-       .open           = cache_open_procfs,
-       .release        = cache_release_procfs,
+static const struct proc_ops cache_channel_proc_ops = {
+       .proc_lseek     = no_llseek,
+       .proc_read      = cache_read_procfs,
+       .proc_write     = cache_write_procfs,
+       .proc_poll      = cache_poll_procfs,
+       .proc_ioctl     = cache_ioctl_procfs, /* for FIONREAD */
+       .proc_open      = cache_open_procfs,
+       .proc_release   = cache_release_procfs,
 };
 
 static int content_open_procfs(struct inode *inode, struct file *filp)
@@ -1596,11 +1600,11 @@ static int content_release_procfs(struct inode *inode, struct file *filp)
        return content_release(inode, filp, cd);
 }
 
-static const struct file_operations content_file_operations_procfs = {
-       .open           = content_open_procfs,
-       .read           = seq_read,
-       .llseek         = seq_lseek,
-       .release        = content_release_procfs,
+static const struct proc_ops content_proc_ops = {
+       .proc_open      = content_open_procfs,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = content_release_procfs,
 };
 
 static int open_flush_procfs(struct inode *inode, struct file *filp)
@@ -1634,12 +1638,12 @@ static ssize_t write_flush_procfs(struct file *filp,
        return write_flush(filp, buf, count, ppos, cd);
 }
 
-static const struct file_operations cache_flush_operations_procfs = {
-       .open           = open_flush_procfs,
-       .read           = read_flush_procfs,
-       .write          = write_flush_procfs,
-       .release        = release_flush_procfs,
-       .llseek         = no_llseek,
+static const struct proc_ops cache_flush_proc_ops = {
+       .proc_open      = open_flush_procfs,
+       .proc_read      = read_flush_procfs,
+       .proc_write     = write_flush_procfs,
+       .proc_release   = release_flush_procfs,
+       .proc_lseek     = no_llseek,
 };
 
 static void remove_cache_proc_entries(struct cache_detail *cd)
@@ -1662,19 +1666,19 @@ static int create_cache_proc_entries(struct cache_detail *cd, struct net *net)
                goto out_nomem;
 
        p = proc_create_data("flush", S_IFREG | 0600,
-                            cd->procfs, &cache_flush_operations_procfs, cd);
+                            cd->procfs, &cache_flush_proc_ops, cd);
        if (p == NULL)
                goto out_nomem;
 
        if (cd->cache_request || cd->cache_parse) {
                p = proc_create_data("channel", S_IFREG | 0600, cd->procfs,
-                                    &cache_file_operations_procfs, cd);
+                                    &cache_channel_proc_ops, cd);
                if (p == NULL)
                        goto out_nomem;
        }
        if (cd->cache_show) {
                p = proc_create_data("content", S_IFREG | 0400, cd->procfs,
-                                    &content_file_operations_procfs, cd);
+                                    &content_proc_ops, cd);
                if (p == NULL)
                        goto out_nomem;
        }
@@ -1886,10 +1890,9 @@ void sunrpc_cache_unhash(struct cache_detail *cd, struct cache_head *h)
 {
        spin_lock(&cd->hash_lock);
        if (!hlist_unhashed(&h->cache_list)){
-               hlist_del_init_rcu(&h->cache_list);
-               cd->entries--;
+               sunrpc_begin_cache_remove_entry(h, cd);
                spin_unlock(&cd->hash_lock);
-               cache_put(h, cd);
+               sunrpc_end_cache_remove_entry(h, cd);
        } else
                spin_unlock(&cd->hash_lock);
 }
index a337976..7324b21 100644 (file)
@@ -2130,6 +2130,7 @@ call_connect_status(struct rpc_task *task)
        case -ENETUNREACH:
        case -EHOSTUNREACH:
        case -EPIPE:
+       case -EPROTO:
                xprt_conditional_disconnect(task->tk_rqstp->rq_xprt,
                                            task->tk_rqstp->rq_connect_cookie);
                if (RPC_IS_SOFTCONN(task))
index 9c79548..55e9002 100644 (file)
@@ -846,6 +846,8 @@ void rpc_signal_task(struct rpc_task *task)
 
        if (!RPC_IS_ACTIVATED(task))
                return;
+
+       trace_rpc_task_signalled(task, task->tk_action);
        set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate);
        smp_mb__after_atomic();
        queue = READ_ONCE(task->tk_waitqueue);
@@ -949,7 +951,7 @@ static void __rpc_execute(struct rpc_task *task)
                         * clean up after sleeping on some queue, we don't
                         * break the loop here, but go around once more.
                         */
-                       dprintk("RPC: %5u got signal\n", task->tk_pid);
+                       trace_rpc_task_signalled(task, task->tk_action);
                        set_bit(RPC_TASK_SIGNALLED, &task->tk_runstate);
                        task->tk_rpc_status = -ERESTARTSYS;
                        rpc_exit(task, -ERESTARTSYS);
index 7c74197..c964b48 100644 (file)
@@ -69,12 +69,11 @@ static int rpc_proc_open(struct inode *inode, struct file *file)
        return single_open(file, rpc_proc_show, PDE_DATA(inode));
 }
 
-static const struct file_operations rpc_proc_fops = {
-       .owner = THIS_MODULE,
-       .open = rpc_proc_open,
-       .read  = seq_read,
-       .llseek = seq_lseek,
-       .release = single_release,
+static const struct proc_ops rpc_proc_ops = {
+       .proc_open      = rpc_proc_open,
+       .proc_read      = seq_read,
+       .proc_lseek     = seq_lseek,
+       .proc_release   = single_release,
 };
 
 /*
@@ -281,19 +280,19 @@ EXPORT_SYMBOL_GPL(rpc_clnt_show_stats);
  */
 static inline struct proc_dir_entry *
 do_register(struct net *net, const char *name, void *data,
-           const struct file_operations *fops)
+           const struct proc_ops *proc_ops)
 {
        struct sunrpc_net *sn;
 
        dprintk("RPC:       registering /proc/net/rpc/%s\n", name);
        sn = net_generic(net, sunrpc_net_id);
-       return proc_create_data(name, 0, sn->proc_net_rpc, fops, data);
+       return proc_create_data(name, 0, sn->proc_net_rpc, proc_ops, data);
 }
 
 struct proc_dir_entry *
 rpc_proc_register(struct net *net, struct rpc_stat *statp)
 {
-       return do_register(net, statp->program->name, statp, &rpc_proc_fops);
+       return do_register(net, statp->program->name, statp, &rpc_proc_ops);
 }
 EXPORT_SYMBOL_GPL(rpc_proc_register);
 
@@ -308,9 +307,9 @@ rpc_proc_unregister(struct net *net, const char *name)
 EXPORT_SYMBOL_GPL(rpc_proc_unregister);
 
 struct proc_dir_entry *
-svc_proc_register(struct net *net, struct svc_stat *statp, const struct file_operations *fops)
+svc_proc_register(struct net *net, struct svc_stat *statp, const struct proc_ops *proc_ops)
 {
-       return do_register(net, statp->program->pg_name, statp, fops);
+       return do_register(net, statp->program->pg_name, statp, proc_ops);
 }
 EXPORT_SYMBOL_GPL(svc_proc_register);
 
index f3104be..e5497dc 100644 (file)
@@ -1079,7 +1079,7 @@ void xdr_enter_page(struct xdr_stream *xdr, unsigned int len)
 }
 EXPORT_SYMBOL_GPL(xdr_enter_page);
 
-static struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0};
+static const struct kvec empty_iov = {.iov_base = NULL, .iov_len = 0};
 
 void
 xdr_buf_from_iov(struct kvec *iov, struct xdr_buf *buf)
index 9d02eae..1a0ae0c 100644 (file)
@@ -194,6 +194,10 @@ create_req:
        req = rpcrdma_req_create(r_xprt, size, GFP_KERNEL);
        if (!req)
                return NULL;
+       if (rpcrdma_req_setup(r_xprt, req)) {
+               rpcrdma_req_destroy(req);
+               return NULL;
+       }
 
        xprt->bc_alloc_count++;
        rqst = &req->rl_slot;
index 523722b..095be88 100644 (file)
 #endif
 
 /**
- * frwr_is_supported - Check if device supports FRWR
- * @device: interface adapter to check
- *
- * Returns true if device supports FRWR, otherwise false
- */
-bool frwr_is_supported(struct ib_device *device)
-{
-       struct ib_device_attr *attrs = &device->attrs;
-
-       if (!(attrs->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS))
-               goto out_not_supported;
-       if (attrs->max_fast_reg_page_list_len == 0)
-               goto out_not_supported;
-       return true;
-
-out_not_supported:
-       pr_info("rpcrdma: 'frwr' mode is not supported by device %s\n",
-               device->name);
-       return false;
-}
-
-/**
  * frwr_release_mr - Destroy one MR
  * @mr: MR allocated by frwr_init_mr
  *
@@ -170,26 +148,48 @@ out_list_err:
 }
 
 /**
- * frwr_open - Prepare an endpoint for use with FRWR
- * @ia: interface adapter this endpoint will use
- * @ep: endpoint to prepare
+ * frwr_query_device - Prepare a transport for use with FRWR
+ * @r_xprt: controlling transport instance
+ * @device: RDMA device to query
  *
  * On success, sets:
- *     ep->rep_attr.cap.max_send_wr
- *     ep->rep_attr.cap.max_recv_wr
+ *     ep->rep_attr
  *     ep->rep_max_requests
- *     ia->ri_max_segs
+ *     ia->ri_max_rdma_segs
  *
  * And these FRWR-related fields:
  *     ia->ri_max_frwr_depth
  *     ia->ri_mrtype
  *
- * On failure, a negative errno is returned.
+ * Return values:
+ *   On success, returns zero.
+ *   %-EINVAL - the device does not support FRWR memory registration
+ *   %-ENOMEM - the device is not sufficiently capable for NFS/RDMA
  */
-int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep)
+int frwr_query_device(struct rpcrdma_xprt *r_xprt,
+                     const struct ib_device *device)
 {
-       struct ib_device_attr *attrs = &ia->ri_id->device->attrs;
+       const struct ib_device_attr *attrs = &device->attrs;
+       struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+       struct rpcrdma_ep *ep = &r_xprt->rx_ep;
        int max_qp_wr, depth, delta;
+       unsigned int max_sge;
+
+       if (!(attrs->device_cap_flags & IB_DEVICE_MEM_MGT_EXTENSIONS) ||
+           attrs->max_fast_reg_page_list_len == 0) {
+               pr_err("rpcrdma: 'frwr' mode is not supported by device %s\n",
+                      device->name);
+               return -EINVAL;
+       }
+
+       max_sge = min_t(unsigned int, attrs->max_send_sge,
+                       RPCRDMA_MAX_SEND_SGES);
+       if (max_sge < RPCRDMA_MIN_SEND_SGES) {
+               pr_err("rpcrdma: HCA provides only %u send SGEs\n", max_sge);
+               return -ENOMEM;
+       }
+       ep->rep_attr.cap.max_send_sge = max_sge;
+       ep->rep_attr.cap.max_recv_sge = 1;
 
        ia->ri_mrtype = IB_MR_TYPE_MEM_REG;
        if (attrs->device_cap_flags & IB_DEVICE_SG_GAPS_REG)
@@ -199,14 +199,12 @@ int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep)
         * capability, but perform optimally when the MRs are not larger
         * than a page.
         */
-       if (attrs->max_sge_rd > 1)
+       if (attrs->max_sge_rd > RPCRDMA_MAX_HDR_SEGS)
                ia->ri_max_frwr_depth = attrs->max_sge_rd;
        else
                ia->ri_max_frwr_depth = attrs->max_fast_reg_page_list_len;
        if (ia->ri_max_frwr_depth > RPCRDMA_MAX_DATA_SEGS)
                ia->ri_max_frwr_depth = RPCRDMA_MAX_DATA_SEGS;
-       dprintk("RPC:       %s: max FR page list depth = %u\n",
-               __func__, ia->ri_max_frwr_depth);
 
        /* Add room for frwr register and invalidate WRs.
         * 1. FRWR reg WR for head
@@ -230,7 +228,7 @@ int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep)
                } while (delta > 0);
        }
 
-       max_qp_wr = ia->ri_id->device->attrs.max_qp_wr;
+       max_qp_wr = attrs->max_qp_wr;
        max_qp_wr -= RPCRDMA_BACKWARD_WRS;
        max_qp_wr -= 1;
        if (max_qp_wr < RPCRDMA_MIN_SLOT_TABLE)
@@ -241,7 +239,7 @@ int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep)
        if (ep->rep_attr.cap.max_send_wr > max_qp_wr) {
                ep->rep_max_requests = max_qp_wr / depth;
                if (!ep->rep_max_requests)
-                       return -EINVAL;
+                       return -ENOMEM;
                ep->rep_attr.cap.max_send_wr = ep->rep_max_requests * depth;
        }
        ep->rep_attr.cap.max_send_wr += RPCRDMA_BACKWARD_WRS;
@@ -250,30 +248,22 @@ int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep)
        ep->rep_attr.cap.max_recv_wr += RPCRDMA_BACKWARD_WRS;
        ep->rep_attr.cap.max_recv_wr += 1; /* for ib_drain_rq */
 
-       ia->ri_max_segs =
+       ia->ri_max_rdma_segs =
                DIV_ROUND_UP(RPCRDMA_MAX_DATA_SEGS, ia->ri_max_frwr_depth);
        /* Reply chunks require segments for head and tail buffers */
-       ia->ri_max_segs += 2;
-       if (ia->ri_max_segs > RPCRDMA_MAX_HDR_SEGS)
-               ia->ri_max_segs = RPCRDMA_MAX_HDR_SEGS;
-       return 0;
-}
-
-/**
- * frwr_maxpages - Compute size of largest payload
- * @r_xprt: transport
- *
- * Returns maximum size of an RPC message, in pages.
- *
- * FRWR mode conveys a list of pages per chunk segment. The
- * maximum length of that list is the FRWR page list depth.
- */
-size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt)
-{
-       struct rpcrdma_ia *ia = &r_xprt->rx_ia;
+       ia->ri_max_rdma_segs += 2;
+       if (ia->ri_max_rdma_segs > RPCRDMA_MAX_HDR_SEGS)
+               ia->ri_max_rdma_segs = RPCRDMA_MAX_HDR_SEGS;
+
+       /* Ensure the underlying device is capable of conveying the
+        * largest r/wsize NFS will ask for. This guarantees that
+        * failing over from one RDMA device to another will not
+        * break NFS I/O.
+        */
+       if ((ia->ri_max_rdma_segs * ia->ri_max_frwr_depth) < RPCRDMA_MAX_SEGS)
+               return -ENOMEM;
 
-       return min_t(unsigned int, RPCRDMA_MAX_DATA_SEGS,
-                    (ia->ri_max_segs - 2) * ia->ri_max_frwr_depth);
+       return 0;
 }
 
 /**
index aec3beb..28020ec 100644 (file)
@@ -111,7 +111,7 @@ static unsigned int rpcrdma_max_reply_header_size(unsigned int maxsegs)
  */
 void rpcrdma_set_max_header_sizes(struct rpcrdma_xprt *r_xprt)
 {
-       unsigned int maxsegs = r_xprt->rx_ia.ri_max_segs;
+       unsigned int maxsegs = r_xprt->rx_ia.ri_max_rdma_segs;
        struct rpcrdma_ep *ep = &r_xprt->rx_ep;
 
        ep->rep_max_inline_send =
@@ -145,7 +145,7 @@ static bool rpcrdma_args_inline(struct rpcrdma_xprt *r_xprt,
                        remaining -= min_t(unsigned int,
                                           PAGE_SIZE - offset, remaining);
                        offset = 0;
-                       if (++count > r_xprt->rx_ia.ri_max_send_sges)
+                       if (++count > r_xprt->rx_ep.rep_attr.cap.max_send_sge)
                                return false;
                }
        }
@@ -580,22 +580,19 @@ void rpcrdma_sendctx_unmap(struct rpcrdma_sendctx *sc)
 
 /* Prepare an SGE for the RPC-over-RDMA transport header.
  */
-static bool rpcrdma_prepare_hdr_sge(struct rpcrdma_xprt *r_xprt,
+static void rpcrdma_prepare_hdr_sge(struct rpcrdma_xprt *r_xprt,
                                    struct rpcrdma_req *req, u32 len)
 {
        struct rpcrdma_sendctx *sc = req->rl_sendctx;
        struct rpcrdma_regbuf *rb = req->rl_rdmabuf;
        struct ib_sge *sge = &sc->sc_sges[req->rl_wr.num_sge++];
 
-       if (!rpcrdma_regbuf_dma_map(r_xprt, rb))
-               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);
-       return true;
 }
 
 /* The head iovec is straightforward, as it is usually already
@@ -836,10 +833,9 @@ inline int rpcrdma_prepare_send_sges(struct rpcrdma_xprt *r_xprt,
        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 out_unmap;
+       rpcrdma_prepare_hdr_sge(r_xprt, req, hdrlen);
 
+       ret = -EIO;
        switch (rtype) {
        case rpcrdma_noch_pullup:
                if (!rpcrdma_prepare_noch_pullup(r_xprt, req, xdr))
@@ -909,7 +905,7 @@ rpcrdma_marshal_req(struct rpcrdma_xprt *r_xprt, struct rpc_rqst *rqst)
                goto out_err;
        *p++ = rqst->rq_xid;
        *p++ = rpcrdma_version;
-       *p++ = cpu_to_be32(r_xprt->rx_buf.rb_max_requests);
+       *p++ = r_xprt->rx_buf.rb_max_requests;
 
        /* When the ULP employs a GSS flavor that guarantees integrity
         * or privacy, direct data placement of individual data items
@@ -1480,8 +1476,8 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep)
 
        if (credits == 0)
                credits = 1;    /* don't deadlock */
-       else if (credits > buf->rb_max_requests)
-               credits = buf->rb_max_requests;
+       else if (credits > r_xprt->rx_ep.rep_max_requests)
+               credits = r_xprt->rx_ep.rep_max_requests;
        if (buf->rb_credits != credits)
                rpcrdma_update_cwnd(r_xprt, credits);
        rpcrdma_post_recvs(r_xprt, false);
index 7395eb2..3cfeba6 100644 (file)
@@ -316,7 +316,8 @@ xprt_setup_rdma(struct xprt_create *args)
        if (args->addrlen > sizeof(xprt->addr))
                return ERR_PTR(-EBADF);
 
-       xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt), 0, 0);
+       xprt = xprt_alloc(args->net, sizeof(struct rpcrdma_xprt), 0,
+                         xprt_rdma_slot_table_entries);
        if (!xprt)
                return ERR_PTR(-ENOMEM);
 
@@ -358,19 +359,13 @@ xprt_setup_rdma(struct xprt_create *args)
        if (rc)
                goto out3;
 
-       INIT_DELAYED_WORK(&new_xprt->rx_connect_worker,
-                         xprt_rdma_connect_worker);
-
-       xprt->max_payload = frwr_maxpages(new_xprt);
-       if (xprt->max_payload == 0)
-               goto out4;
-       xprt->max_payload <<= PAGE_SHIFT;
-       dprintk("RPC:       %s: transport data payload maximum: %zu bytes\n",
-               __func__, xprt->max_payload);
-
        if (!try_module_get(THIS_MODULE))
                goto out4;
 
+       INIT_DELAYED_WORK(&new_xprt->rx_connect_worker,
+                         xprt_rdma_connect_worker);
+       xprt->max_payload = RPCRDMA_MAX_DATA_SEGS << PAGE_SHIFT;
+
        dprintk("RPC:       %s: %s:%s\n", __func__,
                xprt->address_strings[RPC_DISPLAY_ADDR],
                xprt->address_strings[RPC_DISPLAY_PORT]);
index fda3889..353f61a 100644 (file)
 /*
  * internal functions
  */
+static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt);
+static void rpcrdma_sendctxs_destroy(struct rpcrdma_xprt *r_xprt);
 static void rpcrdma_sendctx_put_locked(struct rpcrdma_xprt *r_xprt,
                                       struct rpcrdma_sendctx *sc);
+static int rpcrdma_reqs_setup(struct rpcrdma_xprt *r_xprt);
 static void rpcrdma_reqs_reset(struct rpcrdma_xprt *r_xprt);
+static void rpcrdma_rep_destroy(struct rpcrdma_rep *rep);
 static void rpcrdma_reps_unmap(struct rpcrdma_xprt *r_xprt);
 static void rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt);
 static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt);
@@ -174,7 +178,7 @@ rpcrdma_wc_receive(struct ib_cq *cq, struct ib_wc *wc)
        return;
 
 out_flushed:
-       rpcrdma_recv_buffer_put(rep);
+       rpcrdma_rep_destroy(rep);
 }
 
 static void rpcrdma_update_cm_private(struct rpcrdma_xprt *r_xprt,
@@ -366,18 +370,6 @@ rpcrdma_ia_open(struct rpcrdma_xprt *xprt)
                goto out_err;
        }
 
-       switch (xprt_rdma_memreg_strategy) {
-       case RPCRDMA_FRWR:
-               if (frwr_is_supported(ia->ri_id->device))
-                       break;
-               /*FALLTHROUGH*/
-       default:
-               pr_err("rpcrdma: Device %s does not support memreg mode %d\n",
-                      ia->ri_id->device->name, xprt_rdma_memreg_strategy);
-               rc = -EINVAL;
-               goto out_err;
-       }
-
        return 0;
 
 out_err:
@@ -391,6 +383,8 @@ out_err:
  *
  * Divest transport H/W resources associated with this adapter,
  * but allow it to be restored later.
+ *
+ * Caller must hold the transport send lock.
  */
 void
 rpcrdma_ia_remove(struct rpcrdma_ia *ia)
@@ -398,8 +392,6 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
        struct rpcrdma_xprt *r_xprt = container_of(ia, struct rpcrdma_xprt,
                                                   rx_ia);
        struct rpcrdma_ep *ep = &r_xprt->rx_ep;
-       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
-       struct rpcrdma_req *req;
 
        /* This is similar to rpcrdma_ep_destroy, but:
         * - Don't cancel the connect worker.
@@ -422,12 +414,9 @@ rpcrdma_ia_remove(struct rpcrdma_ia *ia)
         * mappings and MRs are gone.
         */
        rpcrdma_reps_unmap(r_xprt);
-       list_for_each_entry(req, &buf->rb_allreqs, rl_all) {
-               rpcrdma_regbuf_dma_unmap(req->rl_rdmabuf);
-               rpcrdma_regbuf_dma_unmap(req->rl_sendbuf);
-               rpcrdma_regbuf_dma_unmap(req->rl_recvbuf);
-       }
+       rpcrdma_reqs_reset(r_xprt);
        rpcrdma_mrs_destroy(r_xprt);
+       rpcrdma_sendctxs_destroy(r_xprt);
        ib_dealloc_pd(ia->ri_pd);
        ia->ri_pd = NULL;
 
@@ -470,30 +459,20 @@ int rpcrdma_ep_create(struct rpcrdma_xprt *r_xprt)
        struct rpcrdma_ia *ia = &r_xprt->rx_ia;
        struct rpcrdma_connect_private *pmsg = &ep->rep_cm_private;
        struct ib_cq *sendcq, *recvcq;
-       unsigned int max_sge;
        int rc;
 
-       ep->rep_max_requests = xprt_rdma_slot_table_entries;
+       ep->rep_max_requests = r_xprt->rx_xprt.max_reqs;
        ep->rep_inline_send = xprt_rdma_max_inline_write;
        ep->rep_inline_recv = xprt_rdma_max_inline_read;
 
-       max_sge = min_t(unsigned int, ia->ri_id->device->attrs.max_send_sge,
-                       RPCRDMA_MAX_SEND_SGES);
-       if (max_sge < RPCRDMA_MIN_SEND_SGES) {
-               pr_warn("rpcrdma: HCA provides only %d send SGEs\n", max_sge);
-               return -ENOMEM;
-       }
-       ia->ri_max_send_sges = max_sge;
-
-       rc = frwr_open(ia, ep);
+       rc = frwr_query_device(r_xprt, ia->ri_id->device);
        if (rc)
                return rc;
+       r_xprt->rx_buf.rb_max_requests = cpu_to_be32(ep->rep_max_requests);
 
        ep->rep_attr.event_handler = rpcrdma_qp_event_handler;
        ep->rep_attr.qp_context = ep;
        ep->rep_attr.srq = NULL;
-       ep->rep_attr.cap.max_send_sge = max_sge;
-       ep->rep_attr.cap.max_recv_sge = 1;
        ep->rep_attr.cap.max_inline_data = 0;
        ep->rep_attr.sq_sig_type = IB_SIGNAL_REQ_WR;
        ep->rep_attr.qp_type = IB_QPT_RC;
@@ -716,6 +695,10 @@ retry:
        rpcrdma_reset_cwnd(r_xprt);
        rpcrdma_post_recvs(r_xprt, true);
 
+       rc = rpcrdma_sendctxs_create(r_xprt);
+       if (rc)
+               goto out;
+
        rc = rdma_connect(ia->ri_id, &ep->rep_remote_cma);
        if (rc)
                goto out;
@@ -730,6 +713,11 @@ retry:
                goto out;
        }
 
+       rc = rpcrdma_reqs_setup(r_xprt);
+       if (rc) {
+               rpcrdma_ep_disconnect(ep, ia);
+               goto out;
+       }
        rpcrdma_mrs_create(r_xprt);
 
 out:
@@ -768,6 +756,7 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
        rpcrdma_xprt_drain(r_xprt);
        rpcrdma_reqs_reset(r_xprt);
        rpcrdma_mrs_destroy(r_xprt);
+       rpcrdma_sendctxs_destroy(r_xprt);
 }
 
 /* Fixed-size circular FIFO queue. This implementation is wait-free and
@@ -787,20 +776,24 @@ rpcrdma_ep_disconnect(struct rpcrdma_ep *ep, struct rpcrdma_ia *ia)
  * queue activity, and rpcrdma_xprt_drain has flushed all remaining
  * Send requests.
  */
-static void rpcrdma_sendctxs_destroy(struct rpcrdma_buffer *buf)
+static void rpcrdma_sendctxs_destroy(struct rpcrdma_xprt *r_xprt)
 {
+       struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        unsigned long i;
 
+       if (!buf->rb_sc_ctxs)
+               return;
        for (i = 0; i <= buf->rb_sc_last; i++)
                kfree(buf->rb_sc_ctxs[i]);
        kfree(buf->rb_sc_ctxs);
+       buf->rb_sc_ctxs = NULL;
 }
 
-static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ia *ia)
+static struct rpcrdma_sendctx *rpcrdma_sendctx_create(struct rpcrdma_ep *ep)
 {
        struct rpcrdma_sendctx *sc;
 
-       sc = kzalloc(struct_size(sc, sc_sges, ia->ri_max_send_sges),
+       sc = kzalloc(struct_size(sc, sc_sges, ep->rep_attr.cap.max_send_sge),
                     GFP_KERNEL);
        if (!sc)
                return NULL;
@@ -820,21 +813,22 @@ static int rpcrdma_sendctxs_create(struct rpcrdma_xprt *r_xprt)
         * the ->send_request call to fail temporarily before too many
         * Sends are posted.
         */
-       i = buf->rb_max_requests + RPCRDMA_MAX_BC_REQUESTS;
-       dprintk("RPC:       %s: allocating %lu send_ctxs\n", __func__, i);
+       i = r_xprt->rx_ep.rep_max_requests + RPCRDMA_MAX_BC_REQUESTS;
        buf->rb_sc_ctxs = kcalloc(i, sizeof(sc), GFP_KERNEL);
        if (!buf->rb_sc_ctxs)
                return -ENOMEM;
 
        buf->rb_sc_last = i - 1;
        for (i = 0; i <= buf->rb_sc_last; i++) {
-               sc = rpcrdma_sendctx_create(&r_xprt->rx_ia);
+               sc = rpcrdma_sendctx_create(&r_xprt->rx_ep);
                if (!sc)
                        return -ENOMEM;
 
                buf->rb_sc_ctxs[i] = sc;
        }
 
+       buf->rb_sc_head = 0;
+       buf->rb_sc_tail = 0;
        return 0;
 }
 
@@ -933,7 +927,7 @@ rpcrdma_mrs_create(struct rpcrdma_xprt *r_xprt)
        struct rpcrdma_ia *ia = &r_xprt->rx_ia;
        unsigned int count;
 
-       for (count = 0; count < ia->ri_max_segs; count++) {
+       for (count = 0; count < ia->ri_max_rdma_segs; count++) {
                struct rpcrdma_mr *mr;
                int rc;
 
@@ -1005,32 +999,19 @@ struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, size_t size,
                                       gfp_t flags)
 {
        struct rpcrdma_buffer *buffer = &r_xprt->rx_buf;
-       struct rpcrdma_regbuf *rb;
        struct rpcrdma_req *req;
-       size_t maxhdrsize;
 
        req = kzalloc(sizeof(*req), flags);
        if (req == NULL)
                goto out1;
 
-       /* Compute maximum header buffer size in bytes */
-       maxhdrsize = rpcrdma_fixed_maxsz + 3 +
-                    r_xprt->rx_ia.ri_max_segs * rpcrdma_readchunk_maxsz;
-       maxhdrsize *= sizeof(__be32);
-       rb = rpcrdma_regbuf_alloc(__roundup_pow_of_two(maxhdrsize),
-                                 DMA_TO_DEVICE, flags);
-       if (!rb)
-               goto out2;
-       req->rl_rdmabuf = rb;
-       xdr_buf_init(&req->rl_hdrbuf, rdmab_data(rb), rdmab_length(rb));
-
        req->rl_sendbuf = rpcrdma_regbuf_alloc(size, DMA_TO_DEVICE, flags);
        if (!req->rl_sendbuf)
-               goto out3;
+               goto out2;
 
        req->rl_recvbuf = rpcrdma_regbuf_alloc(size, DMA_NONE, flags);
        if (!req->rl_recvbuf)
-               goto out4;
+               goto out3;
 
        INIT_LIST_HEAD(&req->rl_free_mrs);
        INIT_LIST_HEAD(&req->rl_registered);
@@ -1039,10 +1020,8 @@ struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, size_t size,
        spin_unlock(&buffer->rb_lock);
        return req;
 
-out4:
-       kfree(req->rl_sendbuf);
 out3:
-       kfree(req->rl_rdmabuf);
+       kfree(req->rl_sendbuf);
 out2:
        kfree(req);
 out1:
@@ -1050,27 +1029,90 @@ out1:
 }
 
 /**
- * rpcrdma_reqs_reset - Reset all reqs owned by a transport
+ * rpcrdma_req_setup - Per-connection instance setup of an rpcrdma_req object
  * @r_xprt: controlling transport instance
+ * @req: rpcrdma_req object to set up
  *
- * ASSUMPTION: the rb_allreqs list is stable for the duration,
+ * Returns zero on success, and a negative errno on failure.
+ */
+int rpcrdma_req_setup(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req)
+{
+       struct rpcrdma_regbuf *rb;
+       size_t maxhdrsize;
+
+       /* Compute maximum header buffer size in bytes */
+       maxhdrsize = rpcrdma_fixed_maxsz + 3 +
+                    r_xprt->rx_ia.ri_max_rdma_segs * rpcrdma_readchunk_maxsz;
+       maxhdrsize *= sizeof(__be32);
+       rb = rpcrdma_regbuf_alloc(__roundup_pow_of_two(maxhdrsize),
+                                 DMA_TO_DEVICE, GFP_KERNEL);
+       if (!rb)
+               goto out;
+
+       if (!__rpcrdma_regbuf_dma_map(r_xprt, rb))
+               goto out_free;
+
+       req->rl_rdmabuf = rb;
+       xdr_buf_init(&req->rl_hdrbuf, rdmab_data(rb), rdmab_length(rb));
+       return 0;
+
+out_free:
+       rpcrdma_regbuf_free(rb);
+out:
+       return -ENOMEM;
+}
+
+/* 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)
+static int rpcrdma_reqs_setup(struct rpcrdma_xprt *r_xprt)
 {
        struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        struct rpcrdma_req *req;
+       int rc;
 
        list_for_each_entry(req, &buf->rb_allreqs, rl_all) {
-               /* Credits are valid only for one connection */
-               req->rl_slot.rq_cong = 0;
+               rc = rpcrdma_req_setup(r_xprt, req);
+               if (rc)
+                       return rc;
        }
+       return 0;
 }
 
-static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
-                                             bool temp)
+static void rpcrdma_req_reset(struct rpcrdma_req *req)
+{
+       /* Credits are valid for only one connection */
+       req->rl_slot.rq_cong = 0;
+
+       rpcrdma_regbuf_free(req->rl_rdmabuf);
+       req->rl_rdmabuf = NULL;
+
+       rpcrdma_regbuf_dma_unmap(req->rl_sendbuf);
+       rpcrdma_regbuf_dma_unmap(req->rl_recvbuf);
+}
+
+/* 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)
+               rpcrdma_req_reset(req);
+}
+
+/* No locking needed here. This function is called only by the
+ * Receive completion handler.
+ */
+static noinline
+struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
+                                      bool temp)
 {
        struct rpcrdma_rep *rep;
 
@@ -1083,6 +1125,9 @@ static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
        if (!rep->rr_rdmabuf)
                goto out_free;
 
+       if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf))
+               goto out_free_regbuf;
+
        xdr_buf_init(&rep->rr_hdrbuf, rdmab_data(rep->rr_rdmabuf),
                     rdmab_length(rep->rr_rdmabuf));
        rep->rr_cqe.done = rpcrdma_wc_receive;
@@ -1095,12 +1140,17 @@ static struct rpcrdma_rep *rpcrdma_rep_create(struct rpcrdma_xprt *r_xprt,
        list_add(&rep->rr_all, &r_xprt->rx_buf.rb_all_reps);
        return rep;
 
+out_free_regbuf:
+       rpcrdma_regbuf_free(rep->rr_rdmabuf);
 out_free:
        kfree(rep);
 out:
        return NULL;
 }
 
+/* No locking needed here. This function is invoked only by the
+ * Receive completion handler, or during transport shutdown.
+ */
 static void rpcrdma_rep_destroy(struct rpcrdma_rep *rep)
 {
        list_del(&rep->rr_all);
@@ -1130,8 +1180,10 @@ static void rpcrdma_reps_unmap(struct rpcrdma_xprt *r_xprt)
        struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        struct rpcrdma_rep *rep;
 
-       list_for_each_entry(rep, &buf->rb_all_reps, rr_all)
+       list_for_each_entry(rep, &buf->rb_all_reps, rr_all) {
                rpcrdma_regbuf_dma_unmap(rep->rr_rdmabuf);
+               rep->rr_temp = true;
+       }
 }
 
 static void rpcrdma_reps_destroy(struct rpcrdma_buffer *buf)
@@ -1153,7 +1205,6 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
        struct rpcrdma_buffer *buf = &r_xprt->rx_buf;
        int i, rc;
 
-       buf->rb_max_requests = r_xprt->rx_ep.rep_max_requests;
        buf->rb_bc_srv_max_requests = 0;
        spin_lock_init(&buf->rb_lock);
        INIT_LIST_HEAD(&buf->rb_mrs);
@@ -1165,7 +1216,7 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
        INIT_LIST_HEAD(&buf->rb_all_reps);
 
        rc = -ENOMEM;
-       for (i = 0; i < buf->rb_max_requests; i++) {
+       for (i = 0; i < r_xprt->rx_xprt.max_reqs; i++) {
                struct rpcrdma_req *req;
 
                req = rpcrdma_req_create(r_xprt, RPCRDMA_V1_DEF_INLINE_SIZE * 2,
@@ -1177,10 +1228,6 @@ int rpcrdma_buffer_create(struct rpcrdma_xprt *r_xprt)
 
        init_llist_head(&buf->rb_free_reps);
 
-       rc = rpcrdma_sendctxs_create(r_xprt);
-       if (rc)
-               goto out;
-
        return 0;
 out:
        rpcrdma_buffer_destroy(buf);
@@ -1256,7 +1303,6 @@ static void rpcrdma_mrs_destroy(struct rpcrdma_xprt *r_xprt)
 void
 rpcrdma_buffer_destroy(struct rpcrdma_buffer *buf)
 {
-       rpcrdma_sendctxs_destroy(buf);
        rpcrdma_reps_destroy(buf);
 
        while (!list_empty(&buf->rb_send_bufs)) {
@@ -1497,7 +1543,7 @@ 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;
-       struct ib_recv_wr *i, *wr, *bad_wr;
+       struct ib_recv_wr *wr, *bad_wr;
        struct rpcrdma_rep *rep;
        int needed, count, rc;
 
@@ -1524,23 +1570,15 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp)
                if (!rep)
                        break;
 
+               trace_xprtrdma_post_recv(rep);
                rep->rr_recv_wr.next = wr;
                wr = &rep->rr_recv_wr;
                --needed;
+               ++count;
        }
        if (!wr)
                goto out;
 
-       for (i = wr; i; i = i->next) {
-               rep = container_of(i, struct rpcrdma_rep, rr_recv_wr);
-
-               if (!rpcrdma_regbuf_dma_map(r_xprt, rep->rr_rdmabuf))
-                       goto release_wrs;
-
-               trace_xprtrdma_post_recv(rep);
-               ++count;
-       }
-
        rc = ib_post_recv(r_xprt->rx_ia.ri_id->qp, wr,
                          (const struct ib_recv_wr **)&bad_wr);
 out:
@@ -1557,11 +1595,4 @@ out:
        }
        ep->rep_receive_count += count;
        return;
-
-release_wrs:
-       for (i = wr; i;) {
-               rep = container_of(i, struct rpcrdma_rep, rr_recv_wr);
-               i = i->next;
-               rpcrdma_recv_buffer_put(rep);
-       }
 }
index d796d68..37d5080 100644 (file)
@@ -71,9 +71,8 @@ struct rpcrdma_ia {
        struct rdma_cm_id       *ri_id;
        struct ib_pd            *ri_pd;
        int                     ri_async_rc;
-       unsigned int            ri_max_segs;
+       unsigned int            ri_max_rdma_segs;
        unsigned int            ri_max_frwr_depth;
-       unsigned int            ri_max_send_sges;
        bool                    ri_implicit_roundup;
        enum ib_mr_type         ri_mrtype;
        unsigned long           ri_flags;
@@ -99,7 +98,7 @@ struct rpcrdma_ep {
        wait_queue_head_t       rep_connect_wait;
        struct rpcrdma_connect_private  rep_cm_private;
        struct rdma_conn_param  rep_remote_cma;
-       unsigned int            rep_max_requests;       /* set by /proc */
+       unsigned int            rep_max_requests;       /* depends on device */
        unsigned int            rep_inline_send;        /* negotiated */
        unsigned int            rep_inline_recv;        /* negotiated */
        int                     rep_receive_count;
@@ -373,7 +372,7 @@ struct rpcrdma_buffer {
 
        struct llist_head       rb_free_reps;
 
-       u32                     rb_max_requests;
+       __be32                  rb_max_requests;
        u32                     rb_credits;     /* most recent credit grant */
 
        u32                     rb_bc_srv_max_requests;
@@ -479,6 +478,7 @@ void rpcrdma_post_recvs(struct rpcrdma_xprt *r_xprt, bool temp);
  */
 struct rpcrdma_req *rpcrdma_req_create(struct rpcrdma_xprt *r_xprt, size_t size,
                                       gfp_t flags);
+int rpcrdma_req_setup(struct rpcrdma_xprt *r_xprt, struct rpcrdma_req *req);
 void rpcrdma_req_destroy(struct rpcrdma_req *req);
 int rpcrdma_buffer_create(struct rpcrdma_xprt *);
 void rpcrdma_buffer_destroy(struct rpcrdma_buffer *);
@@ -535,12 +535,11 @@ rpcrdma_data_dir(bool writing)
 
 /* Memory registration calls xprtrdma/frwr_ops.c
  */
-bool frwr_is_supported(struct ib_device *device);
 void frwr_reset(struct rpcrdma_req *req);
-int frwr_open(struct rpcrdma_ia *ia, struct rpcrdma_ep *ep);
+int frwr_query_device(struct rpcrdma_xprt *r_xprt,
+                     const struct ib_device *device);
 int frwr_init_mr(struct rpcrdma_ia *ia, struct rpcrdma_mr *mr);
 void frwr_release_mr(struct rpcrdma_mr *mr);
-size_t frwr_maxpages(struct rpcrdma_xprt *r_xprt);
 struct rpcrdma_mr_seg *frwr_map(struct rpcrdma_xprt *r_xprt,
                                struct rpcrdma_mr_seg *seg,
                                int nsegs, bool writing, __be32 xid,
@@ -583,7 +582,6 @@ static inline void rpcrdma_set_xdrlen(struct xdr_buf *xdr, size_t len)
 
 /* RPC/RDMA module init - xprtrdma/transport.c
  */
-extern unsigned int xprt_rdma_slot_table_entries;
 extern unsigned int xprt_rdma_max_inline_read;
 extern unsigned int xprt_rdma_max_inline_write;
 void xprt_rdma_format_addresses(struct rpc_xprt *xprt, struct sockaddr *sap);
index 321af97..62c12cb 100644 (file)
@@ -189,11 +189,17 @@ static inline int unix_may_send(struct sock *sk, struct sock *osk)
        return unix_peer(osk) == NULL || unix_our_peer(sk, osk);
 }
 
-static inline int unix_recvq_full(struct sock const *sk)
+static inline int unix_recvq_full(const struct sock *sk)
 {
        return skb_queue_len(&sk->sk_receive_queue) > sk->sk_max_ack_backlog;
 }
 
+static inline int unix_recvq_full_lockless(const struct sock *sk)
+{
+       return skb_queue_len_lockless(&sk->sk_receive_queue) >
+               READ_ONCE(sk->sk_max_ack_backlog);
+}
+
 struct sock *unix_peer_get(struct sock *s)
 {
        struct sock *peer;
@@ -1758,7 +1764,8 @@ restart_locked:
         * - unix_peer(sk) == sk by time of get but disconnected before lock
         */
        if (other != sk &&
-           unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
+           unlikely(unix_peer(other) != sk &&
+           unix_recvq_full_lockless(other))) {
                if (timeo) {
                        timeo = unix_wait_for_peer(other, timeo);
 
index 297d1eb..dbda08e 100644 (file)
@@ -3189,7 +3189,7 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
                                            flags | XFRM_LOOKUP_QUEUE |
                                            XFRM_LOOKUP_KEEP_DST_REF);
 
-       if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE)
+       if (PTR_ERR(dst) == -EREMOTE)
                return make_blackhole(net, dst_orig->ops->family, dst_orig);
 
        if (IS_ERR(dst))
index 0b5acd7..c91e913 100644 (file)
@@ -83,7 +83,6 @@ static u32 opt_xdp_bind_flags = XDP_USE_NEED_WAKEUP;
 static u32 opt_umem_flags;
 static int opt_unaligned_chunks;
 static int opt_mmap_flags;
-static u32 opt_xdp_bind_flags;
 static int opt_xsk_frame_size = XSK_UMEM__DEFAULT_FRAME_SIZE;
 static int opt_timeout = 1000;
 static bool opt_need_wakeup = true;
@@ -789,7 +788,8 @@ static void kick_tx(struct xsk_socket_info *xsk)
        int ret;
 
        ret = sendto(xsk_socket__fd(xsk->xsk), NULL, 0, MSG_DONTWAIT, NULL, 0);
-       if (ret >= 0 || errno == ENOBUFS || errno == EAGAIN || errno == EBUSY)
+       if (ret >= 0 || errno == ENOBUFS || errno == EAGAIN ||
+           errno == EBUSY || errno == ENETDOWN)
                return;
        exit_with_error(errno);
 }
index 9ca3e44..c406f03 100644 (file)
@@ -142,11 +142,10 @@ static ssize_t fifo_read(struct file *file, char __user *buf,
        return ret ? ret : copied;
 }
 
-static const struct file_operations fifo_fops = {
-       .owner          = THIS_MODULE,
-       .read           = fifo_read,
-       .write          = fifo_write,
-       .llseek         = noop_llseek,
+static const struct proc_ops fifo_proc_ops = {
+       .proc_read      = fifo_read,
+       .proc_write     = fifo_write,
+       .proc_lseek     = noop_llseek,
 };
 
 static int __init example_init(void)
@@ -169,7 +168,7 @@ static int __init example_init(void)
                return -EIO;
        }
 
-       if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
+       if (proc_create(PROC_FIFO, 0, NULL, &fifo_proc_ops) == NULL) {
 #ifdef DYNAMIC
                kfifo_free(&test);
 #endif
index 6cdeb72..78977fc 100644 (file)
@@ -135,11 +135,10 @@ static ssize_t fifo_read(struct file *file, char __user *buf,
        return ret ? ret : copied;
 }
 
-static const struct file_operations fifo_fops = {
-       .owner          = THIS_MODULE,
-       .read           = fifo_read,
-       .write          = fifo_write,
-       .llseek         = noop_llseek,
+static const struct proc_ops fifo_proc_ops = {
+       .proc_read      = fifo_read,
+       .proc_write     = fifo_write,
+       .proc_lseek     = noop_llseek,
 };
 
 static int __init example_init(void)
@@ -160,7 +159,7 @@ static int __init example_init(void)
                return -EIO;
        }
 
-       if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
+       if (proc_create(PROC_FIFO, 0, NULL, &fifo_proc_ops) == NULL) {
 #ifdef DYNAMIC
                kfifo_free(&test);
 #endif
index 79ae8bb..c507998 100644 (file)
@@ -149,11 +149,10 @@ static ssize_t fifo_read(struct file *file, char __user *buf,
        return ret ? ret : copied;
 }
 
-static const struct file_operations fifo_fops = {
-       .owner          = THIS_MODULE,
-       .read           = fifo_read,
-       .write          = fifo_write,
-       .llseek         = noop_llseek,
+static const struct proc_ops fifo_proc_ops = {
+       .proc_read      = fifo_read,
+       .proc_write     = fifo_write,
+       .proc_lseek     = noop_llseek,
 };
 
 static int __init example_init(void)
@@ -176,7 +175,7 @@ static int __init example_init(void)
                return -EIO;
        }
 
-       if (proc_create(PROC_FIFO, 0, NULL, &fifo_fops) == NULL) {
+       if (proc_create(PROC_FIFO, 0, NULL, &fifo_proc_ops) == NULL) {
 #ifdef DYNAMIC
                kfifo_free(&test);
 #endif
index 9330d42..3357bf4 100644 (file)
@@ -91,8 +91,6 @@ position p;
 |
  kzfree@p(x)
 |
- __krealloc@p(x, ...)
-|
  krealloc@p(x, ...)
 |
  free_pages@p(x, ...)
@@ -116,8 +114,6 @@ position p != safe.p;
 |
 * kzfree@p(x)
 |
-* __krealloc@p(x, ...)
-|
 * krealloc@p(x, ...)
 |
 * free_pages@p(x, ...)
index 470ccfe..a8f0c00 100755 (executable)
@@ -272,7 +272,7 @@ sub check_sphinx()
 
        open IN, "$sphinx --version 2>&1 |" or die "$sphinx returned an error";
        while (<IN>) {
-               if (m/^\s*sphinx-build\s+([\d\.]+)$/) {
+               if (m/^\s*sphinx-build\s+([\d\.]+)(\+\/[\da-f]+)?$/) {
                        $cur_version=$1;
                        last;
                }
index d9e8b21..4b6991e 100644 (file)
@@ -2778,7 +2778,7 @@ static int selinux_fs_context_dup(struct fs_context *fc,
        return 0;
 }
 
-static const struct fs_parameter_spec selinux_param_specs[] = {
+static const struct fs_parameter_spec selinux_fs_parameters[] = {
        fsparam_string(CONTEXT_STR,     Opt_context),
        fsparam_string(DEFCONTEXT_STR,  Opt_defcontext),
        fsparam_string(FSCONTEXT_STR,   Opt_fscontext),
@@ -2787,18 +2787,13 @@ static const struct fs_parameter_spec selinux_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description selinux_fs_parameters = {
-       .name           = "SELinux",
-       .specs          = selinux_param_specs,
-};
-
 static int selinux_fs_context_parse_param(struct fs_context *fc,
                                          struct fs_parameter *param)
 {
        struct fs_parse_result result;
        int opt, rc;
 
-       opt = fs_parse(fc, &selinux_fs_parameters, param, &result);
+       opt = fs_parse(fc, selinux_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -7193,7 +7188,7 @@ static __init int selinux_init(void)
        else
                pr_debug("SELinux:  Starting in permissive mode\n");
 
-       fs_validate_description(&selinux_fs_parameters);
+       fs_validate_description("selinux", selinux_fs_parameters);
 
        return 0;
 }
index ecea41c..8c61d17 100644 (file)
@@ -678,7 +678,7 @@ static int smack_fs_context_dup(struct fs_context *fc,
        return 0;
 }
 
-static const struct fs_parameter_spec smack_param_specs[] = {
+static const struct fs_parameter_spec smack_fs_parameters[] = {
        fsparam_string("smackfsdef",            Opt_fsdefault),
        fsparam_string("smackfsdefault",        Opt_fsdefault),
        fsparam_string("smackfsfloor",          Opt_fsfloor),
@@ -688,11 +688,6 @@ static const struct fs_parameter_spec smack_param_specs[] = {
        {}
 };
 
-static const struct fs_parameter_description smack_fs_parameters = {
-       .name           = "smack",
-       .specs          = smack_param_specs,
-};
-
 /**
  * smack_fs_context_parse_param - Parse a single mount parameter
  * @fc: The new filesystem context being constructed.
@@ -707,7 +702,7 @@ static int smack_fs_context_parse_param(struct fs_context *fc,
        struct fs_parse_result result;
        int opt, rc;
 
-       opt = fs_parse(fc, &smack_fs_parameters, param, &result);
+       opt = fs_parse(fc, smack_fs_parameters, param, &result);
        if (opt < 0)
                return opt;
 
@@ -2831,42 +2826,39 @@ static int smack_socket_connect(struct socket *sock, struct sockaddr *sap,
                                int addrlen)
 {
        int rc = 0;
-#if IS_ENABLED(CONFIG_IPV6)
-       struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
-#endif
-#ifdef SMACK_IPV6_SECMARK_LABELING
-       struct smack_known *rsp;
-       struct socket_smack *ssp;
-#endif
 
        if (sock->sk == NULL)
                return 0;
-
+       if (sock->sk->sk_family != PF_INET &&
+           (!IS_ENABLED(CONFIG_IPV6) || sock->sk->sk_family != PF_INET6))
+               return 0;
+       if (addrlen < offsetofend(struct sockaddr, sa_family))
+               return 0;
+       if (IS_ENABLED(CONFIG_IPV6) && sap->sa_family == AF_INET6) {
+               struct sockaddr_in6 *sip = (struct sockaddr_in6 *)sap;
 #ifdef SMACK_IPV6_SECMARK_LABELING
-       ssp = sock->sk->sk_security;
+               struct smack_known *rsp;
 #endif
 
-       switch (sock->sk->sk_family) {
-       case PF_INET:
-               if (addrlen < sizeof(struct sockaddr_in) ||
-                   sap->sa_family != AF_INET)
-                       return -EINVAL;
-               rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
-               break;
-       case PF_INET6:
-               if (addrlen < SIN6_LEN_RFC2133 || sap->sa_family != AF_INET6)
-                       return -EINVAL;
+               if (addrlen < SIN6_LEN_RFC2133)
+                       return 0;
 #ifdef SMACK_IPV6_SECMARK_LABELING
                rsp = smack_ipv6host_label(sip);
-               if (rsp != NULL)
+               if (rsp != NULL) {
+                       struct socket_smack *ssp = sock->sk->sk_security;
+
                        rc = smk_ipv6_check(ssp->smk_out, rsp, sip,
-                                               SMK_CONNECTING);
+                                           SMK_CONNECTING);
+               }
 #endif
 #ifdef SMACK_IPV6_PORT_LABELING
                rc = smk_ipv6_port_check(sock->sk, sip, SMK_CONNECTING);
 #endif
-               break;
+               return rc;
        }
+       if (sap->sa_family != AF_INET || addrlen < sizeof(struct sockaddr_in))
+               return 0;
+       rc = smack_netlabel_send(sock->sk, (struct sockaddr_in *)sap);
        return rc;
 }
 
index 6801d81..ca87ae4 100644 (file)
@@ -282,17 +282,16 @@ static int snd_info_entry_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static const struct file_operations snd_info_entry_operations =
-{
-       .owner =                THIS_MODULE,
-       .llseek =               snd_info_entry_llseek,
-       .read =                 snd_info_entry_read,
-       .write =                snd_info_entry_write,
-       .poll =                 snd_info_entry_poll,
-       .unlocked_ioctl =       snd_info_entry_ioctl,
-       .mmap =                 snd_info_entry_mmap,
-       .open =                 snd_info_entry_open,
-       .release =              snd_info_entry_release,
+static const struct proc_ops snd_info_entry_operations =
+{
+       .proc_lseek     = snd_info_entry_llseek,
+       .proc_read      = snd_info_entry_read,
+       .proc_write     = snd_info_entry_write,
+       .proc_poll      = snd_info_entry_poll,
+       .proc_ioctl     = snd_info_entry_ioctl,
+       .proc_mmap      = snd_info_entry_mmap,
+       .proc_open      = snd_info_entry_open,
+       .proc_release   = snd_info_entry_release,
 };
 
 /*
@@ -421,14 +420,13 @@ static int snd_info_text_entry_release(struct inode *inode, struct file *file)
        return 0;
 }
 
-static const struct file_operations snd_info_text_entry_ops =
+static const struct proc_ops snd_info_text_entry_ops =
 {
-       .owner =                THIS_MODULE,
-       .open =                 snd_info_text_entry_open,
-       .release =              snd_info_text_entry_release,
-       .write =                snd_info_text_entry_write,
-       .llseek =               seq_lseek,
-       .read =                 seq_read,
+       .proc_open      = snd_info_text_entry_open,
+       .proc_release   = snd_info_text_entry_release,
+       .proc_write     = snd_info_text_entry_write,
+       .proc_lseek     = seq_lseek,
+       .proc_read      = seq_read,
 };
 
 static struct snd_info_entry *create_subdir(struct module *mod,
@@ -810,7 +808,7 @@ static int __snd_info_register(struct snd_info_entry *entry)
                        return -ENOMEM;
                }
        } else {
-               const struct file_operations *ops;
+               const struct proc_ops *ops;
                if (entry->content == SNDRV_INFO_CONTENT_DATA)
                        ops = &snd_info_entry_operations;
                else
index 967c689..590a46a 100644 (file)
@@ -156,7 +156,7 @@ static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
 #endif /* CONFIG_X86_X32 */
 
 struct compat_snd_pcm_status64 {
-       s32 state;
+       snd_pcm_state_t state;
        u8 rsvd[4]; /* alignment */
        s64 trigger_tstamp_sec;
        s64 trigger_tstamp_nsec;
@@ -168,7 +168,7 @@ struct compat_snd_pcm_status64 {
        u32 avail;
        u32 avail_max;
        u32 overrange;
-       s32 suspended_state;
+       snd_pcm_state_t suspended_state;
        u32 audio_tstamp_data;
        s64 audio_tstamp_sec;
        s64 audio_tstamp_nsec;
@@ -376,13 +376,13 @@ static int snd_pcm_ioctl_xfern_compat(struct snd_pcm_substream *substream,
 #ifdef CONFIG_X86_X32
 /* X32 ABI has 64bit timespec and 64bit alignment */
 struct snd_pcm_mmap_status_x32 {
-       s32 state;
+       snd_pcm_state_t state;
        s32 pad1;
        u32 hw_ptr;
        u32 pad2; /* alignment */
        s64 tstamp_sec;
        s64 tstamp_nsec;
-       s32 suspended_state;
+       snd_pcm_state_t suspended_state;
        s32 pad3;
        s64 audio_tstamp_sec;
        s64 audio_tstamp_nsec;
index bb23f50..336406b 100644 (file)
@@ -551,7 +551,8 @@ static int period_to_usecs(struct snd_pcm_runtime *runtime)
        return usecs;
 }
 
-static void snd_pcm_set_state(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_set_state(struct snd_pcm_substream *substream,
+                             snd_pcm_state_t state)
 {
        snd_pcm_stream_lock_irq(substream);
        if (substream->runtime->status->state != SNDRV_PCM_STATE_DISCONNECTED)
@@ -786,10 +787,22 @@ end:
        return err;
 }
 
+static int do_hw_free(struct snd_pcm_substream *substream)
+{
+       int result = 0;
+
+       snd_pcm_sync_stop(substream);
+       if (substream->ops->hw_free)
+               result = substream->ops->hw_free(substream);
+       if (substream->managed_buffer_alloc)
+               snd_pcm_lib_free_pages(substream);
+       return result;
+}
+
 static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
 {
        struct snd_pcm_runtime *runtime;
-       int result = 0;
+       int result;
 
        if (PCM_RUNTIME_CHECK(substream))
                return -ENXIO;
@@ -806,11 +819,7 @@ static int snd_pcm_hw_free(struct snd_pcm_substream *substream)
        snd_pcm_stream_unlock_irq(substream);
        if (atomic_read(&substream->mmap_count))
                return -EBADFD;
-       snd_pcm_sync_stop(substream);
-       if (substream->ops->hw_free)
-               result = substream->ops->hw_free(substream);
-       if (substream->managed_buffer_alloc)
-               snd_pcm_lib_free_pages(substream);
+       result = do_hw_free(substream);
        snd_pcm_set_state(substream, SNDRV_PCM_STATE_OPEN);
        pm_qos_remove_request(&substream->latency_pm_qos_req);
        return result;
@@ -1097,11 +1106,17 @@ static void snd_pcm_trigger_tstamp(struct snd_pcm_substream *substream)
        runtime->trigger_master = NULL;
 }
 
+#define ACTION_ARG_IGNORE      (__force snd_pcm_state_t)0
+
 struct action_ops {
-       int (*pre_action)(struct snd_pcm_substream *substream, int state);
-       int (*do_action)(struct snd_pcm_substream *substream, int state);
-       void (*undo_action)(struct snd_pcm_substream *substream, int state);
-       void (*post_action)(struct snd_pcm_substream *substream, int state);
+       int (*pre_action)(struct snd_pcm_substream *substream,
+                         snd_pcm_state_t state);
+       int (*do_action)(struct snd_pcm_substream *substream,
+                        snd_pcm_state_t state);
+       void (*undo_action)(struct snd_pcm_substream *substream,
+                           snd_pcm_state_t state);
+       void (*post_action)(struct snd_pcm_substream *substream,
+                           snd_pcm_state_t state);
 };
 
 /*
@@ -1111,7 +1126,8 @@ struct action_ops {
  */
 static int snd_pcm_action_group(const struct action_ops *ops,
                                struct snd_pcm_substream *substream,
-                               int state, int do_lock)
+                               snd_pcm_state_t state,
+                               bool do_lock)
 {
        struct snd_pcm_substream *s = NULL;
        struct snd_pcm_substream *s1;
@@ -1168,7 +1184,7 @@ static int snd_pcm_action_group(const struct action_ops *ops,
  */
 static int snd_pcm_action_single(const struct action_ops *ops,
                                 struct snd_pcm_substream *substream,
-                                int state)
+                                snd_pcm_state_t state)
 {
        int res;
        
@@ -1249,14 +1265,14 @@ snd_pcm_stream_group_ref(struct snd_pcm_substream *substream)
  */
 static int snd_pcm_action(const struct action_ops *ops,
                          struct snd_pcm_substream *substream,
-                         int state)
+                         snd_pcm_state_t state)
 {
        struct snd_pcm_group *group;
        int res;
 
        group = snd_pcm_stream_group_ref(substream);
        if (group)
-               res = snd_pcm_action_group(ops, substream, state, 1);
+               res = snd_pcm_action_group(ops, substream, state, true);
        else
                res = snd_pcm_action_single(ops, substream, state);
        snd_pcm_group_unref(group, substream);
@@ -1268,7 +1284,7 @@ static int snd_pcm_action(const struct action_ops *ops,
  */
 static int snd_pcm_action_lock_irq(const struct action_ops *ops,
                                   struct snd_pcm_substream *substream,
-                                  int state)
+                                  snd_pcm_state_t state)
 {
        int res;
 
@@ -1282,14 +1298,14 @@ static int snd_pcm_action_lock_irq(const struct action_ops *ops,
  */
 static int snd_pcm_action_nonatomic(const struct action_ops *ops,
                                    struct snd_pcm_substream *substream,
-                                   int state)
+                                   snd_pcm_state_t state)
 {
        int res;
 
        /* Guarantee the group members won't change during non-atomic action */
        down_read(&snd_pcm_link_rwsem);
        if (snd_pcm_stream_linked(substream))
-               res = snd_pcm_action_group(ops, substream, state, 0);
+               res = snd_pcm_action_group(ops, substream, state, false);
        else
                res = snd_pcm_action_single(ops, substream, state);
        up_read(&snd_pcm_link_rwsem);
@@ -1299,7 +1315,8 @@ static int snd_pcm_action_nonatomic(const struct action_ops *ops,
 /*
  * start callbacks
  */
-static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_pre_start(struct snd_pcm_substream *substream,
+                            snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        if (runtime->status->state != SNDRV_PCM_STATE_PREPARED)
@@ -1312,20 +1329,23 @@ static int snd_pcm_pre_start(struct snd_pcm_substream *substream, int state)
        return 0;
 }
 
-static int snd_pcm_do_start(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_do_start(struct snd_pcm_substream *substream,
+                           snd_pcm_state_t state)
 {
        if (substream->runtime->trigger_master != substream)
                return 0;
        return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_START);
 }
 
-static void snd_pcm_undo_start(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_undo_start(struct snd_pcm_substream *substream,
+                              snd_pcm_state_t state)
 {
        if (substream->runtime->trigger_master == substream)
                substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_STOP);
 }
 
-static void snd_pcm_post_start(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_post_start(struct snd_pcm_substream *substream,
+                              snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_trigger_tstamp(substream);
@@ -1369,7 +1389,8 @@ static int snd_pcm_start_lock_irq(struct snd_pcm_substream *substream)
 /*
  * stop callbacks
  */
-static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_pre_stop(struct snd_pcm_substream *substream,
+                           snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN)
@@ -1378,7 +1399,8 @@ static int snd_pcm_pre_stop(struct snd_pcm_substream *substream, int state)
        return 0;
 }
 
-static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_do_stop(struct snd_pcm_substream *substream,
+                          snd_pcm_state_t state)
 {
        if (substream->runtime->trigger_master == substream &&
            snd_pcm_running(substream))
@@ -1386,7 +1408,8 @@ static int snd_pcm_do_stop(struct snd_pcm_substream *substream, int state)
        return 0; /* unconditonally stop all substreams */
 }
 
-static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_post_stop(struct snd_pcm_substream *substream,
+                             snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        if (runtime->status->state != state) {
@@ -1457,14 +1480,17 @@ int snd_pcm_stop_xrun(struct snd_pcm_substream *substream)
 EXPORT_SYMBOL_GPL(snd_pcm_stop_xrun);
 
 /*
- * pause callbacks
+ * pause callbacks: pass boolean (to start pause or resume) as state argument
  */
-static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push)
+#define pause_pushed(state)    (__force bool)(state)
+
+static int snd_pcm_pre_pause(struct snd_pcm_substream *substream,
+                            snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        if (!(runtime->info & SNDRV_PCM_INFO_PAUSE))
                return -ENOSYS;
-       if (push) {
+       if (pause_pushed(state)) {
                if (runtime->status->state != SNDRV_PCM_STATE_RUNNING)
                        return -EBADFD;
        } else if (runtime->status->state != SNDRV_PCM_STATE_PAUSED)
@@ -1473,13 +1499,14 @@ static int snd_pcm_pre_pause(struct snd_pcm_substream *substream, int push)
        return 0;
 }
 
-static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
+static int snd_pcm_do_pause(struct snd_pcm_substream *substream,
+                           snd_pcm_state_t state)
 {
        if (substream->runtime->trigger_master != substream)
                return 0;
        /* some drivers might use hw_ptr to recover from the pause -
           update the hw_ptr now */
-       if (push)
+       if (pause_pushed(state))
                snd_pcm_update_hw_ptr(substream);
        /* The jiffies check in snd_pcm_update_hw_ptr*() is done by
         * a delta between the current jiffies, this gives a large enough
@@ -1487,23 +1514,27 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push)
         */
        substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000;
        return substream->ops->trigger(substream,
-                                      push ? SNDRV_PCM_TRIGGER_PAUSE_PUSH :
-                                             SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
+                                      pause_pushed(state) ?
+                                      SNDRV_PCM_TRIGGER_PAUSE_PUSH :
+                                      SNDRV_PCM_TRIGGER_PAUSE_RELEASE);
 }
 
-static void snd_pcm_undo_pause(struct snd_pcm_substream *substream, int push)
+static void snd_pcm_undo_pause(struct snd_pcm_substream *substream,
+                              snd_pcm_state_t state)
 {
        if (substream->runtime->trigger_master == substream)
                substream->ops->trigger(substream,
-                                       push ? SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
+                                       pause_pushed(state) ?
+                                       SNDRV_PCM_TRIGGER_PAUSE_RELEASE :
                                        SNDRV_PCM_TRIGGER_PAUSE_PUSH);
 }
 
-static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
+static void snd_pcm_post_pause(struct snd_pcm_substream *substream,
+                              snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_trigger_tstamp(substream);
-       if (push) {
+       if (pause_pushed(state)) {
                runtime->status->state = SNDRV_PCM_STATE_PAUSED;
                snd_pcm_timer_notify(substream, SNDRV_TIMER_EVENT_MPAUSE);
                wake_up(&runtime->sleep);
@@ -1524,15 +1555,24 @@ static const struct action_ops snd_pcm_action_pause = {
 /*
  * Push/release the pause for all linked streams.
  */
-static int snd_pcm_pause(struct snd_pcm_substream *substream, int push)
+static int snd_pcm_pause(struct snd_pcm_substream *substream, bool push)
+{
+       return snd_pcm_action(&snd_pcm_action_pause, substream,
+                             (__force snd_pcm_state_t)push);
+}
+
+static int snd_pcm_pause_lock_irq(struct snd_pcm_substream *substream,
+                                 bool push)
 {
-       return snd_pcm_action(&snd_pcm_action_pause, substream, push);
+       return snd_pcm_action_lock_irq(&snd_pcm_action_pause, substream,
+                                      (__force snd_pcm_state_t)push);
 }
 
 #ifdef CONFIG_PM
-/* suspend */
+/* suspend callback: state argument ignored */
 
-static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream,
+                              snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        switch (runtime->status->state) {
@@ -1548,7 +1588,8 @@ static int snd_pcm_pre_suspend(struct snd_pcm_substream *substream, int state)
        return 0;
 }
 
-static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_do_suspend(struct snd_pcm_substream *substream,
+                             snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        if (runtime->trigger_master != substream)
@@ -1559,7 +1600,8 @@ static int snd_pcm_do_suspend(struct snd_pcm_substream *substream, int state)
        return 0; /* suspend unconditionally */
 }
 
-static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_post_suspend(struct snd_pcm_substream *substream,
+                                snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_trigger_tstamp(substream);
@@ -1590,7 +1632,8 @@ static int snd_pcm_suspend(struct snd_pcm_substream *substream)
        unsigned long flags;
 
        snd_pcm_stream_lock_irqsave(substream, flags);
-       err = snd_pcm_action(&snd_pcm_action_suspend, substream, 0);
+       err = snd_pcm_action(&snd_pcm_action_suspend, substream,
+                            ACTION_ARG_IGNORE);
        snd_pcm_stream_unlock_irqrestore(substream, flags);
        return err;
 }
@@ -1634,9 +1677,10 @@ int snd_pcm_suspend_all(struct snd_pcm *pcm)
 }
 EXPORT_SYMBOL(snd_pcm_suspend_all);
 
-/* resume */
+/* resume callbacks: state argument ignored */
 
-static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_pre_resume(struct snd_pcm_substream *substream,
+                             snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        if (!(runtime->info & SNDRV_PCM_INFO_RESUME))
@@ -1645,7 +1689,8 @@ static int snd_pcm_pre_resume(struct snd_pcm_substream *substream, int state)
        return 0;
 }
 
-static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_do_resume(struct snd_pcm_substream *substream,
+                            snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        if (runtime->trigger_master != substream)
@@ -1658,14 +1703,16 @@ static int snd_pcm_do_resume(struct snd_pcm_substream *substream, int state)
        return substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_RESUME);
 }
 
-static void snd_pcm_undo_resume(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_undo_resume(struct snd_pcm_substream *substream,
+                               snd_pcm_state_t state)
 {
        if (substream->runtime->trigger_master == substream &&
            snd_pcm_running(substream))
                substream->ops->trigger(substream, SNDRV_PCM_TRIGGER_SUSPEND);
 }
 
-static void snd_pcm_post_resume(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_post_resume(struct snd_pcm_substream *substream,
+                               snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_trigger_tstamp(substream);
@@ -1683,7 +1730,8 @@ static const struct action_ops snd_pcm_action_resume = {
 
 static int snd_pcm_resume(struct snd_pcm_substream *substream)
 {
-       return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream, 0);
+       return snd_pcm_action_lock_irq(&snd_pcm_action_resume, substream,
+                                      ACTION_ARG_IGNORE);
 }
 
 #else
@@ -1724,7 +1772,9 @@ static int snd_pcm_xrun(struct snd_pcm_substream *substream)
 /*
  * reset ioctl
  */
-static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
+/* reset callbacks:  state argument ignored */
+static int snd_pcm_pre_reset(struct snd_pcm_substream *substream,
+                            snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        switch (runtime->status->state) {
@@ -1738,7 +1788,8 @@ static int snd_pcm_pre_reset(struct snd_pcm_substream *substream, int state)
        }
 }
 
-static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_do_reset(struct snd_pcm_substream *substream,
+                           snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        int err = snd_pcm_ops_ioctl(substream, SNDRV_PCM_IOCTL1_RESET, NULL);
@@ -1752,7 +1803,8 @@ static int snd_pcm_do_reset(struct snd_pcm_substream *substream, int state)
        return 0;
 }
 
-static void snd_pcm_post_reset(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_post_reset(struct snd_pcm_substream *substream,
+                              snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        runtime->control->appl_ptr = runtime->status->hw_ptr;
@@ -1769,17 +1821,20 @@ static const struct action_ops snd_pcm_action_reset = {
 
 static int snd_pcm_reset(struct snd_pcm_substream *substream)
 {
-       return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream, 0);
+       return snd_pcm_action_nonatomic(&snd_pcm_action_reset, substream,
+                                       ACTION_ARG_IGNORE);
 }
 
 /*
  * prepare ioctl
  */
-/* we use the second argument for updating f_flags */
+/* pass f_flags as state argument */
 static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
-                              int f_flags)
+                              snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
+       int f_flags = (__force int)state;
+
        if (runtime->status->state == SNDRV_PCM_STATE_OPEN ||
            runtime->status->state == SNDRV_PCM_STATE_DISCONNECTED)
                return -EBADFD;
@@ -1789,17 +1844,19 @@ static int snd_pcm_pre_prepare(struct snd_pcm_substream *substream,
        return 0;
 }
 
-static int snd_pcm_do_prepare(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_do_prepare(struct snd_pcm_substream *substream,
+                             snd_pcm_state_t state)
 {
        int err;
        snd_pcm_sync_stop(substream);
        err = substream->ops->prepare(substream);
        if (err < 0)
                return err;
-       return snd_pcm_do_reset(substream, 0);
+       return snd_pcm_do_reset(substream, state);
 }
 
-static void snd_pcm_post_prepare(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_post_prepare(struct snd_pcm_substream *substream,
+                                snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        runtime->control->appl_ptr = runtime->status->hw_ptr;
@@ -1832,7 +1889,7 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
        snd_pcm_stream_lock_irq(substream);
        switch (substream->runtime->status->state) {
        case SNDRV_PCM_STATE_PAUSED:
-               snd_pcm_pause(substream, 0);
+               snd_pcm_pause(substream, false);
                /* fallthru */
        case SNDRV_PCM_STATE_SUSPENDED:
                snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
@@ -1841,14 +1898,17 @@ static int snd_pcm_prepare(struct snd_pcm_substream *substream,
        snd_pcm_stream_unlock_irq(substream);
 
        return snd_pcm_action_nonatomic(&snd_pcm_action_prepare,
-                                       substream, f_flags);
+                                       substream,
+                                       (__force snd_pcm_state_t)f_flags);
 }
 
 /*
  * drain ioctl
  */
 
-static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state)
+/* drain init callbacks: state argument ignored */
+static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream,
+                                 snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        switch (runtime->status->state) {
@@ -1861,7 +1921,8 @@ static int snd_pcm_pre_drain_init(struct snd_pcm_substream *substream, int state
        return 0;
 }
 
-static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
+static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream,
+                                snd_pcm_state_t state)
 {
        struct snd_pcm_runtime *runtime = substream->runtime;
        if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
@@ -1887,7 +1948,9 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
        } else {
                /* stop running stream */
                if (runtime->status->state == SNDRV_PCM_STATE_RUNNING) {
-                       int new_state = snd_pcm_capture_avail(runtime) > 0 ?
+                       snd_pcm_state_t new_state;
+
+                       new_state = snd_pcm_capture_avail(runtime) > 0 ?
                                SNDRV_PCM_STATE_DRAINING : SNDRV_PCM_STATE_SETUP;
                        snd_pcm_do_stop(substream, new_state);
                        snd_pcm_post_stop(substream, new_state);
@@ -1903,7 +1966,8 @@ static int snd_pcm_do_drain_init(struct snd_pcm_substream *substream, int state)
        return 0;
 }
 
-static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream, int state)
+static void snd_pcm_post_drain_init(struct snd_pcm_substream *substream,
+                                   snd_pcm_state_t state)
 {
 }
 
@@ -1946,10 +2010,11 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
        snd_pcm_stream_lock_irq(substream);
        /* resume pause */
        if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
-               snd_pcm_pause(substream, 0);
+               snd_pcm_pause(substream, false);
 
        /* pre-start/stop - all running streams are changed to DRAINING state */
-       result = snd_pcm_action(&snd_pcm_action_drain_init, substream, 0);
+       result = snd_pcm_action(&snd_pcm_action_drain_init, substream,
+                               ACTION_ARG_IGNORE);
        if (result < 0)
                goto unlock;
        /* in non-blocking, we don't wait in ioctl but let caller poll */
@@ -2050,7 +2115,7 @@ static int snd_pcm_drop(struct snd_pcm_substream *substream)
        snd_pcm_stream_lock_irq(substream);
        /* resume pause */
        if (runtime->status->state == SNDRV_PCM_STATE_PAUSED)
-               snd_pcm_pause(substream, 0);
+               snd_pcm_pause(substream, false);
 
        snd_pcm_stop(substream, SNDRV_PCM_STATE_SETUP);
        /* runtime->control->appl_ptr = runtime->status->hw_ptr; */
@@ -2529,9 +2594,7 @@ void snd_pcm_release_substream(struct snd_pcm_substream *substream)
 
        snd_pcm_drop(substream);
        if (substream->hw_opened) {
-               if (substream->ops->hw_free &&
-                   substream->runtime->status->state != SNDRV_PCM_STATE_OPEN)
-                       substream->ops->hw_free(substream);
+               do_hw_free(substream);
                substream->ops->close(substream);
                substream->hw_opened = 0;
        }
@@ -2894,12 +2957,12 @@ static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
 }
 
 struct snd_pcm_mmap_status32 {
-       s32 state;
+       snd_pcm_state_t state;
        s32 pad1;
        u32 hw_ptr;
        s32 tstamp_sec;
        s32 tstamp_nsec;
-       s32 suspended_state;
+       snd_pcm_state_t suspended_state;
        s32 audio_tstamp_sec;
        s32 audio_tstamp_nsec;
 } __attribute__((packed));
@@ -3177,9 +3240,7 @@ static int snd_pcm_common_ioctl(struct file *file,
        case SNDRV_PCM_IOCTL_DROP:
                return snd_pcm_drop(substream);
        case SNDRV_PCM_IOCTL_PAUSE:
-               return snd_pcm_action_lock_irq(&snd_pcm_action_pause,
-                                              substream,
-                                              (int)(unsigned long)arg);
+               return snd_pcm_pause_lock_irq(substream, (unsigned long)arg);
        case SNDRV_PCM_IOCTL_WRITEI_FRAMES:
        case SNDRV_PCM_IOCTL_READI_FRAMES:
                return snd_pcm_xferi_frames_ioctl(substream, arg);
index da0bd89..02ac3f4 100644 (file)
@@ -903,7 +903,7 @@ static void print_formats(struct snd_dummy *dummy,
 {
        int i;
 
-       for (i = 0; i < SNDRV_PCM_FORMAT_LAST; i++) {
+       for (i = 0; i <= SNDRV_PCM_FORMAT_LAST; i++) {
                if (dummy->pcm_hw.formats & (1ULL << i))
                        snd_iprintf(buffer, " %s", snd_pcm_format_name(i));
        }
index d01e691..a314b03 100644 (file)
@@ -631,20 +631,27 @@ void snd_hdac_stream_sync(struct hdac_stream *azx_dev, bool start,
                nwait = 0;
                i = 0;
                list_for_each_entry(s, &bus->stream_list, list) {
-                       if (streams & (1 << i)) {
-                               if (start) {
-                                       /* check FIFO gets ready */
-                                       if (!(snd_hdac_stream_readb(s, SD_STS) &
-                                             SD_STS_FIFO_READY))
-                                               nwait++;
-                               } else {
-                                       /* check RUN bit is cleared */
-                                       if (snd_hdac_stream_readb(s, SD_CTL) &
-                                           SD_CTL_DMA_START)
-                                               nwait++;
+                       if (!(streams & (1 << i++)))
+                               continue;
+
+                       if (start) {
+                               /* check FIFO gets ready */
+                               if (!(snd_hdac_stream_readb(s, SD_STS) &
+                                     SD_STS_FIFO_READY))
+                                       nwait++;
+                       } else {
+                               /* check RUN bit is cleared */
+                               if (snd_hdac_stream_readb(s, SD_CTL) &
+                                   SD_CTL_DMA_START) {
+                                       nwait++;
+                                       /*
+                                        * Perform stream reset if DMA RUN
+                                        * bit not cleared within given timeout
+                                        */
+                                       if (timeout == 1)
+                                               snd_hdac_stream_reset(s);
                                }
                        }
-                       i++;
                }
                if (!nwait)
                        break;
index 6b7ff4a..4e76ed0 100644 (file)
@@ -463,7 +463,7 @@ static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode,
        u_int32_t *code;
        if (snd_BUG_ON(*ptr >= 512))
                return;
-       code = (u_int32_t __force *)icode->code + (*ptr) * 2;
+       code = icode->code + (*ptr) * 2;
        set_bit(*ptr, icode->code_valid);
        code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff);
        code[1] = ((op & 0x0f) << 20) | ((r & 0x3ff) << 10) | (a & 0x3ff);
@@ -480,7 +480,7 @@ static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode,
        u_int32_t *code;
        if (snd_BUG_ON(*ptr >= 1024))
                return;
-       code = (u_int32_t __force *)icode->code + (*ptr) * 2;
+       code = icode->code + (*ptr) * 2;
        set_bit(*ptr, icode->code_valid);
        code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff);
        code[1] = ((op & 0x0f) << 24) | ((r & 0x7ff) << 12) | (a & 0x7ff);
@@ -513,8 +513,8 @@ static int snd_emu10k1_gpr_poke(struct snd_emu10k1 *emu,
                if (!test_bit(gpr, icode->gpr_valid))
                        continue;
                if (in_kernel)
-                       val = *(__force u32 *)&icode->gpr_map[gpr];
-               else if (get_user(val, &icode->gpr_map[gpr]))
+                       val = icode->gpr_map[gpr];
+               else if (get_user(val, (__user u32 *)&icode->gpr_map[gpr]))
                        return -EFAULT;
                snd_emu10k1_ptr_write(emu, emu->gpr_base + gpr, 0, val);
        }
@@ -530,7 +530,7 @@ static int snd_emu10k1_gpr_peek(struct snd_emu10k1 *emu,
        for (gpr = 0; gpr < (emu->audigy ? 0x200 : 0x100); gpr++) {
                set_bit(gpr, icode->gpr_valid);
                val = snd_emu10k1_ptr_read(emu, emu->gpr_base + gpr, 0);
-               if (put_user(val, &icode->gpr_map[gpr]))
+               if (put_user(val, (__user u32 *)&icode->gpr_map[gpr]))
                        return -EFAULT;
        }
        return 0;
@@ -547,11 +547,11 @@ static int snd_emu10k1_tram_poke(struct snd_emu10k1 *emu,
                if (!test_bit(tram, icode->tram_valid))
                        continue;
                if (in_kernel) {
-                       val = *(__force u32 *)&icode->tram_data_map[tram];
-                       addr = *(__force u32 *)&icode->tram_addr_map[tram];
+                       val = icode->tram_data_map[tram];
+                       addr = icode->tram_addr_map[tram];
                } else {
-                       if (get_user(val, &icode->tram_data_map[tram]) ||
-                           get_user(addr, &icode->tram_addr_map[tram]))
+                       if (get_user(val, (__user __u32 *)&icode->tram_data_map[tram]) ||
+                           get_user(addr, (__user __u32 *)&icode->tram_addr_map[tram]))
                                return -EFAULT;
                }
                snd_emu10k1_ptr_write(emu, TANKMEMDATAREGBASE + tram, 0, val);
@@ -581,8 +581,8 @@ static int snd_emu10k1_tram_peek(struct snd_emu10k1 *emu,
                        addr = snd_emu10k1_ptr_read(emu, TANKMEMADDRREGBASE + tram, 0) >> 12;
                        addr |= snd_emu10k1_ptr_read(emu, A_TANKMEMCTLREGBASE + tram, 0) << 20;
                }
-               if (put_user(val, &icode->tram_data_map[tram]) ||
-                   put_user(addr, &icode->tram_addr_map[tram]))
+               if (put_user(val, (__user u32 *)&icode->tram_data_map[tram]) ||
+                   put_user(addr, (__user u32 *)&icode->tram_addr_map[tram]))
                        return -EFAULT;
        }
        return 0;
@@ -598,11 +598,11 @@ static int snd_emu10k1_code_poke(struct snd_emu10k1 *emu,
                if (!test_bit(pc / 2, icode->code_valid))
                        continue;
                if (in_kernel) {
-                       lo = *(__force u32 *)&icode->code[pc + 0];
-                       hi = *(__force u32 *)&icode->code[pc + 1];
+                       lo = icode->code[pc + 0];
+                       hi = icode->code[pc + 1];
                } else {
-                       if (get_user(lo, &icode->code[pc + 0]) ||
-                           get_user(hi, &icode->code[pc + 1]))
+                       if (get_user(lo, (__user u32 *)&icode->code[pc + 0]) ||
+                           get_user(hi, (__user u32 *)&icode->code[pc + 1]))
                                return -EFAULT;
                }
                snd_emu10k1_efx_write(emu, pc + 0, lo);
@@ -619,17 +619,21 @@ static int snd_emu10k1_code_peek(struct snd_emu10k1 *emu,
        memset(icode->code_valid, 0, sizeof(icode->code_valid));
        for (pc = 0; pc < (emu->audigy ? 2*1024 : 2*512); pc += 2) {
                set_bit(pc / 2, icode->code_valid);
-               if (put_user(snd_emu10k1_efx_read(emu, pc + 0), &icode->code[pc + 0]))
+               if (put_user(snd_emu10k1_efx_read(emu, pc + 0),
+                            (__user u32 *)&icode->code[pc + 0]))
                        return -EFAULT;
-               if (put_user(snd_emu10k1_efx_read(emu, pc + 1), &icode->code[pc + 1]))
+               if (put_user(snd_emu10k1_efx_read(emu, pc + 1),
+                            (__user u32 *)&icode->code[pc + 1]))
                        return -EFAULT;
        }
        return 0;
 }
 
 static struct snd_emu10k1_fx8010_ctl *
-snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu, struct emu10k1_ctl_elem_id *id)
+snd_emu10k1_look_for_ctl(struct snd_emu10k1 *emu,
+                        struct emu10k1_ctl_elem_id *_id)
 {
+       struct snd_ctl_elem_id *id = (struct snd_ctl_elem_id *)_id;
        struct snd_emu10k1_fx8010_ctl *ctl;
        struct snd_kcontrol *kcontrol;
 
@@ -672,41 +676,60 @@ static unsigned int *copy_tlv(const unsigned int __user *_tlv, bool in_kernel)
 }
 
 static int copy_gctl(struct snd_emu10k1 *emu,
-                    struct snd_emu10k1_fx8010_control_gpr *gctl,
-                    struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
+                    struct snd_emu10k1_fx8010_control_gpr *dst,
+                    struct snd_emu10k1_fx8010_control_gpr *src,
                     int idx, bool in_kernel)
 {
-       struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
+       struct snd_emu10k1_fx8010_control_gpr __user *_src;
+       struct snd_emu10k1_fx8010_control_old_gpr *octl;
+       struct snd_emu10k1_fx8010_control_old_gpr __user *_octl;
 
+       _src = (struct snd_emu10k1_fx8010_control_gpr __user *)src;
        if (emu->support_tlv) {
                if (in_kernel)
-                       memcpy(gctl, (__force void *)&_gctl[idx], sizeof(*gctl));
-               else if (copy_from_user(gctl, &_gctl[idx], sizeof(*gctl)))
+                       *dst = src[idx];
+               else if (copy_from_user(dst, &_src[idx], sizeof(*src)))
                        return -EFAULT;
                return 0;
        }
 
-       octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
+       octl = (struct snd_emu10k1_fx8010_control_old_gpr *)src;
+       _octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)octl;
        if (in_kernel)
-               memcpy(gctl, (__force void *)&octl[idx], sizeof(*octl));
-       else if (copy_from_user(gctl, &octl[idx], sizeof(*octl)))
+               memcpy(dst, &octl[idx], sizeof(*octl));
+       else if (copy_from_user(dst, &_octl[idx], sizeof(*octl)))
                return -EFAULT;
-       gctl->tlv = NULL;
+       dst->tlv = NULL;
        return 0;
 }
 
 static int copy_gctl_to_user(struct snd_emu10k1 *emu,
-                    struct snd_emu10k1_fx8010_control_gpr __user *_gctl,
-                    struct snd_emu10k1_fx8010_control_gpr *gctl,
+                    struct snd_emu10k1_fx8010_control_gpr *dst,
+                    struct snd_emu10k1_fx8010_control_gpr *src,
                     int idx)
 {
+       struct snd_emu10k1_fx8010_control_gpr __user *_dst;
        struct snd_emu10k1_fx8010_control_old_gpr __user *octl;
 
+       _dst = (struct snd_emu10k1_fx8010_control_gpr __user *)dst;
        if (emu->support_tlv)
-               return copy_to_user(&_gctl[idx], gctl, sizeof(*gctl));
+               return copy_to_user(&_dst[idx], src, sizeof(*src));
        
-       octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)_gctl;
-       return copy_to_user(&octl[idx], gctl, sizeof(*octl));
+       octl = (struct snd_emu10k1_fx8010_control_old_gpr __user *)dst;
+       return copy_to_user(&octl[idx], src, sizeof(*octl));
+}
+
+static int copy_ctl_elem_id(const struct emu10k1_ctl_elem_id *list, int i,
+                           struct emu10k1_ctl_elem_id *ret, bool in_kernel)
+{
+       struct emu10k1_ctl_elem_id __user *_id =
+               (struct emu10k1_ctl_elem_id __user *)&list[i];
+
+       if (in_kernel)
+               *ret = list[i];
+       else if (copy_from_user(ret, _id, sizeof(*ret)))
+               return -EFAULT;
+       return 0;
 }
 
 static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
@@ -714,17 +737,16 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
                                       bool in_kernel)
 {
        unsigned int i;
-       struct emu10k1_ctl_elem_id __user *_id;
        struct emu10k1_ctl_elem_id id;
        struct snd_emu10k1_fx8010_control_gpr *gctl;
+       struct snd_ctl_elem_id *gctl_id;
        int err;
        
-       _id = (__force struct emu10k1_ctl_elem_id __user *)icode->gpr_del_controls;
-       for (i = 0; i < icode->gpr_del_control_count; i++, _id++) {
-               if (in_kernel)
-                       id = *(__force struct emu10k1_ctl_elem_id *)_id;
-               else if (copy_from_user(&id, _id, sizeof(id)))
-                       return -EFAULT;
+       for (i = 0; i < icode->gpr_del_control_count; i++) {
+               err = copy_ctl_elem_id(icode->gpr_del_controls, i, &id,
+                                      in_kernel);
+               if (err < 0)
+                       return err;
                if (snd_emu10k1_look_for_ctl(emu, &id) == NULL)
                        return -ENOENT;
        }
@@ -740,16 +762,16 @@ static int snd_emu10k1_verify_controls(struct snd_emu10k1 *emu,
                }
                if (snd_emu10k1_look_for_ctl(emu, &gctl->id))
                        continue;
+               gctl_id = (struct snd_ctl_elem_id *)&gctl->id;
                down_read(&emu->card->controls_rwsem);
-               if (snd_ctl_find_id(emu->card,
-                                   (struct snd_ctl_elem_id *)&gctl->id)) {
+               if (snd_ctl_find_id(emu->card, gctl_id)) {
                        up_read(&emu->card->controls_rwsem);
                        err = -EEXIST;
                        goto __error;
                }
                up_read(&emu->card->controls_rwsem);
-               if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
-                   gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
+               if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
+                   gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {
                        err = -EINVAL;
                        goto __error;
                }
@@ -784,6 +806,7 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
 {
        unsigned int i, j;
        struct snd_emu10k1_fx8010_control_gpr *gctl;
+       struct snd_ctl_elem_id *gctl_id;
        struct snd_emu10k1_fx8010_ctl *ctl, *nctl;
        struct snd_kcontrol_new knew;
        struct snd_kcontrol *kctl;
@@ -804,24 +827,25 @@ static int snd_emu10k1_add_controls(struct snd_emu10k1 *emu,
                        err = -EFAULT;
                        goto __error;
                }
-               if (gctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
-                   gctl->id.iface != SNDRV_CTL_ELEM_IFACE_PCM) {
+               gctl_id = (struct snd_ctl_elem_id *)&gctl->id;
+               if (gctl_id->iface != SNDRV_CTL_ELEM_IFACE_MIXER &&
+                   gctl_id->iface != SNDRV_CTL_ELEM_IFACE_PCM) {
                        err = -EINVAL;
                        goto __error;
                }
-               if (! gctl->id.name[0]) {
+               if (!*gctl_id->name) {
                        err = -EINVAL;
                        goto __error;
                }
                ctl = snd_emu10k1_look_for_ctl(emu, &gctl->id);
                memset(&knew, 0, sizeof(knew));
-               knew.iface = gctl->id.iface;
-               knew.name = gctl->id.name;
-               knew.index = gctl->id.index;
-               knew.device = gctl->id.device;
-               knew.subdevice = gctl->id.subdevice;
+               knew.iface = gctl_id->iface;
+               knew.name = gctl_id->name;
+               knew.index = gctl_id->index;
+               knew.device = gctl_id->device;
+               knew.subdevice = gctl_id->subdevice;
                knew.info = snd_emu10k1_gpr_ctl_info;
-               knew.tlv.p = copy_tlv((__force const unsigned int __user *)gctl->tlv, in_kernel);
+               knew.tlv.p = copy_tlv((const unsigned int __user *)gctl->tlv, in_kernel);
                if (knew.tlv.p)
                        knew.access = SNDRV_CTL_ELEM_ACCESS_READWRITE |
                                SNDRV_CTL_ELEM_ACCESS_TLV_READ;
@@ -878,17 +902,15 @@ static int snd_emu10k1_del_controls(struct snd_emu10k1 *emu,
 {
        unsigned int i;
        struct emu10k1_ctl_elem_id id;
-       struct emu10k1_ctl_elem_id __user *_id;
        struct snd_emu10k1_fx8010_ctl *ctl;
        struct snd_card *card = emu->card;
+       int err;
        
-       _id = (__force struct emu10k1_ctl_elem_id __user *)icode->gpr_del_controls;
-
-       for (i = 0; i < icode->gpr_del_control_count; i++, _id++) {
-               if (in_kernel)
-                       id = *(__force struct emu10k1_ctl_elem_id *)_id;
-               else if (copy_from_user(&id, _id, sizeof(id)))
-                       return -EFAULT;
+       for (i = 0; i < icode->gpr_del_control_count; i++) {
+               err = copy_ctl_elem_id(icode->gpr_del_controls, i, &id,
+                                      in_kernel);
+               if (err < 0)
+                       return err;
                down_write(&card->controls_rwsem);
                ctl = snd_emu10k1_look_for_ctl(emu, &id);
                if (ctl)
@@ -917,7 +939,7 @@ static int snd_emu10k1_list_controls(struct snd_emu10k1 *emu,
                    i < icode->gpr_list_control_count) {
                        memset(gctl, 0, sizeof(*gctl));
                        id = &ctl->kcontrol->id;
-                       gctl->id.iface = id->iface;
+                       gctl->id.iface = (__force int)id->iface;
                        strlcpy(gctl->id.name, id->name, sizeof(gctl->id.name));
                        gctl->id.index = id->index;
                        gctl->id.device = id->device;
@@ -1095,7 +1117,7 @@ static void
 snd_emu10k1_init_mono_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
                              const char *name, int gpr, int defval)
 {
-       ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
        strcpy(ctl->id.name, name);
        ctl->vcount = ctl->count = 1;
        ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
@@ -1116,7 +1138,7 @@ static void
 snd_emu10k1_init_stereo_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
                                const char *name, int gpr, int defval)
 {
-       ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
        strcpy(ctl->id.name, name);
        ctl->vcount = ctl->count = 2;
        ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
@@ -1138,7 +1160,7 @@ static void
 snd_emu10k1_init_mono_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
                                    const char *name, int gpr, int defval)
 {
-       ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
        strcpy(ctl->id.name, name);
        ctl->vcount = ctl->count = 1;
        ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
@@ -1151,7 +1173,7 @@ static void
 snd_emu10k1_init_stereo_onoff_control(struct snd_emu10k1_fx8010_control_gpr *ctl,
                                      const char *name, int gpr, int defval)
 {
-       ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
        strcpy(ctl->id.name, name);
        ctl->vcount = ctl->count = 2;
        ctl->gpr[0] = gpr + 0; ctl->value[0] = defval;
@@ -1204,8 +1226,8 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
        if (!icode)
                return err;
 
-       icode->gpr_map = (u_int32_t __user *) kcalloc(512 + 256 + 256 + 2 * 1024,
-                                                     sizeof(u_int32_t), GFP_KERNEL);
+       icode->gpr_map = kcalloc(512 + 256 + 256 + 2 * 1024,
+                                sizeof(u_int32_t), GFP_KERNEL);
        if (!icode->gpr_map)
                goto __err_gpr;
        controls = kcalloc(SND_EMU10K1_GPR_CONTROLS,
@@ -1213,7 +1235,7 @@ static int _snd_emu10k1_audigy_init_efx(struct snd_emu10k1 *emu)
        if (!controls)
                goto __err_ctrls;
 
-       gpr_map = (u32 __force *)icode->gpr_map;
+       gpr_map = icode->gpr_map;
 
        icode->tram_data_map = icode->gpr_map + 512;
        icode->tram_addr_map = icode->tram_data_map + 256;
@@ -1468,7 +1490,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
        
 
        ctl = &controls[nctl + 0];
-       ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
        strcpy(ctl->id.name, "Tone Control - Bass");
        ctl->vcount = 2;
        ctl->count = 10;
@@ -1477,7 +1499,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
        ctl->value[0] = ctl->value[1] = 20;
        ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
        ctl = &controls[nctl + 1];
-       ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
        strcpy(ctl->id.name, "Tone Control - Treble");
        ctl->vcount = 2;
        ctl->count = 10;
@@ -1758,7 +1780,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
                A_OP(icode, &ptr, 0x0f, 0xc0, 0xc0, 0xcf, 0xc0);
 
        icode->gpr_add_control_count = nctl;
-       icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
+       icode->gpr_add_controls = controls;
        emu->support_tlv = 1; /* support TLV */
        err = snd_emu10k1_icode_poke(emu, icode, true);
        emu->support_tlv = 0; /* clear again */
@@ -1766,7 +1788,7 @@ A_OP(icode, &ptr, iMAC0, A_GPR(var), A_GPR(var), A_GPR(vol), A_EXTIN(input))
 __err:
        kfree(controls);
 __err_ctrls:
-       kfree((void __force *)icode->gpr_map);
+       kfree(icode->gpr_map);
 __err_gpr:
        kfree(icode);
        return err;
@@ -1839,8 +1861,8 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
        if (!icode)
                return err;
 
-       icode->gpr_map = (u_int32_t __user *) kcalloc(256 + 160 + 160 + 2 * 512,
-                                                     sizeof(u_int32_t), GFP_KERNEL);
+       icode->gpr_map = kcalloc(256 + 160 + 160 + 2 * 512,
+                                sizeof(u_int32_t), GFP_KERNEL);
        if (!icode->gpr_map)
                goto __err_gpr;
 
@@ -1854,7 +1876,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
        if (!ipcm)
                goto __err_ipcm;
 
-       gpr_map = (u32 __force *)icode->gpr_map;
+       gpr_map = icode->gpr_map;
 
        icode->tram_data_map = icode->gpr_map + 256;
        icode->tram_addr_map = icode->tram_data_map + 160;
@@ -2188,7 +2210,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
        OP(icode, &ptr, iACC3, GPR(playback + SND_EMU10K1_PLAYBACK_CHANNELS + 5), GPR(playback + 5), C_00000000, C_00000000); /* LFE */
 
        ctl = &controls[i + 0];
-       ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
        strcpy(ctl->id.name, "Tone Control - Bass");
        ctl->vcount = 2;
        ctl->count = 10;
@@ -2198,7 +2220,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
        ctl->tlv = snd_emu10k1_bass_treble_db_scale;
        ctl->translation = EMU10K1_GPR_TRANSLATION_BASS;
        ctl = &controls[i + 1];
-       ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
+       ctl->id.iface = (__force int)SNDRV_CTL_ELEM_IFACE_MIXER;
        strcpy(ctl->id.name, "Tone Control - Treble");
        ctl->vcount = 2;
        ctl->count = 10;
@@ -2384,7 +2406,7 @@ static int _snd_emu10k1_init_efx(struct snd_emu10k1 *emu)
        if ((err = snd_emu10k1_fx8010_tram_setup(emu, ipcm->buffer_size)) < 0)
                goto __err;
        icode->gpr_add_control_count = i;
-       icode->gpr_add_controls = (struct snd_emu10k1_fx8010_control_gpr __user *)controls;
+       icode->gpr_add_controls = controls;
        emu->support_tlv = 1; /* support TLV */
        err = snd_emu10k1_icode_poke(emu, icode, true);
        emu->support_tlv = 0; /* clear again */
@@ -2395,7 +2417,7 @@ __err:
 __err_ipcm:
        kfree(controls);
 __err_ctrls:
-       kfree((void __force *)icode->gpr_map);
+       kfree(icode->gpr_map);
 __err_gpr:
        kfree(icode);
        return err;
index 9757667..2609e39 100644 (file)
@@ -1110,16 +1110,23 @@ irqreturn_t azx_interrupt(int irq, void *dev_id)
                if (snd_hdac_bus_handle_stream_irq(bus, status, stream_update))
                        active = true;
 
-               /* clear rirb int */
                status = azx_readb(chip, RIRBSTS);
                if (status & RIRB_INT_MASK) {
+                       /*
+                        * Clearing the interrupt status here ensures that no
+                        * interrupt gets masked after the RIRB wp is read in
+                        * snd_hdac_bus_update_rirb. This avoids a possible
+                        * race condition where codec response in RIRB may
+                        * remain unserviced by IRQ, eventually falling back
+                        * to polling mode in azx_rirb_get_response.
+                        */
+                       azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
                        active = true;
                        if (status & RIRB_INT_RESPONSE) {
                                if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND)
                                        udelay(80);
                                snd_hdac_bus_update_rirb(bus);
                        }
-                       azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
                }
        } while (active && ++repeat < 10);
 
index b5e8d43..92a042e 100644 (file)
@@ -2451,6 +2451,8 @@ static const struct pci_device_id azx_ids[] = {
        /* Jasperlake */
        { PCI_DEVICE(0x8086, 0x38c8),
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
+       { PCI_DEVICE(0x8086, 0x4dc8),
+         .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
        /* Tigerlake */
        { PCI_DEVICE(0x8086, 0xa0c8),
          .driver_data = AZX_DRIVER_SKL | AZX_DCAPS_INTEL_SKYLAKE},
index 48bddc2..5119a9a 100644 (file)
@@ -1550,6 +1550,34 @@ static bool update_eld(struct hda_codec *codec,
        return eld_changed;
 }
 
+static struct snd_jack *pin_idx_to_pcm_jack(struct hda_codec *codec,
+                                           struct hdmi_spec_per_pin *per_pin)
+{
+       struct hdmi_spec *spec = codec->spec;
+       struct snd_jack *jack = NULL;
+       struct hda_jack_tbl *jack_tbl;
+
+       /* if !dyn_pcm_assign, get jack from hda_jack_tbl
+        * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not
+        * NULL even after snd_hda_jack_tbl_clear() is called to
+        * free snd_jack. This may cause access invalid memory
+        * when calling snd_jack_report
+        */
+       if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign) {
+               jack = spec->pcm_rec[per_pin->pcm_idx].jack;
+       } else if (!spec->dyn_pcm_assign) {
+               /*
+                * jack tbl doesn't support DP MST
+                * DP MST will use dyn_pcm_assign,
+                * so DP MST will never come here
+                */
+               jack_tbl = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid,
+                                                   per_pin->dev_id);
+               if (jack_tbl)
+                       jack = jack_tbl->jack;
+       }
+       return jack;
+}
 /* update ELD and jack state via HD-audio verbs */
 static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
                                         int repoll)
@@ -1571,6 +1599,7 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
        int present;
        bool ret;
        bool do_repoll = false;
+       struct snd_jack *pcm_jack = NULL;
 
        present = snd_hda_jack_pin_sense(codec, pin_nid, dev_id);
 
@@ -1598,10 +1627,19 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
                        do_repoll = true;
        }
 
-       if (do_repoll)
+       if (do_repoll) {
                schedule_delayed_work(&per_pin->work, msecs_to_jiffies(300));
-       else
+       } else {
+               /*
+                * pcm_idx >=0 before update_eld() means it is in monitor
+                * disconnected event. Jack must be fetched before
+                * update_eld().
+                */
+               pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
                update_eld(codec, per_pin, eld);
+               if (!pcm_jack)
+                       pcm_jack = pin_idx_to_pcm_jack(codec, per_pin);
+       }
 
        ret = !repoll || !eld->monitor_present || eld->eld_valid;
 
@@ -1610,38 +1648,32 @@ static bool hdmi_present_sense_via_verbs(struct hdmi_spec_per_pin *per_pin,
                jack->block_report = !ret;
                jack->pin_sense = (eld->monitor_present && eld->eld_valid) ?
                        AC_PINSENSE_PRESENCE : 0;
-       }
-       mutex_unlock(&per_pin->lock);
-       return ret;
-}
 
-static struct snd_jack *pin_idx_to_jack(struct hda_codec *codec,
-                                struct hdmi_spec_per_pin *per_pin)
-{
-       struct hdmi_spec *spec = codec->spec;
-       struct snd_jack *jack = NULL;
-       struct hda_jack_tbl *jack_tbl;
+               if (spec->dyn_pcm_assign && pcm_jack && !do_repoll) {
+                       int state = 0;
+
+                       if (jack->pin_sense & AC_PINSENSE_PRESENCE)
+                               state = SND_JACK_AVOUT;
+                       snd_jack_report(pcm_jack, state);
+               }
 
-       /* if !dyn_pcm_assign, get jack from hda_jack_tbl
-        * in !dyn_pcm_assign case, spec->pcm_rec[].jack is not
-        * NULL even after snd_hda_jack_tbl_clear() is called to
-        * free snd_jack. This may cause access invalid memory
-        * when calling snd_jack_report
-        */
-       if (per_pin->pcm_idx >= 0 && spec->dyn_pcm_assign)
-               jack = spec->pcm_rec[per_pin->pcm_idx].jack;
-       else if (!spec->dyn_pcm_assign) {
                /*
-                * jack tbl doesn't support DP MST
-                * DP MST will use dyn_pcm_assign,
-                * so DP MST will never come here
+                * snd_hda_jack_pin_sense() call at the beginning of this
+                * function, updates jack->pins_sense and clears
+                * jack->jack_dirty, therefore snd_hda_jack_report_sync() will
+                * not override the jack->pin_sense.
+                *
+                * snd_hda_jack_report_sync() is superfluous for dyn_pcm_assign
+                * case. The jack->pin_sense update was already performed, and
+                * hda_jack->jack is NULL for dyn_pcm_assign.
+                *
+                * Don't call snd_hda_jack_report_sync() for
+                * dyn_pcm_assign.
                 */
-               jack_tbl = snd_hda_jack_tbl_get_mst(codec, per_pin->pin_nid,
-                                                   per_pin->dev_id);
-               if (jack_tbl)
-                       jack = jack_tbl->jack;
+               ret = ret && !spec->dyn_pcm_assign;
        }
-       return jack;
+       mutex_unlock(&per_pin->lock);
+       return ret;
 }
 
 /* update ELD and jack state via audio component */
@@ -1677,10 +1709,10 @@ static void sync_eld_via_acomp(struct hda_codec *codec,
        /* pcm_idx >=0 before update_eld() means it is in monitor
         * disconnected event. Jack must be fetched before update_eld()
         */
-       jack = pin_idx_to_jack(codec, per_pin);
+       jack = pin_idx_to_pcm_jack(codec, per_pin);
        changed = update_eld(codec, per_pin, eld);
        if (jack == NULL)
-               jack = pin_idx_to_jack(codec, per_pin);
+               jack = pin_idx_to_pcm_jack(codec, per_pin);
        if (changed && jack)
                snd_jack_report(jack,
                                (eld->monitor_present && eld->eld_valid) ?
@@ -4256,6 +4288,7 @@ HDA_CODEC_ENTRY(0x8086280c, "Cannonlake HDMI",    patch_i915_glk_hdmi),
 HDA_CODEC_ENTRY(0x8086280d, "Geminilake HDMI", patch_i915_glk_hdmi),
 HDA_CODEC_ENTRY(0x8086280f, "Icelake HDMI",    patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x80862812, "Tigerlake HDMI",  patch_i915_tgl_hdmi),
+HDA_CODEC_ENTRY(0x8086281a, "Jasperlake HDMI", patch_i915_icl_hdmi),
 HDA_CODEC_ENTRY(0x80862880, "CedarTrail HDMI", patch_generic_hdmi),
 HDA_CODEC_ENTRY(0x80862882, "Valleyview2 HDMI",        patch_i915_byt_hdmi),
 HDA_CODEC_ENTRY(0x80862883, "Braswell HDMI",   patch_i915_byt_hdmi),
index 3b38a13..4770fb3 100644 (file)
@@ -9111,6 +9111,7 @@ static const struct snd_hda_pin_quirk alc662_pin_fixup_tbl[] = {
        SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
                {0x14, 0x01014010},
                {0x17, 0x90170150},
+               {0x19, 0x02a11060},
                {0x1b, 0x01813030},
                {0x21, 0x02211020}),
        SND_HDA_PIN_QUIRK(0x10ec0671, 0x103c, "HP cPC", ALC671_FIXUP_HP_HEADSET_MIC2,
index c1e15ec..cc06f0a 100644 (file)
@@ -4802,7 +4802,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
                break;
        }
        case SNDRV_HDSP_IOCTL_UPLOAD_FIRMWARE: {
-               struct hdsp_firmware __user *firmware;
+               struct hdsp_firmware firmware;
                u32 __user *firmware_data;
                int err;
 
@@ -4815,10 +4815,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne
 
                dev_info(hdsp->card->dev,
                         "initializing firmware upload\n");
-               firmware = (struct hdsp_firmware __user *)argp;
-
-               if (get_user(firmware_data, (__force void __user **)&firmware->firmware_data))
+               if (copy_from_user(&firmware, argp, sizeof(firmware)))
                        return -EFAULT;
+               firmware_data = (u32 __user *)firmware.firmware_data;
 
                if (hdsp_check_for_iobox (hdsp))
                        return -EIO;
index bf51cad..31cd400 100644 (file)
@@ -234,30 +234,32 @@ static int acp3x_i2s_trigger(struct snd_pcm_substream *substream,
                        switch (rtd->i2s_instance) {
                        case I2S_BT_INSTANCE:
                                reg_val = mmACP_BTTDM_ITER;
-                               ier_val = mmACP_BTTDM_IER;
                                break;
                        case I2S_SP_INSTANCE:
                        default:
                                reg_val = mmACP_I2STDM_ITER;
-                               ier_val = mmACP_I2STDM_IER;
                        }
 
                } else {
                        switch (rtd->i2s_instance) {
                        case I2S_BT_INSTANCE:
                                reg_val = mmACP_BTTDM_IRER;
-                               ier_val = mmACP_BTTDM_IER;
                                break;
                        case I2S_SP_INSTANCE:
                        default:
                                reg_val = mmACP_I2STDM_IRER;
-                               ier_val = mmACP_I2STDM_IER;
                        }
                }
                val = rv_readl(rtd->acp3x_base + reg_val);
                val = val & ~BIT(0);
                rv_writel(val, rtd->acp3x_base + reg_val);
-               rv_writel(0, rtd->acp3x_base + ier_val);
+
+               if (!(rv_readl(rtd->acp3x_base + mmACP_BTTDM_ITER) & BIT(0)) &&
+                    !(rv_readl(rtd->acp3x_base + mmACP_BTTDM_IRER) & BIT(0)))
+                       rv_writel(0, rtd->acp3x_base + mmACP_BTTDM_IER);
+               if (!(rv_readl(rtd->acp3x_base + mmACP_I2STDM_ITER) & BIT(0)) &&
+                    !(rv_readl(rtd->acp3x_base + mmACP_I2STDM_IRER) & BIT(0)))
+                       rv_writel(0, rtd->acp3x_base + mmACP_I2STDM_IER);
                ret = 0;
                break;
        default:
index 5c3ec3c..aecc3c0 100644 (file)
@@ -349,13 +349,6 @@ static int acp3x_dma_close(struct snd_soc_component *component,
        component = snd_soc_rtdcom_lookup(prtd, DRV_NAME);
        adata = dev_get_drvdata(component->dev);
 
-       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-               adata->play_stream = NULL;
-               adata->i2ssp_play_stream = NULL;
-       } else {
-               adata->capture_stream = NULL;
-               adata->i2ssp_capture_stream = NULL;
-       }
 
        /* Disable ACP irq, when the current stream is being closed and
         * another stream is also not active.
@@ -363,6 +356,13 @@ static int acp3x_dma_close(struct snd_soc_component *component,
        if (!adata->play_stream && !adata->capture_stream &&
                !adata->i2ssp_play_stream && !adata->i2ssp_capture_stream)
                rv_writel(0, adata->acp3x_base + mmACP_EXTERNAL_INTR_ENB);
+       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
+               adata->play_stream = NULL;
+               adata->i2ssp_play_stream = NULL;
+       } else {
+               adata->capture_stream = NULL;
+               adata->i2ssp_capture_stream = NULL;
+       }
        return 0;
 }
 
index c9eb683..7e90f5d 100644 (file)
@@ -214,7 +214,7 @@ config SND_SOC_ALL_CODECS
        select SND_SOC_UDA134X
        select SND_SOC_UDA1380 if I2C
        select SND_SOC_WCD9335 if SLIMBUS
-       select SND_SOC_WCD934X if MFD_WCD934X
+       select SND_SOC_WCD934X if MFD_WCD934X && COMMON_CLK
        select SND_SOC_WL1273 if MFD_WL1273_CORE
        select SND_SOC_WM0010 if SPI_MASTER
        select SND_SOC_WM1250_EV1 if I2C
@@ -1334,6 +1334,7 @@ config SND_SOC_WCD9335
 
 config SND_SOC_WCD934X
        tristate "WCD9340/WCD9341 Codec"
+       depends on COMMON_CLK
        depends on MFD_WCD934X
        help
          The WCD9340/9341 is a audio codec IC Integrated in
index e8c5fda..979cfb1 100644 (file)
@@ -295,8 +295,7 @@ static int ak4104_spi_probe(struct spi_device *spi)
 
        reset_gpiod = devm_gpiod_get_optional(&spi->dev, "reset",
                                              GPIOD_OUT_HIGH);
-       if (IS_ERR(reset_gpiod) &&
-           PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
+       if (PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
        /* read the 'reserved' register - according to the datasheet, it
index 793a14d..5f25b9f 100644 (file)
@@ -681,8 +681,7 @@ static int cs4270_i2c_probe(struct i2c_client *i2c_client,
 
        reset_gpiod = devm_gpiod_get_optional(&i2c_client->dev, "reset",
                                              GPIOD_OUT_HIGH);
-       if (IS_ERR(reset_gpiod) &&
-           PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
+       if (PTR_ERR(reset_gpiod) == -EPROBE_DEFER)
                return -EPROBE_DEFER;
 
        cs4270->regmap = devm_regmap_init_i2c(i2c_client, &cs4270_regmap);
index 0313e11..5bc2c64 100644 (file)
@@ -52,7 +52,8 @@ static void max98090_shdn_restore_locked(struct max98090_priv *max98090)
 
 static void max98090_shdn_save(struct max98090_priv *max98090)
 {
-       mutex_lock(&max98090->component->card->dapm_mutex);
+       mutex_lock_nested(&max98090->component->card->dapm_mutex,
+                         SND_SOC_DAPM_CLASS_RUNTIME);
        max98090_shdn_save_locked(max98090);
 }
 
index 4a9c5b5..6d490e2 100644 (file)
@@ -389,7 +389,7 @@ static const char * const rt1015_boost_mode[] = {
        "Bypass", "Adaptive", "Fixed Adaptive"
 };
 
-static const SOC_ENUM_SINGLE_DECL(rt1015_boost_mode_enum, 0, 0,
+static SOC_ENUM_SINGLE_DECL(rt1015_boost_mode_enum, 0, 0,
        rt1015_boost_mode);
 
 static int rt1015_boost_mode_get(struct snd_kcontrol *kcontrol,
index 8a03dbf..d930f60 100644 (file)
@@ -673,7 +673,7 @@ static const struct sdw_device_id rt1308_id[] = {
 };
 MODULE_DEVICE_TABLE(sdw, rt1308_id);
 
-static int rt1308_dev_suspend(struct device *dev)
+static int __maybe_unused rt1308_dev_suspend(struct device *dev)
 {
        struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
 
@@ -687,7 +687,7 @@ static int rt1308_dev_suspend(struct device *dev)
 
 #define RT1308_PROBE_TIMEOUT 2000
 
-static int rt1308_dev_resume(struct device *dev)
+static int __maybe_unused rt1308_dev_resume(struct device *dev)
 {
        struct sdw_slave *slave = dev_to_sdw_dev(dev);
        struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(dev);
index a4b9542..d4e0f95 100644 (file)
@@ -486,7 +486,7 @@ static const struct sdw_device_id rt700_id[] = {
 };
 MODULE_DEVICE_TABLE(sdw, rt700_id);
 
-static int rt700_dev_suspend(struct device *dev)
+static int __maybe_unused rt700_dev_suspend(struct device *dev)
 {
        struct rt700_priv *rt700 = dev_get_drvdata(dev);
 
@@ -500,7 +500,7 @@ static int rt700_dev_suspend(struct device *dev)
 
 #define RT700_PROBE_TIMEOUT 2000
 
-static int rt700_dev_resume(struct device *dev)
+static int __maybe_unused rt700_dev_resume(struct device *dev)
 {
        struct sdw_slave *slave = dev_to_sdw_dev(dev);
        struct rt700_priv *rt700 = dev_get_drvdata(dev);
index 85e62e1..fc3a3fa 100644 (file)
@@ -487,7 +487,7 @@ static const struct sdw_device_id rt711_id[] = {
 };
 MODULE_DEVICE_TABLE(sdw, rt711_id);
 
-static int rt711_dev_suspend(struct device *dev)
+static int __maybe_unused rt711_dev_suspend(struct device *dev)
 {
        struct rt711_priv *rt711 = dev_get_drvdata(dev);
 
@@ -501,7 +501,7 @@ static int rt711_dev_suspend(struct device *dev)
 
 #define RT711_PROBE_TIMEOUT 2000
 
-static int rt711_dev_resume(struct device *dev)
+static int __maybe_unused rt711_dev_resume(struct device *dev)
 {
        struct sdw_slave *slave = dev_to_sdw_dev(dev);
        struct rt711_priv *rt711 = dev_get_drvdata(dev);
index 6d892c4..64ef56e 100644 (file)
@@ -549,7 +549,7 @@ static const struct sdw_device_id rt715_id[] = {
 };
 MODULE_DEVICE_TABLE(sdw, rt715_id);
 
-static int rt715_dev_suspend(struct device *dev)
+static int __maybe_unused rt715_dev_suspend(struct device *dev)
 {
        struct rt715_priv *rt715 = dev_get_drvdata(dev);
 
@@ -563,7 +563,7 @@ static int rt715_dev_suspend(struct device *dev)
 
 #define RT715_PROBE_TIMEOUT 2000
 
-static int rt715_dev_resume(struct device *dev)
+static int __maybe_unused rt715_dev_resume(struct device *dev)
 {
        struct sdw_slave *slave = dev_to_sdw_dev(dev);
        struct rt715_priv *rt715 = dev_get_drvdata(dev);
index b4e9a6c..d087f3b 100644 (file)
@@ -1098,11 +1098,9 @@ static int aic32x4_setup_regulators(struct device *dev,
                        return PTR_ERR(aic32x4->supply_av);
                }
        } else {
-               if (IS_ERR(aic32x4->supply_dv) &&
-                               PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER)
+               if (PTR_ERR(aic32x4->supply_dv) == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
-               if (IS_ERR(aic32x4->supply_av) &&
-                               PTR_ERR(aic32x4->supply_av) == -EPROBE_DEFER)
+               if (PTR_ERR(aic32x4->supply_av) == -EPROBE_DEFER)
                        return -EPROBE_DEFER;
        }
 
index 33b13f3..9177401 100644 (file)
@@ -617,12 +617,15 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
                snd_soc_dapm_add_routes(&card->dapm, broxton_map,
                                        ARRAY_SIZE(broxton_map));
 
-       pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
-                              head);
-       component = pcm->codec_dai->component;
+       if (list_empty(&ctx->hdmi_pcm_list))
+               return -EINVAL;
 
-       if (ctx->common_hdmi_codec_drv)
+       if (ctx->common_hdmi_codec_drv) {
+               pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
+                                      head);
+               component = pcm->codec_dai->component;
                return hda_dsp_hdmi_build_controls(card, component);
+       }
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
                component = pcm->codec_dai->component;
@@ -643,9 +646,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!component)
-               return -EINVAL;
-
        return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
index 067a97e..4b67f26 100644 (file)
@@ -529,12 +529,15 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
        int err, i = 0;
        char jack_name[NAME_SIZE];
 
-       pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
-                              head);
-       component = pcm->codec_dai->component;
+       if (list_empty(&ctx->hdmi_pcm_list))
+               return -EINVAL;
 
-       if (ctx->common_hdmi_codec_drv)
+       if (ctx->common_hdmi_codec_drv) {
+               pcm = list_first_entry(&ctx->hdmi_pcm_list, struct bxt_hdmi_pcm,
+                                      head);
+               component = pcm->codec_dai->component;
                return hda_dsp_hdmi_build_controls(card, component);
+       }
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
                component = pcm->codec_dai->component;
@@ -555,9 +558,6 @@ static int bxt_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!component)
-               return -EINVAL;
-
        return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
index d6efc55..dd80d01 100644 (file)
@@ -241,12 +241,15 @@ static int sof_card_late_probe(struct snd_soc_card *card)
        struct hdmi_pcm *pcm;
        int ret, i = 0;
 
-       pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
-                              head);
-       component = pcm->codec_dai->component;
+       if (list_empty(&ctx->hdmi_pcm_list))
+               return -EINVAL;
 
-       if (ctx->common_hdmi_codec_drv)
+       if (ctx->common_hdmi_codec_drv) {
+               pcm = list_first_entry(&ctx->hdmi_pcm_list, struct hdmi_pcm,
+                                      head);
+               component = pcm->codec_dai->component;
                return hda_dsp_hdmi_build_controls(card, component);
+       }
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
                component = pcm->codec_dai->component;
@@ -265,8 +268,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
 
                i++;
        }
-       if (!component)
-               return -EINVAL;
 
        return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
index 4a6d117..8e947ba 100644 (file)
@@ -534,15 +534,18 @@ static int glk_card_late_probe(struct snd_soc_card *card)
        struct snd_soc_component *component = NULL;
        char jack_name[NAME_SIZE];
        struct glk_hdmi_pcm *pcm;
-       int err = 0;
+       int err;
        int i = 0;
 
-       pcm = list_first_entry(&ctx->hdmi_pcm_list, struct glk_hdmi_pcm,
-                              head);
-       component = pcm->codec_dai->component;
+       if (list_empty(&ctx->hdmi_pcm_list))
+               return -EINVAL;
 
-       if (ctx->common_hdmi_codec_drv)
+       if (ctx->common_hdmi_codec_drv) {
+               pcm = list_first_entry(&ctx->hdmi_pcm_list, struct glk_hdmi_pcm,
+                                      head);
+               component = pcm->codec_dai->component;
                return hda_dsp_hdmi_build_controls(card, component);
+       }
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
                component = pcm->codec_dai->component;
@@ -563,9 +566,6 @@ static int glk_card_late_probe(struct snd_soc_card *card)
                i++;
        }
 
-       if (!component)
-               return -EINVAL;
-
        return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
 
index 8a13231..5d87887 100644 (file)
@@ -273,19 +273,22 @@ static int sof_card_late_probe(struct snd_soc_card *card)
        struct snd_soc_component *component = NULL;
        char jack_name[NAME_SIZE];
        struct sof_hdmi_pcm *pcm;
-       int err = 0;
+       int err;
        int i = 0;
 
        /* HDMI is not supported by SOF on Baytrail/CherryTrail */
        if (is_legacy_cpu)
                return 0;
 
-       pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
-                              head);
-       component = pcm->codec_dai->component;
+       if (list_empty(&ctx->hdmi_pcm_list))
+               return -EINVAL;
 
-       if (ctx->common_hdmi_codec_drv)
+       if (ctx->common_hdmi_codec_drv) {
+               pcm = list_first_entry(&ctx->hdmi_pcm_list, struct sof_hdmi_pcm,
+                                      head);
+               component = pcm->codec_dai->component;
                return hda_dsp_hdmi_build_controls(card, component);
+       }
 
        list_for_each_entry(pcm, &ctx->hdmi_pcm_list, head) {
                component = pcm->codec_dai->component;
@@ -305,8 +308,6 @@ static int sof_card_late_probe(struct snd_soc_card *card)
 
                i++;
        }
-       if (!component)
-               return -EINVAL;
 
        return hdac_hdmi_jack_port_init(component, &card->dapm);
 }
index 67e9da4..7527330 100644 (file)
@@ -59,7 +59,7 @@ static const u64 rt1308_2_adr[] = {
 };
 
 static const u64 rt715_3_adr[] = {
-       0x000310025D715000
+       0x000310025D071500
 };
 
 static const struct snd_soc_acpi_link_adr icl_3_in_1_default[] = {
index 44f9c04..34cefba 100644 (file)
@@ -224,12 +224,12 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
        if (ret < 0) {
                dev_err(sdev->dev,
                        "error: failed to register DSP DAI driver %d\n", ret);
-               goto fw_run_err;
+               goto fw_trace_err;
        }
 
        ret = snd_sof_machine_register(sdev, plat_data);
        if (ret < 0)
-               goto fw_run_err;
+               goto fw_trace_err;
 
        /*
         * Some platforms in SOF, ex: BYT, may not have their platform PM
@@ -244,7 +244,8 @@ static int sof_probe_continue(struct snd_sof_dev *sdev)
 
        return 0;
 
-#if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE)
+fw_trace_err:
+       snd_sof_free_trace(sdev);
 fw_run_err:
        snd_sof_fw_unload(sdev);
 fw_load_err:
@@ -253,21 +254,10 @@ ipc_err:
        snd_sof_free_debug(sdev);
 dbg_err:
        snd_sof_remove(sdev);
-#else
-
-       /*
-        * when the probe_continue is handled in a work queue, the
-        * probe does not fail so we don't release resources here.
-        * They will be released with an explicit call to
-        * snd_sof_device_remove() when the PCI/ACPI device is removed
-        */
-
-fw_run_err:
-fw_load_err:
-ipc_err:
-dbg_err:
 
-#endif
+       /* all resources freed, update state to match */
+       sdev->fw_state = SOF_FW_BOOT_NOT_STARTED;
+       sdev->first_boot = true;
 
        return ret;
 }
@@ -350,10 +340,12 @@ int snd_sof_device_remove(struct device *dev)
        if (IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE))
                cancel_work_sync(&sdev->probe_work);
 
-       snd_sof_fw_unload(sdev);
-       snd_sof_ipc_free(sdev);
-       snd_sof_free_debug(sdev);
-       snd_sof_free_trace(sdev);
+       if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED) {
+               snd_sof_fw_unload(sdev);
+               snd_sof_ipc_free(sdev);
+               snd_sof_free_debug(sdev);
+               snd_sof_free_trace(sdev);
+       }
 
        /*
         * Unregister machine driver. This will unbind the snd_card which
@@ -361,13 +353,15 @@ int snd_sof_device_remove(struct device *dev)
         * before freeing the snd_card.
         */
        snd_sof_machine_unregister(sdev, pdata);
+
        /*
         * Unregistering the machine driver results in unloading the topology.
         * Some widgets, ex: scheduler, attempt to power down the core they are
         * scheduled on, when they are unloaded. Therefore, the DSP must be
         * removed only after the topology has been unloaded.
         */
-       snd_sof_remove(sdev);
+       if (sdev->fw_state > SOF_FW_BOOT_NOT_STARTED)
+               snd_sof_remove(sdev);
 
        /* release firmware */
        release_firmware(pdata->fw);
index 78dfd5f..9106ab8 100644 (file)
@@ -170,23 +170,14 @@ EXPORT_SYMBOL_NS(hda_codec_probe_bus, SND_SOC_SOF_HDA_AUDIO_CODEC);
 #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \
        IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI)
 
-void hda_codec_i915_get(struct snd_sof_dev *sdev)
+void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable)
 {
        struct hdac_bus *bus = sof_to_bus(sdev);
 
-       dev_dbg(bus->dev, "Turning i915 HDAC power on\n");
-       snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, true);
+       dev_dbg(bus->dev, "Turning i915 HDAC power %d\n", enable);
+       snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, enable);
 }
-EXPORT_SYMBOL_NS(hda_codec_i915_get, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
-
-void hda_codec_i915_put(struct snd_sof_dev *sdev)
-{
-       struct hdac_bus *bus = sof_to_bus(sdev);
-
-       dev_dbg(bus->dev, "Turning i915 HDAC power off\n");
-       snd_hdac_display_power(bus, HDA_CODEC_IDX_CONTROLLER, false);
-}
-EXPORT_SYMBOL_NS(hda_codec_i915_put, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
+EXPORT_SYMBOL_NS(hda_codec_i915_display_power, SND_SOC_SOF_HDA_AUDIO_CODEC_I915);
 
 int hda_codec_i915_init(struct snd_sof_dev *sdev)
 {
@@ -198,7 +189,7 @@ int hda_codec_i915_init(struct snd_sof_dev *sdev)
        if (ret < 0)
                return ret;
 
-       hda_codec_i915_get(sdev);
+       hda_codec_i915_display_power(sdev, true);
 
        return 0;
 }
@@ -209,7 +200,7 @@ int hda_codec_i915_exit(struct snd_sof_dev *sdev)
        struct hdac_bus *bus = sof_to_bus(sdev);
        int ret;
 
-       hda_codec_i915_put(sdev);
+       hda_codec_i915_display_power(sdev, false);
 
        ret = snd_hdac_i915_exit(bus);
 
index d08462f..65b86dd 100644 (file)
@@ -380,7 +380,8 @@ static int hda_init_caps(struct snd_sof_dev *sdev)
        /* create codec instances */
        hda_codec_probe_bus(sdev, hda_codec_use_common_hdmi);
 
-       hda_codec_i915_put(sdev);
+       if (!HDA_IDISP_CODEC(bus->codec_mask))
+               hda_codec_i915_display_power(sdev, false);
 
        /*
         * we are done probing so decrement link counts
index a4d030b..6191d91 100644 (file)
@@ -586,15 +586,14 @@ void hda_codec_jack_check(struct snd_sof_dev *sdev);
        (IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI) || \
         IS_ENABLED(CONFIG_SND_SOC_HDAC_HDMI))
 
-void hda_codec_i915_get(struct snd_sof_dev *sdev);
-void hda_codec_i915_put(struct snd_sof_dev *sdev);
+void hda_codec_i915_display_power(struct snd_sof_dev *sdev, bool enable);
 int hda_codec_i915_init(struct snd_sof_dev *sdev);
 int hda_codec_i915_exit(struct snd_sof_dev *sdev);
 
 #else
 
-static inline void hda_codec_i915_get(struct snd_sof_dev *sdev)  { }
-static inline void hda_codec_i915_put(struct snd_sof_dev *sdev)  { }
+static inline void hda_codec_i915_display_power(struct snd_sof_dev *sdev,
+                                               bool enable) { }
 static inline int hda_codec_i915_init(struct snd_sof_dev *sdev) { return 0; }
 static inline int hda_codec_i915_exit(struct snd_sof_dev *sdev) { return 0; }
 
index 314f309..29435ba 100644 (file)
@@ -591,6 +591,11 @@ static int sof_pcm_new(struct snd_soc_component *component,
                "spcm: allocate %s playback DMA buffer size 0x%x max 0x%x\n",
                caps->name, caps->buffer_size_min, caps->buffer_size_max);
 
+       if (!pcm->streams[stream].substream) {
+               dev_err(component->dev, "error: NULL playback substream!\n");
+               return -EINVAL;
+       }
+
        snd_pcm_set_managed_buffer(pcm->streams[stream].substream,
                                   SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
                                   le32_to_cpu(caps->buffer_size_min),
@@ -609,6 +614,11 @@ capture:
                "spcm: allocate %s capture DMA buffer size 0x%x max 0x%x\n",
                caps->name, caps->buffer_size_min, caps->buffer_size_max);
 
+       if (!pcm->streams[stream].substream) {
+               dev_err(component->dev, "error: NULL capture substream!\n");
+               return -EINVAL;
+       }
+
        snd_pcm_set_managed_buffer(pcm->streams[stream].substream,
                                   SNDRV_DMA_TYPE_DEV_SG, sdev->dev,
                                   le32_to_cpu(caps->buffer_size_min),
index 84290bb..a0cde05 100644 (file)
@@ -56,6 +56,10 @@ static int sof_resume(struct device *dev, bool runtime_resume)
        if (!sof_ops(sdev)->resume || !sof_ops(sdev)->runtime_resume)
                return 0;
 
+       /* DSP was never successfully started, nothing to resume */
+       if (sdev->first_boot)
+               return 0;
+
        /*
         * if the runtime_resume flag is set, call the runtime_resume routine
         * or else call the system resume routine
index d855bc2..cec631a 100644 (file)
@@ -235,6 +235,7 @@ static const struct sof_dev_desc jsl_desc = {
        .chip_info = &jsl_chip_info,
        .default_fw_path = "intel/sof",
        .default_tplg_path = "intel/sof-tplg",
+       .default_fw_filename = "sof-jsl.ri",
        .nocodec_tplg_filename = "sof-jsl-nocodec.tplg",
        .ops = &sof_cnl_ops,
 };
@@ -416,6 +417,8 @@ static const struct pci_device_id sof_pci_ids[] = {
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE)
        { PCI_DEVICE(0x8086, 0x38c8),
                .driver_data = (unsigned long)&jsl_desc},
+       { PCI_DEVICE(0x8086, 0x4dc8),
+               .driver_data = (unsigned long)&jsl_desc},
 #endif
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE_LP)
        { PCI_DEVICE(0x8086, 0x02c8),
index 4bb6503..d815090 100644 (file)
@@ -343,7 +343,10 @@ void snd_sof_free_trace(struct snd_sof_dev *sdev)
 
        snd_sof_release_trace(sdev);
 
-       snd_dma_free_pages(&sdev->dmatb);
-       snd_dma_free_pages(&sdev->dmatp);
+       if (sdev->dma_trace_pages) {
+               snd_dma_free_pages(&sdev->dmatb);
+               snd_dma_free_pages(&sdev->dmatp);
+               sdev->dma_trace_pages = 0;
+       }
 }
 EXPORT_SYMBOL(snd_sof_free_trace);
index cbe598b..98a9fe6 100644 (file)
@@ -555,7 +555,7 @@ static int sun4i_spdif_probe(struct platform_device *pdev)
        if (quirks->has_reset) {
                host->rst = devm_reset_control_get_optional_exclusive(&pdev->dev,
                                                                      NULL);
-               if (IS_ERR(host->rst) && PTR_ERR(host->rst) == -EPROBE_DEFER) {
+               if (PTR_ERR(host->rst) == -EPROBE_DEFER) {
                        ret = -EPROBE_DEFER;
                        dev_err(&pdev->dev, "Failed to get reset: %d\n", ret);
                        return ret;
index dbed3c5..d59882e 100644 (file)
@@ -127,7 +127,7 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
        struct device *dev = dai->dev;
        struct tegra30_i2s *i2s = snd_soc_dai_get_drvdata(dai);
        unsigned int mask, val, reg;
-       int ret, sample_size, srate, i2sclock, bitcnt, audio_bits;
+       int ret, sample_size, srate, i2sclock, bitcnt;
        struct tegra30_ahub_cif_conf cif_conf;
 
        if (params_channels(params) != 2)
@@ -137,19 +137,8 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
        switch (params_format(params)) {
        case SNDRV_PCM_FORMAT_S16_LE:
                val = TEGRA30_I2S_CTRL_BIT_SIZE_16;
-               audio_bits = TEGRA30_AUDIOCIF_BITS_16;
                sample_size = 16;
                break;
-       case SNDRV_PCM_FORMAT_S24_LE:
-               val = TEGRA30_I2S_CTRL_BIT_SIZE_24;
-               audio_bits = TEGRA30_AUDIOCIF_BITS_24;
-               sample_size = 24;
-               break;
-       case SNDRV_PCM_FORMAT_S32_LE:
-               val = TEGRA30_I2S_CTRL_BIT_SIZE_32;
-               audio_bits = TEGRA30_AUDIOCIF_BITS_32;
-               sample_size = 32;
-               break;
        default:
                return -EINVAL;
        }
@@ -181,8 +170,8 @@ static int tegra30_i2s_hw_params(struct snd_pcm_substream *substream,
        cif_conf.threshold = 0;
        cif_conf.audio_channels = 2;
        cif_conf.client_channels = 2;
-       cif_conf.audio_bits = audio_bits;
-       cif_conf.client_bits = audio_bits;
+       cif_conf.audio_bits = TEGRA30_AUDIOCIF_BITS_16;
+       cif_conf.client_bits = TEGRA30_AUDIOCIF_BITS_16;
        cif_conf.expand = 0;
        cif_conf.stereo_conv = 0;
        cif_conf.replicate = 0;
@@ -317,18 +306,14 @@ static const struct snd_soc_dai_driver tegra30_i2s_dai_template = {
                .channels_min = 2,
                .channels_max = 2,
                .rates = SNDRV_PCM_RATE_8000_96000,
-               .formats = SNDRV_PCM_FMTBIT_S32_LE |
-                          SNDRV_PCM_FMTBIT_S24_LE |
-                          SNDRV_PCM_FMTBIT_S16_LE,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
        },
        .capture = {
                .stream_name = "Capture",
                .channels_min = 2,
                .channels_max = 2,
                .rates = SNDRV_PCM_RATE_8000_96000,
-               .formats = SNDRV_PCM_FMTBIT_S32_LE |
-                          SNDRV_PCM_FMTBIT_S24_LE |
-                          SNDRV_PCM_FMTBIT_S16_LE,
+               .formats = SNDRV_PCM_FMTBIT_S16_LE,
        },
        .ops = &tegra30_i2s_dai_ops,
        .symmetric_rates = 1,
index 94b903d..74c00c9 100644 (file)
@@ -558,11 +558,11 @@ static const struct scarlett2_config
 
 /* proprietary request/response format */
 struct scarlett2_usb_packet {
-       u32 cmd;
-       u16 size;
-       u16 seq;
-       u32 error;
-       u32 pad;
+       __le32 cmd;
+       __le16 size;
+       __le16 seq;
+       __le32 error;
+       __le32 pad;
        u8 data[];
 };
 
@@ -664,11 +664,11 @@ static int scarlett2_usb(
                        "Scarlett Gen 2 USB invalid response; "
                           "cmd tx/rx %d/%d seq %d/%d size %d/%d "
                           "error %d pad %d\n",
-                       le16_to_cpu(req->cmd), le16_to_cpu(resp->cmd),
+                       le32_to_cpu(req->cmd), le32_to_cpu(resp->cmd),
                        le16_to_cpu(req->seq), le16_to_cpu(resp->seq),
                        resp_size, le16_to_cpu(resp->size),
-                       le16_to_cpu(resp->error),
-                       le16_to_cpu(resp->pad));
+                       le32_to_cpu(resp->error),
+                       le32_to_cpu(resp->pad));
                err = -EINVAL;
                goto unlock;
        }
@@ -687,7 +687,7 @@ error:
 /* Send SCARLETT2_USB_DATA_CMD SCARLETT2_USB_CONFIG_SAVE */
 static void scarlett2_config_save(struct usb_mixer_interface *mixer)
 {
-       u32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE);
+       __le32 req = cpu_to_le32(SCARLETT2_USB_CONFIG_SAVE);
 
        scarlett2_usb(mixer, SCARLETT2_USB_DATA_CMD,
                      &req, sizeof(u32),
@@ -713,11 +713,11 @@ static int scarlett2_usb_set_config(
        const struct scarlett2_config config_item =
               scarlett2_config_items[config_item_num];
        struct {
-               u32 offset;
-               u32 bytes;
-               s32 value;
+               __le32 offset;
+               __le32 bytes;
+               __le32 value;
        } __packed req;
-       u32 req2;
+       __le32 req2;
        int err;
        struct scarlett2_mixer_data *private = mixer->private_data;
 
@@ -753,8 +753,8 @@ static int scarlett2_usb_get(
        int offset, void *buf, int size)
 {
        struct {
-               u32 offset;
-               u32 size;
+               __le32 offset;
+               __le32 size;
        } __packed req;
 
        req.offset = cpu_to_le32(offset);
@@ -794,8 +794,8 @@ static int scarlett2_usb_set_mix(struct usb_mixer_interface *mixer,
        const struct scarlett2_device_info *info = private->info;
 
        struct {
-               u16 mix_num;
-               u16 data[SCARLETT2_INPUT_MIX_MAX];
+               __le16 mix_num;
+               __le16 data[SCARLETT2_INPUT_MIX_MAX];
        } __packed req;
 
        int i, j;
@@ -850,9 +850,9 @@ static int scarlett2_usb_set_mux(struct usb_mixer_interface *mixer)
        };
 
        struct {
-               u16 pad;
-               u16 num;
-               u32 data[SCARLETT2_MUX_MAX];
+               __le16 pad;
+               __le16 num;
+               __le32 data[SCARLETT2_MUX_MAX];
        } __packed req;
 
        req.pad = 0;
@@ -911,9 +911,9 @@ static int scarlett2_usb_get_meter_levels(struct usb_mixer_interface *mixer,
                                          u16 *levels)
 {
        struct {
-               u16 pad;
-               u16 num_meters;
-               u32 magic;
+               __le16 pad;
+               __le16 num_meters;
+               __le32 magic;
        } __packed req;
        u32 resp[SCARLETT2_NUM_METERS];
        int i, err;
index 4034c20..6fe206f 100644 (file)
@@ -110,7 +110,7 @@ static bool validate_processing_unit(const void *p,
        default:
                if (v->type == UAC1_EXTENSION_UNIT)
                        return true; /* OK */
-               switch (d->wProcessType) {
+               switch (le16_to_cpu(d->wProcessType)) {
                case UAC_PROCESS_UP_DOWNMIX:
                case UAC_PROCESS_DOLBY_PROLOGIC:
                        if (d->bLength < len + 1) /* bNrModes */
@@ -125,7 +125,7 @@ static bool validate_processing_unit(const void *p,
        case UAC_VERSION_2:
                if (v->type == UAC2_EXTENSION_UNIT_V2)
                        return true; /* OK */
-               switch (d->wProcessType) {
+               switch (le16_to_cpu(d->wProcessType)) {
                case UAC2_PROCESS_UP_DOWNMIX:
                case UAC2_PROCESS_DOLBY_PROLOCIC: /* SiC! */
                        if (d->bLength < len + 1) /* bNrModes */
@@ -142,7 +142,7 @@ static bool validate_processing_unit(const void *p,
                        len += 2; /* wClusterDescrID */
                        break;
                }
-               switch (d->wProcessType) {
+               switch (le16_to_cpu(d->wProcessType)) {
                case UAC3_PROCESS_UP_DOWNMIX:
                        if (d->bLength < len + 1) /* bNrModes */
                                return false;
index 7e42f7b..bd77881 100644 (file)
@@ -28,6 +28,7 @@ help:
        @echo '  pci                    - PCI tools'
        @echo '  perf                   - Linux performance measurement and analysis tool'
        @echo '  selftests              - various kernel selftests'
+       @echo '  bootconfig             - boot config tool'
        @echo '  spi                    - spi tools'
        @echo '  tmon                   - thermal monitoring and tuning tool'
        @echo '  turbostat              - Intel CPU idle stats and freq reporting tool'
@@ -63,7 +64,7 @@ acpi: FORCE
 cpupower: FORCE
        $(call descend,power/$@)
 
-cgroup firewire hv guest spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging: FORCE
+cgroup firewire hv guest bootconfig spi usb virtio vm bpf iio gpio objtool leds wmi pci firmware debugging: FORCE
        $(call descend,$@)
 
 liblockdep: FORCE
@@ -96,7 +97,7 @@ kvm_stat: FORCE
        $(call descend,kvm/$@)
 
 all: acpi cgroup cpupower gpio hv firewire liblockdep \
-               perf selftests spi turbostat usb \
+               perf selftests bootconfig spi turbostat usb \
                virtio vm bpf x86_energy_perf_policy \
                tmon freefall iio objtool kvm_stat wmi \
                pci debugging
@@ -107,7 +108,7 @@ acpi_install:
 cpupower_install:
        $(call descend,power/$(@:_install=),install)
 
-cgroup_install firewire_install gpio_install hv_install iio_install perf_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install:
+cgroup_install firewire_install gpio_install hv_install iio_install perf_install bootconfig_install spi_install usb_install virtio_install vm_install bpf_install objtool_install wmi_install pci_install debugging_install:
        $(call descend,$(@:_install=),install)
 
 liblockdep_install:
@@ -141,7 +142,7 @@ acpi_clean:
 cpupower_clean:
        $(call descend,power/cpupower,clean)
 
-cgroup_clean hv_clean firewire_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean:
+cgroup_clean hv_clean firewire_clean bootconfig_clean spi_clean usb_clean virtio_clean vm_clean wmi_clean bpf_clean iio_clean gpio_clean objtool_clean leds_clean pci_clean firmware_clean debugging_clean:
        $(call descend,$(@:_clean=),clean)
 
 liblockdep_clean:
@@ -176,7 +177,7 @@ build_clean:
        $(call descend,build,clean)
 
 clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean \
-               perf_clean selftests_clean turbostat_clean spi_clean usb_clean virtio_clean \
+               perf_clean selftests_clean turbostat_clean bootconfig_clean spi_clean usb_clean virtio_clean \
                vm_clean bpf_clean iio_clean x86_energy_perf_policy_clean tmon_clean \
                freefall_clean build_clean libbpf_clean libsubcmd_clean liblockdep_clean \
                gpio_clean objtool_clean leds_clean wmi_clean pci_clean firmware_clean debugging_clean \
diff --git a/tools/bootconfig/.gitignore b/tools/bootconfig/.gitignore
new file mode 100644 (file)
index 0000000..e7644df
--- /dev/null
@@ -0,0 +1 @@
+bootconfig
diff --git a/tools/bootconfig/Makefile b/tools/bootconfig/Makefile
new file mode 100644 (file)
index 0000000..a6146ac
--- /dev/null
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0
+# Makefile for bootconfig command
+
+bindir ?= /usr/bin
+
+HEADER = include/linux/bootconfig.h
+CFLAGS = -Wall -g -I./include
+
+PROGS = bootconfig
+
+all: $(PROGS)
+
+bootconfig: ../../lib/bootconfig.c main.c $(HEADER)
+       $(CC) $(filter %.c,$^) $(CFLAGS) -o $@
+
+install: $(PROGS)
+       install bootconfig $(DESTDIR)$(bindir)
+
+test: bootconfig
+       ./test-bootconfig.sh
+
+clean:
+       $(RM) -f *.o bootconfig
diff --git a/tools/bootconfig/include/linux/bootconfig.h b/tools/bootconfig/include/linux/bootconfig.h
new file mode 100644 (file)
index 0000000..078cbd2
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _BOOTCONFIG_LINUX_BOOTCONFIG_H
+#define _BOOTCONFIG_LINUX_BOOTCONFIG_H
+
+#include "../../../../include/linux/bootconfig.h"
+
+#endif
diff --git a/tools/bootconfig/include/linux/bug.h b/tools/bootconfig/include/linux/bug.h
new file mode 100644 (file)
index 0000000..7b65a38
--- /dev/null
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _SKC_LINUX_BUG_H
+#define _SKC_LINUX_BUG_H
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#define WARN_ON(cond)  \
+       ((cond) ? printf("Internal warning(%s:%d, %s): %s\n",   \
+                       __FILE__, __LINE__, __func__, #cond) : 0)
+
+#endif
diff --git a/tools/bootconfig/include/linux/ctype.h b/tools/bootconfig/include/linux/ctype.h
new file mode 100644 (file)
index 0000000..c56ecc1
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _SKC_LINUX_CTYPE_H
+#define _SKC_LINUX_CTYPE_H
+
+#include <ctype.h>
+
+#endif
diff --git a/tools/bootconfig/include/linux/errno.h b/tools/bootconfig/include/linux/errno.h
new file mode 100644 (file)
index 0000000..5d9f91e
--- /dev/null
@@ -0,0 +1,7 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _SKC_LINUX_ERRNO_H
+#define _SKC_LINUX_ERRNO_H
+
+#include <asm/errno.h>
+
+#endif
diff --git a/tools/bootconfig/include/linux/kernel.h b/tools/bootconfig/include/linux/kernel.h
new file mode 100644 (file)
index 0000000..2d93320
--- /dev/null
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _SKC_LINUX_KERNEL_H
+#define _SKC_LINUX_KERNEL_H
+
+#include <stdlib.h>
+#include <stdbool.h>
+
+#include <linux/printk.h>
+
+typedef unsigned short u16;
+typedef unsigned int   u32;
+
+#define unlikely(cond) (cond)
+
+#define __init
+#define __initdata
+
+#endif
diff --git a/tools/bootconfig/include/linux/printk.h b/tools/bootconfig/include/linux/printk.h
new file mode 100644 (file)
index 0000000..017bcd6
--- /dev/null
@@ -0,0 +1,17 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _SKC_LINUX_PRINTK_H
+#define _SKC_LINUX_PRINTK_H
+
+#include <stdio.h>
+
+/* controllable printf */
+extern int pr_output;
+#define printk(fmt, ...)       \
+       (pr_output ? printf(fmt, __VA_ARGS__) : 0)
+
+#define pr_err printk
+#define pr_warn        printk
+#define pr_info        printk
+#define pr_debug printk
+
+#endif
diff --git a/tools/bootconfig/include/linux/string.h b/tools/bootconfig/include/linux/string.h
new file mode 100644 (file)
index 0000000..8267af7
--- /dev/null
@@ -0,0 +1,32 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _SKC_LINUX_STRING_H
+#define _SKC_LINUX_STRING_H
+
+#include <string.h>
+
+/* Copied from lib/string.c */
+static inline char *skip_spaces(const char *str)
+{
+       while (isspace(*str))
+               ++str;
+       return (char *)str;
+}
+
+static inline char *strim(char *s)
+{
+       size_t size;
+       char *end;
+
+       size = strlen(s);
+       if (!size)
+               return s;
+
+       end = s + size - 1;
+       while (end >= s && isspace(*end))
+               end--;
+       *(end + 1) = '\0';
+
+       return skip_spaces(s);
+}
+
+#endif
diff --git a/tools/bootconfig/main.c b/tools/bootconfig/main.c
new file mode 100644 (file)
index 0000000..47f4884
--- /dev/null
@@ -0,0 +1,354 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Boot config tool for initrd image
+ */
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <linux/kernel.h>
+#include <linux/bootconfig.h>
+
+int pr_output = 1;
+
+static int xbc_show_array(struct xbc_node *node)
+{
+       const char *val;
+       int i = 0;
+
+       xbc_array_for_each_value(node, val) {
+               printf("\"%s\"%s", val, node->next ? ", " : ";\n");
+               i++;
+       }
+       return i;
+}
+
+static void xbc_show_compact_tree(void)
+{
+       struct xbc_node *node, *cnode;
+       int depth = 0, i;
+
+       node = xbc_root_node();
+       while (node && xbc_node_is_key(node)) {
+               for (i = 0; i < depth; i++)
+                       printf("\t");
+               cnode = xbc_node_get_child(node);
+               while (cnode && xbc_node_is_key(cnode) && !cnode->next) {
+                       printf("%s.", xbc_node_get_data(node));
+                       node = cnode;
+                       cnode = xbc_node_get_child(node);
+               }
+               if (cnode && xbc_node_is_key(cnode)) {
+                       printf("%s {\n", xbc_node_get_data(node));
+                       depth++;
+                       node = cnode;
+                       continue;
+               } else if (cnode && xbc_node_is_value(cnode)) {
+                       printf("%s = ", xbc_node_get_data(node));
+                       if (cnode->next)
+                               xbc_show_array(cnode);
+                       else
+                               printf("\"%s\";\n", xbc_node_get_data(cnode));
+               } else {
+                       printf("%s;\n", xbc_node_get_data(node));
+               }
+
+               if (node->next) {
+                       node = xbc_node_get_next(node);
+                       continue;
+               }
+               while (!node->next) {
+                       node = xbc_node_get_parent(node);
+                       if (!node)
+                               return;
+                       if (!xbc_node_get_child(node)->next)
+                               continue;
+                       depth--;
+                       for (i = 0; i < depth; i++)
+                               printf("\t");
+                       printf("}\n");
+               }
+               node = xbc_node_get_next(node);
+       }
+}
+
+/* Simple real checksum */
+int checksum(unsigned char *buf, int len)
+{
+       int i, sum = 0;
+
+       for (i = 0; i < len; i++)
+               sum += buf[i];
+
+       return sum;
+}
+
+#define PAGE_SIZE      4096
+
+int load_xbc_fd(int fd, char **buf, int size)
+{
+       int ret;
+
+       *buf = malloc(size + 1);
+       if (!*buf)
+               return -ENOMEM;
+
+       ret = read(fd, *buf, size);
+       if (ret < 0)
+               return -errno;
+       (*buf)[size] = '\0';
+
+       return ret;
+}
+
+/* Return the read size or -errno */
+int load_xbc_file(const char *path, char **buf)
+{
+       struct stat stat;
+       int fd, ret;
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0)
+               return -errno;
+       ret = fstat(fd, &stat);
+       if (ret < 0)
+               return -errno;
+
+       ret = load_xbc_fd(fd, buf, stat.st_size);
+
+       close(fd);
+
+       return ret;
+}
+
+int load_xbc_from_initrd(int fd, char **buf)
+{
+       struct stat stat;
+       int ret;
+       u32 size = 0, csum = 0, rcsum;
+
+       ret = fstat(fd, &stat);
+       if (ret < 0)
+               return -errno;
+
+       if (stat.st_size < 8)
+               return 0;
+
+       if (lseek(fd, -8, SEEK_END) < 0) {
+               printf("Failed to lseek: %d\n", -errno);
+               return -errno;
+       }
+
+       if (read(fd, &size, sizeof(u32)) < 0)
+               return -errno;
+
+       if (read(fd, &csum, sizeof(u32)) < 0)
+               return -errno;
+
+       /* Wrong size, maybe no boot config here */
+       if (stat.st_size < size + 8)
+               return 0;
+
+       if (lseek(fd, stat.st_size - 8 - size, SEEK_SET) < 0) {
+               printf("Failed to lseek: %d\n", -errno);
+               return -errno;
+       }
+
+       ret = load_xbc_fd(fd, buf, size);
+       if (ret < 0)
+               return ret;
+
+       /* Wrong Checksum, maybe no boot config here */
+       rcsum = checksum((unsigned char *)*buf, size);
+       if (csum != rcsum) {
+               printf("checksum error: %d != %d\n", csum, rcsum);
+               return 0;
+       }
+
+       ret = xbc_init(*buf);
+       /* Wrong data, maybe no boot config here */
+       if (ret < 0)
+               return 0;
+
+       return size;
+}
+
+int show_xbc(const char *path)
+{
+       int ret, fd;
+       char *buf = NULL;
+
+       fd = open(path, O_RDONLY);
+       if (fd < 0) {
+               printf("Failed to open initrd %s: %d\n", path, fd);
+               return -errno;
+       }
+
+       ret = load_xbc_from_initrd(fd, &buf);
+       if (ret < 0)
+               printf("Failed to load a boot config from initrd: %d\n", ret);
+       else
+               xbc_show_compact_tree();
+
+       close(fd);
+       free(buf);
+
+       return ret;
+}
+
+int delete_xbc(const char *path)
+{
+       struct stat stat;
+       int ret = 0, fd, size;
+       char *buf = NULL;
+
+       fd = open(path, O_RDWR);
+       if (fd < 0) {
+               printf("Failed to open initrd %s: %d\n", path, fd);
+               return -errno;
+       }
+
+       /*
+        * Suppress error messages in xbc_init() because it can be just a
+        * data which concidentally matches the size and checksum footer.
+        */
+       pr_output = 0;
+       size = load_xbc_from_initrd(fd, &buf);
+       pr_output = 1;
+       if (size < 0) {
+               ret = size;
+               printf("Failed to load a boot config from initrd: %d\n", ret);
+       } else if (size > 0) {
+               ret = fstat(fd, &stat);
+               if (!ret)
+                       ret = ftruncate(fd, stat.st_size - size - 8);
+               if (ret)
+                       ret = -errno;
+       } /* Ignore if there is no boot config in initrd */
+
+       close(fd);
+       free(buf);
+
+       return ret;
+}
+
+int apply_xbc(const char *path, const char *xbc_path)
+{
+       u32 size, csum;
+       char *buf, *data;
+       int ret, fd;
+
+       ret = load_xbc_file(xbc_path, &buf);
+       if (ret < 0) {
+               printf("Failed to load %s : %d\n", xbc_path, ret);
+               return ret;
+       }
+       size = strlen(buf) + 1;
+       csum = checksum((unsigned char *)buf, size);
+
+       /* Prepare xbc_path data */
+       data = malloc(size + 8);
+       if (!data)
+               return -ENOMEM;
+       strcpy(data, buf);
+       *(u32 *)(data + size) = size;
+       *(u32 *)(data + size + 4) = csum;
+
+       /* Check the data format */
+       ret = xbc_init(buf);
+       if (ret < 0) {
+               printf("Failed to parse %s: %d\n", xbc_path, ret);
+               free(data);
+               free(buf);
+               return ret;
+       }
+       printf("Apply %s to %s\n", xbc_path, path);
+       printf("\tNumber of nodes: %d\n", ret);
+       printf("\tSize: %u bytes\n", (unsigned int)size);
+       printf("\tChecksum: %d\n", (unsigned int)csum);
+
+       /* TODO: Check the options by schema */
+       xbc_destroy_all();
+       free(buf);
+
+       /* Remove old boot config if exists */
+       ret = delete_xbc(path);
+       if (ret < 0) {
+               printf("Failed to delete previous boot config: %d\n", ret);
+               return ret;
+       }
+
+       /* Apply new one */
+       fd = open(path, O_RDWR | O_APPEND);
+       if (fd < 0) {
+               printf("Failed to open %s: %d\n", path, fd);
+               return fd;
+       }
+       /* TODO: Ensure the @path is initramfs/initrd image */
+       ret = write(fd, data, size + 8);
+       if (ret < 0) {
+               printf("Failed to apply a boot config: %d\n", ret);
+               return ret;
+       }
+       close(fd);
+       free(data);
+
+       return 0;
+}
+
+int usage(void)
+{
+       printf("Usage: bootconfig [OPTIONS] <INITRD>\n"
+               " Apply, delete or show boot config to initrd.\n"
+               " Options:\n"
+               "               -a <config>: Apply boot config to initrd\n"
+               "               -d : Delete boot config file from initrd\n\n"
+               " If no option is given, show current applied boot config.\n");
+       return -1;
+}
+
+int main(int argc, char **argv)
+{
+       char *path = NULL;
+       char *apply = NULL;
+       bool delete = false;
+       int opt;
+
+       while ((opt = getopt(argc, argv, "hda:")) != -1) {
+               switch (opt) {
+               case 'd':
+                       delete = true;
+                       break;
+               case 'a':
+                       apply = optarg;
+                       break;
+               case 'h':
+               default:
+                       return usage();
+               }
+       }
+
+       if (apply && delete) {
+               printf("Error: You can not specify both -a and -d at once.\n");
+               return usage();
+       }
+
+       if (optind >= argc) {
+               printf("Error: No initrd is specified.\n");
+               return usage();
+       }
+
+       path = argv[optind];
+
+       if (apply)
+               return apply_xbc(path, apply);
+       else if (delete)
+               return delete_xbc(path);
+
+       return show_xbc(path);
+}
diff --git a/tools/bootconfig/samples/bad-array-space-comment.bconf b/tools/bootconfig/samples/bad-array-space-comment.bconf
new file mode 100644 (file)
index 0000000..fda19e4
--- /dev/null
@@ -0,0 +1,5 @@
+key =  # comment
+       "value1",         # comment1
+       "value2"          # comment2
+,
+       "value3"
diff --git a/tools/bootconfig/samples/bad-array.bconf b/tools/bootconfig/samples/bad-array.bconf
new file mode 100644 (file)
index 0000000..0174af0
--- /dev/null
@@ -0,0 +1,2 @@
+# Array must be comma separated.
+key = "value1" "value2"
diff --git a/tools/bootconfig/samples/bad-dotword.bconf b/tools/bootconfig/samples/bad-dotword.bconf
new file mode 100644 (file)
index 0000000..ba5557b
--- /dev/null
@@ -0,0 +1,4 @@
+# do not start keyword with .
+key {
+  .word = 1
+}
diff --git a/tools/bootconfig/samples/bad-empty.bconf b/tools/bootconfig/samples/bad-empty.bconf
new file mode 100644 (file)
index 0000000..2ba3f6c
--- /dev/null
@@ -0,0 +1 @@
+# Wrong boot config: comment only
diff --git a/tools/bootconfig/samples/bad-keyerror.bconf b/tools/bootconfig/samples/bad-keyerror.bconf
new file mode 100644 (file)
index 0000000..b6e247a
--- /dev/null
@@ -0,0 +1,2 @@
+# key word can not contain ","
+key,word
diff --git a/tools/bootconfig/samples/bad-longkey.bconf b/tools/bootconfig/samples/bad-longkey.bconf
new file mode 100644 (file)
index 0000000..eb97369
--- /dev/null
@@ -0,0 +1 @@
+key_word_is_too_long01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
diff --git a/tools/bootconfig/samples/bad-manywords.bconf b/tools/bootconfig/samples/bad-manywords.bconf
new file mode 100644 (file)
index 0000000..8db8196
--- /dev/null
@@ -0,0 +1 @@
+key1.is2.too3.long4.5.6.7.8.9.10.11.12.13.14.15.16.17
diff --git a/tools/bootconfig/samples/bad-no-keyword.bconf b/tools/bootconfig/samples/bad-no-keyword.bconf
new file mode 100644 (file)
index 0000000..eff2680
--- /dev/null
@@ -0,0 +1,2 @@
+# No keyword
+{}
diff --git a/tools/bootconfig/samples/bad-nonprintable.bconf b/tools/bootconfig/samples/bad-nonprintable.bconf
new file mode 100644 (file)
index 0000000..3bb1a28
--- /dev/null
@@ -0,0 +1,2 @@
+# Non printable
+key = "\ 2"
diff --git a/tools/bootconfig/samples/bad-spaceword.bconf b/tools/bootconfig/samples/bad-spaceword.bconf
new file mode 100644 (file)
index 0000000..90c703d
--- /dev/null
@@ -0,0 +1,2 @@
+# No space between words
+key . word
diff --git a/tools/bootconfig/samples/bad-tree.bconf b/tools/bootconfig/samples/bad-tree.bconf
new file mode 100644 (file)
index 0000000..5a6038e
--- /dev/null
@@ -0,0 +1,5 @@
+# brace is not closing
+tree {
+  node {
+    value = 1
+}
diff --git a/tools/bootconfig/samples/bad-value.bconf b/tools/bootconfig/samples/bad-value.bconf
new file mode 100644 (file)
index 0000000..a1217fe
--- /dev/null
@@ -0,0 +1,3 @@
+# Quotes error
+value = "data
+
diff --git a/tools/bootconfig/samples/escaped.bconf b/tools/bootconfig/samples/escaped.bconf
new file mode 100644 (file)
index 0000000..9f72043
--- /dev/null
@@ -0,0 +1,3 @@
+key1 = "A\B\C"
+key2 = '\'\''
+key3 = "\\"
diff --git a/tools/bootconfig/samples/good-array-space-comment.bconf b/tools/bootconfig/samples/good-array-space-comment.bconf
new file mode 100644 (file)
index 0000000..45b938d
--- /dev/null
@@ -0,0 +1,4 @@
+key =  # comment
+       "value1",         # comment1
+       "value2"         , # comment2
+       "value3"
diff --git a/tools/bootconfig/samples/good-comment-after-value.bconf b/tools/bootconfig/samples/good-comment-after-value.bconf
new file mode 100644 (file)
index 0000000..0d92a85
--- /dev/null
@@ -0,0 +1 @@
+key = "value"  # comment
diff --git a/tools/bootconfig/samples/good-printables.bconf b/tools/bootconfig/samples/good-printables.bconf
new file mode 100644 (file)
index 0000000..ebb985a
--- /dev/null
@@ -0,0 +1,2 @@
+key = "        
+\v\f !#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
diff --git a/tools/bootconfig/samples/good-simple.bconf b/tools/bootconfig/samples/good-simple.bconf
new file mode 100644 (file)
index 0000000..37dd6d2
--- /dev/null
@@ -0,0 +1,11 @@
+# A good simple bootconfig
+
+key.word1 = 1
+key.word2=2
+key.word3 = 3;
+
+key {
+word4 = 4 }
+
+key { word5 = 5; word6 = 6 }
+
diff --git a/tools/bootconfig/samples/good-single.bconf b/tools/bootconfig/samples/good-single.bconf
new file mode 100644 (file)
index 0000000..98e55ad
--- /dev/null
@@ -0,0 +1,4 @@
+# single key style
+key = 1
+key2 = 2
+key3 = "alpha", "beta"
diff --git a/tools/bootconfig/samples/good-space-after-value.bconf b/tools/bootconfig/samples/good-space-after-value.bconf
new file mode 100644 (file)
index 0000000..56c15cb
--- /dev/null
@@ -0,0 +1 @@
+key = "value"   
diff --git a/tools/bootconfig/samples/good-tree.bconf b/tools/bootconfig/samples/good-tree.bconf
new file mode 100644 (file)
index 0000000..f2ddefc
--- /dev/null
@@ -0,0 +1,12 @@
+key {
+  word {
+    tree {
+      value = "0"}
+  }
+  word2 {
+    tree {
+      value = 1,2 }
+  }
+}
+other.tree {
+  value = 2; value2 = 3;}
diff --git a/tools/bootconfig/test-bootconfig.sh b/tools/bootconfig/test-bootconfig.sh
new file mode 100755 (executable)
index 0000000..87725e8
--- /dev/null
@@ -0,0 +1,105 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-only
+
+echo "Boot config test script"
+
+BOOTCONF=./bootconfig
+INITRD=`mktemp initrd-XXXX`
+TEMPCONF=`mktemp temp-XXXX.bconf`
+NG=0
+
+cleanup() {
+  rm -f $INITRD $TEMPCONF
+  exit $NG
+}
+
+trap cleanup EXIT TERM
+
+NO=1
+
+xpass() { # pass test command
+  echo "test case $NO ($3)... "
+  if ! ($@ && echo "\t\t[OK]"); then
+     echo "\t\t[NG]"; NG=$((NG + 1))
+  fi
+  NO=$((NO + 1))
+}
+
+xfail() { # fail test command
+  echo "test case $NO ($3)... "
+  if ! (! $@ && echo "\t\t[OK]"); then
+     echo "\t\t[NG]"; NG=$((NG + 1))
+  fi
+  NO=$((NO + 1))
+}
+
+echo "Basic command test"
+xpass $BOOTCONF $INITRD
+
+echo "Delete command should success without bootconfig"
+xpass $BOOTCONF -d $INITRD
+
+dd if=/dev/zero of=$INITRD bs=4096 count=1
+echo "key = value;" > $TEMPCONF
+bconf_size=$(stat -c %s $TEMPCONF)
+initrd_size=$(stat -c %s $INITRD)
+
+echo "Apply command test"
+xpass $BOOTCONF -a $TEMPCONF $INITRD
+new_size=$(stat -c %s $INITRD)
+
+echo "File size check"
+xpass test $new_size -eq $(expr $bconf_size + $initrd_size + 9)
+
+echo "Apply command repeat test"
+xpass $BOOTCONF -a $TEMPCONF $INITRD
+
+echo "File size check"
+xpass test $new_size -eq $(stat -c %s $INITRD)
+
+echo "Delete command check"
+xpass $BOOTCONF -d $INITRD
+
+echo "File size check"
+new_size=$(stat -c %s $INITRD)
+xpass test $new_size -eq $initrd_size
+
+echo "Max node number check"
+
+echo -n > $TEMPCONF
+for i in `seq 1 1024` ; do
+   echo "node$i" >> $TEMPCONF
+done
+xpass $BOOTCONF -a $TEMPCONF $INITRD
+
+echo "badnode" >> $TEMPCONF
+xfail $BOOTCONF -a $TEMPCONF $INITRD
+
+echo "Max filesize check"
+
+# Max size is 32767 (including terminal byte)
+echo -n "data = \"" > $TEMPCONF
+dd if=/dev/urandom bs=768 count=32 | base64 -w0 >> $TEMPCONF
+echo "\"" >> $TEMPCONF
+xfail $BOOTCONF -a $TEMPCONF $INITRD
+
+truncate -s 32764 $TEMPCONF
+echo "\"" >> $TEMPCONF # add 2 bytes + terminal ('\"\n\0')
+xpass $BOOTCONF -a $TEMPCONF $INITRD
+
+echo "=== expected failure cases ==="
+for i in samples/bad-* ; do
+  xfail $BOOTCONF -a $i $INITRD
+done
+
+echo "=== expected success cases ==="
+for i in samples/good-* ; do
+  xpass $BOOTCONF -a $i $INITRD
+done
+
+echo
+if [ $NG -eq 0 ]; then
+       echo "All tests passed"
+else
+       echo "$NG tests failed"
+fi
index 446ba89..941873d 100644 (file)
@@ -580,7 +580,7 @@ probe_large_insn_limit(const char *define_prefix, __u32 ifindex)
        res = bpf_probe_large_insn_limit(ifindex);
        print_bool_feature("have_large_insn_limit",
                           "Large program size limit",
-                          "HAVE_LARGE_INSN_LIMIT",
+                          "LARGE_INSN_LIMIT",
                           res, define_prefix);
 }
 
index a3521de..b352ab0 100644 (file)
@@ -536,7 +536,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode,
                buf = (unsigned char *)(info->jited_prog_insns);
                member_len = info->jited_prog_len;
        } else {        /* DUMP_XLATED */
-               if (info->xlated_prog_len == 0) {
+               if (info->xlated_prog_len == 0 || !info->xlated_prog_insns) {
                        p_err("error retrieving insn dump: kernel.kptr_restrict set?");
                        return -1;
                }
index 0c02135..39edd68 100644 (file)
@@ -41,7 +41,7 @@ clean:
 
 $(OUTPUT)/runqslower: $(OUTPUT)/runqslower.o $(BPFOBJ)
        $(call msg,BINARY,$@)
-       $(Q)$(CC) $(CFLAGS) -lelf -lz $^ -o $@
+       $(Q)$(CC) $(CFLAGS) $^ -lelf -lz -o $@
 
 $(OUTPUT)/runqslower.o: runqslower.h $(OUTPUT)/runqslower.skel.h             \
                        $(OUTPUT)/runqslower.bpf.o
@@ -75,7 +75,7 @@ $(OUTPUT)/vmlinux.h: $(VMLINUX_BTF_PATH) | $(OUTPUT) $(BPFTOOL)
        fi
        $(Q)$(BPFTOOL) btf dump file $(VMLINUX_BTF_PATH) format c > $@
 
-$(BPFOBJ): | $(OUTPUT)
+$(BPFOBJ): $(wildcard $(LIBBPF_SRC)/*.[ch] $(LIBBPF_SRC)/Makefile) | $(OUTPUT)
        $(Q)$(MAKE) $(submake_extras) -C $(LIBBPF_SRC)                         \
                    OUTPUT=$(abspath $(dir $@))/ $(abspath $@)
 
index aea2d91..16d629b 100644 (file)
@@ -80,6 +80,8 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg)
 
        error = 0;
 done:
+       if (error)
+               target_fname[0] = '\0';
        return error;
 }
 
@@ -108,15 +110,29 @@ static int hv_copy_data(struct hv_do_fcopy *cpmsg)
        return ret;
 }
 
+/*
+ * Reset target_fname to "" in the two below functions for hibernation: if
+ * the fcopy operation is aborted by hibernation, the daemon should remove the
+ * partially-copied file; to achieve this, the hv_utils driver always fakes a
+ * CANCEL_FCOPY message upon suspend, and later when the VM resumes back,
+ * the daemon calls hv_copy_cancel() to remove the file; if a file is copied
+ * successfully before suspend, hv_copy_finished() must reset target_fname to
+ * avoid that the file can be incorrectly removed upon resume, since the faked
+ * CANCEL_FCOPY message is spurious in this case.
+ */
 static int hv_copy_finished(void)
 {
        close(target_fd);
+       target_fname[0] = '\0';
        return 0;
 }
 static int hv_copy_cancel(void)
 {
        close(target_fd);
-       unlink(target_fname);
+       if (strlen(target_fname) > 0) {
+               unlink(target_fname);
+               target_fname[0] = '\0';
+       }
        return 0;
 
 }
@@ -131,7 +147,7 @@ void print_usage(char *argv[])
 
 int main(int argc, char *argv[])
 {
-       int fcopy_fd;
+       int fcopy_fd = -1;
        int error;
        int daemonize = 1, long_index = 0, opt;
        int version = FCOPY_CURRENT_VERSION;
@@ -141,7 +157,7 @@ int main(int argc, char *argv[])
                struct hv_do_fcopy copy;
                __u32 kernel_modver;
        } buffer = { };
-       int in_handshake = 1;
+       int in_handshake;
 
        static struct option long_options[] = {
                {"help",        no_argument,       0,  'h' },
@@ -170,6 +186,12 @@ int main(int argc, char *argv[])
        openlog("HV_FCOPY", 0, LOG_USER);
        syslog(LOG_INFO, "starting; pid is:%d", getpid());
 
+reopen_fcopy_fd:
+       if (fcopy_fd != -1)
+               close(fcopy_fd);
+       /* Remove any possible partially-copied file on error */
+       hv_copy_cancel();
+       in_handshake = 1;
        fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR);
 
        if (fcopy_fd < 0) {
@@ -196,7 +218,7 @@ int main(int argc, char *argv[])
                len = pread(fcopy_fd, &buffer, sizeof(buffer), 0);
                if (len < 0) {
                        syslog(LOG_ERR, "pread failed: %s", strerror(errno));
-                       exit(EXIT_FAILURE);
+                       goto reopen_fcopy_fd;
                }
 
                if (in_handshake) {
@@ -231,9 +253,14 @@ int main(int argc, char *argv[])
 
                }
 
+               /*
+                * pwrite() may return an error due to the faked CANCEL_FCOPY
+                * message upon hibernation. Ignore the error by resetting the
+                * dev file, i.e. closing and re-opening it.
+                */
                if (pwrite(fcopy_fd, &error, sizeof(int), 0) != sizeof(int)) {
                        syslog(LOG_ERR, "pwrite failed: %s", strerror(errno));
-                       exit(EXIT_FAILURE);
+                       goto reopen_fcopy_fd;
                }
        }
 }
index e9ef4ca..ee9c1bb 100644 (file)
@@ -76,7 +76,7 @@ enum {
        DNS
 };
 
-static int in_hand_shake = 1;
+static int in_hand_shake;
 
 static char *os_name = "";
 static char *os_major = "";
@@ -1360,7 +1360,7 @@ void print_usage(char *argv[])
 
 int main(int argc, char *argv[])
 {
-       int kvp_fd, len;
+       int kvp_fd = -1, len;
        int error;
        struct pollfd pfd;
        char    *p;
@@ -1400,14 +1400,6 @@ int main(int argc, char *argv[])
        openlog("KVP", 0, LOG_USER);
        syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
 
-       kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC);
-
-       if (kvp_fd < 0) {
-               syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
-                       errno, strerror(errno));
-               exit(EXIT_FAILURE);
-       }
-
        /*
         * Retrieve OS release information.
         */
@@ -1423,6 +1415,18 @@ int main(int argc, char *argv[])
                exit(EXIT_FAILURE);
        }
 
+reopen_kvp_fd:
+       if (kvp_fd != -1)
+               close(kvp_fd);
+       in_hand_shake = 1;
+       kvp_fd = open("/dev/vmbus/hv_kvp", O_RDWR | O_CLOEXEC);
+
+       if (kvp_fd < 0) {
+               syslog(LOG_ERR, "open /dev/vmbus/hv_kvp failed; error: %d %s",
+                      errno, strerror(errno));
+               exit(EXIT_FAILURE);
+       }
+
        /*
         * Register ourselves with the kernel.
         */
@@ -1456,9 +1460,7 @@ int main(int argc, char *argv[])
                if (len != sizeof(struct hv_kvp_msg)) {
                        syslog(LOG_ERR, "read failed; error:%d %s",
                               errno, strerror(errno));
-
-                       close(kvp_fd);
-                       return EXIT_FAILURE;
+                       goto reopen_kvp_fd;
                }
 
                /*
@@ -1617,13 +1619,17 @@ int main(int argc, char *argv[])
                        break;
                }
 
-               /* Send the value back to the kernel. */
+               /*
+                * Send the value back to the kernel. Note: the write() may
+                * return an error due to hibernation; we can ignore the error
+                * by resetting the dev file, i.e. closing and re-opening it.
+                */
 kvp_done:
                len = write(kvp_fd, hv_msg, sizeof(struct hv_kvp_msg));
                if (len != sizeof(struct hv_kvp_msg)) {
                        syslog(LOG_ERR, "write failed; error: %d %s", errno,
                               strerror(errno));
-                       exit(EXIT_FAILURE);
+                       goto reopen_kvp_fd;
                }
        }
 
index 92902a8..dd11187 100644 (file)
@@ -28,6 +28,8 @@
 #include <stdbool.h>
 #include <dirent.h>
 
+static bool fs_frozen;
+
 /* Don't use syslog() in the function since that can cause write to disk */
 static int vss_do_freeze(char *dir, unsigned int cmd)
 {
@@ -155,18 +157,27 @@ static int vss_operate(int operation)
                        continue;
                }
                error |= vss_do_freeze(ent->mnt_dir, cmd);
-               if (error && operation == VSS_OP_FREEZE)
-                       goto err;
+               if (operation == VSS_OP_FREEZE) {
+                       if (error)
+                               goto err;
+                       fs_frozen = true;
+               }
        }
 
        endmntent(mounts);
 
        if (root_seen) {
                error |= vss_do_freeze("/", cmd);
-               if (error && operation == VSS_OP_FREEZE)
-                       goto err;
+               if (operation == VSS_OP_FREEZE) {
+                       if (error)
+                               goto err;
+                       fs_frozen = true;
+               }
        }
 
+       if (operation == VSS_OP_THAW && !error)
+               fs_frozen = false;
+
        goto out;
 err:
        save_errno = errno;
@@ -175,6 +186,7 @@ err:
                endmntent(mounts);
        }
        vss_operate(VSS_OP_THAW);
+       fs_frozen = false;
        /* Call syslog after we thaw all filesystems */
        if (ent)
                syslog(LOG_ERR, "FREEZE of %s failed; error:%d %s",
@@ -196,13 +208,13 @@ void print_usage(char *argv[])
 
 int main(int argc, char *argv[])
 {
-       int vss_fd, len;
+       int vss_fd = -1, len;
        int error;
        struct pollfd pfd;
        int     op;
        struct hv_vss_msg vss_msg[1];
        int daemonize = 1, long_index = 0, opt;
-       int in_handshake = 1;
+       int in_handshake;
        __u32 kernel_modver;
 
        static struct option long_options[] = {
@@ -232,6 +244,18 @@ int main(int argc, char *argv[])
        openlog("Hyper-V VSS", 0, LOG_USER);
        syslog(LOG_INFO, "VSS starting; pid is:%d", getpid());
 
+reopen_vss_fd:
+       if (vss_fd != -1)
+               close(vss_fd);
+       if (fs_frozen) {
+               if (vss_operate(VSS_OP_THAW) || fs_frozen) {
+                       syslog(LOG_ERR, "failed to thaw file system: err=%d",
+                              errno);
+                       exit(EXIT_FAILURE);
+               }
+       }
+
+       in_handshake = 1;
        vss_fd = open("/dev/vmbus/hv_vss", O_RDWR);
        if (vss_fd < 0) {
                syslog(LOG_ERR, "open /dev/vmbus/hv_vss failed; error: %d %s",
@@ -284,8 +308,7 @@ int main(int argc, char *argv[])
                if (len != sizeof(struct hv_vss_msg)) {
                        syslog(LOG_ERR, "read failed; error:%d %s",
                               errno, strerror(errno));
-                       close(vss_fd);
-                       return EXIT_FAILURE;
+                       goto reopen_vss_fd;
                }
 
                op = vss_msg->vss_hdr.operation;
@@ -312,14 +335,18 @@ int main(int argc, char *argv[])
                default:
                        syslog(LOG_ERR, "Illegal op:%d\n", op);
                }
+
+               /*
+                * The write() may return an error due to the faked VSS_OP_THAW
+                * message upon hibernation. Ignore the error by resetting the
+                * dev file, i.e. closing and re-opening it.
+                */
                vss_msg->error = error;
                len = write(vss_fd, vss_msg, sizeof(struct hv_vss_msg));
                if (len != sizeof(struct hv_vss_msg)) {
                        syslog(LOG_ERR, "write failed; error: %d %s", errno,
                               strerror(errno));
-
-                       if (op == VSS_OP_FREEZE)
-                               vss_operate(VSS_OP_THAW);
+                       goto reopen_vss_fd;
                }
        }
 
index 140c836..5fca38f 100644 (file)
 #include <linux/bits.h>
 #include <linux/compiler.h>
 
-#define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
-#define BITS_TO_U64(nr)                DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
-#define BITS_TO_U32(nr)                DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
-#define BITS_TO_BYTES(nr)      DIV_ROUND_UP(nr, BITS_PER_BYTE)
+#define BITS_PER_TYPE(type)    (sizeof(type) * BITS_PER_BYTE)
+#define BITS_TO_LONGS(nr)      DIV_ROUND_UP(nr, BITS_PER_TYPE(long))
+#define BITS_TO_U64(nr)                DIV_ROUND_UP(nr, BITS_PER_TYPE(u64))
+#define BITS_TO_U32(nr)                DIV_ROUND_UP(nr, BITS_PER_TYPE(u32))
+#define BITS_TO_BYTES(nr)      DIV_ROUND_UP(nr, BITS_PER_TYPE(char))
 
 extern unsigned int __sw_hweight8(unsigned int w);
 extern unsigned int __sw_hweight16(unsigned int w);
index ede040c..2898cfd 100644 (file)
@@ -226,7 +226,7 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu,
                if (term->type != PERF_EVSEL__CONFIG_TERM_DRV_CFG)
                        continue;
 
-               sink = term->val.drv_cfg;
+               sink = term->val.str;
                snprintf(path, PATH_MAX, "sinks/%s", sink);
 
                ret = perf_pmu__scan_file(pmu, path, "%x", &hash);
index 4ac5674..29c793a 100644 (file)
@@ -131,7 +131,6 @@ int test__cpu_map_merge(struct test *test __maybe_unused, int subtest __maybe_un
        TEST_ASSERT_VAL("failed to merge map: bad nr", c->nr == 5);
        cpu_map__snprint(c, buf, sizeof(buf));
        TEST_ASSERT_VAL("failed to merge map: bad result", !strcmp(buf, "1-2,4-5,7"));
-       perf_cpu_map__put(a);
        perf_cpu_map__put(b);
        perf_cpu_map__put(c);
        return 0;
index a69e642..c8dc445 100644 (file)
@@ -808,12 +808,12 @@ static void apply_config_terms(struct evsel *evsel,
                                perf_evsel__reset_sample_bit(evsel, TIME);
                        break;
                case PERF_EVSEL__CONFIG_TERM_CALLGRAPH:
-                       callgraph_buf = term->val.callgraph;
+                       callgraph_buf = term->val.str;
                        break;
                case PERF_EVSEL__CONFIG_TERM_BRANCH:
-                       if (term->val.branch && strcmp(term->val.branch, "no")) {
+                       if (term->val.str && strcmp(term->val.str, "no")) {
                                perf_evsel__set_sample_bit(evsel, BRANCH_STACK);
-                               parse_branch_str(term->val.branch,
+                               parse_branch_str(term->val.str,
                                                 &attr->branch_sample_type);
                        } else
                                perf_evsel__reset_sample_bit(evsel, BRANCH_STACK);
@@ -1265,6 +1265,8 @@ static void perf_evsel__free_config_terms(struct evsel *evsel)
 
        list_for_each_entry_safe(term, h, &evsel->config_terms, list) {
                list_del_init(&term->list);
+               if (term->free_str)
+                       zfree(&term->val.str);
                free(term);
        }
 }
index 1f8d2fe..e026ab6 100644 (file)
@@ -32,22 +32,21 @@ enum evsel_term_type {
 struct perf_evsel_config_term {
        struct list_head      list;
        enum evsel_term_type  type;
+       bool                  free_str;
        union {
                u64           period;
                u64           freq;
                bool          time;
-               char          *callgraph;
-               char          *drv_cfg;
                u64           stack_user;
                int           max_stack;
                bool          inherit;
                bool          overwrite;
-               char          *branch;
                unsigned long max_events;
                bool          percore;
                bool          aux_output;
                u32           aux_sample_size;
                u64           cfg_chg;
+               char          *str;
        } val;
        bool weak;
 };
index fdd5bdd..f67960b 100644 (file)
@@ -549,6 +549,7 @@ void maps__insert(struct maps *maps, struct map *map)
 
                        if (maps_by_name == NULL) {
                                __maps__free_maps_by_name(maps);
+                               up_write(&maps->lock);
                                return;
                        }
 
index ed7c008..c01ba6f 100644 (file)
@@ -1219,8 +1219,7 @@ static int config_attr(struct perf_event_attr *attr,
 static int get_config_terms(struct list_head *head_config,
                            struct list_head *head_terms __maybe_unused)
 {
-#define ADD_CONFIG_TERM(__type, __name, __val)                 \
-do {                                                           \
+#define ADD_CONFIG_TERM(__type)                                        \
        struct perf_evsel_config_term *__t;                     \
                                                                \
        __t = zalloc(sizeof(*__t));                             \
@@ -1229,9 +1228,24 @@ do {                                                             \
                                                                \
        INIT_LIST_HEAD(&__t->list);                             \
        __t->type       = PERF_EVSEL__CONFIG_TERM_ ## __type;   \
-       __t->val.__name = __val;                                \
        __t->weak       = term->weak;                           \
-       list_add_tail(&__t->list, head_terms);                  \
+       list_add_tail(&__t->list, head_terms)
+
+#define ADD_CONFIG_TERM_VAL(__type, __name, __val)             \
+do {                                                           \
+       ADD_CONFIG_TERM(__type);                                \
+       __t->val.__name = __val;                                \
+} while (0)
+
+#define ADD_CONFIG_TERM_STR(__type, __val)                     \
+do {                                                           \
+       ADD_CONFIG_TERM(__type);                                \
+       __t->val.str = strdup(__val);                           \
+       if (!__t->val.str) {                                    \
+               zfree(&__t);                                    \
+               return -ENOMEM;                                 \
+       }                                                       \
+       __t->free_str = true;                                   \
 } while (0)
 
        struct parse_events_term *term;
@@ -1239,53 +1253,62 @@ do {                                                            \
        list_for_each_entry(term, head_config, list) {
                switch (term->type_term) {
                case PARSE_EVENTS__TERM_TYPE_SAMPLE_PERIOD:
-                       ADD_CONFIG_TERM(PERIOD, period, term->val.num);
+                       ADD_CONFIG_TERM_VAL(PERIOD, period, term->val.num);
                        break;
                case PARSE_EVENTS__TERM_TYPE_SAMPLE_FREQ:
-                       ADD_CONFIG_TERM(FREQ, freq, term->val.num);
+                       ADD_CONFIG_TERM_VAL(FREQ, freq, term->val.num);
                        break;
                case PARSE_EVENTS__TERM_TYPE_TIME:
-                       ADD_CONFIG_TERM(TIME, time, term->val.num);
+                       ADD_CONFIG_TERM_VAL(TIME, time, term->val.num);
                        break;
                case PARSE_EVENTS__TERM_TYPE_CALLGRAPH:
-                       ADD_CONFIG_TERM(CALLGRAPH, callgraph, term->val.str);
+                       ADD_CONFIG_TERM_STR(CALLGRAPH, term->val.str);
                        break;
                case PARSE_EVENTS__TERM_TYPE_BRANCH_SAMPLE_TYPE:
-                       ADD_CONFIG_TERM(BRANCH, branch, term->val.str);
+                       ADD_CONFIG_TERM_STR(BRANCH, term->val.str);
                        break;
                case PARSE_EVENTS__TERM_TYPE_STACKSIZE:
-                       ADD_CONFIG_TERM(STACK_USER, stack_user, term->val.num);
+                       ADD_CONFIG_TERM_VAL(STACK_USER, stack_user,
+                                           term->val.num);
                        break;
                case PARSE_EVENTS__TERM_TYPE_INHERIT:
-                       ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 1 : 0);
+                       ADD_CONFIG_TERM_VAL(INHERIT, inherit,
+                                           term->val.num ? 1 : 0);
                        break;
                case PARSE_EVENTS__TERM_TYPE_NOINHERIT:
-                       ADD_CONFIG_TERM(INHERIT, inherit, term->val.num ? 0 : 1);
+                       ADD_CONFIG_TERM_VAL(INHERIT, inherit,
+                                           term->val.num ? 0 : 1);
                        break;
                case PARSE_EVENTS__TERM_TYPE_MAX_STACK:
-                       ADD_CONFIG_TERM(MAX_STACK, max_stack, term->val.num);
+                       ADD_CONFIG_TERM_VAL(MAX_STACK, max_stack,
+                                           term->val.num);
                        break;
                case PARSE_EVENTS__TERM_TYPE_MAX_EVENTS:
-                       ADD_CONFIG_TERM(MAX_EVENTS, max_events, term->val.num);
+                       ADD_CONFIG_TERM_VAL(MAX_EVENTS, max_events,
+                                           term->val.num);
                        break;
                case PARSE_EVENTS__TERM_TYPE_OVERWRITE:
-                       ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 1 : 0);
+                       ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite,
+                                           term->val.num ? 1 : 0);
                        break;
                case PARSE_EVENTS__TERM_TYPE_NOOVERWRITE:
-                       ADD_CONFIG_TERM(OVERWRITE, overwrite, term->val.num ? 0 : 1);
+                       ADD_CONFIG_TERM_VAL(OVERWRITE, overwrite,
+                                           term->val.num ? 0 : 1);
                        break;
                case PARSE_EVENTS__TERM_TYPE_DRV_CFG:
-                       ADD_CONFIG_TERM(DRV_CFG, drv_cfg, term->val.str);
+                       ADD_CONFIG_TERM_STR(DRV_CFG, term->val.str);
                        break;
                case PARSE_EVENTS__TERM_TYPE_PERCORE:
-                       ADD_CONFIG_TERM(PERCORE, percore,
-                                       term->val.num ? true : false);
+                       ADD_CONFIG_TERM_VAL(PERCORE, percore,
+                                           term->val.num ? true : false);
                        break;
                case PARSE_EVENTS__TERM_TYPE_AUX_OUTPUT:
-                       ADD_CONFIG_TERM(AUX_OUTPUT, aux_output, term->val.num ? 1 : 0);
+                       ADD_CONFIG_TERM_VAL(AUX_OUTPUT, aux_output,
+                                           term->val.num ? 1 : 0);
                        break;
                case PARSE_EVENTS__TERM_TYPE_AUX_SAMPLE_SIZE:
-                       ADD_CONFIG_TERM(AUX_SAMPLE_SIZE, aux_sample_size, term->val.num);
+                       ADD_CONFIG_TERM_VAL(AUX_SAMPLE_SIZE, aux_sample_size,
+                                           term->val.num);
                        break;
                default:
                        break;
@@ -1322,7 +1345,7 @@ static int get_config_chgs(struct perf_pmu *pmu, struct list_head *head_config,
        }
 
        if (bits)
-               ADD_CONFIG_TERM(CFG_CHG, cfg_chg, bits);
+               ADD_CONFIG_TERM_VAL(CFG_CHG, cfg_chg, bits);
 
 #undef ADD_CONFIG_TERM
        return 0;
index c470c49..1c817ad 100644 (file)
@@ -303,7 +303,8 @@ static int convert_variable_type(Dwarf_Die *vr_die,
        char prefix;
 
        /* TODO: check all types */
-       if (cast && strcmp(cast, "string") != 0 && strcmp(cast, "x") != 0 &&
+       if (cast && strcmp(cast, "string") != 0 && strcmp(cast, "ustring") &&
+           strcmp(cast, "x") != 0 &&
            strcmp(cast, "s") != 0 && strcmp(cast, "u") != 0) {
                /* Non string type is OK */
                /* and respect signedness/hexadecimal cast */
index 6ccf6f6..5b7d6c1 100644 (file)
@@ -193,16 +193,30 @@ static void find_address_in_section(bfd *abfd, asection *section, void *data)
        bfd_vma pc, vma;
        bfd_size_type size;
        struct a2l_data *a2l = data;
+       flagword flags;
 
        if (a2l->found)
                return;
 
-       if ((bfd_get_section_flags(abfd, section) & SEC_ALLOC) == 0)
+#ifdef bfd_get_section_flags
+       flags = bfd_get_section_flags(abfd, section);
+#else
+       flags = bfd_section_flags(section);
+#endif
+       if ((flags & SEC_ALLOC) == 0)
                return;
 
        pc = a2l->addr;
+#ifdef bfd_get_section_vma
        vma = bfd_get_section_vma(abfd, section);
+#else
+       vma = bfd_section_vma(section);
+#endif
+#ifdef bfd_get_section_size
        size = bfd_get_section_size(section);
+#else
+       size = bfd_section_size(section);
+#endif
 
        if (pc < vma || pc >= vma + size)
                return;
diff --git a/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c b/tools/testing/selftests/bpf/prog_tests/sockmap_basic.c
new file mode 100644 (file)
index 0000000..07f5b46
--- /dev/null
@@ -0,0 +1,74 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright (c) 2020 Cloudflare
+
+#include "test_progs.h"
+
+static int connected_socket_v4(void)
+{
+       struct sockaddr_in addr = {
+               .sin_family = AF_INET,
+               .sin_port = htons(80),
+               .sin_addr = { inet_addr("127.0.0.1") },
+       };
+       socklen_t len = sizeof(addr);
+       int s, repair, err;
+
+       s = socket(AF_INET, SOCK_STREAM, 0);
+       if (CHECK_FAIL(s == -1))
+               goto error;
+
+       repair = TCP_REPAIR_ON;
+       err = setsockopt(s, SOL_TCP, TCP_REPAIR, &repair, sizeof(repair));
+       if (CHECK_FAIL(err))
+               goto error;
+
+       err = connect(s, (struct sockaddr *)&addr, len);
+       if (CHECK_FAIL(err))
+               goto error;
+
+       repair = TCP_REPAIR_OFF_NO_WP;
+       err = setsockopt(s, SOL_TCP, TCP_REPAIR, &repair, sizeof(repair));
+       if (CHECK_FAIL(err))
+               goto error;
+
+       return s;
+error:
+       perror(__func__);
+       close(s);
+       return -1;
+}
+
+/* Create a map, populate it with one socket, and free the map. */
+static void test_sockmap_create_update_free(enum bpf_map_type map_type)
+{
+       const int zero = 0;
+       int s, map, err;
+
+       s = connected_socket_v4();
+       if (CHECK_FAIL(s == -1))
+               return;
+
+       map = bpf_create_map(map_type, sizeof(int), sizeof(int), 1, 0);
+       if (CHECK_FAIL(map == -1)) {
+               perror("bpf_create_map");
+               goto out;
+       }
+
+       err = bpf_map_update_elem(map, &zero, &s, BPF_NOEXIST);
+       if (CHECK_FAIL(err)) {
+               perror("bpf_map_update");
+               goto out;
+       }
+
+out:
+       close(map);
+       close(s);
+}
+
+void test_sockmap_basic(void)
+{
+       if (test__start_subtest("sockmap create_update_free"))
+               test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKMAP);
+       if (test__start_subtest("sockhash create_update_free"))
+               test_sockmap_create_update_free(BPF_MAP_TYPE_SOCKHASH);
+}
index 1235f3d..1f6ccda 100644 (file)
@@ -46,7 +46,7 @@ void test_trampoline_count(void)
        const char *fentry_name = "fentry/__set_task_comm";
        const char *fexit_name = "fexit/__set_task_comm";
        const char *object = "test_trampoline_count.o";
-       struct inst inst[MAX_TRAMP_PROGS] = { 0 };
+       struct inst inst[MAX_TRAMP_PROGS] = {};
        int err, i = 0, duration = 0;
        struct bpf_object *obj;
        struct bpf_link *link;
index 45115f8..eab79b9 100755 (executable)
@@ -14,6 +14,7 @@ ALL_TESTS="
        ipv4_plen
        ipv4_replay
        ipv4_flush
+       ipv4_local_replace
        ipv6_add
        ipv6_metric
        ipv6_append_single
@@ -26,6 +27,7 @@ ALL_TESTS="
        ipv6_delete_multipath
        ipv6_replay_single
        ipv6_replay_multipath
+       ipv6_local_replace
 "
 NUM_NETIFS=0
 source $lib_dir/lib.sh
@@ -89,6 +91,43 @@ ipv4_flush()
        fib_ipv4_flush_test "testns1"
 }
 
+ipv4_local_replace()
+{
+       local ns="testns1"
+
+       RET=0
+
+       ip -n $ns link add name dummy1 type dummy
+       ip -n $ns link set dev dummy1 up
+
+       ip -n $ns route add table local 192.0.2.1/32 dev dummy1
+       fib4_trap_check $ns "table local 192.0.2.1/32 dev dummy1" false
+       check_err $? "Local table route not in hardware when should"
+
+       ip -n $ns route add table main 192.0.2.1/32 dev dummy1
+       fib4_trap_check $ns "table main 192.0.2.1/32 dev dummy1" true
+       check_err $? "Main table route in hardware when should not"
+
+       fib4_trap_check $ns "table local 192.0.2.1/32 dev dummy1" false
+       check_err $? "Local table route was replaced when should not"
+
+       # Test that local routes can replace routes in main table.
+       ip -n $ns route add table main 192.0.2.2/32 dev dummy1
+       fib4_trap_check $ns "table main 192.0.2.2/32 dev dummy1" false
+       check_err $? "Main table route not in hardware when should"
+
+       ip -n $ns route add table local 192.0.2.2/32 dev dummy1
+       fib4_trap_check $ns "table local 192.0.2.2/32 dev dummy1" false
+       check_err $? "Local table route did not replace route in main table when should"
+
+       fib4_trap_check $ns "table main 192.0.2.2/32 dev dummy1" true
+       check_err $? "Main table route was not replaced when should"
+
+       log_test "IPv4 local table route replacement"
+
+       ip -n $ns link del dev dummy1
+}
+
 ipv6_add()
 {
        fib_ipv6_add_test "testns1"
@@ -149,6 +188,43 @@ ipv6_replay_multipath()
        fib_ipv6_replay_multipath_test "testns1" "$DEVLINK_DEV"
 }
 
+ipv6_local_replace()
+{
+       local ns="testns1"
+
+       RET=0
+
+       ip -n $ns link add name dummy1 type dummy
+       ip -n $ns link set dev dummy1 up
+
+       ip -n $ns route add table local 2001:db8:1::1/128 dev dummy1
+       fib6_trap_check $ns "table local 2001:db8:1::1/128 dev dummy1" false
+       check_err $? "Local table route not in hardware when should"
+
+       ip -n $ns route add table main 2001:db8:1::1/128 dev dummy1
+       fib6_trap_check $ns "table main 2001:db8:1::1/128 dev dummy1" true
+       check_err $? "Main table route in hardware when should not"
+
+       fib6_trap_check $ns "table local 2001:db8:1::1/128 dev dummy1" false
+       check_err $? "Local table route was replaced when should not"
+
+       # Test that local routes can replace routes in main table.
+       ip -n $ns route add table main 2001:db8:1::2/128 dev dummy1
+       fib6_trap_check $ns "table main 2001:db8:1::2/128 dev dummy1" false
+       check_err $? "Main table route not in hardware when should"
+
+       ip -n $ns route add table local 2001:db8:1::2/128 dev dummy1
+       fib6_trap_check $ns "table local 2001:db8:1::2/128 dev dummy1" false
+       check_err $? "Local route route did not replace route in main table when should"
+
+       fib6_trap_check $ns "table main 2001:db8:1::2/128 dev dummy1" true
+       check_err $? "Main table route was not replaced when should"
+
+       log_test "IPv6 local table route replacement"
+
+       ip -n $ns link del dev dummy1
+}
+
 setup_prepare()
 {
        ip netns add testns1
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-syntax-errors.tc b/tools/testing/selftests/ftrace/test.d/trigger/trigger-hist-syntax-errors.tc
new file mode 100644 (file)
index 0000000..d44087a
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+# description: event trigger - test histogram parser errors
+
+if [ ! -f set_event -o ! -d events/kmem ]; then
+    echo "event tracing is not supported"
+    exit_unsupported
+fi
+
+if [ ! -f events/kmem/kmalloc/trigger ]; then
+    echo "event trigger is not supported"
+    exit_unsupported
+fi
+
+if [ ! -f events/kmem/kmalloc/hist ]; then
+    echo "hist trigger is not supported"
+    exit_unsupported
+fi
+
+[ -f error_log ] || exit_unsupported
+
+check_error() { # command-with-error-pos-by-^
+    ftrace_errlog_check 'hist:kmem:kmalloc' "$1" 'events/kmem/kmalloc/trigger'
+}
+
+check_error 'hist:keys=common_pid:vals=bytes_req:sort=common_pid,^junk'        # INVALID_SORT_FIELD
+check_error 'hist:keys=common_pid:vals=bytes_req:^sort='               # EMPTY_ASSIGNMENT
+check_error 'hist:keys=common_pid:vals=bytes_req:^sort=common_pid,'    # EMPTY_SORT_FIELD
+check_error 'hist:keys=common_pid:vals=bytes_req:sort=common_pid.^junk'        # INVALID_SORT_MODIFIER
+check_error 'hist:keys=common_pid:vals=bytes_req,bytes_alloc:^sort=common_pid,bytes_req,bytes_alloc'   # TOO_MANY_SORT_FIELDS
+
+exit 0
index 608fa83..67abc1d 100644 (file)
@@ -36,6 +36,7 @@ TEST_GEN_PROGS_aarch64 += kvm_create_max_vcpus
 
 TEST_GEN_PROGS_s390x = s390x/memop
 TEST_GEN_PROGS_s390x += s390x/sync_regs_test
+TEST_GEN_PROGS_s390x += s390x/resets
 TEST_GEN_PROGS_s390x += dirty_log_test
 TEST_GEN_PROGS_s390x += kvm_create_max_vcpus
 
index 29cccaf..ae0d14c 100644 (file)
@@ -125,6 +125,12 @@ void vcpu_sregs_set(struct kvm_vm *vm, uint32_t vcpuid,
                    struct kvm_sregs *sregs);
 int _vcpu_sregs_set(struct kvm_vm *vm, uint32_t vcpuid,
                    struct kvm_sregs *sregs);
+void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid,
+                 struct kvm_fpu *fpu);
+void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid,
+                 struct kvm_fpu *fpu);
+void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
+void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg);
 #ifdef __KVM_HAVE_VCPU_EVENTS
 void vcpu_events_get(struct kvm_vm *vm, uint32_t vcpuid,
                     struct kvm_vcpu_events *events);
index 41cf454..a6dd040 100644 (file)
@@ -1373,6 +1373,42 @@ int _vcpu_sregs_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_sregs *sregs)
        return ioctl(vcpu->fd, KVM_SET_SREGS, sregs);
 }
 
+void vcpu_fpu_get(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu)
+{
+       int ret;
+
+       ret = _vcpu_ioctl(vm, vcpuid, KVM_GET_FPU, fpu);
+       TEST_ASSERT(ret == 0, "KVM_GET_FPU failed, rc: %i errno: %i (%s)",
+                   ret, errno, strerror(errno));
+}
+
+void vcpu_fpu_set(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_fpu *fpu)
+{
+       int ret;
+
+       ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_FPU, fpu);
+       TEST_ASSERT(ret == 0, "KVM_SET_FPU failed, rc: %i errno: %i (%s)",
+                   ret, errno, strerror(errno));
+}
+
+void vcpu_get_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg)
+{
+       int ret;
+
+       ret = _vcpu_ioctl(vm, vcpuid, KVM_GET_ONE_REG, reg);
+       TEST_ASSERT(ret == 0, "KVM_GET_ONE_REG failed, rc: %i errno: %i (%s)",
+                   ret, errno, strerror(errno));
+}
+
+void vcpu_set_reg(struct kvm_vm *vm, uint32_t vcpuid, struct kvm_one_reg *reg)
+{
+       int ret;
+
+       ret = _vcpu_ioctl(vm, vcpuid, KVM_SET_ONE_REG, reg);
+       TEST_ASSERT(ret == 0, "KVM_SET_ONE_REG failed, rc: %i errno: %i (%s)",
+                   ret, errno, strerror(errno));
+}
+
 /*
  * VCPU Ioctl
  *
diff --git a/tools/testing/selftests/kvm/s390x/resets.c b/tools/testing/selftests/kvm/s390x/resets.c
new file mode 100644 (file)
index 0000000..1485bc6
--- /dev/null
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Test for s390x CPU resets
+ *
+ * Copyright (C) 2020, IBM
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+
+#define VCPU_ID 3
+#define LOCAL_IRQS 32
+
+struct kvm_s390_irq buf[VCPU_ID + LOCAL_IRQS];
+
+struct kvm_vm *vm;
+struct kvm_run *run;
+struct kvm_sync_regs *regs;
+static uint64_t regs_null[16];
+
+static uint64_t crs[16] = { 0x40000ULL,
+                           0x42000ULL,
+                           0, 0, 0, 0, 0,
+                           0x43000ULL,
+                           0, 0, 0, 0, 0,
+                           0x44000ULL,
+                           0, 0
+};
+
+static void guest_code_initial(void)
+{
+       /* Round toward 0 */
+       uint32_t fpc = 0x11;
+
+       /* Dirty registers */
+       asm volatile (
+               "       lctlg   0,15,%0\n"
+               "       sfpc    %1\n"
+               : : "Q" (crs), "d" (fpc));
+       GUEST_SYNC(0);
+}
+
+static void test_one_reg(uint64_t id, uint64_t value)
+{
+       struct kvm_one_reg reg;
+       uint64_t eval_reg;
+
+       reg.addr = (uintptr_t)&eval_reg;
+       reg.id = id;
+       vcpu_get_reg(vm, VCPU_ID, &reg);
+       TEST_ASSERT(eval_reg == value, "value == %s", value);
+}
+
+static void assert_noirq(void)
+{
+       struct kvm_s390_irq_state irq_state;
+       int irqs;
+
+       irq_state.len = sizeof(buf);
+       irq_state.buf = (unsigned long)buf;
+       irqs = _vcpu_ioctl(vm, VCPU_ID, KVM_S390_GET_IRQ_STATE, &irq_state);
+       /*
+        * irqs contains the number of retrieved interrupts. Any interrupt
+        * (notably, the emergency call interrupt we have injected) should
+        * be cleared by the resets, so this should be 0.
+        */
+       TEST_ASSERT(irqs >= 0, "Could not fetch IRQs: errno %d\n", errno);
+       TEST_ASSERT(!irqs, "IRQ pending");
+}
+
+static void assert_clear(void)
+{
+       struct kvm_sregs sregs;
+       struct kvm_regs regs;
+       struct kvm_fpu fpu;
+
+       vcpu_regs_get(vm, VCPU_ID, &regs);
+       TEST_ASSERT(!memcmp(&regs.gprs, regs_null, sizeof(regs.gprs)), "grs == 0");
+
+       vcpu_sregs_get(vm, VCPU_ID, &sregs);
+       TEST_ASSERT(!memcmp(&sregs.acrs, regs_null, sizeof(sregs.acrs)), "acrs == 0");
+
+       vcpu_fpu_get(vm, VCPU_ID, &fpu);
+       TEST_ASSERT(!memcmp(&fpu.fprs, regs_null, sizeof(fpu.fprs)), "fprs == 0");
+}
+
+static void assert_initial(void)
+{
+       struct kvm_sregs sregs;
+       struct kvm_fpu fpu;
+
+       vcpu_sregs_get(vm, VCPU_ID, &sregs);
+       TEST_ASSERT(sregs.crs[0] == 0xE0UL, "cr0 == 0xE0");
+       TEST_ASSERT(sregs.crs[14] == 0xC2000000UL, "cr14 == 0xC2000000");
+       TEST_ASSERT(!memcmp(&sregs.crs[1], regs_null, sizeof(sregs.crs[1]) * 12),
+                   "cr1-13 == 0");
+       TEST_ASSERT(sregs.crs[15] == 0, "cr15 == 0");
+
+       vcpu_fpu_get(vm, VCPU_ID, &fpu);
+       TEST_ASSERT(!fpu.fpc, "fpc == 0");
+
+       test_one_reg(KVM_REG_S390_GBEA, 1);
+       test_one_reg(KVM_REG_S390_PP, 0);
+       test_one_reg(KVM_REG_S390_TODPR, 0);
+       test_one_reg(KVM_REG_S390_CPU_TIMER, 0);
+       test_one_reg(KVM_REG_S390_CLOCK_COMP, 0);
+}
+
+static void assert_normal(void)
+{
+       test_one_reg(KVM_REG_S390_PFTOKEN, KVM_S390_PFAULT_TOKEN_INVALID);
+       assert_noirq();
+}
+
+static void inject_irq(int cpu_id)
+{
+       struct kvm_s390_irq_state irq_state;
+       struct kvm_s390_irq *irq = &buf[0];
+       int irqs;
+
+       /* Inject IRQ */
+       irq_state.len = sizeof(struct kvm_s390_irq);
+       irq_state.buf = (unsigned long)buf;
+       irq->type = KVM_S390_INT_EMERGENCY;
+       irq->u.emerg.code = cpu_id;
+       irqs = _vcpu_ioctl(vm, cpu_id, KVM_S390_SET_IRQ_STATE, &irq_state);
+       TEST_ASSERT(irqs >= 0, "Error injecting EMERGENCY IRQ errno %d\n", errno);
+}
+
+static void test_normal(void)
+{
+       printf("Testing normal reset\n");
+       /* Create VM */
+       vm = vm_create_default(VCPU_ID, 0, guest_code_initial);
+       run = vcpu_state(vm, VCPU_ID);
+       regs = &run->s.regs;
+
+       vcpu_run(vm, VCPU_ID);
+
+       inject_irq(VCPU_ID);
+
+       vcpu_ioctl(vm, VCPU_ID, KVM_S390_NORMAL_RESET, 0);
+       assert_normal();
+       kvm_vm_free(vm);
+}
+
+static void test_initial(void)
+{
+       printf("Testing initial reset\n");
+       vm = vm_create_default(VCPU_ID, 0, guest_code_initial);
+       run = vcpu_state(vm, VCPU_ID);
+       regs = &run->s.regs;
+
+       vcpu_run(vm, VCPU_ID);
+
+       inject_irq(VCPU_ID);
+
+       vcpu_ioctl(vm, VCPU_ID, KVM_S390_INITIAL_RESET, 0);
+       assert_normal();
+       assert_initial();
+       kvm_vm_free(vm);
+}
+
+static void test_clear(void)
+{
+       printf("Testing clear reset\n");
+       vm = vm_create_default(VCPU_ID, 0, guest_code_initial);
+       run = vcpu_state(vm, VCPU_ID);
+       regs = &run->s.regs;
+
+       vcpu_run(vm, VCPU_ID);
+
+       inject_irq(VCPU_ID);
+
+       vcpu_ioctl(vm, VCPU_ID, KVM_S390_CLEAR_RESET, 0);
+       assert_normal();
+       assert_initial();
+       assert_clear();
+       kvm_vm_free(vm);
+}
+
+int main(int argc, char *argv[])
+{
+       setbuf(stdout, NULL);   /* Tell stdout not to buffer its content */
+
+       test_initial();
+       if (kvm_check_cap(KVM_CAP_S390_VCPU_RESETS)) {
+               test_normal();
+               test_clear();
+       }
+       return 0;
+}
index 8aefd81..ecc52d4 100644 (file)
@@ -22,3 +22,4 @@ ipv6_flowlabel_mgr
 so_txtime
 tcp_fastopen_backup_key
 nettest
+fin_ack_lat
index a8e04d6..b569419 100644 (file)
@@ -11,6 +11,7 @@ TEST_PROGS += udpgso_bench.sh fib_rule_tests.sh msg_zerocopy.sh psock_snd.sh
 TEST_PROGS += udpgro_bench.sh udpgro.sh test_vxlan_under_vrf.sh reuseport_addr_any.sh
 TEST_PROGS += test_vxlan_fdb_changelink.sh so_txtime.sh ipv6_flowlabel.sh
 TEST_PROGS += tcp_fastopen_backup_key.sh fcnal-test.sh l2tp.sh traceroute.sh
+TEST_PROGS += fin_ack_lat.sh
 TEST_PROGS_EXTENDED := in_netns.sh
 TEST_GEN_FILES =  socket nettest
 TEST_GEN_FILES += psock_fanout psock_tpacket msg_zerocopy reuseport_addr_any
@@ -18,6 +19,7 @@ TEST_GEN_FILES += tcp_mmap tcp_inq psock_snd txring_overwrite
 TEST_GEN_FILES += udpgso udpgso_bench_tx udpgso_bench_rx ip_defrag
 TEST_GEN_FILES += so_txtime ipv6_flowlabel ipv6_flowlabel_mgr
 TEST_GEN_FILES += tcp_fastopen_backup_key
+TEST_GEN_FILES += fin_ack_lat
 TEST_GEN_PROGS = reuseport_bpf reuseport_bpf_cpu reuseport_bpf_numa
 TEST_GEN_PROGS += reuseport_dualstack reuseaddr_conflict tls
 
diff --git a/tools/testing/selftests/net/fin_ack_lat.c b/tools/testing/selftests/net/fin_ack_lat.c
new file mode 100644 (file)
index 0000000..7018749
--- /dev/null
@@ -0,0 +1,151 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <arpa/inet.h>
+#include <errno.h>
+#include <error.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <unistd.h>
+
+static int child_pid;
+
+static unsigned long timediff(struct timeval s, struct timeval e)
+{
+       unsigned long s_us, e_us;
+
+       s_us = s.tv_sec * 1000000 + s.tv_usec;
+       e_us = e.tv_sec * 1000000 + e.tv_usec;
+       if (s_us > e_us)
+               return 0;
+       return e_us - s_us;
+}
+
+static void client(int port)
+{
+       int sock = 0;
+       struct sockaddr_in addr, laddr;
+       socklen_t len = sizeof(laddr);
+       struct linger sl;
+       int flag = 1;
+       int buffer;
+       struct timeval start, end;
+       unsigned long lat, sum_lat = 0, nr_lat = 0;
+
+       while (1) {
+               gettimeofday(&start, NULL);
+
+               sock = socket(AF_INET, SOCK_STREAM, 0);
+               if (sock < 0)
+                       error(-1, errno, "socket creation");
+
+               sl.l_onoff = 1;
+               sl.l_linger = 0;
+               if (setsockopt(sock, SOL_SOCKET, SO_LINGER, &sl, sizeof(sl)))
+                       error(-1, errno, "setsockopt(linger)");
+
+               if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
+                                       &flag, sizeof(flag)))
+                       error(-1, errno, "setsockopt(nodelay)");
+
+               addr.sin_family = AF_INET;
+               addr.sin_port = htons(port);
+
+               if (inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr) <= 0)
+                       error(-1, errno, "inet_pton");
+
+               if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
+                       error(-1, errno, "connect");
+
+               send(sock, &buffer, sizeof(buffer), 0);
+               if (read(sock, &buffer, sizeof(buffer)) == -1)
+                       error(-1, errno, "waiting read");
+
+               gettimeofday(&end, NULL);
+               lat = timediff(start, end);
+               sum_lat += lat;
+               nr_lat++;
+               if (lat < 100000)
+                       goto close;
+
+               if (getsockname(sock, (struct sockaddr *)&laddr, &len) == -1)
+                       error(-1, errno, "getsockname");
+               printf("port: %d, lat: %lu, avg: %lu, nr: %lu\n",
+                               ntohs(laddr.sin_port), lat,
+                               sum_lat / nr_lat, nr_lat);
+close:
+               fflush(stdout);
+               close(sock);
+       }
+}
+
+static void server(int sock, struct sockaddr_in address)
+{
+       int accepted;
+       int addrlen = sizeof(address);
+       int buffer;
+
+       while (1) {
+               accepted = accept(sock, (struct sockaddr *)&address,
+                               (socklen_t *)&addrlen);
+               if (accepted < 0)
+                       error(-1, errno, "accept");
+
+               if (read(accepted, &buffer, sizeof(buffer)) == -1)
+                       error(-1, errno, "read");
+               close(accepted);
+       }
+}
+
+static void sig_handler(int signum)
+{
+       kill(SIGTERM, child_pid);
+       exit(0);
+}
+
+int main(int argc, char const *argv[])
+{
+       int sock;
+       int opt = 1;
+       struct sockaddr_in address;
+       struct sockaddr_in laddr;
+       socklen_t len = sizeof(laddr);
+
+       if (signal(SIGTERM, sig_handler) == SIG_ERR)
+               error(-1, errno, "signal");
+
+       sock = socket(AF_INET, SOCK_STREAM, 0);
+       if (sock < 0)
+               error(-1, errno, "socket");
+
+       if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT,
+                               &opt, sizeof(opt)) == -1)
+               error(-1, errno, "setsockopt");
+
+       address.sin_family = AF_INET;
+       address.sin_addr.s_addr = INADDR_ANY;
+       /* dynamically allocate unused port */
+       address.sin_port = 0;
+
+       if (bind(sock, (struct sockaddr *)&address, sizeof(address)) < 0)
+               error(-1, errno, "bind");
+
+       if (listen(sock, 3) < 0)
+               error(-1, errno, "listen");
+
+       if (getsockname(sock, (struct sockaddr *)&laddr, &len) == -1)
+               error(-1, errno, "getsockname");
+
+       fprintf(stderr, "server port: %d\n", ntohs(laddr.sin_port));
+       child_pid = fork();
+       if (!child_pid)
+               client(ntohs(laddr.sin_port));
+       else
+               server(sock, laddr);
+
+       return 0;
+}
diff --git a/tools/testing/selftests/net/fin_ack_lat.sh b/tools/testing/selftests/net/fin_ack_lat.sh
new file mode 100755 (executable)
index 0000000..a3ff6e0
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+#
+# Test latency spikes caused by FIN/ACK handling race.
+
+set +x
+set -e
+
+tmpfile=$(mktemp /tmp/fin_ack_latency.XXXX.log)
+
+cleanup() {
+       kill $(pidof fin_ack_lat)
+       rm -f $tmpfile
+}
+
+trap cleanup EXIT
+
+do_test() {
+       RUNTIME=$1
+
+       ./fin_ack_lat | tee $tmpfile &
+       PID=$!
+
+       sleep $RUNTIME
+       NR_SPIKES=$(wc -l $tmpfile | awk '{print $1}')
+       if [ $NR_SPIKES -gt 0 ]
+       then
+               echo "FAIL: $NR_SPIKES spikes detected"
+               return 1
+       fi
+       return 0
+}
+
+do_test "30"
+echo "test done"
index a3dccd8..99579c0 100644 (file)
@@ -634,6 +634,14 @@ static void check_getpeername_connect(int fd)
                        cfg_host, a, cfg_port, b);
 }
 
+static void maybe_close(int fd)
+{
+       unsigned int r = rand();
+
+       if (r & 1)
+               close(fd);
+}
+
 int main_loop_s(int listensock)
 {
        struct sockaddr_storage ss;
@@ -657,6 +665,7 @@ int main_loop_s(int listensock)
        salen = sizeof(ss);
        remotesock = accept(listensock, (struct sockaddr *)&ss, &salen);
        if (remotesock >= 0) {
+               maybe_close(listensock);
                check_sockaddr(pf, &ss, salen);
                check_getpeername(remotesock, &ss, salen);
 
index 26112ab..f52ed92 100755 (executable)
@@ -53,9 +53,13 @@ eeh_one_dev() {
        # is a no-op.
        echo $dev >/sys/kernel/debug/powerpc/eeh_dev_check
 
-       # Enforce a 30s timeout for recovery. Even the IPR, which is infamously
-       # slow to reset, should recover within 30s.
-       max_wait=30
+       # Default to a 60s timeout when waiting for a device to recover. This
+       # is an arbitrary default which can be overridden by setting the
+       # EEH_MAX_WAIT environmental variable when required.
+
+       # The current record holder for longest recovery time is:
+       #  "Adaptec Series 8 12G SAS/PCIe 3" at 39 seconds
+       max_wait=${EEH_MAX_WAIT:=60}
 
        for i in `seq 0 ${max_wait}` ; do
                if pe_ok $dev ; then
index ed15658..b9103c4 100644 (file)
@@ -3,7 +3,7 @@ noarg:
        $(MAKE) -C ../
 
 TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors wild_bctr \
-                 large_vm_fork_separation
+                 large_vm_fork_separation bad_accesses
 TEST_GEN_PROGS_EXTENDED := tlbie_test
 TEST_GEN_FILES := tempfile
 
@@ -16,6 +16,7 @@ $(OUTPUT)/prot_sao: ../utils.c
 
 $(OUTPUT)/wild_bctr: CFLAGS += -m64
 $(OUTPUT)/large_vm_fork_separation: CFLAGS += -m64
+$(OUTPUT)/bad_accesses: CFLAGS += -m64
 
 $(OUTPUT)/tempfile:
        dd if=/dev/zero of=$@ bs=64k count=1
diff --git a/tools/testing/selftests/powerpc/mm/bad_accesses.c b/tools/testing/selftests/powerpc/mm/bad_accesses.c
new file mode 100644 (file)
index 0000000..adc465f
--- /dev/null
@@ -0,0 +1,171 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2019, Michael Ellerman, IBM Corp.
+//
+// Test that out-of-bounds reads/writes behave as expected.
+
+#include <setjmp.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "utils.h"
+
+// Old distros (Ubuntu 16.04 at least) don't define this
+#ifndef SEGV_BNDERR
+#define SEGV_BNDERR    3
+#endif
+
+// 64-bit kernel is always here
+#define PAGE_OFFSET    (0xcul << 60)
+
+static unsigned long kernel_virt_end;
+
+static volatile int fault_code;
+static volatile unsigned long fault_addr;
+static jmp_buf setjmp_env;
+
+static void segv_handler(int n, siginfo_t *info, void *ctxt_v)
+{
+       fault_code = info->si_code;
+       fault_addr = (unsigned long)info->si_addr;
+       siglongjmp(setjmp_env, 1);
+}
+
+int bad_access(char *p, bool write)
+{
+       char x;
+
+       fault_code = 0;
+       fault_addr = 0;
+
+       if (sigsetjmp(setjmp_env, 1) == 0) {
+               if (write)
+                       *p = 1;
+               else
+                       x = *p;
+
+               printf("Bad - no SEGV! (%c)\n", x);
+               return 1;
+       }
+
+       // If we see MAPERR that means we took a page fault rather than an SLB
+       // miss. We only expect to take page faults for addresses within the
+       // valid kernel range.
+       FAIL_IF(fault_code == SEGV_MAPERR && \
+               (fault_addr < PAGE_OFFSET || fault_addr >= kernel_virt_end));
+
+       FAIL_IF(fault_code != SEGV_MAPERR && fault_code != SEGV_BNDERR);
+
+       return 0;
+}
+
+static int using_hash_mmu(bool *using_hash)
+{
+       char line[128];
+       FILE *f;
+       int rc;
+
+       f = fopen("/proc/cpuinfo", "r");
+       FAIL_IF(!f);
+
+       rc = 0;
+       while (fgets(line, sizeof(line), f) != NULL) {
+               if (strcmp(line, "MMU           : Hash\n") == 0) {
+                       *using_hash = true;
+                       goto out;
+               }
+
+               if (strcmp(line, "MMU           : Radix\n") == 0) {
+                       *using_hash = false;
+                       goto out;
+               }
+       }
+
+       rc = -1;
+out:
+       fclose(f);
+       return rc;
+}
+
+static int test(void)
+{
+       unsigned long i, j, addr, region_shift, page_shift, page_size;
+       struct sigaction sig;
+       bool hash_mmu;
+
+       sig = (struct sigaction) {
+               .sa_sigaction = segv_handler,
+               .sa_flags = SA_SIGINFO,
+       };
+
+       FAIL_IF(sigaction(SIGSEGV, &sig, NULL) != 0);
+
+       FAIL_IF(using_hash_mmu(&hash_mmu));
+
+       page_size = sysconf(_SC_PAGESIZE);
+       if (page_size == (64 * 1024))
+               page_shift = 16;
+       else
+               page_shift = 12;
+
+       if (page_size == (64 * 1024) || !hash_mmu) {
+               region_shift = 52;
+
+               // We have 7 512T regions (4 kernel linear, vmalloc, io, vmemmap)
+               kernel_virt_end = PAGE_OFFSET + (7 * (512ul << 40));
+       } else if (page_size == (4 * 1024) && hash_mmu) {
+               region_shift = 46;
+
+               // We have 7 64T regions (4 kernel linear, vmalloc, io, vmemmap)
+               kernel_virt_end = PAGE_OFFSET + (7 * (64ul << 40));
+       } else
+               FAIL_IF(true);
+
+       printf("Using %s MMU, PAGE_SIZE = %dKB start address 0x%016lx\n",
+              hash_mmu ? "hash" : "radix",
+              (1 << page_shift) >> 10,
+              1ul << region_shift);
+
+       // This generates access patterns like:
+       //   0x0010000000000000
+       //   0x0010000000010000
+       //   0x0010000000020000
+       //   ...
+       //   0x0014000000000000
+       //   0x0018000000000000
+       //   0x0020000000000000
+       //   0x0020000000010000
+       //   0x0020000000020000
+       //   ...
+       //   0xf400000000000000
+       //   0xf800000000000000
+
+       for (i = 1; i <= ((0xful << 60) >> region_shift); i++) {
+               for (j = page_shift - 1; j < 60; j++) {
+                       unsigned long base, delta;
+
+                       base  = i << region_shift;
+                       delta = 1ul << j;
+
+                       if (delta >= base)
+                               break;
+
+                       addr = (base | delta) & ~((1 << page_shift) - 1);
+
+                       FAIL_IF(bad_access((char *)addr, false));
+                       FAIL_IF(bad_access((char *)addr, true));
+               }
+       }
+
+       return 0;
+}
+
+int main(void)
+{
+       return test_harness(test, "bad_accesses");
+}
index 7deedbc..fc477df 100644 (file)
@@ -455,9 +455,8 @@ run_tests(pid_t child_pid, struct ppc_debug_info *dbginfo, bool dawr)
        if (dbginfo->features & PPC_DEBUG_FEATURE_DATA_BP_RANGE) {
                test_sethwdebug_exact(child_pid);
 
-               if (!is_8xx)
-                       test_sethwdebug_range_aligned(child_pid);
-               if (dawr && !is_8xx) {
+               test_sethwdebug_range_aligned(child_pid);
+               if (dawr || is_8xx) {
                        test_sethwdebug_range_unaligned(child_pid);
                        test_sethwdebug_range_unaligned_dar(child_pid);
                        test_sethwdebug_dawr_max_range(child_pid);
index e98c367..d34fe06 100644 (file)
@@ -54,7 +54,7 @@ class SubPlugin(TdcPlugin):
             shell=True,
             stdout=subprocess.PIPE,
             stderr=subprocess.PIPE,
-            env=ENVIR)
+            env=os.environ.copy())
         (rawout, serr) = proc.communicate()
 
         if proc.returncode != 0 and len(serr) > 0:
index 2e361ce..98a20fa 100644 (file)
@@ -6,6 +6,9 @@
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
@@ -25,6 +28,9 @@
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
@@ -44,6 +50,9 @@
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
@@ -63,6 +72,9 @@
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
@@ -82,6 +94,9 @@
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
             "filter",
             "basic"
         ],
+        "plugins": {
+            "requires": "nsPlugin"
+        },
         "setup": [
             "$TC qdisc add dev $DEV1 ingress"
         ],
index d5c85c7..f5ab1cd 100755 (executable)
@@ -38,9 +38,8 @@ ip0() { pretty 0 "ip $*"; ip -n $netns0 "$@"; }
 ip1() { pretty 1 "ip $*"; ip -n $netns1 "$@"; }
 ip2() { pretty 2 "ip $*"; ip -n $netns2 "$@"; }
 sleep() { read -t "$1" -N 1 || true; }
-waitiperf() { pretty "${1//*-}" "wait for iperf:5201"; while [[ $(ss -N "$1" -tlp 'sport = 5201') != *iperf3* ]]; do sleep 0.1; done; }
-waitncatudp() { pretty "${1//*-}" "wait for udp:1111"; while [[ $(ss -N "$1" -ulp 'sport = 1111') != *ncat* ]]; do sleep 0.1; done; }
-waitncattcp() { pretty "${1//*-}" "wait for tcp:1111"; while [[ $(ss -N "$1" -tlp 'sport = 1111') != *ncat* ]]; do sleep 0.1; done; }
+waitiperf() { pretty "${1//*-}" "wait for iperf:5201 pid $2"; while [[ $(ss -N "$1" -tlpH 'sport = 5201') != *\"iperf3\",pid=$2,fd=* ]]; do sleep 0.1; done; }
+waitncatudp() { pretty "${1//*-}" "wait for udp:1111 pid $2"; while [[ $(ss -N "$1" -ulpH 'sport = 1111') != *\"ncat\",pid=$2,fd=* ]]; do sleep 0.1; done; }
 waitiface() { pretty "${1//*-}" "wait for $2 to come up"; ip netns exec "$1" bash -c "while [[ \$(< \"/sys/class/net/$2/operstate\") != up ]]; do read -t .1 -N 0 || true; done;"; }
 
 cleanup() {
@@ -119,22 +118,22 @@ tests() {
 
        # TCP over IPv4
        n2 iperf3 -s -1 -B 192.168.241.2 &
-       waitiperf $netns2
+       waitiperf $netns2 $!
        n1 iperf3 -Z -t 3 -c 192.168.241.2
 
        # TCP over IPv6
        n1 iperf3 -s -1 -B fd00::1 &
-       waitiperf $netns1
+       waitiperf $netns1 $!
        n2 iperf3 -Z -t 3 -c fd00::1
 
        # UDP over IPv4
        n1 iperf3 -s -1 -B 192.168.241.1 &
-       waitiperf $netns1
+       waitiperf $netns1 $!
        n2 iperf3 -Z -t 3 -b 0 -u -c 192.168.241.1
 
        # UDP over IPv6
        n2 iperf3 -s -1 -B fd00::2 &
-       waitiperf $netns2
+       waitiperf $netns2 $!
        n1 iperf3 -Z -t 3 -b 0 -u -c fd00::2
 }
 
@@ -207,7 +206,7 @@ n1 ping -W 1 -c 1 192.168.241.2
 n1 wg set wg0 peer "$pub2" allowed-ips 192.168.241.0/24
 exec 4< <(n1 ncat -l -u -p 1111)
 ncat_pid=$!
-waitncatudp $netns1
+waitncatudp $netns1 $ncat_pid
 n2 ncat -u 192.168.241.1 1111 <<<"X"
 read -r -N 1 -t 1 out <&4 && [[ $out == "X" ]]
 kill $ncat_pid
@@ -216,7 +215,7 @@ n1 wg set wg0 peer "$more_specific_key" allowed-ips 192.168.241.2/32
 n2 wg set wg0 listen-port 9997
 exec 4< <(n1 ncat -l -u -p 1111)
 ncat_pid=$!
-waitncatudp $netns1
+waitncatudp $netns1 $ncat_pid
 n2 ncat -u 192.168.241.1 1111 <<<"X"
 ! read -r -N 1 -t 1 out <&4 || false
 kill $ncat_pid
@@ -516,6 +515,12 @@ n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0,10.0.0.0/8,100.0.0.0/10,172.16.
 n0 wg set wg0 peer "$pub2" allowed-ips 0.0.0.0/0
 n0 wg set wg0 peer "$pub2" allowed-ips ::/0,1700::/111,5000::/4,e000::/37,9000::/75
 n0 wg set wg0 peer "$pub2" allowed-ips ::/0
+n0 wg set wg0 peer "$pub2" remove
+low_order_points=( AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= 4Ot6fDtBuK4WVuP68Z/EatoJjeucMrH9hmIFFl9JuAA= X5yVvKNQjCSx0LFVnIPvWwREXMRYHI6G2CJO3dCfEVc= 7P///////////////////////////////////////38= 7f///////////////////////////////////////38= 7v///////////////////////////////////////38= )
+n0 wg set wg0 private-key /dev/null ${low_order_points[@]/#/peer }
+[[ -z $(n0 wg show wg0 peers) ]]
+n0 wg set wg0 private-key <(echo "$key1") ${low_order_points[@]/#/peer }
+[[ -z $(n0 wg show wg0 peers) ]]
 ip0 link del wg0
 
 declare -A objects
index b9c7270..5909e7e 100644 (file)
@@ -1,5 +1,4 @@
 CONFIG_LOCALVERSION="-debug"
-CONFIG_ENABLE_WARN_DEPRECATED=y
 CONFIG_ENABLE_MUST_CHECK=y
 CONFIG_FRAME_POINTER=y
 CONFIG_STACK_VALIDATION=y
index 529caab..bdf5bbd 100644 (file)
@@ -102,6 +102,7 @@ config RD_LZ4
 
 choice
        prompt "Built-in initramfs compression mode"
+       depends on INITRAMFS_SOURCE != ""
        help
          This option allows you to decide by which algorithm the builtin
          initramfs will be compressed.  Several compression algorithms are
index 244862b..b6081bb 100644 (file)
@@ -8,7 +8,7 @@
 # with unpack_to_rootfs(). Make size_append no-op.
 override size_append := :
 
-compress-$(CONFIG_INITRAMFS_COMPRESSION_NONE)  := shipped
+compress-y                                     := shipped
 compress-$(CONFIG_INITRAMFS_COMPRESSION_GZIP)  := gzip
 compress-$(CONFIG_INITRAMFS_COMPRESSION_BZIP2) := bzip2
 compress-$(CONFIG_INITRAMFS_COMPRESSION_LZMA)  := lzma
index 7e63a32..67ae2d5 100644 (file)
@@ -186,6 +186,7 @@ bool kvm_is_reserved_pfn(kvm_pfn_t pfn)
         */
        if (pfn_valid(pfn))
                return PageReserved(pfn_to_page(pfn)) &&
+                      !is_zero_pfn(pfn) &&
                       !kvm_is_zone_device_pfn(pfn);
 
        return true;